构建一个简单的php扩展

17 篇文章 0 订阅
9 篇文章 1 订阅

构建一个简单的php扩展

基本步骤

1  ./ext_skel --extname=myext

2  修改 config.m4文件
    去掉这几行前面的dl
    PHP_ARG_ENABLE(myext, whether to enable myext support,
        Make sure that the comment is aligned:
        [  --enable-myext           Enable myext support])
3  ./phpize生成扩展的模块

4 修改php_myext.h文件 新增一行(定义函数) PHP_FUNCTION(myext_self_concat); 

5 在mytexc.c中注册函数
    const zend_function_entry myext_functions[] = {
        PHP_FE(myext_self_concat,NULL)
        PHP_FE(confirm_myext_compiled,  NULL)   
        PHP_FE_END
    };

6 编写函数代码
    PHP_FUNCTION(myext_self_concat){
            char *arg = NULL;
            int arg_len, len;
            char *strg;
            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
                "s", &arg, &arg_len) == FAILURE) {
                return;
            }
            php_printf("myext_self_concat\n");
            RETURN_TRUE;
        }
7 ./configure && make && make install

8 在php的配置上加上扩展
    如果没有配置文件自己加一个比如我的/Users/kang/Documents/CProject/php566/lib/php.ini
    /Users/kang/Documents/CProject/software/bin/php -m 查看模块

9 运行扩展中的函数

    查看扩展的函数
     /Users/kang/Documents/CProject/software/bin/php -r "print_r(get_extension_funcs('myext'));"

     使用扩展的函数
    /Users/kang/Documents/CProject/software/bin/php -r  "myext_self_conc

构建一个简单的扩展需要掌握的知识

在网上找了一些知识,我觉得条目不够清楚,所以做了一个整理

对php的运行机制有个基本的理解

一切的php都从SAPI Server Application Programming Interface开始运行

在SAPI下面是各种模式 例如cli

php的执行流程,以我的扩展为例子:
    PHP_MINIT(ext_start1),
    PHP_MSHUTDOWN(ext_start1),
    PHP_RINIT(ext_start1),      
    PHP_RSHUTDOWN(ext_start1),

在多进程挂起的情况下可能是:

    PHP_MINIT 后不会PHP_RSHUTDOWN
    然后PHP_RINIT,加载脚本,执行程序,最后PHP_MSHUTDOWN

php的线程安全:
    抽象层:TSRM(Thread Safe Resource Management)
    线程安全模块和非线程模块有点不一样,我觉得主要是锁的问题,如果是多线程模式,
    资源需要加锁,抽象层就是锁等等进行了封装和集中处理

对php里面变量的表示有个基础的了解

每个变量都会做些类似的转换


struct _zval_struct {
    zvalue_value value; /* 变量的值 */
    zend_uint refcount__gc;
    zend_uchar type;    /* 变量当前的数据类型 */
    zend_uchar is_ref__gc;
};
typedef struct _zval_struct zval;

//在Zend/zend_types.h里定义的:
typedef unsigned int zend_uint;
typedef unsigned char zend_uchar;

typedef union _zvalue_value {
    long lval;  /* long value */
    double dval;    /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;  /* hash table value */
    zend_object_value obj;
} zvalue_value;

函数接收参数

zend_parse_parameters() 读取函数的值
TSRMLS_CC TSRM表示Thread Safe Resource Manager,可能跟线程安全有关

例如:
    zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"l", &foo) == FAILURE
    TSRMLS_CC  TSRM相关的宏---这个坑待我以后看看
    ZEND_NUM_ARGS()表示参数的个数

type_spec是格式化字符串,其常见的含义如下:
    参数   代表着的类型
    b   Boolean
    l   Integer 整型
    d   Floating point 浮点型
    s   String 字符串
    r   Resource 资源
    a   Array 数组
    o   Object instance 对象
    O   Object instance of a specified type 特定类型的对象
    z   Non-specific zval 任意类型~
    Z   zval**类型
    f   表示函数、方法名称,PHP5.1里貌似木有... ...


读取字符串变量:

    char *name;
    int name_len;

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

为变量分配内存

C语言原生函数 
void *malloc(size_t count);
void *calloc(size_t count);
void *realloc(void *ptr, size_t count);
void *strdup(void *ptr);
void free(void *ptr);

PHP内核封装后的函数 -- 带p表示永久性
void *emalloc(size_t count);
void *pemalloc(size_t count, char persistent);

void *ecalloc(size_t count);
void *pecalloc(size_t count, char persistent);

void *erealloc(void *ptr, size_t count);
void *perealloc(void *ptr, size_t count, char persistent);

void *estrdup(void *ptr);
void *pestrdup(void *ptr, char persistent);

void efree(void *ptr);
void pefree(void *ptr, char persistent);

返回结果

咱们可能任务返回结果一遍得这么写

ZEND_FUNCTION(sample_long_wrong)
{
    zval *retval;

    MAKE_STD_ZVAL(retval);
    ZVAL_LONG(retval, 42);

    return retval;
}

其实我们可以,php已经帮我们做好了上述的工作

PHP_FUNCTION(sample_long)
{
    RETVAL_LONG(42);
    //展开后相当与ZVAL_LONG(return_value, 42);
    return;
}

参考资料:

TIPI项目:http://www.php-internals.com/book/
挖路项目:http://www.cunmou.com/phpbook/
鸟哥的博客 http://www.laruence.com/2009/04/28/719.html
我的博客 http://www.beckbi.cn/?p=328
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值