【问题标题】:Adding an array to a class in PHP extension将数组添加到 PHP 扩展中的类
【发布时间】:2016-06-11 18:06:53
【问题描述】:

我正在尝试创建一个具有类的 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);
}

【问题讨论】:

    标签: c php-extension


    【解决方案1】:

    你必须声明一个空的 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-11
      • 2014-11-25
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多