将数组添加到 PHP 扩展中的 class
Adding an array to a class in PHP extension
我正在尝试创建一个具有 class 的 PHP 扩展,其中一个元素应该是一个字符串数组。当我尝试像下面那样做时,当我取消注释我在 test_init_test()
中创建和实现数组的尝试时,我收到错误“PHP Fatal error: Internal zval's can't be arrays, objects or resources in Unknown on line 0
”。
我要么不了解如何创建数组,要么就是不了解 zend_declare_property
函数。我该怎么做?
#include "php.h"
#include "php_myextension.h"
#include "test.h"
zend_class_entry *test_ce_test;
static zend_function_entry test_methods[] = {
PHP_ME(Test, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
{NULL, NULL, NULL}
};
void test_init_test(TSRMLS_D) {
zend_class_entry ce;
// zval *cachedirs_array = emalloc(sizeof(zval));
// array_init(cachedirs_array);
INIT_CLASS_ENTRY(ce, "Test", test_methods);
test_ce_test = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_string(test_ce_test, "arch", sizeof("arch"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
// zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cachedirs_array, ZEND_ACC_PUBLIC TSRMLS_CC);
// zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cachedirs_array, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "dbpath", sizeof("dbpath"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "root", sizeof("root"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
}
PHP_METHOD(Test, __construct) {
char *rootpath;
char *dbpath;
size_t rp, dp;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &rootpath, &rp, &dbpath, &dp) == FAILURE) {
RETURN_NULL()
}
object_init_ex(return_value, test_ce_test);
zend_update_property_stringl(test_ce_test, getThis(), "root", sizeof("root"), rootpath, rp TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "dbpath", sizeof("dbpath"), dbpath, dp TSRMLS_CC);
}
您必须声明一个空的 zval,然后在构造函数中用数组更新它。
void test_init_test(TSRMLS_D) {
zend_class_entry ce;
zval *cd = (zval*)malloc(sizeof(zval)); /* empty zval */
INIT_CLASS_ENTRY(ce, "Test", test_methods);
test_ce_test = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_string(test_ce_test, "arch", sizeof("arch"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cd, ZEND_ACC_PUBLIC TSRMLS_CC); /* declare with empty zval */
zend_declare_property_string(test_ce_test, "dbpath", sizeof("dbpath"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "root", sizeof("root"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
}
PHP_METHOD(Test, __construct) {
char *rootpath;
char *dbpath;
size_t rp, dp;
/* create zval */
zval cd;
/* init array */
array_init(&cd);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &rootpath, &rp, &dbpath, &dp) == FAILURE) {
RETURN_NULL()
}
object_init_ex(return_value, test_ce_test);
/* update property with new array */
zend_update_property(alpm_ce_handle, getThis(), "cachedirs", sizeof("cachedirs") - 1, &cd TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "root", sizeof("root"), rootpath, rp TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "dbpath", sizeof("dbpath"), dbpath, dp TSRMLS_CC);
}
我正在尝试创建一个具有 class 的 PHP 扩展,其中一个元素应该是一个字符串数组。当我尝试像下面那样做时,当我取消注释我在 test_init_test()
中创建和实现数组的尝试时,我收到错误“PHP Fatal error: Internal zval's can't be arrays, objects or resources in Unknown on line 0
”。
我要么不了解如何创建数组,要么就是不了解 zend_declare_property
函数。我该怎么做?
#include "php.h"
#include "php_myextension.h"
#include "test.h"
zend_class_entry *test_ce_test;
static zend_function_entry test_methods[] = {
PHP_ME(Test, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
{NULL, NULL, NULL}
};
void test_init_test(TSRMLS_D) {
zend_class_entry ce;
// zval *cachedirs_array = emalloc(sizeof(zval));
// array_init(cachedirs_array);
INIT_CLASS_ENTRY(ce, "Test", test_methods);
test_ce_test = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_string(test_ce_test, "arch", sizeof("arch"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
// zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cachedirs_array, ZEND_ACC_PUBLIC TSRMLS_CC);
// zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cachedirs_array, ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "dbpath", sizeof("dbpath"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "root", sizeof("root"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
}
PHP_METHOD(Test, __construct) {
char *rootpath;
char *dbpath;
size_t rp, dp;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &rootpath, &rp, &dbpath, &dp) == FAILURE) {
RETURN_NULL()
}
object_init_ex(return_value, test_ce_test);
zend_update_property_stringl(test_ce_test, getThis(), "root", sizeof("root"), rootpath, rp TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "dbpath", sizeof("dbpath"), dbpath, dp TSRMLS_CC);
}
您必须声明一个空的 zval,然后在构造函数中用数组更新它。
void test_init_test(TSRMLS_D) {
zend_class_entry ce;
zval *cd = (zval*)malloc(sizeof(zval)); /* empty zval */
INIT_CLASS_ENTRY(ce, "Test", test_methods);
test_ce_test = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_string(test_ce_test, "arch", sizeof("arch"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property(test_ce_test, "cachedirs", sizeof("cachedirs"), cd, ZEND_ACC_PUBLIC TSRMLS_CC); /* declare with empty zval */
zend_declare_property_string(test_ce_test, "dbpath", sizeof("dbpath"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_string(test_ce_test, "root", sizeof("root"), "", ZEND_ACC_PUBLIC TSRMLS_CC);
}
PHP_METHOD(Test, __construct) {
char *rootpath;
char *dbpath;
size_t rp, dp;
/* create zval */
zval cd;
/* init array */
array_init(&cd);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &rootpath, &rp, &dbpath, &dp) == FAILURE) {
RETURN_NULL()
}
object_init_ex(return_value, test_ce_test);
/* update property with new array */
zend_update_property(alpm_ce_handle, getThis(), "cachedirs", sizeof("cachedirs") - 1, &cd TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "root", sizeof("root"), rootpath, rp TSRMLS_CC);
zend_update_property_stringl(test_ce_test, getThis(), "dbpath", sizeof("dbpath"), dbpath, dp TSRMLS_CC);
}