Home > Article > Backend Development > PHP extension development notes (1) Create array attributes of classes
It is very easy to initialize a class, such as the code below
MYCLASS_PROTERTY_* This is related to the macro string of define
zend_class_entry *myclass_ce;
zend_function_entry myclass_methods[] = {
PHP_FE_END
};
PHP_MINIT_FUNCTION(myext)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "MyClass", myclass_methods);
myclass_ce = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_class_constant_string(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_VERSION), PHP_SLIM_VERSION);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_CONTAINER), ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_APPS), ZEND_ACC_STATIC|ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_NAME), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_ERROR), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_NOTFOUND), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_MIDDLEWARE), ZEND_ACC_PROTECTED TSRMLS_CC);
return SUCCESS;
}
The above codes are all simple properties.
When trying to initialize the attributes of an array for the class myclass, it failed. The code relative to PHP is as follows
classMyClass {
public $myArray = array();
}
/* 对应的C代码 */
zval *myArray;
MAKE_STD_ZVAL(myArray);
array_init(myArray);
zend_declare_property(myclass_ce, ZEND_STRL(MYCLASS_PROTERTY_NAME_MYCLASS), myArray, ZEND_ACC_PUBLICTSRMLS_CC);
No problem was found when the above C code was mutated. When new MyClass() was executed, There is a problem, the error is as follows:
Internal zval's can't be arrays, objects or resources
Look at the source code of zend as follows:
if (ce->type & ZEND_INTERNAL_CLASS) {
switch(Z_TYPE_P(property)) {
caseIS_ARRAY:
caseIS_CONSTANT_ARRAY:
caseIS_OBJECT:
caseIS_RESOURCE:
zend_error(E_CORE_ERROR, "Internalzval'scan'tbearrays, objectsorresources");
break;
default:
break;
}
}
When we call zend_register_internal_class, myclass_ce has been initialized to ZEND_INTERNAL_CLASS, and the myArray parameter of zend_declare_property at this time is of type IS_ARRAY. So this error occurred.
Why does such an error occur?
The result I got after searching is: http://grokbase.com/t/php/php-internals/07a4b14xvb/php-dev-how-declare-protected-array-property-at-internal-class-properly this It is the result of 2007. I am using the PHP5.4 version, and I still have this problem for the time being. The article also gives a method to implement array attributes in disguise, by implementing it in the constructor.
PHP_METHOD(myclass, __construct) {
zval *apps, *pThis;
pThis = getThis();
MAKE_STD_ZVAL(apps);
array_init(apps);
add_property_zval_ex(pThis, ZEND_STRL(SLIM_SLIM_PROTERTY_NAME_APPS), apps);
}
The corresponding php code for this implementation
classMyClass {function__construct() {$this->app = array();
}
}
The above introduces the PHP extension development notes (1) Array attributes of the created class, including aspects of the content. I hope it will be helpful to friends who are interested in PHP tutorials.