英文:
PHP class out of vision in other files despite "use" directive
问题
有一个名为User
的小类:
namespace App\src\entities;
class User{
//在这里添加代码
}
我尝试在另一个文件中使用"use"关键字访问这个类。
namespace App;
use App\src\entities\User;
$user = new User("Test", "test");
IDE可以理解存在一个名为User的类,甚至在自动填充时提供了它。然而,当我运行这段代码时,我得到的是以下致命错误:Fatal error: Uncaught Error: Class 'App\src\entities\User' not found in /var/www/app/app/public/test.php:5 Stack trace: #0 {main} thrown in /var/www/app/app/public/test.php on line 5
我尝试修改composer.json并添加以下内容:
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
然后重新生成文件。但这并没有帮助,也没有改变任何情况。
为什么会发生这种情况,我该怎么办?我是从C#转到PHP的,现在感到非常沮丧。
英文:
There is a small class User
:
<?php
namespace App\src\entities;
class User{
//code here
}
I tried acessing this class in another file with "use" keyword.
<?php
namespace App;
use App\src\entities\User;
$user = new User("Test", "test");
IDE can understand that there is a class User and even have given me it with autofilling. However, when i run this code, all i get is Fatal error: Uncaught Error: Class 'App\src\entities\User' not found in /var/www/app/app/public/test.php:5 Stack trace: #0 {main} thrown in /var/www/app/app/public/test.php on line 5
I tried modifying composer.json adding this:
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
Then i autogenerated files again. That didn't help and nothing has changed.
Why is this happening and what can i do about it? I came to php from C# and am suffering from frustration now.
答案1
得分: 0
不同于编译的C#,PHP只是加载。
因此,在编译成目标文件后构建阶段中链接器通常会执行的操作,在PHP中不存在。PHP有一种不同的机制,称为类自动加载,通常缩写为自动加载。(参考链接)
也就是说,如果启动一个PHP程序,通常只有一个文件(PHP脚本),在解析PHP代码后,它会被转换为OP-Codes并传递给解释器。
当你将一个PHP项目组织成Composer项目时,Composer会负责生成一个自动加载器。然后,初始的PHP脚本需要引用该自动加载器以激活它。
require 'vendor/autoload.php';
然后,每当PHP需要一个新的类定义时,例如第一个new User()
,User类尚未被加载,然后自动加载器会负责加载它。
每当自动加载不起作用(未激活)时,类就会保持未定义,因此无法找到该类。
致命错误:未捕获的错误:类 'Foo\Bar\Baz' 未找到...
这就是为什么在引用vendor/autoload.php
文件之前首次出现错误,但引用后错误消失的原因。
这只需要在每个进程中执行一次,所以通常在启动过程中找到需要引用自动加载器脚本的地方。
IDE中的解析与vendor/autoload.php
文件无关 - 至少我记得在PhpStorm中是这样的 - 但它可能仍然会从composer.json
读取PSR命名空间根的composer项目配置。但是IDE还有另一个好处,它可以扫描所有文件,然后知道每个类在哪里。因此,在IDE中的解析可能已经起作用,即使项目配置尚未具备最终的autoload配置(在您的示例中没有问题),或者autoload.php脚本尚未转储/加载。
英文:
Different than C# that is compiled, PHP is just loaded.
So what a linker normally does in the build phase after compiling to object files, does not exists in PHP. PHP has a different mechanism, and it is called class auto loading or commonly autoloading in short (ref).
That is, if a PHP program is started, it commonly only has a single file (the PHP script), after parsing the PHP code is translated to OP-Codes and fed to the interpreter.
When you organize a PHP project as a Composer project, Composer takes care of generating an autoloader. The initial PHP script then needs to require that autoloader so that it is active.
require 'vendor/autoload.php';
Then whenever PHP needs a new class definition, for example the first new User()
, the User class has not yet been loaded and then the autoloader will take care to load it.
Whenever the autoloading does not work (is not in action), it is that the class remains undefined and therefore the class is not found.
> Fatal error: Uncaught Error: Class 'Foo\Bar\Baz' not found in ...
That's why you first had the error but once requiring the vendor/autoload.php file it went away.
This only needs to be done once per process, so you often find requiring the autoloader script during bootstrapping.
The resolution in the IDE is independent to that vendor/autoload.php file - at least IIRC in PhpStorm that is - but it may still read the composer project configuration from composer.json for the PSR namespace roots. But the IDE has another benefit, it can scan just all files and then it knows where each class is. So resolution in the IDE may already work, even if the project configuration has not yet the final autoload configuration (was not a problem in your example) or the autoload.php script was not yet dumped / loaded.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论