Getting AMFPHP to turn NaN into null

Annoyingly the NaN (not a number) value of Number objects in AS3 is often quite hard to translate into a server-side equivalent and ends up breaking AMFPHP, and apparently BlazeDS too.

Here is a simple modification that will make AMFPHP turn NaN into a PHP null value on de-serialization.  Unfortunately on the return journey – trying to return NaN to AS3 – there doesn’t seem to be anything clever that can be done and the Flash Player insists on turning undefined numbers into 0.  A glance through the AMF spec doesn’t reveal anything useful, and if you need this functionality you are best off creating a custom class wrapping the value of the number and including a isNotANumber:Boolean or something that you can examine and set on the server.

Anyway, here’s the code.  In AMFBaseDeserializer.php find the following function:

   1: function readDouble() {

   2:     $bytes = substr($this->raw_data, $this->current_byte, 8);

   3:     $this->current_byte += 8;

   4:     if ($this->isBigEndian) {

   5:          $bytes = strrev($bytes);

   6:     } 

   7:     $zz = unpack("dflt", $bytes); // unpack the bytes

   8:     

   9:     return $zz['flt']; // return the number from the associative array

  10: } 

and change the last line so it reads:

   1: function readDouble() {

   2:     $bytes = substr($this->raw_data, $this->current_byte, 8);

   3:     $this->current_byte += 8;

   4:     if ($this->isBigEndian) {

   5:          $bytes = strrev($bytes);

   6:     } 

   7:     $zz = unpack("dflt", $bytes); // unpack the bytes

   8:     

   9:     return ($zz['flt'] != 'NAN') ? $zz['flt'] : null; // return the number from the associative array

  10: } 

Hope that helps someone!

1 comment

  1. Thanks for saving my day. Better and PHP 5.3.4 compatible solution:
    return (is_nan($zz[‘flt’])) ? null : $zz[‘flt’];

Leave a Reply

Your email address will not be published. Required fields are marked *