Writing PHP Extensions1. Setting up Your PHP Build Environment on Linux2. Generating a PHP Extension Skeleton3. Building and Installing a PHP Extension4. Rebuilding Extensions for Production5. Extension Skeleton File Content6. Running PHP Extension Tests7. Adding New Functionality8. Basic PHP Structures9. PHP Arrays10. Catching Memory Leaks11. PHP Memory Management12. PHP References13. Copy on Write14. PHP Classes and Objects15. Using OOP in our Example Extension16. Embedding C Data into PHP Objects17. Overriding Object Handlers18. Answers to Common Extension Questions16. Embedding C Data into PHP ObjectsLet’s convert our regular PHP $factor property into embedded C data. To do this, zend_object must be allocated in a special way. C data and zend_object must be allocated together: C data above the pointed address and zend_object below. This way, such custom objects may be simply used by PHP core as regular objects and we may get C data using negative offsets. Anyway, PHP core should at least know the real address of the allocated block to free it. And we may inform it about this negative offset overriding the corresponding field in object_handlers. So, we need to override object handlers table, and to do this we usea global variable of type “scaler_object_handlers”. (We will initialize it later.) We declare new type “scaler_t” that unites our C data and zend_object. (It’s possible to use many fields, of course.) zend_object must be the last element of the structure, because the PHP engine may also allocate memory for defined properties after it. (See the picture in the start of “PHP Classes and Objects” chapter.) We also define a macro Z_SCALER_P(), to perform pointer arithmetic and to get the address of our structure from the PHP object value, and a callback function scaler_new(), that creates objects of type Scale. static zend_object_handlers scaler_object_handlers; typedef struct scaler_t { zend_long factor; zend_object std; } scaler_t; #define Z_SCALER_P(zv) \ ((scaler_t*)((char*)(Z_OBJ_P(zv)) - XtOffsetOf(scaler_t, std))) zend_object *scaler_new(zend_class_entry *ce) { scaler_t *scaler = zend_object alloc(sizeof(scaler_t), ce); zend_object_std_init(&scaler->std, ce); scaler->std.handlers = &scaler_object_handlers; return &scaler->std; }This function allocates the necessary amount of memory, initializes the standard PHP part of the object, overrides default object handlers, and returns the pointer to the standard part of the object. The existing methods are converted to use new C field. They give the address of our custom object, and then use C data fields directly (no hash lookups, no type checks, conversions, etc). PHP_METHOD(Scaler, __construct) { scaler_t *scaler = Z_SCALER_P(ZEND_THIS); zend_long factor = DEFAULT_SCALE_FACTOR; // default value ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL Z_PARAM_LONG(factor) ZEND_PARSE_PARAMETERS_END(); scaler->factor = factor; } PHP_METHOD(Scaler, scale) { zval *x; scaler_t *scaler = Z_SCALER_P(ZEND_THIS); ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ZVAL(x) ZEND_PARSE_PARAMETERS_END(); do_scale_ref(x, scaler->factor); }In MINIT, we override the “create_object” callback, copy the default object handlers table to our own, and override the “offset” field (to inform the engine about special object layout). PHP_MINIT_FUNCTION(test) { zend_class_entry ce; REGISTER_INI_ENTRIES(); INIT_CLASS_ENTRY(ce, “Scaler”, scaler_functions); scaler_class_entry = zend_register_internal_class(&ce); scaler_class_entry->create_object = scaler_new; memcpy(&scaler_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); scaler_object_handlers.offset = XtOffsetOf(scaler_t, std); zend_declare_class_constant_long(scaler_class_entry, “DEFAULT_FACTOR”, sizeof(“DEFAULT_FACTOR”)-1, DEFAULT_SCALE_FACTOR); return SUCCESS; }Testing: $ php -r ‘$o = new Scaler(4); $x = 5; $o->scale($x); var_dump($x,$o);’ int(20) object(Scaler)#1 (0) { }Everything is fine, except that we don’t see the value of “factor” stored as C variable, but this is easy to fix. See the next section to learn how. Request PDF VersionBook traversal links for 16. Embedding C Data into PHP Objects‹ 15. Using OOP in our Example ExtensionWriting PHP Extensions17. Overriding Object Handlers ›