不管你所开发的网站的规模是大是小,你都应该要认识到重复使用程序代码的重要性,不论你重复使用的是 PHP 程序或者是 HTML 原始码。

举个例子来说,网站页尾的版权宣告至少每年都得修改一次,如果你的网站有许多个页面,该怎么办呢?动手一个一个修改这些页面肯定是一件头痛的事情。通过 PHP 我们可以用几个不同的方式来重复使用程序代码。要使用哪些函数端视你要重复使用的是怎样的内容而定。

这些主要的函数包 括:

* include() 与 include_once()

* require() 与 require_once()

 

1、include()

函数会将指定的档案读入并且执行里面的程序。

例 如:include('/home/me/myfile');

被导入的档案中的程序代码都会被执行,而且这些程序在执行的时候会拥有和源文件中呼叫到 include() 函数的位置相同的变量范围(variable scope)。你可以导入同一个服务器中的静态档案,甚至可以通过合并使用 include() 与 fopen() 函数来导入其它服务器上面的档案。

 

2、include_once()

函数的作用和 include() 是几乎相同的

唯一的差别在于 include_once() 函数会先检查要导入的档案是不是已经在该程序中的其它地方被导入过了,如果有的话就不会再次重复导入该档案(这项功能有时候是很重要的,比方说要导入的档案里面宣告了一些你自行定义好的函数,那么如果在同一个程序重复导入这个档案,在第二次导入的时候便会发生错误讯息,因为 PHP 不允许相同名称的函数被重复宣告第二次)。

 

3、require()

require() 函数会将目标档案的内容读入,并且把自己本身代换成这些读入的内容

这个读入并且代换的动作是在 PHP 引擎编译你的程序代码的时候发生的,而不是发生在 PHP 引擎开始执行编译好的程序代码的时候(PHP 3.0 引擎的工作方式是编译一行执行一行,但是到了 PHP 4.0 就有所改变了,PHP 4.0 是先把整个程序代码全部编译完成后,再将这些编译好的程序代码一次执行完毕,在编译的过程中不会执行任何程序代码)。

require() 通常来导入静态的内容(例如配置文件,全局变量等静态值),而 include() 则适合用来导入动态的程序代码(例如JS,AJAX)

 

4、require_once()

如同 include_once()函数,require_once() 函数会先检查目标档案的内容是不是在之前就已经导入过了,如果是的话,便不会再次重复导入同样的内容。

一般使用 require() 函数来导入版权宣告(copyrights),静态文字或其它本身不含有变量,或者本身需要倚赖其它执行过的程序才能正确执行的程序代码。例如:

<HTML>
<HEAD> <TITLE>网页标题</TITLE></HEAD>
<BODY>
[一堆内容]
<?
	// 导入版权宣告文字
	require('/home/me/mycopyright');
?>
</BODY> 
</HTML>

 

另一方面,通常在程序的开头使用 include() 函数来导入一些函式库或者类似的程序代码:

<?
// 导入我的函式库
include('/home/me/myfunctions');

// 利用之前导入的函式库里面定义好的 PHP 函数执行一些功能?>
<HTML>
<HEAD><TITLE>网页标题</TITLE></HEAD>
<BODY>
[一 堆内容]
</BODY>
</HTML>

接下来你可能会问这第一个挺符合逻辑的问题:

这些被导入的档案要放在哪儿呢?答案是:放在服务器档案系统里的任何地方都行。

然而,要留意的是如果被导入的档案除了单纯的程序代码片段以外还包含了一些敏感资料,例如连结数据库系统要用到的帐号和密码,那么建议你不要把这些档案放在 Web 服务器的文件根目录之下,因为那样的话他人便可以很容易地窃取到这些资料了。

你可以将这些被包含的档案放在系统的任何一个目录里面,唯一的条件是 PHP 本身用来执行的身分(www,nobody 或者其它身分)必须要有足够的权限能够读取这些档案就可以了。这些档案的扩展名也可以任意取,甚至没有附档名也无所谓。

善用 include()和 require()来将网站里面经常需要变动的共享内容做合理的分割,在更新网站内容的时候将会容易进行得多。

 

