2016-06-10 3 views
1

PHP 7 확장을 생성한다고 가정 해 봅시다 (C에서는 C++이 아니므로 PHP-CPP에 관한 답변을 원하지 않습니다). 그리고 PHP 객체를 만들고 싶습니다. Dog 그리고 변수 자체에 확장 기능을 제공하십시오.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로 작성된 확장에서이 작업을 수행 할 것입니다 ... 우리는이 같은 PHP 클래스가 있다고 가정하자? 이것은 가능한가?

답변

2

클래스의 예를 들어 설명 하겠지만이 링크는 github에 놓을 것입니다. 확장 기능을 만드는 방법에 대한 나머지 정보를 얻을 수있는 출발점이 될 것이라고 생각하기 때문입니다. 여기 https://github.com/twigphp/Twig/blob/1.x/ext/twig/twig.c

그리고

는 매우 자세한의 클래스 정의 코드와 매크로를 사용할 수 있으며 기능은 상용구 코드의 양을 줄이기 위해 호출하지만 난 그냥 방법을 설명하기 위해 노력하고있어 최선을 다해 모든 것을 할 수있는 최선의 방법을 보여주지 마십시오.

참고 사항 : 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; 
} 
/* }}} */