PHP扩展:处理类对象 我们假设我创建了一个PHP 7扩展(C,不是C++,我不想回答PHP CPP的所有答案),我想制作一个PHP对象,比如“代码>狗< /C>”,并在扩展本身中给出变量和函数。

PHP扩展:处理类对象 我们假设我创建了一个PHP 7扩展(C,不是C++,我不想回答PHP CPP的所有答案),我想制作一个PHP对象,比如“代码>狗< /C>”,并在扩展本身中给出变量和函数。,c,php-extension,C,Php Extension,假设我们有一个像这样的PHP类 class Dog { public name; public age; private color; private function play_ball() { echo $this->name . " is playing with a ball!"; } public function get_color() { $this->play_ball();

假设我们有一个像这样的PHP类

class Dog {
    public name;
    public age;
    private color;

    private function play_ball() {
        echo $this->name . " is playing with a ball!";
    }

    public function get_color() {
        $this->play_ball();
        return $this->color;
    }
}

在用C编写的扩展中,人们如何做到这一点?这可能吗?

我会给你一个这个类的例子,但是我会把这个链接放到github上,因为我认为它会给你一个起点,你可以从这里获得关于如何创建扩展的其余信息

这里是类定义代码,非常详细,可以使用宏和函数调用来减少样板代码的数量,但我只是试图解释如何做到这一点,而不是向您展示完成所有事情的最终最佳方法

请注意:我没有编译这段代码,尽管我确信它99%的准确率,也许你需要解决一些小问题,如果你有疑问,尽管问我

//  I won't include this file, but just look at the twig.c extension source code
//  It's mostly boilerplate and you just copy and paste what you need
#include "php_myanimals.h"

//  This is the "class entry" php will use to define your class
zend_class_entry *dog_ce;

#define DECLARE_MEMBER(type,name,value,access) \
    type(dog_ce, name, strlen(name), value, access TSRMLS_CC)

#define DECLARE_STRING(name,value,access) \
    DECLARE_MEMBER(zend_declare_property_string,name,value,access)

#define DECLARE_LONG(name,value,access) \
    DECLARE_MEMBER(zend_declare_property_long,name,value,access)

#define SET_PARAM(name,value) \
    zend_update_property(dog_ce, this_ptr, name, strlen(name), value TSRMLS_CC)

#define GET_PARAM(name) \
    zend_read_property(dog_ce, this_ptr, name, strlen(name), 1 TSRMLS_CC)

/* {{{ Method: Dog::__construct() */
PHP_METHOD(dog, __construct)
{
    zval *name = NULL;
    zval *colour = NULL;

    //  First look in the parameter list for a server string 
    //  The | means that all parameters afterwards, are optional
    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &name, &colour) == FAILURE)
    {
        EX_INVALID_ARG("MyAnimals\\Dog::__construct(string name, [string colour]), parameters were not valid");
    }

    SET_PARAM("name",name);
    SET_PARAM("colour",colour);
}
/* }}} */

/* {{{ Method: Dog::playBall) */
PHP_METHOD(dog, playBall)
{
    php_printf("%s is playing with a ball!", Z_STRVAL_P(GET_PARAM("name")));
}
/* }}} */

/* {{{ Method: bool Dog::getColour() */
PHP_METHOD(dog, getColour)
{
    //  yeah, the stupid zend engine programmers made a function
    //  that can take 0, 1 or 2 arguments, but if you want 3 or 4 args?
    //  then you have to use this enormous chunk of boilerplate code
    //  see: https://github.com/twigphp/Twig/blob/1.x/ext/twig/twig.c
    //  search for: TWIG_CALL_USER_FUNC_ARRAY

    //  You probably should wrap up this ugly shit in a function call
    //  But I've copied it directly here because it's easier
    zend_call_method(
        &this_ptr, Z_OBJCE_P(this_ptr), NULL, 
        //  CAREFUL! php methods are in lower case!!
        "playball", strlen("playball"),
        // this is zval *retval or NULL if you dont want a return value
        NULL,  
        // means zero parameters
        0, 
        // arg 1
        NULL,
        // arg 2 
        NULL 
        TSRMLS_CC
    );

    RETURN(GET_PARAM("colour"));
}
/* }}} */

ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1)
    ZEND_ARG_INFO(0, name)
    ZEND_ARG_INFO(0, colour)
ZEND_END_ARG_INFO()

const zend_function_entry dog_functions[] = {
    //  public methods
    PHP_ME(dog, __construct, arginfo_construct, ZEND_ACC_PUBLIC)
    PHP_ME(dog, getColour, NULL, ZEND_ACC_PUBLIC)

    //  protected methods
    PHP_ME(dog, playBall, arginfo_createmanager, ZEND_ACC_PROTECTED)

    PHP_FE_END
};

/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(MyAnimals)
{
    zend_class_entry entry;

    //  Creates a class like this \MyAnimals\Dog
    INIT_NS_CLASS_ENTRY(entry, "MyAnimals", "Dog", dog_functions);

    dog_ce = zend_register_internal_class(&entry TSRMLS_CC);

    //  Declare the state / error properties
    DECLARE_STRING("name", "", ZEND_ACC_PUBLIC);
    DECLARE_LONG("age", 0, ZEND_ACC_PRIVATE);
    DECLARE_STRING("colour", "", ZEND_ACC_PROTECTED);

    return SUCCESS;
}
/* }}} */