区别对比和使用场景

include、include_once、require、require_once这4个函数:

1)include函数:会将指定的文件读入并且执行里面的程序(动态加载,PHP输出等);

2)require函数:会将目标文件的内容读入,并且把自己本身代换成这些读入的内容(静态载入,加载配置参数、全局变量等);

3)include_once 函数:在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次;

4)require_once 函数:和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

四个函数加载文件的执行时间基本上差不多,区别在于,如果存在一个文件多次加载的情况,include和require函数会加载多次,而 include_once和require_once函数只会加载一次

require() 通常来导入静态的内容(例如配置文件,全局变量等静态值),而 include() 则适合用来导入动态的程序代码

include()和require()函数,这两种结构除了在如何处理失败之外完全一样,二者在处理加载失败的情况不同

include() 和 include_once() 产生一个警告,而 require() 和 require_once() 则导致一个致命错误

换句话说,如果想在遇到丢失文件时停止处理页面就用 require()。include() 就不是这样,脚本会继续运行。

所以,一般重要文件用require(如:类库),不重要的用include(如:模板)

 

同时也要确认设置了合适的 include_path。注意在 PHP 4.3.5 之前,包含文件中的语法错误不会导致程序停止,但从此版本之后会。

寻找包含文件的顺序先是在当前工作目录的相对的 include_path 下寻找,然后是当前运行脚本所在目录相对的 include_path 下寻找。例如 include_path 是 .,当前工作目录是 /www/,脚本中要 include 一个 include/a.php 并且在该文件中有一句 include "b.php",则寻找 b.php 的顺序先是 /www/,然后是 /www/include/。如果文件名以 ./ 或者 ../ 开始,则只在当前工作目录相对的 include_path 下寻找。

当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。

include_once() 和require_once()函数

include_once() 和require_once()语句在脚本执行期间包含并运行指定文件。此行为和 include() 和require() 语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。

include_once() 和require_once()应该用于在脚本执行期间同一个文件有可能被包含超过一次的情况下,想确保它只被包含一次以避免函数重定义,变量重新赋值等问题。

 

 

1、include与require的区别

1)引入文件的方式不同

include 会读取指定文件,并执行里面的程序,一般在PHP文件的中间或底部;

requrire 将目标文件内容替换到自身,一般在PHP文件的开头;

 

2)通常放置的位置不同

include 一般放在流程控制的处理部分,当执行到include时再读取文件,可将程序流程简单化;

requrire 一般放在PHP程序最前面,在程序代码执行前,先读取指定的文件,将其作为程序的一部分;

 

3)当引入文件不存在时,处理行为不同

include 会产生一个警告,但脚本会继续运行;

requrire 会导致一个致命错误,并停止运行;

所以,一般重要文件用require(如:类库),不重要的用include(如:模板)

include与require除了在处理引入文件的方式不同外,最大的区别就是:

include在引入不存文件时产生一个警告且脚本还会继续执行,而require则会导致一个致命性错误且脚本停止执行。

<?php
  include 'no.php';
  echo '123';
?>

如果 include no.php文件不存在,echo '123'这句是可以继续执行的.

 

你看到的可能是类似下边的情况:

<?php
require 'no.php';
echo '123';
?>

如果 require no.php文件不存在,echo '123'这句是不执行的,在require时就停止了。

你看到的可能是类似下边的情况:

4)功能相似,执行的条件不同

include 在下面例子中,只有$val为真,才包含文件file;

requrire 在下面例子中,不管$val真假,都会包含文件file;

include()与require()的功能相同,但在用法上却有一些不同,

include()是有条件包含函数,而 require()则是无条件包含函数

例如:在下面的一个例子中,如果变量$somgthing为真,则将包含文件somefile:

if($something){
include("somefile");
}

但不管$something取何值,下面的代码将把文件somefile包含进文件里:

if($something){
require("somefile");
}

 

5、返回值

如果被包含的文件内用return返回,那么无论include/require就会有return的值返回;

如果被包含的文件内没有使用return返回,那么无论include/require,成功返回int(1),失败返回boolean(false)

