购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.9 require、require_once、include、include_once与autoload

这是一个老问题。我们先进入一个情境,在写代码时,我们会把刚写完的函数或类归并到不同的文件中,根据功能把这些文件保存在某个目录里,再使用include()/include_once()或require()/require_once()包含它们来执行,以提高代码的重用性和简洁性。

这4个函数在产品代码里可以交替使用,但在性能上有着一些细微差别,特别是对性能要求高的项目,需要花点儿心思来分析。

include()(中文意为包含)和require()(中文意为必须)允许在当前脚本中多次执行包含的文件。include_once()和require_once()确保在执行时对包含的文件只执行一次,即使在代码中调用很多次。

如果PHP虚拟机在PHP脚本中扫描到include()或include_once()语句,若包含文件失败,会显示警告错误(Warning Error),然后还会继续执行。如果是require()或require_once()语句,包含文件失败后会抛出致命的错误提示(Fatal Error)并且中止脚本的执行。

这样当文件意外丢失或者逻辑(比如重复性包含、函数重命名等)出错时,想要脚本继续执行并输出页面,我们可以使用include()或include_once()。

在开发一个严谨应用时,要使用require()或require_once()来进行包含操作,即便包含的不是PHP文件,这样有利于应用程序的安全、完整以及健壮性。

错误只会在一个文件未被包含时触发,多数是目录存取权限或路径写错这些原因引起的。在实际的运营环境里,注意千万别把程序的错误信息抛给用户,可在代码中使用error_reporting(0)禁止所有的错误显示,内部加入完善的错误与日志处理,只给用户显示正常的内容。

从性能角度考虑,由于在导入PHP脚本时进行大量的操作状态(stat)调用,使用require()要快于require_once()。比如你请求包含的文件都在/var/www/myapp/modules/myclasss.php下,则操作系统会在到达myclasss之前的每个目录进行一次stat调用,如代码清单1-11所示:

代码清单1-11 使用require_once()包含文件


<php
require_once'ClassA.php');
require_once'ClassB.php');
require_once'ClassC.php');
require_once'ClassD.php');
echo '测试require_once'
   >

它们一共用了4个文件,均通过require_once()请求并包含。它们所请求的类均在以下代码中,它们仅声明了自己,并没有包含任何函数实现,如代码清单1-12所示:

代码清单1-12 声明要包含的类


<php
class A{
}
class B{
}
class C{
}
class D{
}>

以上4个空类可以帮助我们模仿一个需要在主脚本中使用外部PHP文件的PHP脚本。

我们排除了任何额外的函数调用,专注于使用require_once()函数的文件加载。把每个类分别放于一个单独的文件中,命名为ClasssA.php、ClassB.php、ClassC.php、ClassD.php,与代码清单1-10放在同一个文件夹下。

Apache为我们提供了ab(apache benchmark)工具,可以用它来测试使用require_once()的脚本性能:


ab c 10 n 100000 localhost/index.php

本例中我们模拟了10万个请求,同一时间有10个并发请求,结果如图1-1所示。

图1-1 使用ab测试并发请求结果

使用ab工具测试require_once(),可以看到响应时间为38.653 ms,另外结果还显示,这个脚本每秒可以支持2587.10个请求。

现在我们将require_once()改为require(),如代码清单1-13所示:

代码清单1-13 使用require()包含文件


<php
require'ClassA.php');
require'ClassB.php');
require'ClassC.php');
require'ClassD.php');
echo '测试require_once'
   >

重新启动Web服务器,再运行刚才的ab测试命令,结果如图1-2所示。

测试结果表明,使用require()后,每秒可以支持的请求数量有所提升,从2587.10提升到2589.38。此结果还说明,代码的响应时间从上面的38.653 ms降到了38.619 ms,减少了2 ms。

如果想自动加载某个文件,可以用类似下面的autoload函数,如代码清单1-14所示:

图1-2 使用ab测试require()函数的性能

代码清单1-14 使用autoload函数自动引用


spl_autoload_register'autoload');
function _autoload$name { 
    require'include/' . $name . '.php');
}

我们用spl_autoload_register告诉PHP在执行时自动加载某函数,在这里我们告诉它调用autoload函数,autoload函数根据需要的文件,使用require来包括相关的文件。

可以确定的是,require_once要慢于require,使用autoload速度最快。另外,在代码中函数调用越少,它的运行速度就越快。 RdO6HE1SgSthrMZmRY6QUHZDkwUuKBA38yQiLwCBUvjBsfC44jmaNF4IER1mneLT

点击中间区域
呼出菜单
上一章
目录
下一章
×