PHP扩展开发 -- 命名空间

widuu 2015-5-12 PHP技术 2,241 0 喜欢 (1)

今天有朋友问我,如何在PHP开发中定义命名空间,其实这个很简单,你只是申明了一个类,而类的名字是 Namespace\StdClass ,而已。

1.官方提供的 INIT_NS_CLASS_ENTRY

我们可以使用 INIT_NS_CLASS_ENTRY 来注册,如下

INIT_NS_CLASS_ENTRY(ce,"Widuu","widuuweb",widuuweb_method);

它的核心实现是

INIT_CLASS_ENTRY(ce,ZEND_NS_NAME("Widuu","widuuweb"),widuuweb_method);

而 ZEND_NS_NAME 实现又是如下:

#define ZEND_NS_NAME   ns \\ name 

所以,其实本质上是:

INIT_CLASS_ENTRY(ce,"Widuu\\widuuweb",widuuweb_method);

简单例子

widuuweb.c

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

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_widuuweb.h"


ZEND_DECLARE_MODULE_GLOBALS(widuuweb);

static zend_class_entry *widuuweb_ce,ce;

/* {{{ widuuweb_functions[]
 *
 * Every user visible function must have an entry in widuuweb_functions[].
 */
const zend_function_entry widuuweb_functions[] = {
    PHP_FE_END    /* Must be the last line in widuuweb_functions[] */
};

const zend_function_entry widuuweb_method[] ={
    PHP_ME(widuuweb, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
      PHP_FE_END
};

PHP_METHOD(widuuweb,__construct){
    zval *name;
    if ( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"z",&name) == FAILURE ){
        return;
    }
    if( Z_TYPE_P(name)!= IS_STRING ){
        php_error_docref(NULL TSRMLS_CC,E_ERROR,"Type ERROR");
    }
    zend_update_property_string(widuuweb_ce,getThis(),"name",sizeof("name")-1,Z_STRVAL_P(name) TSRMLS_CC);
}
/* }}} */

/* {{{ widuuweb_module_entry
 */
zend_module_entry widuuweb_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    "widuuweb",
    widuuweb_functions,
    PHP_MINIT(widuuweb),
    PHP_MSHUTDOWN(widuuweb),
    NULL,        
    NULL,    
    PHP_MINFO(widuuweb),
#if ZEND_MODULE_API_NO >= 20010901
    PHP_WIDUUWEB_VERSION,
#endif
    PHP_MODULE_GLOBALS(widuuweb),
    NULL,    /* GINIT */
    NULL,    /* GSHUTDOWN */
    NULL,    /* RPOSTSHUTDOWN */
    STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */

#ifdef COMPILE_DL_WIDUUWEB
ZEND_GET_MODULE(widuuweb)
#endif

/* {{{ PHP_INI
 */

PHP_INI_BEGIN()
    STD_PHP_INI_BOOLEAN("widuuweb.use_namespace", "1" , PHP_INI_ALL, OnUpdateBool, use_namespace, zend_widuuweb_globals, widuuweb_globals)
PHP_INI_END();

/* }}} */


/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(widuuweb)
{

    REGISTER_INI_ENTRIES();
    // judge use namespace
    if (WIDUUWEB_G(use_namespace)){

        INIT_NS_CLASS_ENTRY(ce,"Widuu","widuuweb",widuuweb_method);
        /*{{{ same as
            INIT_CLASS_ENTRY(ce,ZEND_NS_NAME("Widuu","widuuweb"),widuuweb_method);
            #define ZEND_NS_NAME ns \\ name
            INIT_CLASS_ENTRY(ce,"Widuu\\widuuweb",widuuweb_method);
        }}} */
    }else{
        INIT_CLASS_ENTRY(ce,"widuuweb",widuuweb_method);
    }
    // register class
    widuuweb_ce = zend_register_internal_class(&ce TSRMLS_CC);
    zend_declare_property_string(widuuweb_ce,"name",strlen("name"),"widuu",ZEND_ACC_PUBLIC TSRMLS_CC);
    return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(widuuweb)
{
    UNREGISTER_INI_ENTRIES();
    return SUCCESS;
}
/* }}} */


/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(widuuweb)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "widuuweb support", "enabled");
    php_info_print_table_row(2,"Author","widuu<admin@widuu.com>");
    php_info_print_table_end();

    DISPLAY_INI_ENTRIES();

}
/* }}} */

php_widuuweb.h

#ifndef PHP_WIDUUWEB_H
#define PHP_WIDUUWEB_H

extern zend_module_entry widuuweb_module_entry;
#define phpext_widuuweb_ptr &widuuweb_module_entry

#define PHP_WIDUUWEB_VERSION "0.1.0" /* Replace with version number for your extension */

#ifdef PHP_WIN32
#    define PHP_WIDUUWEB_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#    define PHP_WIDUUWEB_API __attribute__ ((visibility("default")))
#else
#    define PHP_WIDUUWEB_API
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

PHP_MINIT_FUNCTION(widuuweb);
PHP_MSHUTDOWN_FUNCTION(widuuweb);
PHP_MINFO_FUNCTION(widuuweb);

PHP_METHOD(widuuweb,__construct);


ZEND_BEGIN_MODULE_GLOBALS(widuuweb)
    zend_bool  use_namespace;
ZEND_END_MODULE_GLOBALS(widuuweb)


#ifdef ZTS
#define WIDUUWEB_G(v) TSRMG(widuuweb_globals_id, zend_widuuweb_globals *, v)
#else
#define WIDUUWEB_G(v) (widuuweb_globals.v)
#endif

extern ZEND_DECLARE_MODULE_GLOBALS(widuuweb);

#endif    /* PHP_WIDUUWEB_H */

OK,就先简单说到这里。

转载请注明来自微度网络,本文标题:《PHP扩展开发 -- 命名空间》

喜欢 1 发布评论
Top