Okay, so num2name() converts the decimal representation of a natural number into its English representation. But there are two types of natural numbers. There are the cardinals (which are used for counting how many there are of something), and there are the ordinals (which are used for ordering). The fact is that English distinguishes between the two.
The cardinals run "zero", "one", "two", "three", and so forth. The ordinals are called (in order!) "first", "second", "third", "forth", etc. Note that in conventional English there is no ordinal corresponding to "zero". I need only mention zero-indexed arrays and you'll recognise some of the issues this difference can cause. There is a need for "zeroth" and so this function supplies it. (Plus, it's the obvious return value when 0 is passed in.
For convenience this function takes the same input as num2name().
num2ordinal($number)
{
$cardinal = num2name($number);
$replacements = array(
'one'=>'first',
'two'=>'second',
'three'=>'third',
'five'=>'fifth',
'nine'=>'ninth',
'twelve'=>'twelfth',
'y'=>'ieth');
foreach($replacements as $card=>$ord)
{
$len=-strlen($card);
if(substr($cardinal,$len)==$card)
return substr($cardinal,0,$len).$ord;
}
return $cardinal.'th';
}

)