PHP不建议使用include_once和requer_once

PHP不建议使用include_once和requer_once

  • 前言,百度到的原因(来自鸟哥)

于使用include还是include_once(以下,都包含require_once), 这个讨论很长了, 结论也一直有, 就是尽量使用include, 而不是include_once,

 最多的理由的是, include_once需要查询一遍已加载的文件列表, 确认是否存在, 然后再加载,此操作势必对效率有所影响.

我们知道, PHP去判断一个文件是否被加载, 是需要得到这个文件的opened_path的, 意思是说, 比如:

[php] view plain copy

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


当PHP看到include_once “2.php”的时候, 他并不知道这个文件的实际路径是什么, 也就无法从已加载的文件列表去判断是否已经加载, 所以在include_once的实现中, 

会首先尝试解析这个文件的真实路径(对于普通文件这个解析仅仅类似是检查getcwd和文件路径, 所以如果是相对路径, 一般是不会成功), 如果解析成功, 则查找EG(include_files), 如果存在则说明包含过了, 返回, 否则open这个文件, 从而得到这个文件的opened_path. 比如上面的例子, 这个文件存在于 “/tmp2/2.php”.

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

[php] view plain copy

    1. 尝试解析文件的绝对路径, 如果能解析成功, 则检查EG(included_files), 存在则返回, 不存在继续  
    2. 打开文件, 得到文件的打开路径(opened path)  
    3. 拿opened path去EG(included_files)查找, 是否存在, 如果存在则返回, 不存在继续  
    4. 编译文件(compile_file)  


排除这些技术因素, 我也一直认为, 我们应该使用include, 而不是include_once, 因为我们完全能做到自己规划, 一个文件只被加载一次. 还可以借助自动加载, 来做到这一点.

你使用include_once, 只能证明, 你对自己的代码没信心.

所以, 建议大家, 不要再使用include_once

  • 解决方案

# 保持类名和文件名一致,判断该是否被定义,即知该文件是否被加载过.

# 方案1
# 通过使用class_exists判断该类未被加载
if(!class_exists('demo')){
    include('文件路径/demo.php');
}


# 方案2
# 通过定义的static静态变量来判断是否已被加载
/**
 * Method  checkIncludeFile
 * @desc  检查文件是否已被加载
 *
 * @author  LiuHao <lh@btctrade.com>
 * @param $name
 *
 * @return  bool
 */
function checkIncludeFile($name)
{
    # 静态变量
    static $exist = [];

    # 组装路径
    $path = "./{$name}.php";

    # 生成文件key
    $key = md5($path);

    # 判断文件是否存在
    if (file_exists($path)) {

        # 通过key判断文件已被加载过,不再加载
        if (isset($exist[$key])) {

            echo "该文件已被加载<br/>";

            return true;
        }

        # 加载文件
        include($path);

        # 寄存文件key
        $exist[$key] = 1;

        echo "成功加载该文件<br/>";
    } else {

        exit('文件不存在');
    }

    return true;
}

checkIncludeFile('nihao');
checkIncludeFile('nihao');
checkIncludeFile('nihao');
checkIncludeFile('nihao');
checkIncludeFile('nihao');

注意:
    1. 基本上, 如果文件名和类名保持一致.
    2. 重复引入同一个PHP文件,会报错: because the name is already in use in
    3. 原因在于, 该类名会被重复定义.
    4. 而静态文件,不会报错, 无论多少次include()该文件都不会报错.需要注意这一点.
    

echo "<hr/>";

function includeDiy($name = '')
{
    $path = "./{$name}.html";
    include($path);
    echo '加载成功';
    echo "<br/>";
}

includeDiy('nihao');
includeDiy('nihao');
includeDiy('nihao');
includeDiy('nihao');



转载于:https://my.oschina.net/chinaliuhan/blog/3064513

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值