파라메터를 받아올 때는 zend_parse_parameters() 를 이용함.
파라메터의 종류는 다음과 같음.

PHP의 변수를 구성하는 zval 이 중요함. (copy on write)


type specification characters
b (Boolean) [zend_bool]
l  (Long) [long]
d (Double) [double]
s (String) [char*, int]
r (Resource) [zval*]
a (Array) [zval*]
o (Object - of any type) [zval*]
O (Object - of specific type, specified by class entry) [zval*]
h (HashTable) [HashTable*]
z (zval) [zval*]
f (function or array containing php method call info [returned as zend_fcall_info* and zend_fcall_info_cache*])

type specification modifiers
| (optional. 그러니까 파라메터를 넣든지 말든지 라는 뜻)
/ (be separated from calling parameter. 만약 원본 파라메터가 copy on write 레퍼런스라면 zval을 하나 더 만든다)
! (zval parameter[a, o, O, r, z]만 가능. NULL이 들어올 수 있다는 뜻)




아래는 각 파라메터를 받아 다루는 법에 대한 간단한 예제

stdafx.h 는 생략

php_myext.h
#ifndef PHP_MYEXT_H
#define PHP_MYEXT_H 1

#define PHP_MYEXT_VERSION "1.0"
#define PHP_MYEXT_EXTNAME "myext"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

extern "C" {
    #ifdef ZTS
    #include "TSRM.h"
    #endif
}


PHP_FUNCTION(myext_func_s);
PHP_FUNCTION(myext_func_l);
PHP_FUNCTION(myext_func_d);
PHP_FUNCTION(myext_func_b);
PHP_FUNCTION(myext_func_sl);
PHP_FUNCTION(myext_func_a);


extern zend_module_entry myext_module_entry;
#define phpext_myext_ptr &myext_module_enrty;

#endif




myext.cpp
#include "stdafx.h"

static function_entry myext_functions[] = {
    PHP_FE(myext_func_s, NULL)
    PHP_FE(myext_func_l, NULL)
    PHP_FE(myext_func_d, NULL)
    PHP_FE(myext_func_b, NULL)
    PHP_FE(myext_func_sl, NULL)
    PHP_FE(myext_func_a, NULL)
    PHP_FE(myext_func_var_dump, NULL)
    {NULL, NULL, NULL}
};

zend_module_entry myext_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_MYEXT_EXTNAME,
    myext_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#if ZEND_MODULE_API_NO >= 20010901
    PHP_MYEXT_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};

extern "C" {
    ZEND_GET_MODULE(myext)
}

// String
PHP_FUNCTION(myext_func_s)
{
    char* s;
    long len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &len) == FAILURE) {
        RETURN_NULL();
    }

    php_printf("String(%d) : %s\n", len, s);
}

// Long
PHP_FUNCTION(myext_func_l)
{
    long param;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &param) == FAILURE) {
        RETURN_NULL();
    }

    php_printf("Long : %d\n", param);
}

// Double
PHP_FUNCTION(myext_func_d)
{
    double param;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &param) == FAILURE) {
        RETURN_NULL();
    }

    php_printf("Double : %d\n", param);
}

// Boolean
PHP_FUNCTION(myext_func_b)
{
    zend_bool param;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &param) == FAILURE) {
        RETURN_NULL();
    }

    php_printf("Boolean : %s\n", param ? "True" : "False");
}

// String, Long(optional)
PHP_FUNCTION(myext_func_sl)
{
    char* s;
    long len;
    long param = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &s, &len, &param) == FAILURE) {
        RETURN_NULL();
    }

    if (param == 0) {
        php_printf("String(%d) : %s\n", len, s);
    }
    else {
        php_printf("String(%d) : %s , Long : %d\n", len, s, param);
    }
}

// Array
PHP_FUNCTION(myext_func_a)
{
    zval *arr, **data;
    HashTable *arr_hash;
    HashPosition pointer;
    int array_count;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
        RETURN_NULL();
    }

    arr_hash = Z_ARRVAL_P(arr);
    array_count = zend_hash_num_elements(arr_hash);
    php_printf("Array (%d)\n", array_count);

    for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
         zend_hash_get_current_data_ex(arr_hash, (void**)&data, &pointer) == SUCCESS;
         zend_hash_move_forward_ex(arr_hash, &pointer)) {
           zval temp;
           char* key;
           uint key_len;
           ulong index;

           if (zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) ==       HASH_KEY_IS_STRING) {
               php_printf("\t%s => ", key);
           }
           else {
               php_printf("\t%d => ", index);
           }

           temp = **data;
           zval_copy_ctor(&temp);
           convert_to_string(&temp);
           php_printf("%s\n", Z_STRVAL(temp));
           zval_dtor(&temp);
       }
}

// zval
PHP_FUNCTION(myext_func_var_dump)
{
    zval *param;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &param) == FAILURE) {
        RETURN_NULL();
    }

    switch (Z_TYPE_P(param)) {
        case IS_NULL:
            php_printf("param is NULL\n");
            break;
        case IS_BOOL:
            php_printf("param is Boolean: %s\n", Z_LVAL_P(param) ? "TRUE" : "FALSE");
            break;
        case IS_LONG:
            php_printf("param is Long: %ld\n", Z_LVAL_P(param));
            break;
        case IS_DOUBLE:
            php_printf("param is Double: %f\n", Z_DVAL_P(param));
            break;
        case IS_STRING:
            php_printf("param is String(%d): %s\n", Z_STRLEN_P(param), Z_STRVAL_P(param));
            break;
        case IS_RESOURCE:
            php_printf("param is Resource\n");
            break;
        case IS_ARRAY:
            php_printf("param is Array\n");
            break;
        case IS_OBJECT:
            php_printf("param is Object\n");
            break;
        default:
            php_printf("param is Unknown\n");
       }
}


















Posted by bloodguy
,