为什么PHP的Autoload功能不能在CLI模式下工作?

时间:2013-02-04 22:31:38

标签: php autoload internals

这比我自己的个人启发更重要,但是,这一直困扰着我:为什么在CLI模式下PHP无法执行“自动加载”?

我多年来一直在阅读这个免责声明,但我从未读过任何涉及原因的内容:

  

http://php.net/manual/en/language.oop5.autoload.php

     
    

注意:如果在CLI交互模式下使用PHP,则无法进行自动加载。

  

有没有人知道什么阻止PHP作为一种语言,在CLI模式下工作时自动加载?

3 个答案:

答案 0 :(得分:6)

命令行上的自动加载有效。请注意提及“互动”。

PHP提供了两种交互模式,但不幸的是,它们都是在命令shell上使用php -a调用的。

如果使用readline支持编译PHP,则会获得“交互式shell”。在这种模式下,每个命令几乎立即被评估,并且您还可以获得有关任何解析错误的即时反馈。

在此模式下,自动加载有效。

另一种模式称为“交互模式”。这种模式没有任何花哨的东西,它只发出一条短消息,然后你基本上写了一个PHP脚本 - 除非你关闭STDIN,否则什么都不会完成。只有这样,编写的代码才会被解析和执行。这是唯一不为未知类调用__autoload()函数的情况。

交互式shell会话的示例(在Linux上使用PHP 5.3.2):

vagrant@lucid32:/etc/apache2$ php -a
Interactive shell

php > function __autoload($classname) {
php { echo "Autoload $classname";
php { eval("class $classname{}");
php { return true;
php { }
php > new Bar();
Autoload ▒▒Bar
php > new FooBar();
Autoload ▒▒FooBar
php > var_dump($a = get_declared_classes());
array(123) {
[0]=>
string(8) "stdClass"
[1]=>
string(9) "Exception"
[2]=>
string(14) "ErrorException"
   ... lots of internal classes here ...
[121]=>
string(3) "Bar"
[122]=>
string(6) "FooBar"
}
php >

交互模式示例(在Windows上使用PHP 5.3.18)

PS C:\Users\sven> php -a
Interactive mode enabled

<?php
function __autoload($class) { echo "Auto: $class"; eval("class $class {}"); }
echo "Hello World";
$x = new Foo;
var_dump($x);
var_dump($a = get_declared_classes());
^Z
Hello World
Fatal error: Class 'Foo' not found in - on line 4

Call Stack:
  100.6337    1114608   1. {main}() -:0

答案 1 :(得分:3)

考虑PHP的交互式CLI的方法基本上是:PHP启动一个空脚本,然后从PHP://stdin读取一个文件,然后解析并执行该文件。将忽略文件位置,因此包括路径和其他环境变量。当前__FILE__,如果您不存在的话 嗯,这只是一种观察它的方式,它并不能说明整个故事(远离它),但在实践中,这就是你能想到它的方式。根本不需要在交互式CLI中启动文件:

$ php '<?php echo "this is read from STDIN"; ?>'

As can be deduced from the docs

  

args ...传递给脚本的参数。第一个参数时使用 - args   以 - 或从stdin读取脚本

开头

答案 2 :(得分:1)

我想说,他们不是在谈论他们正在谈论的PHP互动模式,即php -a

为什么?因为它仅用于测试目的和短小的snipplet,如果ANYTHING被自动加载,行为可能会很疯狂。

http://www.php.net/manual/en/features.commandline.interactive.php