标签:风雪之隅

浏览模式: 标准 | 列表 | 图文
杂谈

杂谈

1、高春辉表示升级到了5.3.3,不知道是不是手机之家,但,我真的不敢升级,即使我的版本中basename对中文的处理一塌糊涂,我也不敢升,因为实在不知道升级后会出现什么样奇怪的错误。高春辉说:

1、parse_url 执行出错的时候不再报 warning 错误了,不再需要使用 @ 了,但是要仔细判断结果是否为 FALSE 了;
2、FPM 终于内置了,配置文件从 XML 改成 INI 方式了,增加了例如 xxx.com/status 的报告,和例如 xxx.com/ping 的健康检查功能了,挺好;
3、另外这次编译的时候把 ereg 模块也干掉了。以前是为了兼容 PMA,现在 PMA 也不用 ereg 了,就可以 DROP 它了。

2、对于typecho,我对牧师的网站上的两个模版,我很喜欢。。。

  1. http://typecho.demo.m4go.com/m4tom/
  2. http://bl.typecho.me/

这可能是个人爱好问题,并非其他模版不好看。

3、上次我在博客里贴了老王的:<?php if($a = 100 && $b= 200){var_dump($a,$b);}?>,结果风雪之隅解释的更详细:http://www.laruence.com/2010/07/26/1668.html,他说,手册上说了:

Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.
差不多就是说:其实也简单, 运算符优先级是在存在二义性文法的时候的一种规约规则选择的手段, 而PHP的语法分析文件定义中, 却让等号和T_BOOLEAN_AND(&&)之前不存在了规约冲突.
PHP调试技术手册发布

PHP调试技术手册发布

这个PDF确实不错。只是。。。没有介绍netbeans下如何调试。phped下也没有介绍。仅介绍了zendstudio for eclipse和pdt还有vim的调试。不过。。。还是有很用处的东西。

对于浏览器的测试,除了PHP方面的print_r,var_dump等。他也介绍了firephp这个firefox的插件(基于firebug,如果不知道firebug那我也没啥好说的了)

对于最后简单的测试时间花费,也是用的传统的microtime来取的。额。。。他用的是PHP4的写法。只是最后介绍phpUnit就有点简单了。

1 内置API输出调试
1.1 基本调试API
1.1.1 echo (print):
1.1.2 printf
1.1.3 print_r、var_dump(var_export)、debug_zval_dump
1.2 错误控制和日志记录调试
1.2.1 错误选项控制
1.2.2 错误抛出和处理
1.2.3 使用错误抑制符
1.2.4 日志记录
2 浏览器调试
2.1 页面输出调试
2.2 FirePHP 调试
2.2.1 普通变量监测
2.2.2 调用栈监测
2.2.3 监测抛出异常
2.2.4 组显示信息
3 IDE 调试
3.1 基本常用IDE介绍
3.1.1 Vim
3.1.2 Zend Studio
3.1.3 Eclipse
3.1.4 NetBeans
3.2 IDE调试
3.2.1 Zend Studio + Zend Debugger
3.2.2 Eclipse (PDT) + Xdebug
3.2.3 Vim + Xdebug + DBGp
4 PHP 性能调试技术
4.1 基本时间占用监测
4.2 使用 Xdebug 进行性能分析
4.2.1 安装配置:
4.3 APD(Advanced PHP Debugger)
4.3.1 安装配置
4.3.2 使用APD
4.4 使用Xhprof 进行性能分析
4.4.1 Xhprof 的优点:
5 PHP单元测试技术
5.1 PHPUnit
下载地址: http://heiyeluren-doc.googlecode.com/files/PHP-Debug-Manual-public.pdf

本地备份:d55ae9b2213402dd2c92fc94d5792a9b

来源网址:http://www.laruence.com/2010/06/21/1608.html

数组非数字键名引号的必要性

数组非数字键名引号的必要性

风雪之隅的网站上大多是对PHP的底层进行关注的文章,如果对PHP的核心内容有兴趣不妨多翻阅一下他的网站。

本文的标题,其实是一个老问题了。
大家都知道,PHP对于没有引号的字符串,会当成常量来处理,如果该常量不存在,则直接输出该字符串。也就是多做了几步处理。
事实上,上面的这个知识点,很早就知道,但,不是我自己研究出来的。虽然自己写过代码进行测试过。

