Some more on Object Oriented PHP Extensions
Hopefully this is the last of the series on Object Oriented PHP Extensions. We left the last post with a question of how to create objects of a certain class in a method of another. This is especially relevant to the libixp extension, since classes like IxpStat, IxpQid and IxpCFid don’t have any constructors of their own, but are rather returned by methods of the IxpClient class. For example, an open() on IxpClient returns a IxpCFid, and the IxpQid is a property of the IxpStat and IxpCFid classes.
How do we get this to work? The helpful folks at #php.pecl on EFNet pointed me to a few examples in the existing PHP codebase that do this. First, you need to initialize an object - which essentially involves:
- Calling ALLOC_ZVAL on the zval.
- Setting the type to OBJECT using Z_TYPE_P.
- Calling object_init_ex(), which in turn will call the corresponding create_object method for the class entry.
- Setting the object’s refcount to 1.
Once you’ve done this, most often you’d need to set up certain properties on the class object. In libixp’s case, we need to populate IxpStat’s, IxpCFid’s or IxpQid’s properties. You can create a method to populate each classes properties. I use a set of PROP_SET macros to update properties correctly. Check out the code to clear things up - object_instantiate() is the generic method for allocating memory for a object, and the PHP_initialize() set of methods set properties for particular classes. These functions are used in almost all of IxpClient’s methods.
Before signing off, another quick word about using properties in your classes. If your class doesn’t use any properties, you can get away without doing any memory allocation at all, see the FliteTTS extension for an example of this. However, if you do plan on using properties, you need a bunch of methods for allocating memory to the HashTable that will hold the properties, as well as the structures that your class will use. You can create a generic method create_object_ex() that does this, and then create two more methods create_object_new() and create_object_clone() that will act as handlers for new object creation as well cloning. These handlers are set during the class initialization (most probably located or called in PHP_MINIT) by setting the create_object member on the class entry struct and the clone_obj member on the classes' standard object handlers.