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


·        作者Laruence(   )

·        本文地址http://www.laruence.com/2009/04/24/695.html

·        转载请注明出处

我看到过很多人操作数组的时候, 对于数组中的非数字键名不使用引号,

1.         $array[key] = $value;

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

1.       error_reporting = ~E_NOTICE

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

, 我们一起来看看:

1.       good.php:

2.       <?php

3.          $array = array();

4.          $i = 0;

5.          while(++$i < 1000){

6.              $array['good'] = 2;

7.          }

8.       ?>

9.        

10.    bad.php:

11.    <?php

12.       $array = array();

13.       $i = 0;

14.       while(++$i < 1000){

15.           $array[good] = 2;

16.       }

17.    ?>

分别看运行时间(多次平均时间):
加引号的:

1.       $ time php -f good.php

2.        

3.       real    0m0.013s

4.       user    0m0.005s

5.       sys     0m0.007s

不加引号的:

1.       $ time php -f bad.php

2.        

3.       PHP Notice:  Use ofundefined constant bad - assumed 'bad' in /home/huixinchen/tmp/bad.php

4.       on line (此处省略999NOTICE)

5.       real    0m0.100s

6.       user    0m0.020s

7.       sys     0m0.029s

看看,差别有多大?
, 或许我们应该模拟一下那些幸运的人们的情况, 去掉花费在记录NOTICE的开销, 看看~

1.       $ time php -f bad.php

2.        

3.       real    0m0.037s

4.       user    0m0.018s

5.       sys     0m0.018s

我们可以看出, 基本上, 使用引号,和不使用引号的效率损失在3倍以上

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

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

good.php:

1.       filename:      /home/huixinchen/tmp/good.php

2.       compiled vars:  !0= $array, !1 = $i

3.       line     #  op                           fetch          ext return  operands

4.       -------------------------------------------------------------------------------

5.          2    0  INIT_ARRAY                                       ~0

6.                1  ASSIGN                                                  !0, ~0

7.          3    2 ASSIGN                                                  !1, 0

8.          4    3  PRE_INC                                         $3      !1

9.                4  IS_SMALLER                                       ~4      $3, 1000

10.             5  JMPZ                                                     ~4, ->9

11.       5    6  ZEND_ASSIGN_DIM                                          !0,'good'

12.             7  ZEND_OP_DATA                                             2,$6

13.       6    8  JMP                                                     ->3

14.       8    9  RETURN                                                  1

15.            10*ZEND_HANDLE_EXCEPTION

bad.php:

1.       filename:      /home/huixinchen/tmp/bad.php

2.       compiled vars:  !0= $array, !1 = $i

3.       line     #  op                           fetch          ext return  operands

4.       -------------------------------------------------------------------------------

5.          2    0  INIT_ARRAY                                       ~0

6.                1  ASSIGN                                                  !0, ~0

7.          3    2  ASSIGN                                                  !1, 0

8.          4    3  PRE_INC                                         $3      !1

9.                4  IS_SMALLER                                       ~4      $3, 1000

10.             5  JMPZ                                                     ~4, ->10

11.       5    6  FETCH_CONSTANT                                   ~5      'bad'

12.             7  ZEND_ASSIGN_DIM                                          !0,~5

13.             8  ZEND_OP_DATA                                             2, $7

14.       6    9  JMP                                                     ->3

15.       8   10  RETURN                                                  1

16.            11*ZEND_HANDLE_EXCEPTION

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

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

1.       define('key_name' , 'laruence');

2.       ....

3.       //省略很多行代码

4.       $array[key_name] = 2;//变成了 $array['laruence'] = 2;

5.       //这样的错误, 你会很郁闷吧?

明白了么? 数组中的非数字键的键名一定要有引号啊~
, 还记得有人会说, 那在字符串变量替换的时候,写引号会导致错误,
, 标准写法:

1.       $string = "variable value is {$array['key']}"

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

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

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

1.       ....

2.       if (!zend_get_constant(opline->op2.u.constant.value.str.val,

3.            opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {

4.              zend_error(E_NOTICE, "Use of undefined constant %s - assumed'%s'",

5.                       opline->op2.u.constant.value.str.val,

6.                       opline->op2.u.constant.value.str.val);

7.              EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;//获取"常量"名字符串

8.              zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);//分配空间,生成字符串

9.       }

10.    ....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值