11

这更多是为了我个人的启迪,但是,这一直困扰着我:为什么 PHP 在 CLI 模式下不能执行“自动加载”?

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

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

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

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

4

3 回答 3

7

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

PHP 带有两种交互模式,但不幸的是,它们都是通过php -a在命令 shell 上使用来调用的。

如果 PHP 使用 readline 支持编译,您将获得“交互式 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
于 2013-02-04T22:33:23.617 回答
3

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

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

从文档中可以推断出

args... 传递给脚本的参数。当第一个参数以 - 开头或从标准输入读取脚本时使用 --args

于 2013-02-04T22:47:11.050 回答
1

我想说,他们不是在谈论 CLI,而是在谈论 PHP 交互模式,也就是php -a.

为什么?因为它仅用于测试目的和简短的片段,如果自动加载任何东西,行为可能会很疯狂。

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

于 2013-02-04T22:34:19.787 回答