Press "Enter" to skip to content

PHP RFC: 让PHP的foreach支持list

上个月, 终于算加入了PHP developer team, 一直以来最大的障碍就是语言, 现在想起来, 当年真应该更加认真努力的去学习英语.
得到的第一个任务是: 解决一个feature request, 请求在allow foreach($array as list($a,$b)
大意是说, 希望PHP能支持如下语法:

<?php
foreach (array(array(24,2333), array(31,4666)) as $k => list($a, $b)) {
    printf("key:%s, a=>%s, b=>%s\n", $k, $a, $b);
}
/** output:
key:0, a=>24, b=>2333
key:1, a=>31, b=>4666
*/

实现这个功能, 入手点就是去改写PHP的语法分析逻辑, 具体的实现我会再后面附上对PHP5.4的patch.

Filed in PHP源码分析, 转载
with 8 Comments

Zend Parameters Parser新增类型描述符介绍

从PHP5.3开始, zend_parse_paramters_*函数新增了如下几个新的类型描述符:

f  - function or array containing php method call info (returned as
      zend_fcall_info and zend_fcall_info_cache)
H  - array or HASH_OF(object) (returned as HashTable*)
L  - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (long)
Z  - the actual zval (zval**)
*  - variable arguments list (0 or more)
+  - variable arguments list (1 or more)

这也使得我们做扩展开发的时候, 能更加轻松的处理输入参数, 得到想要的值.

Filed in PHP应用, PHP源码分析
with 4 Comments

深入理解PHP内存管理之谁动了我的内存

首先让我们看一个问题: 如下代码的输出,

var_dump(memory_get_usage());
$a = "laruence";
var_dump(memory_get_usage());
unset($a);
var_dump(memory_get_usage());

输出(在我的个人电脑上, 可能会因为系统,PHP版本,载入的扩展不同而不同):

int(90440)
int(90640)
int(90472)

注意到 90472-90440=32, 于是就有了各种的结论, 有的人说PHP的unset并不真正释放内存, 有的说, PHP的unset只是在释放大变量(大量字符串, 大数组)的时候才会真正free内存, 更有人说, 在PHP层面讨论内存是没有意义的.
那么, 到底unset会不会释放内存? 这32个字节跑哪里去了?

Filed in PHP应用, PHP源码分析
with 46 Comments

加速PHP的ECHO

你也许注意到过, 在PHP中使用ECHO输出大段字符串的时候, 执行时间会明显的长, 也就会有朋友认为PHP的ECHO性能很差.
我在之前的文章中, 已经解释过了原因, 也希望能纠正"PHP的ECHO性能差"的这个误会.
然而之前的文章, 也仅仅是给出了原因, 并没有介绍如何避免这个问题, 在今天公司内的某个产品线(Apache with PHP)发现了一个问题, 有用户在短时间内大量发起下载请求, 导致http连接数和数据库连接数剧增,
而数据库连接数剧增的原因是因为数据库的连接是单列模式, 一直到请求处理结束, 才会释放数据库链接. 这样就有了一个问题, 如果请求处理时间过长, 就会造成大量的数据库链接存在.
而这个用户的网速很慢,, 下载时间很长~, 这也就意味着, ECHO的"性能"很差~
这也就引出了今天我要谈的这个问题, 如何让ECHO变快, 让PHP的请求处理过程, 尽快结束...

Filed in PHP应用, PHP源码分析
with 33 Comments

深入理解PHP内存管理之一个低概率Core的分析

一个同事forward过来一个, 公司某产品线遇到的一个低概率, 但长时间出现了几次的Core的bt信息, 找我帮忙分析下原因.
bt栈如下(路径信息以*代替):

#0  0x00000000004a75e5 in _zend_mm_alloc_int (heap=0xd61260, size=79)
at /*/php-5.2.6/Zend/zend_alloc.c:1879
#1  0x000000000048d3cd in vspprintf (pbuf=0x7fbffe9cd8, max_len=1024, format=Variable "format" is not available.
)
    at /*/php-5.2.6/main/spprintf.c:224
#2  0x0000000000489747 in php_error_cb (type=1, error_filename=0x2a9a787ee8 "/*/application/helpers/util.php",
    error_lineno=1149, format=Variable "format" is not available.
) at /*/php-5.2.6/main/main.c:799
#3  0x000000000061db35 in soap_error_handler (error_num=1,
    error_filename=0x2a9a787ee8 "/*/application/helpers/util.php", error_lineno=1149,
    format=0x7b9cb8 "Maximum execution time of %d second%s exceeded", args=0x7fbffea3b0)
    at /*/php-5.2.6/ext/soap/soap.c:2178
#4  0x00000000004c2576 in zend_error (type=1, format=0x7b9cb8 "Maximum execution time of %d second%s exceeded")
    at /*/php-5.2.6/Zend/zend.c:976
#5  <signal handler called>
#6  0x00000000004a720f in _zend_mm_free_int (heap=0xd61260, p=Variable "p" is not available.
) at /*/php-5.2.6/Zend/zend_alloc.c:844
...以下省略

Filed in PHP应用, PHP源码分析
with 12 Comments