为啥在方法中使用 require_once 有时会失败?

Posted

技术标签:

【中文标题】为啥在方法中使用 require_once 有时会失败?【英文标题】:Why require_once sometimes fails when used within a method?为什么在方法中使用 require_once 有时会失败? 【发布时间】:2020-02-20 14:02:51 【问题描述】:

如果我做这样的事情(这只是一个虚拟示例,但对解释问题很有用):

variables.php:

<?php
$foo = 'foo';
$bar = 'bar';
?>

SomeClass.php:

<?php
class SomeClass 

    public static function do_something() 
        // XXX Sometimes this works well; but sometimes,
        //     imported variables are null or empty for some
        //     reason within this method's scope
        require_once( dirname(__FILE__) . '/variables.php' );

        echo '<p>foo = '.$foo.'</p>';
        echo '<p>bar = '.$bar.'</p>';
    

?>

两个文件都在同一个文件夹中;虽然这个类实际上在其他文件夹中的脚本中是必需的。

大多数时候它只是按预期打印:foo = foobar = bar;但是当一些执行一些繁重操作的脚本需要这个类时(在数组中填充大量变量以及其他东西,比如计算),它的行为就像导入的变量根本不存在(打印foo =bar = )。

查看 apache 的 error.logrequire_once 根本不会抛出任何错误;但它会打印如下内容:

 PHP Notice:  Undefined variable: foo in /path/to/class_and_variables/SomeClass.php at line 10
 PHP Notice:  Undefined variable: bar in /path/to/class_and_variables/SomeClass.php at line 11

通常情况下,它按预期工作,变量在do_something的范围内正确导入;但对于一些特定的脚本,它不会。

这就像(我猜)PHP 内存不足并默默地破坏了导入的变量?我不知道为什么 PHP 的 require_once 有时会表现得如此奇怪......

【问题讨论】:

失败时能举个例子吗 我只是不知道require_once 会首先查看当前文件:我以为它只是查看PATH 中的可用目录。所以使用dirname(__FILE__) 看起来是个好主意 @trey 路径不是相对于“当前文件”,它是相对于当前工作目录,它并不总是与“当前文件”相同”。使用__FILE__ 使其绝对化是个好主意。 @deceze:实际上,我用错了词:我的意思不是“会查看当前文件”,而是“在当前目录”。对此感到抱歉 @trey 如果将它们都放入某个子目录并在该子目录之外执行require 'sub/a.php' 的文件,那么当前工作目录,都需要是相对的,不会是sub 【参考方案1】:

我认为这只会包含在方法的第一次执行中,而不会包含在第二次执行中。然后该方法的第二次执行将没有定义变量。你应该改用require

【讨论】:

换句话说,如果该文件之前已经包含在其他任何地方,这将失败。 非常感谢。虽然知道require_oncerequire之间的区别,但我有时还是无法理解require_once的行为(现在我为自己感到羞耻)...... 你不应该感到羞耻,你应该看到 required_once 作为一个布尔值,如果文件已经加载过一次,其余的请求将返回 FALSE,因为它已经被使用过“一次”。

以上是关于为啥在方法中使用 require_once 有时会失败?的主要内容,如果未能解决你的问题,请参考以下文章

为啥函数require_once会阻止我的代码工作[关闭]

为啥人们说 require_once 比 require 慢? [复制]

为啥有时在计时器滴答事件中它会连续两次调用该方法?

为啥 require_once 在以下情况下不起作用?

为啥当代码有效时 JQuery .val() 方法有时会返回 undefined? [复制]

为啥 PasteSpecial 方法有时会抛出错误 1004?