`
simohayha
  • 浏览: 1401043 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

php的c扩展

阅读更多
在php中最核心的一个数据结构就是这个:

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;


struct _zval_struct {
	/* Variable information */
	zvalue_value value;		/* value */
	zend_uint refcount;
	zend_uchar type;	/* active type */
	zend_uchar is_ref;
};


这个数据结构也就是php中的每个数据类型在下层c语言中的表示。可以看到_zval_struct 结构体第一个字段是一个联合体,他来存储实际的值,这些值可以为long,double,字符串,hashtable(也就是php中的数组)和对象。而第2个参数是个引用计数,第三个参数是当前的类型。

也就是说php中的每个类型实际都是一个 struct _zval_struct类型。


1 首先进入php的源码目录下的ext文件夹,然后运行下面的命令,这样将会生成一个my_module的文件夹。:

./ext_skel --extname=my_module


2 然后在my_module.h里面声明你的php函数名:

PHP_FUNCTION(my_function);


2 在my_module.c文件的my_module_functions(这里的module就是你所创建的扩展模块名字)加入你所要写的php方法名:

PHP_FE(my_function,	NULL)


3 接下来就实现PHP_FUNCTION(my_function)。

首先 参数的解析,当传递进来的php的类型和c的类型之间的转换:

这里要用到的函数是:
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);


其中的php类型和c类型的对应如下:

引用
l - long

d - double

s - string (with possible null bytes) and its length

b - boolean

r - resource, stored in zval*

a - array, stored in zval*

o - object (of any class), stored in zval*

O - object (of class specified by class entry), stored in zval*

z - the actual zval*


这边就看到了,这里的zval也就是一开始介绍的那个php的类型结构体。


这边还可以使用三个符号:

| - 这个也就是或者的意思

/ -将会提供当前参数的一个副本。

! - 这个符号他必须进跟在a, o, O, r, z 的后面 ,也就是说当传递进来的参数为NULL的时候,我们pass的那个指针也会被NULL。
例子:

/* 得到一个long,string和一个zval */
long l;
char *s;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                          "lsz", &l, &s, &s_len, &param) == FAILURE) {
    return;
}

/*传递进来的为一个对象或者一个double */
zval *obj;
double d = 0.5;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                          "O|d", &obj, my_ce, &d) == FAILURE) {
    return;
}

/* 传递进来的参数为NULL或者一个对象和一个数组 */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!a", &obj, &arr) == FAILURE) {
    return;
}

/* 得到一个数组 */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &arr) == FAILURE) {
    return;
}

/*得到前三个参数 */
zval *z;
zend_bool b;
zval *r;
if (zend_parse_parameters(3, "zbr!", &z, &b, &r) == FAILURE) {
    return;
}




当我们传递进来的为一个数组的时候我们该如何遍历这个数组呢,看下面的代码:

zval *param;
        HashPosition pos;
        zval  **data_value;
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &(param)) == FAILURE) {
    		RETURN_FALSE;
    	}
//遍历数组.
        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(param), &pos);
		 zend_hash_get_current_data_ex(Z_ARRVAL_P(param), (void **)&data_value, &pos) == SUCCESS;
		 zend_hash_move_forward_ex(Z_ARRVAL_P(param), &pos))
        {
            //现在数组里面的值就存储在data_value这个指针里面,我们可以通过对他解引用来提取值,比如假设有个元素是long的,那么我们就可以这样来取(就是根据一开头介绍的那个数据结构来取):

long temp=(*data_value)->value.lval;
        }


接下来是返回值的问题,这里定义了好几个宏:



RETURN_RESOURCE(int r)
RETURN_BOOL(int b) 	
RETURN_NULL( ) 
RETURN_LONG(int l) 	
RETURN_DOUBLE(double d) 	
RETURN_STRING(char *s, int dup) 	
RETURN_STRINGL(char *s, int l, int dup) 	
RETURN_EMPTY_STRING( ) 	
RETURN_FALSE 	
RETURN_TRUE 


比如我要返回个字符串,可以这么写:

 RETURN_STRING("banana", 1);


这里讲下返回一个数组的问题,下面的代码是返回一个嵌套数组:

zval *param:

array_init(param);
//return_value是一个全局的变量(我是这么理解的)
array_init(return_value);
add_index_string(param, 0, "sad",1);
add_index_zval(return_value,0, param);



PS:更详细的还是要看ext目录下面的那些扩展实例
3
0
分享到:
评论

相关推荐

    简单高性能优雅的phpc扩展框架

    【标题】"简单高性能优雅的phpc扩展框架"所指的是一个专门为PHP设计的C扩展框架,旨在提升PHP应用的性能并提供简洁优雅的编程体验。C扩展是将PHP功能用C语言编写,然后编译为PHP可以调用的模块,这样能够利用C语言的...

    一个 PHP C 扩展,可用于在Excel 2007及以上版本XLSX文件中写入多个工作表的文本,数字,公式和超链接

    由于是C语言编写的扩展,xlswriter的运行速度远超纯PHP实现的解决方案,为大型数据导出提供了可能。 使用xlswriter,开发者可以轻松地实现以下功能: 1. **文本写入**:可以在指定的工作表中插入任意文本,支持...

    使用c语言开发php扩展教程

    在本文中,我们将深入探讨如何使用C语言开发PHP扩展,并将其整合到PHP环境中。这是一个涉及多步骤的过程,从设置开发环境到编写C代码并最终在PHP中调用这些扩展。 首先,我们需要建立开发环境。这包括搭建PHP开发...

    如何用C语言编写一个PHP的C扩展.zip

    本教程将详细介绍如何用C语言为PHP编写C扩展。 首先,我们需要理解C扩展的基本原理。PHP的内核是用C编写的,因此我们可以利用C语言直接与PHP引擎交互,创建新的函数、类或模块。C扩展通常用于实现那些在PHP原生语法...

    基于PHP的Leevel高性能开源PHPC扩展开发框架alpha.2源码.zip

    Leevel是一个专为PHP设计的高性能开源框架,其核心特性在于使用C语言编写的PHP扩展,以提升PHP应用的运行效率。Alpha.2版本代表这是一个仍在早期开发阶段的版本,可能包含新功能、优化和bug修复。从提供的压缩包文件...

    使用C语言来扩展PHP,写PHP扩展dll

    ### 使用C语言扩展PHP:构建PHP扩展DLL #### 前言 随着PHP的应用范围不断扩大,对于性能的要求也日益提高。而C语言作为一种底层语言,其执行效率远高于PHP这样的高级语言。因此,通过C语言编写PHP扩展可以显著提升...

    基于PHP的Leevel高性能开源 PHP C扩展开发框架alpha.2.zip

    Leevel是一款专为PHP...总的来说,Leevel框架的alpha.2版本是一个针对性能优化的PHP开发框架,通过C语言扩展,它能够在保持PHP灵活性的同时,显著提升应用程序的运行效率,为开发者提供了一个高效、可靠的开发平台。

    PHP高性能组合框架(C扩展)

    1、考虑之前做的项目都是CI框架,如果全部推翻,将会有超级多的东西需要修改,所以我将CI引擎替换,但是SuperCI对外提供的调用方式不变, 2、框架支持4层架构,Controller、Business、Dao、View 层。 3、首先我将C...

    php intl扩展文件

    - 对于Windows系统,根据系统的位数(32位或64位),intl扩展文件应放置在相应的系统目录下:64位系统放在`C:\Windows\SysWOW64`,32位系统放在`C:\Windows\System32`。 - 安装完成后,还需要在php.ini文件中启用...

    Linux/FreeBSD下用C语言开发PHP的so扩展模块例解

    在Linux和FreeBSD操作系统上,使用...总的来说,开发PHP的C语言扩展需要对PHP内核有深入的理解,同时也需要扎实的C语言基础。通过不断实践和学习,开发者可以创建出强大且高效的自定义扩展,为PHP应用增添新的活力。

    php写扩展文档

    ### PHP扩展开发详解 #### 一、引言 在当今的Web开发领域中,PHP以其易用性与灵活性成为众多开发者的选择。对于那些希望进一步掌握PHP底层机制或想要为自己的项目定制特定功能的开发者而言,了解如何开发PHP扩展是...

    php7.1 oci8扩展

    **PHP 7.1 OCI8 扩展详解** 在 PHP 开发中,Oracle 数据库的交互是一个常见的需求。OCI8 扩展是 PHP 与 Oracle 数据库之间的一个桥梁,它提供了原生的接口来访问 Oracle 数据库。在这个场景下,我们关注的是针对 ...

    php扩展学习PDF

    学习PHP扩展编写,你需要熟悉C语言的基本语法、内存管理、指针操作以及数据结构等概念。书中的内容可能涵盖以下几个方面: 1. **PHP的内核架构**:介绍PHP的执行流程、解析器、ZEND VM(Zend虚拟机)的工作原理,...

    php扩展开发流程,很详细

    1. 安装VC++ 6:这是微软的Visual C++ 6.0编译器,用于编译C语言扩展。 2. PHP二进制环境:你需要下载并安装PHP的二进制版本,这将提供编译扩展所需的库和配置。 3. Cygwin:这是一个在Windows上模拟类UNIX环境的...

    PHP扩展开发中文教程

    这本书深入浅出地讲解了如何构建PHP的C语言扩展,从而增强PHP的功能和性能。PHP作为一种广泛使用的开源脚本语言,其核心在于其丰富的扩展库,通过编写扩展,开发者可以实现自定义功能,优化性能,或者对接底层系统。...

    企业微信会话内容存档php扩展.zip

    描述中提到“目前企业微信会话内容存档sdk只提供c版本的so以及java版本的so”,这意味着企业微信官方提供的SDK主要是面向C和Java开发者的,而这个PHP扩展是社区或个人开发者为填补PHP支持而创建的。PHP版本要求“>= ...

Global site tag (gtag.js) - Google Analytics