Skip to main content

Secondary Navigation

  • PHP Security Center
  • Blog
  • Store
  • Downloads
    • Downloads
    • Plugins
    • MyZend Account
  • Company
    • About Zend by Perforce
    • Careers at Perforce
    • Customers
    • Partners
    • Press
  • Contact
    • Contact Us
    • Request Pricing
    • Request Support
    • Subscribe
Home
Zend

Main Navigation - Mega Menu

  • Products

    Main Navigation - Mega Menu

    • ZendPHP
      PHP Runtime and Support
    • PHP LTS
      Patches for EOL PHP
    • ZendHQ
      Must-Have Extension for ZendPHP
    • Zend Server
      PHP Application Server
  • Services

    Main Navigation - Mega Menu

    • Service Overview
    • Migration Services
    • Audits
    • Custom Consulting
    • Admin as a Service
    • Zend Black Belt Services

    Services

    Innovate faster and cut risk with PHP experts from Zend Services.

    Explore Services

  • Solutions

    Main Navigation - Mega Menu

    • PHP Cloud Solutions
    • PHP Container Solutions
    • PHP Security Solutions
    • Windows Solutions
    • Hosting Provider Solutions

    Zend Solutions Cloud

    See How Zend Helps Leading Hosting Providers Keep Their Managed Sites on Secure PHP

    Read More

  • Training

    Main Navigation - Mega Menu

    • Training Overview
    • Zend PHP Certification

    Training

    Learn PHP from PHP experts with free, on-demand, and instructor led courses.

    Explore Training

  • Resources

    Main Navigation - Mega Menu

    • Explore Resources
    • Events & Webinars
    • Papers & Videos
    • Recorded Webinars
    • Blog
    Cloud Orchestration

    Orchestrating Your PHP Applications

    Watch Now
  • Support

    Main Navigation - Mega Menu

    • Explore Support
    • PHP Long-Term Support
    • Knowledgebase
    • Documentation
    • Download Software
    • Download Plugins
    • Request Support

    Support

    Submit support requests and browse self-service resources.

    Explore Support

  • Try Free
  • PHP Security Center
  • Blog
  • Store
  • Downloads

    Main Navigation - Mega Menu

    • Downloads
    • Plugins
    • MyZend Account
    • Downloads
    • Plugins
    • MyZend Account
  • Company

    Main Navigation - Mega Menu

    • About Zend by Perforce
    • Careers at Perforce
    • Customers
    • Partners
    • About Zend by Perforce
    • Careers at Perforce
    • Customers
    • Partners
  • Contact

    Main Navigation - Mega Menu

    • Contact Us
    • Request Support
    • Subscribe

TECHNICAL GUIDE

Writing PHP Extensions

Request PDF Version
Writing PHP Extensions
1. Setting up Your PHP Build Environment on Linux
2. Generating a PHP Extension Skeleton
3. Building and Installing a PHP Extension
4. Rebuilding Extensions for Production
5. Extension Skeleton File Content
6. Running PHP Extension Tests
7. Adding New Functionality
8. Basic PHP Structures
9. PHP Arrays
10. Catching Memory Leaks
11. PHP Memory Management
12. PHP References
13. Copy on Write
14. PHP Classes and Objects
15. Using OOP in our Example Extension
16. Embedding C Data into PHP Objects
17. Overriding Object Handlers
18. Answers to Common Extension Questions

16. Embedding C Data into PHP Objects

Let’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 Version

Book traversal links for 16. Embedding C Data into PHP Objects

  • ‹ 15. Using OOP in our Example Extension
  • Writing PHP Extensions
  • 17. Overriding Object Handlers ›

Footer menu

  • Products
    • ZendPHP
    • PHP Long-Term Support
    • ZendHQ
    • Zend Server
    • Laminas Enterprise Support
    • PHP Development Tools
  • Services
    • PHP Long-Term Support
    • Migration Services
    • Audits
    • CI/CD Services
    • Custom Consulting
    • Admin as a Service
  • Free Trials and Demos
    • ZendPHP Trial
    • Zend Server Trial
    • ZendHQ Demo
  • Training
  • Resources
    • PHP Security Center
    • Papers & Videos
    • Events & Webinars
    • Recorded Webinars
    • Blog
    • Case Studies
  • Hubs
    • PHP Versions Guide
    • Developing Web Apps With PHP
    • Guide to PHP and IBM i
    • PHP Security
  • Store
  • Downloads
    • MyZend Account
    • Plugins
    • Container Registry
  • Support
    • PHP Long-term Support
    • Knowledgebase
    • Documentation
    • Software End of Life Policy
  • Contact
    • Request Pricing
    • Request Support
    • Subscribe
  • Company
    • About Zend by Perforce
    • Careers at Perforce
    • Customers
    • Partners
    • Press
Home

Zend by Perforce © Perforce Software, Inc.
Terms of Use  |  Privacy Policy | Sitemap

Social Menu

  • Facebook
  • LinkedIn
  • Twitter
  • YouTube
  • RSS
Send Feedback