从方法内部调用PHP require类

13

据我的理解,require将代码粘贴到调用PHP文件中。

如果您在方法内部进行require操作...它将整个代码/类粘贴在该方法中,阻塞该方法中的下一条语句。

例如:

  function test() {

    require 'pathtosomeclasscode';
    somestatement; // any code after the require is blocked.

 }

我该如何解决这个问题,才能够在任何地方调用代码,而不必将其粘贴在特定位置?


为什么它会阻塞下一条语句? - zneak
它将使所有的代码失调,例如将类粘贴在函数内部。 - Jeremy Gwa
1
@jera:这不是发生的情况。我在我的回答中已经说过了,但我在这里要加强一下:您是否遇到了错误/故障,使您相信这是真的?如果是,请向我们提供更多详细信息,以便我们可以纠正问题的根源。 - icio
icio是正确的。这个代码可以正常工作(请参见我的示例代码)。如果您使用require_once,并且您包含的文件仅定义一个类,那么您实际上是在以一种有点混乱的方式进行惰性加载类定义。 - timdev
我曾经遇到过一个相关的问题,但是我的谷歌搜索方式不正确,所以这里提供一个链接给那些可能遇到同样错误的人解决问题: https://dev59.com/5Gct5IYBdhLWcg3wPLCB - Emanuel Graf
嵌套类不被允许,是吗? - s3c
6个回答

22

有点令人惊讶的是,这似乎完全正常。包含的代码将在Baz::bork()的范围内执行 - 但是代码只是定义了一个类,而类是全局的。所以最终你会得到一个已定义的类。

文件:Foo.php:

<?PHP
class Foo{
      function bar(){
               echo "Hello from Foo::bar()!\n";
      }
}

文件:Baz.php:

<?PHP
class Baz{

      function bork(){
               require_once "Foo.php";
               $f = new Foo();
           $f->bar();
      }
}

echo "testing internal definition:\n";
$b = new Baz();
$b->bork();

echo "\ntesting in global scope:\n";

$f = new Foo();
$f->bar();
echo "\nall done\n";

输出:

$ php Baz.php
testing internal definition:
Hello from Foo::bar()!

testing in global scope:
Hello from Foo::bar()!

all done

现在,我想不出有多少地方需要以这种方式进行操作。人们通常会在类文件的顶部、类定义之外使用require_once()来引入所有可能的依赖项。


当所需文件是可变的时,这非常有用:require_once $dirName . "/../{$fileName}.php"; - James P.
1
如果文件还指定了一个命名空间,它会正确处理吗?是的,它可以正常工作。 - SiXoS
@JamesPoulson 这对于条件/延迟加载代码也非常有用。例如,WordPress插件可能具有仅在前端/后端/Ajax调用/特定页面等上使用的代码。由于插件在知道您所在的页面/帖子之前加载,因此需要延迟加载,在wp中使用操作完成,这将调用是的,一个函数...这可以加快服务器端的速度,但也可以避免加载不必要的样式和脚本,从而减少不必要的请求... - user1115652

7
调用requirerequire_onceincludeinclude_once不会停止函数内代码的执行,除非包含的脚本存在问题。被包含文件中的代码在与函数相同的范围内执行(定义的函数和类是全局的),而不是插入到其中替换其他内容。
其他答案建议使用require的替代方法作为解决方案——如果您的脚本错误与命名冲突有关(即尝试重新定义类或函数),则这些解决方案可能适用于您,否则您可能希望提供更多细节来说明发生了什么问题(或未发生),以便我们可以帮助您解决真正的原因。
此外,这些文件包含方法不会将代码“粘贴”到您的脚本中。 “粘贴”是人们用来维护文本的工具。我建议您阅读PHP手册,以进一步了解这些函数的工作方式: 如果您在研究它们后对它们的工作方式有进一步的问题,请再次发帖。

1
如果您使用 include_once('script.php'),就不会遇到有关类重新声明的错误。
我自己没有尝试过以下方法,不过我认为,如果您不想多次使用 include_once() ,这种设置也可能起作用。
class Whatever {

    protected $classObject;
    public function __construct( /*...*/ ) {
        include('anotherClass.php');
        $this->classObject = new anotherClass();
    }

    public function someFunction( /*...*/ ) {
        $this->classObject->classObjectFunction();
    }

    public function anotherFunction( /*...*/ ) {
        $this->classObject->classObjectFunction();
    }
}

您可以调用以下代码,该代码将分别调用同一共享类对象中的函数:
$Whatever = new Whatever();
$Whatever->someFunction();
$Whatever->anotherFunction();

1

尝试使用 require_once 吗?以防您在其他地方包含它。


0

我认为你的意思是你不想让代码立即执行。如果是这样,你有几个选项:

  1. 你可以移动 require。

  2. 你也可以使用 fopen() 读取文件,然后解析它。(你不能调用 eval,因为它无法理解 HTML,但你可以使用解析器)


0

我看到你在使用外部文件来加载类,是吗?为什么不使用自动加载类呢?我知道当你想在不同情况下加载不同的类体时它可能无法正常工作,但我真的不知道这是否是一个好的实践。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接