【问题标题】:include file with visibility scope包含具有可见性范围的文件
【发布时间】:2011-11-04 17:03:07
【问题描述】:

当我们在 PHP 中包含文件时,它们会以某种方式被缓存。因此,如果一个包含一个类定义,当我们尝试包含它两次时,我们会收到一个错误消息“无法重新声明类”。

但是是否有可能在范围设置为当前函数的情况下调用包含文件代码,比如说?

例如如果我们有两个文件:

moo.php

<?php
class Moo
{
  function __construct()
  {
    echo "hello, world!" . PHP_EOL;
  }
}
?>

ma​​in.php

<?php
function foo()
{
  include("moo.php");
  new Moo();
}

foo();

new Moo(); // <-- here should be an error saying "could not find class Moo"

include("moo.php");

new Moo(); // <-- and here should not
?>

就我所尝试的而言,eval(file_get_contents("moo.php")); 和命名空间都没有以最少的代码产生预期的效果...

【问题讨论】:

    标签: php oop scope


    【解决方案1】:

    您应该尝试为您的课程实现autoload。这将有助于防止此类事情发生。

    【讨论】:

    • autoload 将为我提供全局类定义,而我需要 当前函数范围
    • @shybovycha 然后改变你的架构
    【解决方案2】:

    好像猴子在打补丁did the trick

    <?php
    $code = <<<EOS
    namespace monkeypatch;
    
    \$s = "moofoo";
    
    echo "This should six, but is it?: " . strlen(\$s) . PHP_EOL;
    echo "Whoa! And now it is six, right?: " . \strlen(\$s) . PHP_EOL;
    
    function strlen(\$x) 
    {
        return -3.14;
    }
    EOS;
    
    eval($code);
    
    echo "While out of namespaces it is still six...: " . strlen("moofoo") . PHP_EOL;
    

    非常感谢Marc B. 的提示!

    【讨论】:

    • 我不知道您实际上要达到什么目的,并且以任何方式使用eval() 都是不好的做法。至于'monkey patching'...
    • @afuzzyllama,您对如何在一个代码块中使用某些文件代码而不使其可用于其他代码部分有更好的想法吗?
    • 您是要覆盖php核心函数还是添加自己的函数?
    • @afuzzyllama 我有我应该覆盖的“核心”代码(对于一个代码块 - 在其他代码块中应该取消覆盖)而不更改它。另一个问题是覆盖代码可能是类或只是一个 php 代码。
    【解决方案3】:

    使用require_once()include_once()。它们会让 PHP 记住包含了哪些文件,而不是在代码的其他地方再次包含它们。在第一次包含/要求之后,同一文件上的后续内容将基本上成为空操作。

    【讨论】:

    • 不,我需要保留在代码中进一步实例化类的可能性(如果仅包含正确的文件)。
    • 你知道$var = new Class(); 可以做多少次,你知道的。
    • 正如我所说,如果仅包含正确的文件
    • 是的,您可以根据需要多次执行include_once('myclass.php'),因为在第一次之后,PHP 将不再实际包含该文件。所以无论你想在哪里使用你的 moo 类,做一个 include_once 并解决问题。
    • 就像 C++ 一样:只有知道类的定义,才能实例化类。当然你应该使用命名空间,但在这种情况下,似乎我需要某种“几行的命名空间”......但是该代码将在循环中运行,所以使用命名空间不是一个好主意.. .
    【解决方案4】:

    命名空间应该解决这个问题 -> http://php.net/manual/en/language.namespaces.php

    【讨论】:

    • 哎呀,刚刚看到你的代码下的最后一行 :) 你确定你正确使用了命名空间吗?
    • 是的,我需要将该文件包含在一个函数中,创建一个类(在包含的文件中描述)实例并防止在不包含该文件的情况下进一步实例化。
    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 2010-10-06
    • 2016-05-03
    • 2016-08-24
    • 2014-04-05
    相关资源
    最近更新 更多