加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php中include_once和require_once性能分析

发布时间:2020-12-13 20:31:24 所属栏目:PHP教程 来源:网络整理
导读:本文章来给各位朋友介绍php中include_once和require_once性能分析,有需要了解的朋友不防参考参考. 我们知道,PHP去判断一个文件是否被加载,是需要得到这个文件的opened_path的. 实例代码如下: set_include_path( /tmp/:/tmp2/ ); include_once ( 2.php ); ?

本文章来给各位朋友介绍php中include_once和require_once性能分析,有需要了解的朋友不防参考参考.

我们知道,PHP去判断一个文件是否被加载,是需要得到这个文件的opened_path的.

实例代码如下:

  1.    set_include_path("/tmp/:/tmp2/"); 
  2.    include_once("2.php"); 
  3.    ?> 

当PHP看到include_once “2.php”的时候,他并不知道这个文件的实际路径是什么,也就无法从已加载的文件列表去判断是否已经加载,所以在include_once的实现中,会首先尝试解析这个文件的真实路径(对于普通文件这个解析仅仅类似是检查getcwd和文件路径,所以如果是相对路径,一般是不会成功),如果解析成功,则查找EG(include_files),如果存在则说明包含过了,返回,否则open这个文件,从而得到这个文件的opened_path. 比如上面的例子,这个文件存在于 “/tmp2/2.php”.

然后,得到了这个opened_path以后,PHP去已加载的文件列表去查找,是否已经包含,如果没有包含,那么就直接compile,不再需要open file了.

1. 尝试解析文件的绝对路径,如果能解析成功,则检查EG(included_files),存在则返回,不存在继续

2. 打开文件,得到文件的打开路径(opened path)

3. 拿opened path去EG(included_files)查找,是否存在,如果存在则返回,不存在继续

4. 编译文件(compile_file)这个在大多数情况下,不是问题,然而问题出在当你使用APC的时候…

在使用APC的时候,APC劫持了compile_file这个编译文件的指针,从而直接从cache中得到编译结果,避免了对实际文件的open,避免了对open的system call.然而,当你在代码中使用include_once的时候,在compile_file之前,PHP已经尝试去open file了,然后才进入被APC劫持的compile file中,这样一来,就会产生一次额外的open操作. 而APC正是为了解决这个问题,引入了include_once_override,在include_once_override开启的情况下,APC会劫持PHP的ZEND_INCLUDE_OR_EVAL opcode handler,通过stat来确定文件的绝对路径,然后如果发现没有被加载,就改写opcode为include,做一个tricky解决方案.但是,很可惜,如我所说,APC的include_once_override实现的一直不好,会有一些未定义的问题.

实例代码如下:

  1.     set_include_path("/tmp"); 
  2.     function a($arg = array()) { 
  3.         include_once("b.php"); 
  4.     } 
  5.     a(); 
  6.     a(); 
  7.     ?> 

然后,我们的b.php放置在”/tmp/b.php”,内容如下:

实例代码如下

  1.       class B {} 
  2.     ?> 

那么在打开apc.include_once_override的情况下,连续访问就会得到如下错误:

Fatal error – include() : Cannot redeclare class

排除这些技术因素,我也一直认为,我们应该使用include,而不是include_once,因为我们完全能做到自己规划,一个文件只被加载一次. 还可以借助自动加载,来做到这一点.你使用include_once,只能证明,你对自己的代码没信心.所以,建议大家,不要再使用include_once,不过我建义大家使用autoload和spl_autoload自动加载

(1) autoload机制概述

在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利.这 也是OO设计的基本思想之一.在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可.下面是一个实际的例子:

实例代码如下

  1. /* Person.class.php */ 
  2. class Person { 
  3. var $name$age
  4. function __construct ($name$age
  5. $this->name = $name
  6. $this->age = $age
  7. ?> 
  8. /* no_autoload.php */ 
  9. require_once (”Person.class.php”); 
  10. $person = new Person(”Altair”, 6); 
  11. var_dump ($person); 
  12. ?> 

在这个例子中,no-autoload.php文件需要使用Person类,它使用了require_once将其包含,然后就可以直接使用Person类来实例化一个对象.但随着项目规模的不断扩大,使用这种方式会带来一些隐含的问题:如果一个PHP文件需要使用很多其它类,那么就需要很多的require/include语 句,这样有可能会造成遗漏或者包含进不必要的类文件.如果大量的文件都需要使用其它的类,那么要保证每个文件都包含正确的类文件肯定是一个噩梦.

PHP5为这个问题提供了一个解决方案,这就是类的自动装载(autoload)机制.autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading.下面是使用autoload机制加载Person类的例子:

实例代码如下:

  1. /* autoload.php */ 
  2. function __autoload($classname) { 
  3. require_once ($classname . “class.php”); 
  4. $person = new Person(”Altair”, 6); 
  5. var_dump ($person); 
  6. ?> 

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读