Skip to main content
Created with Avocode.

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
    • CI/CD
    • Custom Consulting
    • Admin as a Service

    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

    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 Versio
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

14. PHP Classes and Objects

Objects in PHP are represented by zend_object structure immediately followed by plain array of properties (zvals). The first word of object is defined by zend_refcounted structure and used for reference-counting, then there is a pointer to class entry structure, then pointer to object handlers table (similar to Virtual Methods Table) and HashTable of undeclared properties. All the declared properties are followed and may be accessed by offset. 

php classes

There are two important dependent structures -zend_class_entry and zend_object_handlers. The first one keeps all the static information about the class, including its name, parent, methods, constants, properties — and their default values, values of static properties, etc. Here you can also see, a callback function “create_object”, that may be overridden to create something custom.

typedef struct zend_class_entry {
    char type;
    zend_string *name;
    zend_class_entry *parent;
    int refcount;
    uint32_t ce_flags;
    int default_properties_count;
    int default_static_members_count;
    zval *default_properties_table;
    zval *default_static_members_table;
    zval *static_members_table;
    HashTable function_table;
    HashTable properties_info;
    HashTable constants_table;
    zend_property_info **properties_info_table;
    ...
    zend_object* (*create_object)(zend_class_entry *class_type);
    ...
} zend_class_entry;

The second contains callback functions that determine the object behavior. We may create objects with custom behavior overriding this table and then changing some specific functions. This is advanced PHP internals knowledge. Now you can just read the list of handler names and guess what they are going to do.

typedef struct _zend_object_handlers {
    /* offset of real object header (usually zero) */
    int offset; /* object handlers */
    zend_object_free_obj_t free_obj; /* required */
    zend_object_dtor_obj_t dtor_obj; /* required */
    zend_object_clone_obj_t clone_obj; /* optional */
    zend_object_read_property_t read_property; /* required */
    zend_object_write_property_t write_property; /* required */
    zend_object_read_dimension_t read_dimension; /* required */
    zend_object_write_dimension_t write_dimension; /* required */
    zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */
    zend_object_get_t get; /* optional */
    zend_object_set_t set; /* optional */
    zend_object_has_property_t has_property; /* required */
    zend_object_unset_property_t unset_property; /* required */
    zend_object_has_dimension_t has_dimension; /* required */
    zend_object_unset_dimension_t unset_dimension; /* required */
    zend_object_get_properties_t get_properties; /* required */
    zend_object_get_method_t get_method; /* required */
    zend_object_call_method_t call_method; /* optional */
    zend_object_get_constructor_t get_constructor; /* required */
    zend_object_get_class_name_t get_class_name; /* required */
    zend_object_compare_t compare_objects; /* optional */
    zend_object_cast_t cast_object; /* optional */
    zend_object_count_elements_t count_elements; /* optional */
    zend_object_get_debug_info_t get_debug_info; /* optional */
    zend_object_get_closure_t get_closure; /* optional */
    zend_object_get_gc_t get_gc; /* required */
    zend_object_do_operation_t do_operation; /* optional */
    zend_object_compare_zvals_t compare; /* optional */
    zend_object_get_properties_for_t get_properties_for; /* optional */
} zend_object_handlers;

There are few APIs to work with PHP objects and classes. They are not compact, are not always consistent, and not well organized. I tried to collect the most important groups. The first one is the group of simple getter macros for basic internal object fields: 

  • Z_OBJ(zv) – returns pointer to zend_object structure from the zval (the type must be IS_OBJECT). 
  • Z_OBJCE(zv) – returns pointer to class entry of the given PHP object zval. 
  • Z_OBJ_HANDLE(zv) – returns object handle (unique number) of the given PHP object zval. 
  • Z_OBJ_HT(zv) – returns object handlers table of the given PHP object zval. 
  • Z_OBJ_HANDLER(zv, name) – returns named object handler from the table of the given PHP object zval. 
  • Z_OBJPROP(zv) – returns a HashTable with all properties (both declared and undeclared). Declared properties are stored as zvals of type IS_INDIRECT and the pointer to real value may be retrieved though Z_INDIRECT(zv) macro.

Few useful macros and functions to work with object or static class members: 

  • ZVAL_OBJ(zv, obj) – initializes zval with IS_OBJECT type and given zen_object. 
  • object_init(zv) – creates a new empty stdClass object and store it in zv. 
  • object_init_ex(zv, ce) – creates a new empty object of given class and store it in zv. 
  • zend_objects_new(ce) – creates and return object of the given class. 
  • zend_object_alloc(hdr_size, ce) – allocates a memory block for object with all the properties declared in given class. To create regular PHP objects, hdr_size must be equal to sizeof(zend_object). However, it’s possible to request more memory and use it for keeping additional C data (this will be discussed later). 
  • zend_object_std_init(obj, ce) – initializes fields of the given zend_object as an object of given class. 
  • zend_object_release(obj) – releases object (decrements reference-counter and destroy object if it reaches zero). 
  • add_property_...(zv, name, value) – a family of functions to add named property of different values to the given object. 
  • zend_read_property(ce, zv, name, len, silent, ret) – reads the value of static property, and returns pointer to zval or NULL. “ret“ is an address of zval where the property value should be stored (but not necessary). 
  • zend_read_static_property(ce, name, len, silent) – reads the value of static property, and returns pointer to zval or NULL. 
  • zend_update_property...(ce, zv, name, len, value) – a family of functions to assign values of different types to object property. 
  • zend_update_static_property...(ce, name, len, value) – a family of functions to assign values of different types to static property. 

Here are a few functions to declare internal classes and their elements: 

  • INIT_CLASS_ENTRYce, name, functions) – initializes class entry structure with given name and list of methods. 
  • zend_register_internal_class(ce) – registers the given class entry in the global class table and returns the address of the real class entry. 
  • zend_register_internal_class_ex(ce, parent_ce) – similar to zend_register_internal_class(), but also perform inheritance from the given “parent_ce”. 
  • zend_register_internal_interface(ce) – similar to zend_register_internal_class(ce), but registers interface instead. 
  • zend_class_implements(ce, num_interfaces, …) – makes class to implement given interfaces. 
  • zend_declare_class_constant_...(ce, name, len, value) – a family of function to declare class constants with different value types. 
  • zend_declare_property_...(ce, name, name, len, flags, value) – a family of functions to declare properties with different default value types. The “flags” argument may be used to declare public, protected, private and static properties.

Request PDF Version

Book traversal links for 14. PHP Classes and Objects

  • ‹ 13. Copy on Write
  • Writing PHP Extensions
  • 15. Using OOP in our Example Extension ›

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
  • Store
  • Downloads
    • MyZend Account
    • Plugins
    • Container Registry
  • Support
    • PHP Long-term Support
    • Knowledgebase
    • Documentation
  • 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