Home  >  Article  >  Backend Development  >  PHP extension development notes (1) Create array attributes of classes

PHP extension development notes (1) Create array attributes of classes

WBOY
WBOYOriginal
2016-08-08 09:23:261416browse

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.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:mongodb location searchNext article:mongodb location search