I've been working on and off for some time on a PHP extension (like PECL) which will serialize/unserialize PHP data structures to/from AMF3 format. Thanks to some help from Bradgrafelman, I've got the encoding functions all done except when it comes to serializing an object. I've tested my code and so far its serialization output is identical to that of Flash Player, which makes me proud. Also, it is fast -- about 20-200 times faster than equivalent serialization functions written in PHP.
I'm hoping now to finally implement serializing of objects. For these, AMF3 defines a few distinct scenarios that have different results:
i) This exact object has been encountered and serialized before so we just serialize a reference id that refers to the previously serialized object. I've got this taken care of.
ii) U29O-traits-ref : we have serialized an instance of this class before so we don't need to specify all the trait/property names all over again, we can just serialize the instance values and simply pass a reference for the trait/property names and sequence.
iii) U29O-traits-ext : the object to be serialized implements interface iExternalizable which handles serialization in PHP space. In this case my C code would need to invoke some function in PHP code space.
iv) U29O-traits : Used for both stdClass/generic object and classes that are not iExternalizable. There are two variants: a) object is an 'orthodox' instance of its class (i.e., no extra dynamic properties) or b) Object has dynamically assigned properties beyond those specified by its class.
So in the interest of finishing my encoding functions, I need to be able to accomplish a few things in my C code:
1) Determine if a particular object implements the iExternalizable interface. Since no such interface exists as part of native PHP, this will probably require me to implement code in my extension that defines a class in PHP space and somehow check an incoming object against that interface.
2) Possibly evoke a function defined in PHP space on a particular object and return the results to C space.
3) Determine if a particular object has only 'orthodox' properties or whether someone has dynamically assigned additional ones. Obviously, any stdClass objects are dynamic. This would provide an example of a custom class with dynamic properties:
class foo {
public $orthodox1 = 'orth1';
public $orthodox2 = 'orth2';
}
$v = new foo();
$v->dynamic = "I am a dynamic trait";
var_dump($v);
I've seen C code that, given an object, val, will use the C macros and/or functions to extract some representation of its type:
zend_class_entry *ce = Z_TYPE_P(val) == IS_OBJECT ? Z_OBJCE_P(val) : zend_standard_class_def;
And I've been looking at php_var_serialize_intern and php_var_serialize_class to try and am slowly understanding things, but I'm confused by concepts like an "incomplete class". For example, how does the return value incomplete_class get defined in php_var_serialize_class_name?
Perhaps most confusing at the moment for me is determining which properties are orthodox ones and which are dynamically allocated.
Any help would be much appreciated.