2.php
<?php  
    return 'wakaka';  
?> 

1.php
<?php  
    $ret = include '2.php';  
    echo $ret; //输出wakaka  
?>

如果使用include_once/require_once包含文件,成功返回boolean(true),失败返回boolean(false)

如果前面已经包含了该文件,文件内使用return返回,那么再使用include_once/require_once包含相同文件时是返回boolean(true)

 

2、include 与 include_once的区别(require与require_once的区别,同理)

include_once (require_once)语句在脚本执行期间包含并运行指定文件。

此行为和 include (require)语句类似,区别是如果该文件中的代码已经被包含了,则不会再次包含,只会包含一次。

include_once(require_once)需要查询一遍已加载的文件列表,确认是否存在,若不存在再加载,多一次检查的时间。

<?php
require '1.php';
require '1.php';
?>

这种情况下1.php被包含两次。

<?php
require '1.php';
require_once '1.php';
?>

这种情况下,第二次包含时,是不会进行包含的(检查过,已包含,跳过)。

 

3、include(require)与 include_once(require_once)的抉择问题

通常,include_once和require_once会有性能上的下降,因为他需要判断之前是否包含过。

一般情况下,也不太需要去考虑,除非这已经影响到你程序的性能了。

如果使用 APC 尽量也不要用include_once,因为apc.include_once_override配置项没有很好的被实现(详情百度)。

注:Alternative PHP Cache (APC)是一种对PHP有效的开放源高速缓冲储存器工具,它能够缓存opcode的php中间码。

 

require通常使用方法,这个函数通常放在 PHP 程序的最前面,PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。常用的函数,配置的参数,全局的变量,亦可以这个方法将它引入网页中

include通常使用方法,这个函数一般是放在流程控制的处理部分中。PHP 程序网页在读到执行 include 的文件时,才将它include读进来。这种方式,可以把程序执行时的流程简单化。

包含函数后加不加括号,return 在返回引用的时候加上括号不但效率低而且会造成逻辑错误。

理论上来说:include和require后面加不加括号对执行结果没有区别,但是加上括号效率较低,所以后面能不加括号就不加括号,推荐不加括号。

 

 

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个并发请求。

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

现在我们将require_once()改为require():

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

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

重新启动Web 服务器,再运行刚才的ab测试命令。

测试结果表明,使用require()后,每秒可以支持的请求数量有所提升,每秒可以支持从2587.10提升到2589.38。

此结果还说明,代码的响应时间从上面的38.653 ms降到了38.619 ms,减少了2 ms

 

autoload 函数

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

代码清单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速度最快

另外,在代码中函数调用越少,它的运行速度就越快。

 

 

结论

1、放置位置与功能

1)require 一般在 PHP 文件开头,引入配置文件、全局变量、用到的函数,在程序代码执行前,先读取指定的文件,将其作为程序的一部分;

2)include 一般放在 PHP 中间或底部,放在流程控制的处理部分,当执行到include时再读取文件,可将程序流程简单化;

 

2、尽量使用 require

require 包含多次,不用检查(require_once, include_once)不损失性能

require 有报错提示,及时发现问题;include 则不报错,继续执行,没法发现问题

母版的 header.php,footer.php 大多是多静态、少动态,如配置文件、引入函数、打印日期、JS执行等,使用 require 即可

 

3、require 和 include 尽量不加括号

include和require后面加不加括号对执行结果没有区别,但是加上括号效率较低,所以后面能不加括号就不加括号,推荐不加括号。

 

 

参考推荐:

PHP 多级嵌套的相对目录解决办法

PHP 路径详解 dirname,realpath,__FILE__,getcwd

PHP 出现 Notice: Undefined index: 的几种解决方法

PHP 常见错误处理

PHP在 linux上执行外部命令

PHP 文件操作常用函数

PHP 常用函数总结(数组,字符串,时间,文件操作)

PHP + Selenium + WebDriver 抓取米扑科技首页

PHP 获取网页标题(title)、描述(description)、关键字(keywords)等meta信息

PHP 下载保存文件到本地

PHP下载远程图片

PHP抓取网站ico图标