乐趣区

关于php:彻底搞明白PHP中的include和require

在 PHP 中,有两种蕴含内部文件的形式,别离是 include 和 require。他们之间有什么不同呢?

如果文件不存在或产生了谬误,require 产生 E_COMPILE_ERROR 级别的谬误,程序进行运行。而 include 只产生正告,脚本会继续执行。

这就是它们最次要的区别,其余方面 require 根本等同于 include。

  • 被蕴含文件先按参数给出的门路寻找,如果没有给出目录(只有文件名)时则依照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最初才在调用脚本文件所在的目录和当前工作目录下寻找
  • 如果定义了门路不论是绝对路径还是当前目录的相对路径 include_path 都会被齐全疏忽
  • include_path 在 php.ini 中定义
  • 当一个文件被蕴含时,其中所蕴含的代码继承了 include 所在行的变量范畴。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在蕴含文件中定义的函数和类都具备全局作用域

除了一般的 require 和 include 之外,还有 require_once 和 include_once,他们的作用是:

  • 如果该文件中曾经被蕴含过,则不会再次蕴含。如同此语句名字暗示的那样,只会蕴含一次
  • 能够用于在脚本执行期间同一个文件有可能被蕴含超过一次的状况下,想确保它只被蕴含一次以防止函数重定义,变量从新赋值等问题

咱们来看些例子:


// a.php 不存在
include "a.php"; // warning
// require "a.php"; // error

echo 111; // 应用 include 时 111 会输入

// file1.php 中只有一行代码 echo 'file1';
require_once 'includeandrequire/file1.php'; // file1
require_once 'includeandrequire/file1.php'; // noting

include_once 'includeandrequire/file1.php'; // noting
include_once 'includeandrequire/file1.php'; // noting

require 'includeandrequire/file1.php'; // file1
require 'includeandrequire/file1.php'; // file1

require 'includeandrequire/file1.php'; // file1
require 'includeandrequire/file1.php'; // file1

咱们能够看出当第一个_once 加载胜利后,前面不论是 require_once 还是 include_once,都不会再加载这个文件了。而不带_once 的则会反复加载文件。


file2.php

<?php

echo 'file2:' . $a, PHP_EOL;
echo 'file2:' . $b, PHP_EOL;
$b = "file2";

myFile.php

<?php

$a = 'myFile';
$b = 'youFile';
require_once 'includeandrequire/file2.php';
echo $a, PHP_EOL;
echo $b, PHP_EOL;

// 输入后果
// file2:myFile
// file2:youFile
// myFile
// file2

file3.php
<?php

$c = 'file3';

myFile.php
<?php
function test(){
    require_once 'includeandrequire/file3.php';
    echo $c, PHP_EOL; // file3
}
test();
echo $c, PHP_EOL; // empty

被蕴含文件中能够获取到父文件中的变量,父文件也能够取得蕴含文件中的变量,然而,须要留神_once 的一个非凡状况。


function foo(){
    require_once 'includeandrequire/file3.php';
    return $c;
}

for($a=1;$a<=5;$a++){echo foo(), PHP_EOL;
}

// file3
// empty
// empty
// empty
// empty

应用_once 并循环加载时,只有第一次会输入 file3.php 中的内容,这是为什么呢?因为当初的变量范畴作用域在办法中,第一次加载实现后,前面的的文件不会再被加载了,这时前面四次循环并没有 $c 被定义,$c 默认就是空值了。

如果两个办法中同时用_once 加载了一个文件,第二个办法还会加载吗?


function test1(){require_once 'includeandrequire/file1.php';}
function test2(){require_once 'includeandrequire/file1.php';}
test1(); // file1
test2(); // empty

道歉,只有第一个办法会加载胜利,第二个办法不会再次加载了。

那么,咱们在日常的开发中,应用哪个更好呢?

  • 从效率来说,_once 须要验证是否曾经加载过文件,效率会低一些,然而并不是相对的,甚至是咱们肉眼不可见的升高,所以能够疏忽它的效率问题。而它带来的益处则比不带_once 的多得多
  • 本着谬误提前的准则,应用 require_once 更好。因为将 PHP 报错级别调整为不显示正告后,include 的正告信息会不可见,会带来不可预知的谬误
  • 在办法中应用时,不应该用_once 来加载文件,特地是这个文件须要在多个类或者办法中应用时,应用_once 可能会导致前面的办法中无奈载雷同的文件
  • 应用 require 或 include 时,最好不要用括号,尽管确实能够这么应用,如 include (‘xxx.php’); 它们是表达式关键字,不是零碎办法,所以间接用 include ‘xxx.php’ 即可

include 和 require 的文件如果有 return,能够用变量接管 retun 回来的数据,另外它们还能够加载非 PHP 文件以及近程文件(近程加载须要确定 php.ini 中的 allow_url_include 为 On),如:


file4.php
<?php

return 'file4';

file4.txt
能够吧

myFile.php
<?php
$v = require 'includeandrequire/file4.php';
echo $v, PHP_EOL; // file4

include 'includeandrequire/file4.txt';
// 能够吧

include 'https://www.baidu.com/index.html';
// 百度首页的 html 代码

这下咱们对于 include 和 require 的理解就十分深刻了吧,这两个加载文件的形式并不简单,但也很容易呈现一些坑,特地是_once 在办法中应用的时候肯定要特地留神。最初,给一个小福利,封装一个一次性加载目录中所有文件的办法:


function include_all_once ($pattern) {foreach (glob($pattern) as $file) {require $file;}
}

include_all_once('includeandrequire/*');

测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/201911/source/%E5%BD%BB%E5%BA%95%E6%90%9E%E6%98%8E%E7%99%BDPHP%E4%B8%AD%E7%9A%84include%E5%92%8Crequire.php

参考文档:
https://www.php.net/manual/zh/function.require.php
https://www.php.net/manual/zh/function.include.php
https://www.php.net/manual/zh/function.require-once.php

https://www.php.net/manual/zh/function.include-once.php

各自媒体平台均可搜寻【硬核项目经理】

退出移动版