这更多的是为了我个人的启发,而不是其他任何事情,但这一直困扰着我:为什么PHP在CLI模式下不能执行"自动加载"?
多年来,我一直在阅读这份免责声明,但我从未读过任何涉及原因的内容:
http://php.net/manual/en/language.oop5.autoload.php:
注意:如果在CLI交互模式下使用PHP,则自动加载不可用
有人知道是什么阻止PHP作为一种语言在CLI模式下工作时自动加载吗?
命令行上的自动加载有效。请注意"交互式"的提及。
PHP有两种交互模式,但不幸的是,这两种模式都是通过在命令shell上使用php -a
调用的。
如果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
思考PHP交互式CLI的方法基本上是:PHP启动一个空脚本,从PHP://stdin
读取一个文件,然后解析并执行。文件位置(因此包括路径)和其他环境变量将被忽略。当前的__FILE__
(如果您愿意的话)不存在
好吧,这只是一种看待它的方式,它并不能说明整个故事(远非如此),但在实践中,你可以这样想。根本不需要在交互式CLI中启动一个文件:
$ php '<?php echo "this is read from STDIN"; ?>'
从文件中可以推断出:
args nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp;传递给脚本的参数。第一个参数使用--args nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp;以-开头,或者从stdin 读取脚本
我想说,他们谈论的不是CLI,而是PHP交互模式,也就是php -a
。
为什么?因为它只用于测试目的和简短的剪辑,如果任何东西都是自动加载的,那么行为可能会很疯狂。
http://www.php.net/manual/en/features.commandline.interactive.php