Interfaces
Declaring an interface is just like declaring any other class with the exception of a couple of steps. The first of these steps is declaring all of its methods as abstract, which can be done through using the PHP_ABSTRACT_ME() macro:
static function_entry php_sample3_iface_methods[] = { PHP_ABSTRACT_ME(Sample3_Interface, workerOne, NULL) PHP_ABSTRACT_ME(Sample3_Interface, workerTwo, NULL) PHP_ABSTRACT_ME(Sample3_Interface, workerThree, NULL) { NULL, NULL, NULL } };
Because these methods are abstract, no implementation methods need exist. You're already prepared for the second step, which is registration. Like registration of a real class, this begins with calls to INIT_CLASS_ENTRY and zend_register_internal_class.
When the class entry is available, the last step is to mark the class as an interface so that it can be implemented:
zend_class_entry *php_sample3_iface_entry; PHP_MINIT_FUNCTION(sample3) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Sample3_Interface", php_sample3_iface_methods); php_sample3_iface_entry = zend_register_internal_class(&ce TSRMLS_CC); php_sample3_iface_entry->ce_flags|= ZEND_ACC_INTERFACE; ...
Implementing Interfaces
Assuming you wanted your Sample3_SecondClass class to implement the Sample3_Interface interface, you'd need to implement each of the abstract methods listed as part of the interface within your class:
PHP_METHOD(Sample3_SecondClass,workerOne) { php_printf("Working Hard. "); } PHP_METHOD(Sample3_SecondClass,workerTwo) { php_printf("Hardly Working. "); } PHP_METHOD(Sample3_SecondClass,workerThree) { php_printf("Going wee-wee-wee all the way home. "); }
Then declare them in the php_sample3_sc_functions list:
PHP_ME(Sample3_SecondClass,workerOne,NULL,ZEND_ACC_PUBLIC) PHP_ME(Sample3_SecondClass,workerTwo,NULL,ZEND_ACC_PUBLIC) PHP_ME(Sample3_SecondClass,workerThree,NULL,ZEND_ACC_PUBLIC)
And finally, declare that your newly registered class implements the php_sample3_iface_entry interface:
PHP_MINIT_FUNCTION(sample3) { zend_class_entry ce; /* Register Interface */ INIT_CLASS_ENTRY(ce, "Sample3_Interface", php_sample3_iface_methods); php_sample3_iface_entry = zend_register_internal_class(&ce TSRMLS_CC); php_sample3_iface_entry->ce_flags|= ZEND_ACC_INTERFACE; /* Register Class implementing interface */ INIT_CLASS_ENTRY(ce, PHP_SAMPLE3_SC_NAME, php_sample3_sc_functions); php_sample3_sc_entry = zend_register_internal_class(&ce TSRMLS_CC); php_sample3_register_constants(php_sample3_sc_entry); zend_class_implements(php_sample3_sc_entry TSRMLS_CC, 1, php_sample3_iface_entry); return SUCCESS; }
If Sample3_SecondClass implemented other interfaces, such as ArrayAccess, its class entries could be added as additional parameters to zend_class_implements() by incrementing the one parameter to match the number of interfaces passed.
zend_class_implements(php_sample3_sc_entry TSRMLS_CC, 2, php_sample3_iface_entry, php_other_interface_entry);