- 浏览: 1404174 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
在php中最核心的一个数据结构就是这个:
这个数据结构也就是php中的每个数据类型在下层c语言中的表示。可以看到_zval_struct 结构体第一个字段是一个联合体,他来存储实际的值,这些值可以为long,double,字符串,hashtable(也就是php中的数组)和对象。而第2个参数是个引用计数,第三个参数是当前的类型。
也就是说php中的每个类型实际都是一个 struct _zval_struct类型。
1 首先进入php的源码目录下的ext文件夹,然后运行下面的命令,这样将会生成一个my_module的文件夹。:
2 然后在my_module.h里面声明你的php函数名:
2 在my_module.c文件的my_module_functions(这里的module就是你所创建的扩展模块名字)加入你所要写的php方法名:
3 接下来就实现PHP_FUNCTION(my_function)。
首先 参数的解析,当传递进来的php的类型和c的类型之间的转换:
这里要用到的函数是:
其中的php类型和c类型的对应如下:
这边就看到了,这里的zval也就是一开始介绍的那个php的类型结构体。
这边还可以使用三个符号:
| - 这个也就是或者的意思
/ -将会提供当前参数的一个副本。
! - 这个符号他必须进跟在a, o, O, r, z 的后面 ,也就是说当传递进来的参数为NULL的时候,我们pass的那个指针也会被NULL。
例子:
当我们传递进来的为一个数组的时候我们该如何遍历这个数组呢,看下面的代码:
接下来是返回值的问题,这里定义了好几个宏:
比如我要返回个字符串,可以这么写:
这里讲下返回一个数组的问题,下面的代码是返回一个嵌套数组:
PS:更详细的还是要看ext目录下面的那些扩展实例
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*
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, ¶m) == 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目录下面的那些扩展实例
发表评论
-
gcc的几个自动优化
2009-11-10 00:44 5157我的gcc版本是4.4.1 先来看const和define以 ... -
gdb学习笔记(一)
2009-10-17 14:11 11766这里只是一个摘要。具体的细节还需要去看manual。 1 ... -
ydb的内存模型
2009-09-06 18:02 2011阿宝同学推荐了这个东 ... -
glibc中strlen的实现
2009-08-04 09:10 4534glibc中的strlen的实现主要的思想就是每次检测4个字节 ... -
libevent源码浅析(四)
2009-05-15 23:02 4436最近刚刚一个项目自己用libevent,因此这几天又把libe ... -
libevent源码浅析(三)
2009-03-17 00:08 4602这次我们来看libevent的信号的处理。 在libeven ... -
libevent源码浅析(二)
2009-02-22 00:11 4083我们来看下libevent的定时器的实现 在libevent ... -
libevent源码浅析(一)
2009-02-14 13:23 7450这里分析的是libevent-1.4.9。 PS:前面还看了 ... -
linux下的time处理
2009-01-04 18:02 6863在内核中有3个不同的时间: Wall time(real t ... -
libev简单使用介绍
2008-12-30 09:52 11582更详细的用法请看他的 ... -
linux下的elf结构
2008-12-12 00:20 5200可以看到链接器和加载器看待elf是完全不同的,链接器看到 ... -
linux下的管理内存相关的函数
2008-11-27 00:56 4497malloc的实现,在linux下的实现是这样的,当所需 ... -
linux下的数据对齐
2008-11-25 12:15 3660数据对齐也就是通过硬件来估算在数据的地址和内存块之间的联系。当 ... -
linux下检测ip冲突
2008-11-16 20:18 8200原理其实很简单,那就是广播一个arp包,然后recv,如果没有 ... -
今天碰到的一个问题
2008-10-29 22:33 1295将位图用 bmptopnm 转成pcl6的打印语言,然后直接c ... -
ftruncate和msync
2008-10-23 22:10 3523int ftruncate(int fd, off_t le ... -
GUN C正则表达式
2008-09-25 23:47 6198最近项目中要处理文本,因此就用了gun的正则表达式,它是pos ... -
看代码看的头晕
2008-09-06 01:04 1890最近工作需要在看ghostscript的代码,看得我头晕眼花, ... -
[转帖]MISRA--作为工业标准的C编程规范
2008-08-21 13:19 2841本文档转贴自孟岩的blog ... -
代码大全读书笔记1
2008-04-26 19:16 3830这么好的书,觉得写点东西,记录一下比较好。 4.1选择编程语 ...
相关推荐
【标题】"简单高性能优雅的phpc扩展框架"所指的是一个专门为PHP设计的C扩展框架,旨在提升PHP应用的性能并提供简洁优雅的编程体验。C扩展是将PHP功能用C语言编写,然后编译为PHP可以调用的模块,这样能够利用C语言的...
在PHP开发中,有时需要编写C扩展来实现特定功能或提升性能。本文将详细介绍PHP C扩展开发的相关步骤和核心知识点,帮助开发者理解如何在PHP中构建自定义的扩展。 首先,让我们了解为何要编写PHP扩展。有四个主要...
由于是C语言编写的扩展,xlswriter的运行速度远超纯PHP实现的解决方案,为大型数据导出提供了可能。 使用xlswriter,开发者可以轻松地实现以下功能: 1. **文本写入**:可以在指定的工作表中插入任意文本,支持...
在本文中,我们将深入探讨如何使用C语言开发PHP扩展,并将其整合到PHP环境中。这是一个涉及多步骤的过程,从设置开发环境到编写C代码并最终在PHP中调用这些扩展。 首先,我们需要建立开发环境。这包括搭建PHP开发...
本教程将详细介绍如何用C语言为PHP编写C扩展。 首先,我们需要理解C扩展的基本原理。PHP的内核是用C编写的,因此我们可以利用C语言直接与PHP引擎交互,创建新的函数、类或模块。C扩展通常用于实现那些在PHP原生语法...
Leevel是一个专为PHP设计的高性能开源框架,其核心特性在于使用C语言编写的PHP扩展,以提升PHP应用的运行效率。Alpha.2版本代表这是一个仍在早期开发阶段的版本,可能包含新功能、优化和bug修复。从提供的压缩包文件...
### 使用C语言扩展PHP:构建PHP扩展DLL #### 前言 随着PHP的应用范围不断扩大,对于性能的要求也日益提高。而C语言作为一种底层语言,其执行效率远高于PHP这样的高级语言。因此,通过C语言编写PHP扩展可以显著提升...
Leevel是一款专为PHP...总的来说,Leevel框架的alpha.2版本是一个针对性能优化的PHP开发框架,通过C语言扩展,它能够在保持PHP灵活性的同时,显著提升应用程序的运行效率,为开发者提供了一个高效、可靠的开发平台。
一个简单的扩展通常包括config.m4配置文件,php_扩展名.h头文件,以及扩展名.c源代码文件。这些文件用于定义扩展的接口、配置选项和实现功能。 **7-28. 具体实现** 这部分详细讲解了如何创建ZVAL,处理数组、符号表...
1、考虑之前做的项目都是CI框架,如果全部推翻,将会有超级多的东西需要修改,所以我将CI引擎替换,但是SuperCI对外提供的调用方式不变, 2、框架支持4层架构,Controller、Business、Dao、View 层。 3、首先我将C...
- 对于Windows系统,根据系统的位数(32位或64位),intl扩展文件应放置在相应的系统目录下:64位系统放在`C:\Windows\SysWOW64`,32位系统放在`C:\Windows\System32`。 - 安装完成后,还需要在php.ini文件中启用...
在Linux和FreeBSD操作系统上,使用...总的来说,开发PHP的C语言扩展需要对PHP内核有深入的理解,同时也需要扎实的C语言基础。通过不断实践和学习,开发者可以创建出强大且高效的自定义扩展,为PHP应用增添新的活力。
### PHP扩展开发详解 #### 一、引言 在当今的Web开发领域中,PHP以其易用性与灵活性成为众多开发者的选择。对于那些希望进一步掌握PHP底层机制或想要为自己的项目定制特定功能的开发者而言,了解如何开发PHP扩展是...
**PHP 7.1 OCI8 扩展详解** 在 PHP 开发中,Oracle 数据库的交互是一个常见的需求。OCI8 扩展是 PHP 与 Oracle 数据库之间的一个桥梁,它提供了原生的接口来访问 Oracle 数据库。在这个场景下,我们关注的是针对 ...
学习PHP扩展编写,你需要熟悉C语言的基本语法、内存管理、指针操作以及数据结构等概念。书中的内容可能涵盖以下几个方面: 1. **PHP的内核架构**:介绍PHP的执行流程、解析器、ZEND VM(Zend虚拟机)的工作原理,...
1. 安装VC++ 6:这是微软的Visual C++ 6.0编译器,用于编译C语言扩展。 2. PHP二进制环境:你需要下载并安装PHP的二进制版本,这将提供编译扩展所需的库和配置。 3. Cygwin:这是一个在Windows上模拟类UNIX环境的...
这本书深入浅出地讲解了如何构建PHP的C语言扩展,从而增强PHP的功能和性能。PHP作为一种广泛使用的开源脚本语言,其核心在于其丰富的扩展库,通过编写扩展,开发者可以实现自定义功能,优化性能,或者对接底层系统。...
描述中提到“目前企业微信会话内容存档sdk只提供c版本的so以及java版本的so”,这意味着企业微信官方提供的SDK主要是面向C和Java开发者的,而这个PHP扩展是社区或个人开发者为填补PHP支持而创建的。PHP版本要求“>= ...