Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 6.2.md #158

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions 6.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ byref_compiletime_arginfo是一个arginfo结构体,我们在前面的章节中

<div class="tip-common">原书中此处有arginfo在PHP4里的实现,被我略去了。</div>
在Zend Engine 2 (PHP5+)中,arginfo的数据是由多个zend_arg_info结构体构成的数组,数组的每一个成员即每一个zend_arg_info结构体处理函数的一个参数。zend_arg_info结构体的定义如下:

````c
typedef struct _zend_arg_info {
const char *name; /* 参数的名称*/
Expand All @@ -84,6 +85,7 @@ typedef struct _zend_arg_info {

````
生成zend_arg_info结构的数组比较繁琐,为了方便PHP扩展开发者,内核已经准备好了相应的宏来专门处理此问题,首先先用一个宏函数来生成头部,然后用第二个宏生成具体的数据,最后用一个宏生成尾部代码。

````c
#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1)
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
Expand All @@ -97,20 +99,27 @@ typedef struct _zend_arg_info {
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, 1, allow_null, pass_by_ref, 0, 0 },


#define ZEND_END_ARG_INFO() };
#define ZEND_END_ARG_INFO()

};

````

```
//这里我们先看
ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference)
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference,required_num_args)
```

````
这两个宏函数的前两个参数的含义是一样的,name便是这个zend_arg_info数组变量的名字,这里我们定义它为:byref_compiletime_arginfo。pass_rest_by_reference如果被赋值为1,则代表着所有的参数默认都是需要以引用的方式传递的(在arginfo中单独声明的除外)。而对于ZEND_BEGIN_ARG_INFO_EX的后两个参数:
<ul>
<li>name和pass_rest_by_reference的含义同上。</li>
<li>return_reference:声明这个函数的返回值需要以引用的形式返回,这个参数已经在前面章节用过了。</li>
<li>required_num_args:函数被调用时,传递参数至少为前N个函数(也就是后面参数都有默认值),当设置为-1时,必须传递所有参数</li>
</ul>

接下来让我们看生成具体数据的宏:

````c
ZEND_ARG_PASS_INFO(by_ref)
//强制所有参数使用引用的方式传递
Expand All @@ -130,7 +139,9 @@ ZEND_BEGIN_ARG_INFO(byref_compiletime_arginfo, 0)
ZEND_END_ARG_INFO()

````

为了使我们的扩展能够兼容PHP4,还需要使用#ifdef进行特殊处理。

````c
#ifdef ZEND_ENGINE_2
ZEND_BEGIN_ARG_INFO(byref_compiletime_arginfo, 0)
Expand All @@ -141,7 +152,9 @@ static unsigned char byref_compiletime_arginfo[] = { 1, BYREF_FORCE };
#endif

````

我们copy一份ZEND_FUNCTION(byref_calltime)的实现,并重名成ZEND_FUNCTION(byref_compiletime)就行了。或者直接弄个ZEND_FALIAS就行了:

````c
ZEND_FALIAS(byref_compiletime,byref_calltime,byref_compiletime_arginfo)

Expand Down