php md4,php-core-hack/4.写函数 [ Writing Functions ].md at master · farwish/php-core-hack · GitHub...

/*

|----------------------------------------

| Writing Functions

| @weiChen translate,

| @MIT License

*/

PHP中的函数和方法采用同样的方式,一个方法就是一个有指定作用范围的函数;它们类区域的范围。

Hacker 可以在指南的其它章节中读到关于类的入口。本节的目的是给Hacker剖析函数或方法;

Hacker将学到如何定义方法,如何接收变量和如何返回变量给phper。

一个不能再简单的函数结构:

PHP_FUNCTION(Hackers_function) {

/* your accepted arguments here */

long numer;

/* accepting arguments */

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "1", &number) != SUCCESS) {

return;

}

/* do some work on the input */

number *= 2;

/* set return value */

RETURN_LONG(number);

}

PHP_FUNCTION(hackers_function) 预处理器指令将生成下面的声明:

void zif_hackers_function(INTERNAL_FUNCTION_PARAMETERS)

INTERNAL_FUNCTION_PARAMETERS 作为宏被定义,并被解释成下表中的:

名字和类型

描述

访问宏

int ht

用户传递的实际参数数量

ZEND_NUM_ARGS()

zval* return_value

由返回值填充的传递给用户的PHP变量指针,默认类型是 IS_NULL

RETVAL_, RETURN_

zval** return_value_ptr

当返回的PHP引用设置为一个变量的指针。不建议返回引用。

zval* this_ptr

如果这是一个方法调用,指向PHP变量的是 $this 对象

getThis()

int return_value_used

标记指示返回值是否被调用者使用

清楚起见,PHP_FUNCTION(hackers_function) 完整的扩展声明,看起来像这样:

void zif_hackers_function(int ht, zval* return_value, zval** return_value_ptr,

zval* this_ptr, int return_value_used)

this_ptr 的存在可能令人混淆,后面的章节详细介绍了类,

足以说明白PHP_METHOD(MyClass, hackersFunction)会生成下面的定义:

void zim_MyClass_hackersFunction(INTERNAL_FUNCTION_PARAMETERS)

hackers_function 不做任何有用的事,它使用 zend_parse_parameters API接收一个数字,并让它加倍,

然后返回给引擎。显然,一个普通的函数得做比让输入翻倍更复杂的事,为了教学目的我们让它保持简单。

在函数入口上,return_value 被分配和初始化为 null,让 null 成为任何PHP函数的默认返回值。

如果 zend_parse_parameters 没有接收Hacker指定的正确参数,

且接收的参数不能被转换为符合 type_spec 将产生一个error,并且按惯例,Hacker应该立刻 return。

Note:

数组,对象和资源不能被转换。

解析参数原型

int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...)

int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...)

int zend_parse_parameter(int flags, int num_arg TSRMLS_DC, zval **arg, const char *spec, ...)

Note:

`zend_parse_parameter` 从5.5版本开始可用,它的行为如 `zend_parse_parameters_ex` 期望代替从栈中读取参数,

它接收一个单独的zval来转换,并且这个zval可能会改变。

Note:

`flags` 是一个掩饰,目前只有 `ZEND_PARSE_PARAMS_QUIET` 会有作用(抑制警告)。

这些API函数接收的变量参数被期望是C变量的地址,并且应该被认为是 zend_parse_parameters API函数的输出。

类型说明符

说明符(Spec)

类型(Type)

本地变量(Locals)

a

array

zval*

A

array or object

zval*

b

boolean

zend_bool

C

class

zend_class_entry*

d

double

double

f

function

zend_fcall_info*, zend_fcall_info_cache*

h

array

HashTable*

H

array or object

HashTable*

l

long

long

L

long(limits out-of-range

LONG_MAX/LONG_MIN)

long

o

object

zval*

O

object(of specified zend_class_entry)

zval*, zend_class_entry*

p

string(a valid path)

char*, int

r

resource

zval*

s

string

char*, int

z

mixed

zval*

Z

mixed

zval**

Note:

类型说明符是o的,本地 `zend_class_entry*` 被认为是到 `zend_parse_parameter`的输入(类型说明符的一部分)

高级类型说明符

说明符(Spec)

描述

*

上面类型的可变数量的参数,0 或者更多

+

上面类型的可变数量的参数,1 或者更多

|

表示剩下的参数是可选的

/

SEPARATE_ZVAL_IF_NOT_REF 在它遵循的参数上

!

上面的参数可以是针对'b', 'l', 和 'd' 的null,

一个额外的参数类型zend_bool* 必须在相符的bool*,long* 之后传递,否则接收的 double* 地址如果为 null 将被设为 true。

Note:

查阅包含在源码内的 README.PARAMETER_PARSING_API 获取更多关于解析参数的信息。

一旦Hacker的函数已经执行,无论什么时候被实现执行,是时候返回 return_value 给引擎了。

RETURN_ 和 RETVAL_ 宏仅仅是和 return_value 一起工作的 Z_*_P 宏的包装。

Note:

RETURN_ 宏引起执行来离开函数(如:return;), 当 RETVAL_ 宏允许在 return_value 设置后继续执行时。

Hacker现在应该已经有一个合理的的理解函数的结构,和一些角度,方法的结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值