雪候鸟则直接从OPCODE上进行查看,给你一个直观印象。好,我们来看看原文吧
地址:http://www.laruence.com/2009/04/24/695.html
内容:
我看到过很多人操作数组的时候, 对于数组中的非数字键名不使用引号,

$array[key] = $value;

我可以理解有些人可能会觉得这样的代码很”整洁”, 并且也能正常执行.
更甚至,如果他很”幸运的”php配置的好:

error_reporting = ~E_NOTICE

他也许永远都沉浸在自己的”整洁”风格中, 看不到任何的NOTICE提示, 也不会意识到, 他这么做, 能损失多少的性能~

来, 我们一起来看看:

good.php:
<?php
$array = array();
$i = 0;
while(++$i < 1000){
$array['good'] = 2;
}
?>

bad.php:
<?php
$array = array();
$i = 0;
while(++$i < 1000){
$array[good] = 2;
}
?>
分别看运行时间(多次平均时间):
加引号的:
$ time php -f good.php

real 0m0.013s
user 0m0.005s
sys 0m0.007s
不加引号的:
$ time php -f bad.php

PHP Notice: Use of undefined constant bad - assumed 'bad' in /home/huixinchen/tmp/bad.php on line
(此处省略999行NOTICE)
real 0m0.100s
user 0m0.020s
sys 0m0.029s
看看,差别有多大?
哦, 或许我们应该模拟一下那些”幸运的”人们的情况, 去掉花费在记录NOTICE的开销, 看看~
$ time php -f bad.php

real 0m0.037s
user 0m0.018s
sys 0m0.018s
我们可以看出, 基本上, 使用引号,和不使用引号的效率损失在3倍以上

那么, 这些效率损失到哪里去了呢?

我们分别看下, 俩个文件生成的OPCODE序列:

good.php :

filename: /home/huixinchen/tmp/good.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
2 0 INIT_ARRAY ~0
1 ASSIGN !0, ~0
3 2 ASSIGN !1, 0
4 3 PRE_INC $3 !1
4 IS_SMALLER ~4 $3, 1000
5 JMPZ ~4, ->9
5 6 ZEND_ASSIGN_DIM !0, 'good'
7 ZEND_OP_DATA 2, $6
6 8 JMP ->3
8 9 RETURN 1
10* ZEND_HANDLE_EXCEPTION
bad.php :
filename: /home/huixinchen/tmp/bad.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
2 0 INIT_ARRAY ~0
1 ASSIGN !0, ~0
3 2 ASSIGN !1, 0
4 3 PRE_INC $3 !1
4 IS_SMALLER ~4 $3, 1000
5 JMPZ ~4, ->10
5 6 FETCH_CONSTANT ~5 'bad'
7 ZEND_ASSIGN_DIM !0, ~5
8 ZEND_OP_DATA 2, $7
6 9 JMP ->3
8 10 RETURN

我们可以看出(其实,根据NOTICE的提示也知道), PHP会把没有引号引起来的键名当作是常量去获取, 当找不到的时候, 抛出一个NOTICE, 然后再根据”常量明”生成一个字符串, 然后再讲这个字符串做为键名继续~

聪明的你一定会想到, 可能会出现如下不可预期的错误:

define('key_name' , 'laruence');
....
//省略很多行代码
$array[key_name] = 2; //变成了 $array['laruence'] = 2;
//这样的错误, 你会很郁闷吧?
明白了么? 数组中的非数字键的键名一定要有引号啊~
哦, 还记得有人会说, 那在字符串变量替换的时候, 写引号会导致错误,
恩, 标准写法:
$string = "variable value is {$array['key']}"

我很赞同:”be lazy”, 但是, lazy也是应该有原则的.

最后, 好的代码,不应该通过关闭error_reporting来伪装.

附注, FETCH_CONSTANT OPCODE中找不到常量的相关逻辑:

....
if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
opline->op2.u.constant.value.str.val,
opline->op2.u.constant.value.str.val);
EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;//获取"常量"名字符串
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);//分配空间,生成字符串
}
....

——EOF——

膘叔最受不了的,就是discuz,特别是模版中的变量,全部是不含单引号的。写起来是方便啊。但是性能不敢恭维。所以common.inc.php的前面几句就是error_reporting了。。隐藏掉,看你怎么办,有本事你咬我呀。。

我还能怎么办?