- 浏览: 590050 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
kangh:
转载的也拿出来 都不试一下 完全错误
Nginx+ffmpeg的HLS开源服务器搭建配置及开发详解 -
wangtxlz:
#cd builders/cmake#cmake .系统提示命 ...
crtmpserver流媒体服务器的介绍与搭建 -
hnraysir:
支持支持支持
手机Android音视频采集与直播推送,实现单兵、移动监控类应用 -
wuent:
把web服务器和php框架绑定到一起?真不建议这样。。。
Swoole(PHP高级Web开发框架) -
wuent:
有更详细的性能比较吗?php,python,java
PHP中的(伪)多线程与多进程
最简单的获取函数调用者传递过来的参数便是使用zend_parse_parameters()函数。
zend_parse_parameters()函数的前几个参数我们直接用内核里宏来生成便可以了,形式为:ZEND_NUM_ARGS() TSRMLS_CC,注意两者之间有个空格,但是没有逗号。从名字可以看出,ZEND_NUM_ARGS()代表这参数的个数。
紧接着需要传递个zend_parse_parameters()函数的参数是一个用于格式化的字符串,就像printf的第一个参数一样。下面表示了最常用的几个符号。
01
type_spec是格式化字符串,其常见的含义如下:
02
参数 代表着的类型
03
b Boolean
04
l Integer 整型
05
d Floating point 浮点型
06
s String 字符串
07
r Resource 资源
08
a Array 数组
09
o Object instance 对象
10
O Object instance of a specified type 特定类型的对象
11
z Non-specific zval 任意类型~
12
Z zval**类型
13
f 表示函数、方法名称,PHP5.1里貌似木有... ...
这个函数就像printf()函数一样,后面的参数是与格式化字符串里的格式一一对应的。一些基础类型的数据会直接映射成C语言里的类型。
01
ZEND_FUNCTION(sample_getlong)
02
{
03
long foo;
04
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"l", &foo) == FAILURE)
05
{
06
RETURN_NULL();
07
}
08
php_printf("The integer value of the parameter is: %ld\n", foo);
09
RETURN_TRUE;
10
}
一般来说,int和long这两种数据类型的数据往往是相同的,但也有例外情况。所以我们不应改把long的数组放在一个int里,尤其是在64位平台里,那将引发一些不容易排查的Bug。所以通过zend_parse_parameter()函数接收参数时,我们应该使用内核约定好的那些类型的变量作为载体。
01
参数 对应C里的数据类型
02
b zend_bool
03
l long
04
d double
05
s char*, int 前者接收指针,后者接收长度
06
r zval*
07
a zval*
08
o zval*
09
O zval*, zend_class_entry*
10
z zval*
11
Z zval**
注意,所有的PHP语言中的复合类型参数都需要zval*类型来作为载体,因为它们都是内核自定义的一些数据结构。我们一定要确认参数和载体的类型一直,如果需要,它可以进行类型转换,比如把array转换成stdClass对象。
s和O(字母大写欧)类型需要单独说一些,因为它们都需要两个载体。我们将在接下来的章节里了解php中对象的具体实现。这样我们改写一下我们在第五章定义的一个函数:
1
<?php
2
function sample_hello_world($name)
3
{
4
echo "Hello $name!\n";
5
}
6
?>
在编写扩展时,我们需要用zend_parse_parameters()来接收这个字符串:
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
06
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len) == FAILURE)
07
{
08
RETURN_NULL();
09
}
10
php_printf("Hello ");
11
PHPWRITE(name, name_len);
12
php_printf("!\n");
13
}
如果传递给函数的参数数量小于zend_parse_parameters()要接收的参数数量,它便会执行失败,并返回FAILURE。
如果我们需要接收多个参数,可以直接在zend_parse_paramenters()的参数里罗列接收载体便可以了,如:
1
<?php
2
function sample_hello_world($name, $greeting)
3
{
4
echo "Hello $greeting $name!\n";
5
}
6
sample_hello_world('John Smith', 'Mr.');
7
?>
在PHP扩展里应该这样来实现:
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
char *greeting;
06
int greeting_len;
07
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&name, &name_len, &greeting, &greeting_len) == FAILURE)
08
{
09
RETURN_NULL();
10
}
11
php_printf("Hello ");
12
PHPWRITE(greeting, greeting_len);
13
php_printf(" ");
14
PHPWRITE(name, name_len);
15
php_printf("!\n");
16
}
除了上面定义的参数,还有其它的三个参数来增强我们接受参数的能力,如下:
1
Type Modifier Meaning
2
| 它之前的参数都是必须的,之后的都是非必须的,也就是有默认值的。
3
! 如果接收了一个PHP语言里的null变量,则直接把其转成C语言里的NULL,而不是封装成IS_NULL类型的zval。
4
/ 如果传递过来的变量与别的变量共用一个zval,而且不是引用,则进行强制分离,新的zval的is_ref__gc==0, and refcount__gc==1.
函数参数的默认值
现在让我们继续改写sample_hello_world(), 接下来我们使用一些参数的默认值,在php语言里就像下面这样:
1
<?php
2
function sample_hello_world($name, $greeting='Mr./Ms.')
3
{
4
echo "Hello $greeting $name!\n";
5
}
6
sample_hello_world('Ginger Rogers','Ms.');
7
sample_hello_world('Fred Astaire');
8
?>
此时即可以只向sample_hello_world中传递一个参数,也可以传递完整的两个参数。
那同样的功能我们怎样在扩展函数里实现呢?我们需要借助zend_parse_parameters中的(|)参数,这个参数之前的参数被认为是必须的,之后的便认为是非必须的了,如果没有传递,则不会去修改载体。
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
char *greeting = "Mr./Mrs.";
06
int greeting_len = sizeof("Mr./Mrs.") - 1;
07
08
09
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
10
&name, &name_len, &greeting, &greeting_len) == FAILURE) {
11
RETURN_NULL();
12
}
13
php_printf("Hello ");
14
PHPWRITE(greeting, greeting_len);
15
php_printf(" ");
16
PHPWRITE(name, name_len);
17
php_printf("!\n");
18
}
如果你不传递第二个参数,则扩展函数会被认为默认而不去修改载体。所以,我们需要自己来预先设置有载体的值,它往往是是NULL,或者一个与函数逻辑有关的值。
每个zval,包括IS_NULL型的zval,都需要占用一定的内存空间,并且需要cpu的计算资源来为它申请内存、初始化,并在它们完成工作后释放掉。但是很多代码都都没有意识到这一点。有很多代码都会把一个null型的值包裹成zval的IS_NULL类型,在扩展开发里这种操作是可以优化的,我们可以把参数接收城C语言里的NULL。我们就这一个问题看以下代码:
01
ZEND_FUNCTION(sample_arg_fullnull)
02
{
03
zval *val;
04
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&val) == FAILURE) {
05
RETURN_NULL();
06
}
07
if (Z_TYPE_P(val) == IS_NULL) {
08
val = php_sample_make_defaultval(TSRMLS_C);
09
}
10
...
11
}
12
ZEND_FUNCTION(sample_arg_nullok)
13
{
14
zval *val;
15
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!",
16
&val) == FAILURE) {
17
RETURN_NULL();
18
}
19
if (!val) {
20
val = php_sample_make_defaultval(TSRMLS_C);
21
}
22
}
这两段代码乍看起来并没有什么很大的不同,但是第一段代码确实需要更多的cpu和内存资源。可能这个技巧在平时并没多大用,不过技多不压身,知道总比不知道好。
Forced Separation
当一个变量被传递给函数时候,无论它是否被引用,它的refcoung__gc属性都会加一,至少成为2。一份是它自己,另一份是传递给函数的的copy。在改变这个zval之前,有时会需要提前把它分成实际意义上的两份copy。这就是"/"格式符的作用。它将把写时复制的zval提前分成两个完整独立的copy,从而使我们可以在下面的代码中随意的对其进行操作。否则我们可能需要不停的提醒自己对接收的参数进行分离等操作。Like the NULL flag, this modifier goes after the type it means to impact. Also like the NULL flag, you won't know you need this feature until you actually have a use for it.
zend_get_arguments()
如果你想让你的扩展能够兼容老版本的PHP,或者你只想以zval*为载体来接收参数,便可以考虑使用zend_get_parameters()函数来接收参数。
zend_get_parameters()与zend_parse_parameters()不同,从名字上我们便可以看出,它直接获取,而不做解析。首先,它不会自动进行类型转换,所有的参数在扩展实现中的载体都需要是zval*类型的,下面让我们来看一个最简单的例子:
01
ZEND_FUNCTION(sample_onearg)
02
{
03
zval *firstarg;
04
if (zend_get_parameters(ZEND_NUM_ARGS(), 1, &firstarg)== FAILURE)
05
{
06
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Expected at least 1 parameter.");
07
RETURN_NULL();
08
}
09
/* Do something with firstarg... */
10
}
其次,zend_get_parameters()在接收失败的时候,并不会自己抛出错误,它也不能方便的处理具有默认值的参数。
最后一点与zend_parse_parameters不同的是,它会自动的把所有复合copy-on-write的zval进行强制分离,生成一个崭新的copy送到函数内部。如果你希望用它其它的特性,而唯独不需要这个功能,可以去尝试一下用zend_get_parameters_ex()函数来接收参数。
为了不对copy-on-write的变量进行分离操作,zend_get_parameters_ex()的参数是zval**类型的,而不是zval*。 这个函数不太经常用,可能只会在你碰到一些极端问题时候才会想到它,而它用起来却很简单:
1
ZEND_FUNCTION(sample_onearg)
2
{
3
zval **firstarg;
4
if (zend_get_parameters_ex(1, &firstarg) == FAILURE)
5
{
6
WRONG_PARAM_COUNT;
7
}
8
/* Do something with firstarg... */
9
}
注意zend_get_parameters_ex不需要ZEND_NUM_ARGS()作为参数,因为它是在是在后期加入的,那个参数已经不再需要了。
上面例子中还使用了WRONG_PARAM_COUNT宏,它的功能是抛出一个E_WARNING级别的错误信息,并自动return。
可变参数
有两种其它的zend_get_parameter_**函数,专门用来解决参数很多或者无法提前知道参数数目的问题。想一下php语言中var_dump()函数的用法,我们可以向其传递任意数量的参数,它在内核中的实现其实是这样的:
view sourceprint?
01
ZEND_FUNCTION(var_dump)
02
{
03
int i, argc = ZEND_NUM_ARGS();
04
zval ***args;
05
06
args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
07
if (ZEND_NUM_ARGS() == 0 || zend_get_parameters_array_ex(argc, args) == FAILURE)
08
{
09
efree(args);
10
WRONG_PARAM_COUNT;
11
}
12
for (i=0; i < argc; i++)
13
{
14
php_var_dump(args[i], 1 TSRMLS_CC);
15
}
16
efree(args);
17
}
程序首先获取参数数量,然后通过safe_emalloc函数申请了相应大小的内存来存放这些zval**类型的参数。这里使用了zend_get_parameters_array_ex()函数来把传递给函数的参数填充到args中。你可能已经立即想到,还存在一个名为zend_get_parameters_array()的函数,唯一不同的是它将zval*类型的参数填充到args中,并且需要ZEND_NUM_ARGS()作为参数。
http://www.nowamagic.net/librarys/veda/detail/1467
http://www.laruence.com/2009/04/28/719.html
zend_parse_parameters()函数的前几个参数我们直接用内核里宏来生成便可以了,形式为:ZEND_NUM_ARGS() TSRMLS_CC,注意两者之间有个空格,但是没有逗号。从名字可以看出,ZEND_NUM_ARGS()代表这参数的个数。
紧接着需要传递个zend_parse_parameters()函数的参数是一个用于格式化的字符串,就像printf的第一个参数一样。下面表示了最常用的几个符号。
01
type_spec是格式化字符串,其常见的含义如下:
02
参数 代表着的类型
03
b Boolean
04
l Integer 整型
05
d Floating point 浮点型
06
s String 字符串
07
r Resource 资源
08
a Array 数组
09
o Object instance 对象
10
O Object instance of a specified type 特定类型的对象
11
z Non-specific zval 任意类型~
12
Z zval**类型
13
f 表示函数、方法名称,PHP5.1里貌似木有... ...
这个函数就像printf()函数一样,后面的参数是与格式化字符串里的格式一一对应的。一些基础类型的数据会直接映射成C语言里的类型。
01
ZEND_FUNCTION(sample_getlong)
02
{
03
long foo;
04
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"l", &foo) == FAILURE)
05
{
06
RETURN_NULL();
07
}
08
php_printf("The integer value of the parameter is: %ld\n", foo);
09
RETURN_TRUE;
10
}
一般来说,int和long这两种数据类型的数据往往是相同的,但也有例外情况。所以我们不应改把long的数组放在一个int里,尤其是在64位平台里,那将引发一些不容易排查的Bug。所以通过zend_parse_parameter()函数接收参数时,我们应该使用内核约定好的那些类型的变量作为载体。
01
参数 对应C里的数据类型
02
b zend_bool
03
l long
04
d double
05
s char*, int 前者接收指针,后者接收长度
06
r zval*
07
a zval*
08
o zval*
09
O zval*, zend_class_entry*
10
z zval*
11
Z zval**
注意,所有的PHP语言中的复合类型参数都需要zval*类型来作为载体,因为它们都是内核自定义的一些数据结构。我们一定要确认参数和载体的类型一直,如果需要,它可以进行类型转换,比如把array转换成stdClass对象。
s和O(字母大写欧)类型需要单独说一些,因为它们都需要两个载体。我们将在接下来的章节里了解php中对象的具体实现。这样我们改写一下我们在第五章定义的一个函数:
1
<?php
2
function sample_hello_world($name)
3
{
4
echo "Hello $name!\n";
5
}
6
?>
在编写扩展时,我们需要用zend_parse_parameters()来接收这个字符串:
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
06
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name, &name_len) == FAILURE)
07
{
08
RETURN_NULL();
09
}
10
php_printf("Hello ");
11
PHPWRITE(name, name_len);
12
php_printf("!\n");
13
}
如果传递给函数的参数数量小于zend_parse_parameters()要接收的参数数量,它便会执行失败,并返回FAILURE。
如果我们需要接收多个参数,可以直接在zend_parse_paramenters()的参数里罗列接收载体便可以了,如:
1
<?php
2
function sample_hello_world($name, $greeting)
3
{
4
echo "Hello $greeting $name!\n";
5
}
6
sample_hello_world('John Smith', 'Mr.');
7
?>
在PHP扩展里应该这样来实现:
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
char *greeting;
06
int greeting_len;
07
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&name, &name_len, &greeting, &greeting_len) == FAILURE)
08
{
09
RETURN_NULL();
10
}
11
php_printf("Hello ");
12
PHPWRITE(greeting, greeting_len);
13
php_printf(" ");
14
PHPWRITE(name, name_len);
15
php_printf("!\n");
16
}
除了上面定义的参数,还有其它的三个参数来增强我们接受参数的能力,如下:
1
Type Modifier Meaning
2
| 它之前的参数都是必须的,之后的都是非必须的,也就是有默认值的。
3
! 如果接收了一个PHP语言里的null变量,则直接把其转成C语言里的NULL,而不是封装成IS_NULL类型的zval。
4
/ 如果传递过来的变量与别的变量共用一个zval,而且不是引用,则进行强制分离,新的zval的is_ref__gc==0, and refcount__gc==1.
函数参数的默认值
现在让我们继续改写sample_hello_world(), 接下来我们使用一些参数的默认值,在php语言里就像下面这样:
1
<?php
2
function sample_hello_world($name, $greeting='Mr./Ms.')
3
{
4
echo "Hello $greeting $name!\n";
5
}
6
sample_hello_world('Ginger Rogers','Ms.');
7
sample_hello_world('Fred Astaire');
8
?>
此时即可以只向sample_hello_world中传递一个参数,也可以传递完整的两个参数。
那同样的功能我们怎样在扩展函数里实现呢?我们需要借助zend_parse_parameters中的(|)参数,这个参数之前的参数被认为是必须的,之后的便认为是非必须的了,如果没有传递,则不会去修改载体。
01
ZEND_FUNCTION(sample_hello_world)
02
{
03
char *name;
04
int name_len;
05
char *greeting = "Mr./Mrs.";
06
int greeting_len = sizeof("Mr./Mrs.") - 1;
07
08
09
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
10
&name, &name_len, &greeting, &greeting_len) == FAILURE) {
11
RETURN_NULL();
12
}
13
php_printf("Hello ");
14
PHPWRITE(greeting, greeting_len);
15
php_printf(" ");
16
PHPWRITE(name, name_len);
17
php_printf("!\n");
18
}
如果你不传递第二个参数,则扩展函数会被认为默认而不去修改载体。所以,我们需要自己来预先设置有载体的值,它往往是是NULL,或者一个与函数逻辑有关的值。
每个zval,包括IS_NULL型的zval,都需要占用一定的内存空间,并且需要cpu的计算资源来为它申请内存、初始化,并在它们完成工作后释放掉。但是很多代码都都没有意识到这一点。有很多代码都会把一个null型的值包裹成zval的IS_NULL类型,在扩展开发里这种操作是可以优化的,我们可以把参数接收城C语言里的NULL。我们就这一个问题看以下代码:
01
ZEND_FUNCTION(sample_arg_fullnull)
02
{
03
zval *val;
04
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&val) == FAILURE) {
05
RETURN_NULL();
06
}
07
if (Z_TYPE_P(val) == IS_NULL) {
08
val = php_sample_make_defaultval(TSRMLS_C);
09
}
10
...
11
}
12
ZEND_FUNCTION(sample_arg_nullok)
13
{
14
zval *val;
15
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!",
16
&val) == FAILURE) {
17
RETURN_NULL();
18
}
19
if (!val) {
20
val = php_sample_make_defaultval(TSRMLS_C);
21
}
22
}
这两段代码乍看起来并没有什么很大的不同,但是第一段代码确实需要更多的cpu和内存资源。可能这个技巧在平时并没多大用,不过技多不压身,知道总比不知道好。
Forced Separation
当一个变量被传递给函数时候,无论它是否被引用,它的refcoung__gc属性都会加一,至少成为2。一份是它自己,另一份是传递给函数的的copy。在改变这个zval之前,有时会需要提前把它分成实际意义上的两份copy。这就是"/"格式符的作用。它将把写时复制的zval提前分成两个完整独立的copy,从而使我们可以在下面的代码中随意的对其进行操作。否则我们可能需要不停的提醒自己对接收的参数进行分离等操作。Like the NULL flag, this modifier goes after the type it means to impact. Also like the NULL flag, you won't know you need this feature until you actually have a use for it.
zend_get_arguments()
如果你想让你的扩展能够兼容老版本的PHP,或者你只想以zval*为载体来接收参数,便可以考虑使用zend_get_parameters()函数来接收参数。
zend_get_parameters()与zend_parse_parameters()不同,从名字上我们便可以看出,它直接获取,而不做解析。首先,它不会自动进行类型转换,所有的参数在扩展实现中的载体都需要是zval*类型的,下面让我们来看一个最简单的例子:
01
ZEND_FUNCTION(sample_onearg)
02
{
03
zval *firstarg;
04
if (zend_get_parameters(ZEND_NUM_ARGS(), 1, &firstarg)== FAILURE)
05
{
06
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Expected at least 1 parameter.");
07
RETURN_NULL();
08
}
09
/* Do something with firstarg... */
10
}
其次,zend_get_parameters()在接收失败的时候,并不会自己抛出错误,它也不能方便的处理具有默认值的参数。
最后一点与zend_parse_parameters不同的是,它会自动的把所有复合copy-on-write的zval进行强制分离,生成一个崭新的copy送到函数内部。如果你希望用它其它的特性,而唯独不需要这个功能,可以去尝试一下用zend_get_parameters_ex()函数来接收参数。
为了不对copy-on-write的变量进行分离操作,zend_get_parameters_ex()的参数是zval**类型的,而不是zval*。 这个函数不太经常用,可能只会在你碰到一些极端问题时候才会想到它,而它用起来却很简单:
1
ZEND_FUNCTION(sample_onearg)
2
{
3
zval **firstarg;
4
if (zend_get_parameters_ex(1, &firstarg) == FAILURE)
5
{
6
WRONG_PARAM_COUNT;
7
}
8
/* Do something with firstarg... */
9
}
注意zend_get_parameters_ex不需要ZEND_NUM_ARGS()作为参数,因为它是在是在后期加入的,那个参数已经不再需要了。
上面例子中还使用了WRONG_PARAM_COUNT宏,它的功能是抛出一个E_WARNING级别的错误信息,并自动return。
可变参数
有两种其它的zend_get_parameter_**函数,专门用来解决参数很多或者无法提前知道参数数目的问题。想一下php语言中var_dump()函数的用法,我们可以向其传递任意数量的参数,它在内核中的实现其实是这样的:
view sourceprint?
01
ZEND_FUNCTION(var_dump)
02
{
03
int i, argc = ZEND_NUM_ARGS();
04
zval ***args;
05
06
args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
07
if (ZEND_NUM_ARGS() == 0 || zend_get_parameters_array_ex(argc, args) == FAILURE)
08
{
09
efree(args);
10
WRONG_PARAM_COUNT;
11
}
12
for (i=0; i < argc; i++)
13
{
14
php_var_dump(args[i], 1 TSRMLS_CC);
15
}
16
efree(args);
17
}
程序首先获取参数数量,然后通过safe_emalloc函数申请了相应大小的内存来存放这些zval**类型的参数。这里使用了zend_get_parameters_array_ex()函数来把传递给函数的参数填充到args中。你可能已经立即想到,还存在一个名为zend_get_parameters_array()的函数,唯一不同的是它将zval*类型的参数填充到args中,并且需要ZEND_NUM_ARGS()作为参数。
http://www.nowamagic.net/librarys/veda/detail/1467
http://www.laruence.com/2009/04/28/719.html
发表评论
-
nginx、php-fpm默认配置与性能–TCP socket还是unix domain socket
2015-04-02 11:14 1408前几天看到一篇博客,提到php所在服务器在大并发情况下,频 ... -
使用socket方式连接Nginx优化php-fpm性能
2015-04-01 13:49 0Nginx连接fastcgi的方式有 ... -
PHP中include和require的区别详解
2015-04-01 08:32 01、概要 require()语句的性能与includ ... -
PHP 中cookie 和 session 的分析
2015-03-31 12:33 0HP 中cookie 和session 的分析 ... -
php 经典的算法题你懂的
2015-03-31 12:31 0有5个人偷了一堆苹果,准备在第二天分赃。晚上,有一人遛出来, ... -
PHP最常用的2种设计模式工厂模式和单例模式介绍
2015-03-31 12:26 0简单来说,PHP单例模式就是一个功能用一个类来实现,并且在整 ... -
PHP 数据类型
2015-03-31 12:23 0PHP 数据类型 PHP 支持八种原始类型(type)。 ... -
PHP mcrypt启用、加密以及解密过程详解
2015-03-30 11:32 1414Mcrypt扩展库可以实现加密解密功能,就是既能将明文加密, ... -
PHP扩展实现类扩展
2015-03-27 14:08 523在第一篇文章中,我们所开发的扩展是单个函数,本篇文章看一下 ... -
PHP高级工程师的面试题
2015-03-06 10:35 01. 基本知识点 HTTP协议中几个状态码的含义:1x ... -
PHP面试中常见的面试试题与算法例子
2015-03-05 14:14 0下面是四道比较常见的题目,主要考察的是对字符串函数以及文件操 ... -
PHP实现四种常用的排序算法
2015-03-05 14:09 0插入排序(Insertion Sort),选择排序(Sele ... -
用swagger-php/ui做API测试
2015-02-13 09:46 3599功能: 1 swagger-php根据自定义的规则生成API ... -
app后端设计(0)--总目录
2015-01-23 18:03 0做了3年app相关的系统架构,api设计,先后在3个创业公司中 ... -
PHP中eAccelerator、memcached、xcache、APC 4个加速、缓存扩展的区别
2015-01-23 10:26 872这篇文章主要介绍了PHP ... -
实战:用C写php扩展(二)
2015-01-16 11:05 938一、前言 在我的上一篇文章“实战:用C写php扩展(一)”里介 ... -
实战:用C写php扩展(一)
2015-01-16 11:04 9741、 前言 首先,确保你的机器安装了apache和php。假 ... -
JavaScript or PHP 来检测移动设备
2014-09-22 10:04 590iPhone & iPod Detection T ... -
YII Framework学习教程-YII的Modules(模块化)
2014-08-27 11:04 710一个相对来说大的项目。如果按照yii生成的 ... -
如何编写一个PHP的C扩展
2014-07-28 15:45 735为什么要用C扩展 C是静态编译的,执行效率比PHP代码高很 ...
相关推荐
使用纯Dart管理Parse SDK的软件包。 特征: 解析ACL 解析配置 解析文件 解析对象 解析查询 解析角色 解析会话 ParseUser 安装 添加到pubspec.yaml: dependencies : flutter_parse : ^0.2.3 导入库 import '...
14. URL解析函数:parse_url 26 15. json解析函数:get_json_object 27 16. 空格字符串函数:space 27 17. 重复字符串函数:repeat 27 18. 首字符ascii函数:ascii 28 19. 左补足函数:lpad 28 20. 右补足函数:rpad...
资源分类:Python库 所属语言:Python 资源全名:dbc_parse-1.0.7-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
主要介绍了IDEA与模拟器安装调试失败的处理方法:INSTALL_PARSE_FAILED_NO_CERTIFICATES,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
刚开始解码H264视频时,查阅文档说有Nalu头,参考雷神代码,将文件指针传入去掉头可以解码,但是需要每次传入定量buffer解码,不是传入文件指针,经过修改可以用有bug
资源分类:Python库 所属语言:Python 资源全名:xstavka_parse_package-0.25.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
今天在帮助客户解决一个问题时,由于他们的手机是用的5.0系统身边没有5.0系统的手机,只能用一个模拟器来安装测试应用,但是在安装过程中碰到了以下问题: The application could not be installed: INSTALL_FAILED...
method and a parse method. The parse method uses the eval method to do the parsing, guarding it with several regular expressions to defend against accidental code execution hazards. On current ...
strlen函数说明。 int strlen ( string $string ) ... if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) { return; } RETVAL_LONG(s1_len); } 该文章讲到,该函数很简
需要用到的几个函数: 1、解析JSONJ结构得到cjson对象:cJSON * root=cJSON_Parse(char *buf); 2、获取无格式的json对象:cJSON_PrintUnformatted(cJSON *item) 3、根据键值获取对应的值:cJSON *cJSON_...
Sybase.PowerDesigner.Shell
资源分类:Python库 所属语言:Python 资源全名:draco_parse-0.1-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源分类:Python库 所属语言:Python 资源全名:damask_parse-0.1.5-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
command_line_parse_xml
本文实例讲述了Zend Framework教程之Zend_Config_Ini用法。分享给大家供大家参考,具体如下: Zend_Config_Ini允许开发者通过嵌套的对象属性语法在应用程序中用熟悉的 INI 格式存储...PHP 函数。请复习这个文档了解它的
cvs_java_parse.rar cvs_java_parse.rar
xmlparse.php为封装好的xml与php数组相互转换的函数: XML->PHP: parse_xml_config(); PHP->XML: dump_xml_config(); #将转换好的XML放入文件: file_put_contents_safe().