是的,另一个关于“找不到类”错误的问题。要么是我遗漏了什么,要么是我误解了 PSR-4 逻辑。
我的作曲家库目录结构:
“扫描仪”=>“src”=>“Test.php”
测试.php
namespace MyNS;
class Test
{
}
composer.json
"autoload": {
"psr-4": {
"MyNS\\": "src/"
},
}
所以,现在我使用 Composer 将库加载到我的项目中并尝试使用它。
require_once("../vendor/autoload.php");
$test = new MyNS\Test();
这总是导致
“致命错误:未捕获错误:未找到类‘MyNS\Test’。”
。我缺少什么?我已经盯着这个看了好几天了。我更改了文件夹,更改了文件夹名称,将上层更改为下层,反之亦然。似乎没什么作用。
我正在使用 PHP 7.2.2 和 Composer 版本 1.2.2
甚至尝试过这个:
require_once("../vendor/autoload.php");
use MyNS\Test;
$scanner = new Test();
我调试了 Composer ClassLoader.php 文件 (findFileWithExtension($class, $ext)) 方法,显然我的文件从未加载,因为我得到了 echo“Done”和 die();在此方法的末尾,这意味着找不到该文件,因此未加载该文件。我的composer.json 有什么问题吗?
{
"name": "test/test",
"type": "library",
"description": "",
"keywords": ["php"],
"homepage": "",
"license": "MIT",
"authors": [
{
"name": "",
"email": "",
"homepage": "",
"role": ""
}
],
"require": {
"php": ">=7.2.2"
},
"autoload": {
"psr-4": {
"MyNS\\": "src/"
}
}
}
要调试正在发生的情况,请打开
ClassLoader.php
文件,然后转到定义 findFileWithExtension()
方法的位置添加 echo
语句:
# vendor/composer/ClassLoader.php:386
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
// Add this line
echo $file, PHP_EOL;
}
在您手动修改上述文件后,请勿执行
composer dumpautoload
,直到我们完成为止。
现在,通过执行 PHP 文件,您将在输出的开头看到类似的内容:
path/to/project/vendor/composer/../../src/Test.php
即:
path/to/project/src/Test.php
这就是作曲家正在寻找的文件,并且应该包含这样的内容:
namespace MyNS;
class Test { }
如果包含文件时出现问题,则意味着您必须关心三件事:
我认为问题出在你的命名空间声明中
您从
MyNS
调用该类,但类命名空间是 namespace MyNS\PSR4;
require_once("../vendor/autoload.php");
$test = new MyNS\Test();
// it should be new MyNS\PSR4\Test();
并确保您的类文件位于您在
composer autoload
文件 中提到的同一目录中
您还必须运行
dump-autoload
命令才能更改类名
您可以访问此自动加载功能
搜索“composer psr-4 debug”时,此页面位于顶部,因此可能是为未来访问者留言的好地方
原来
composer.lock
包含自动加载信息。也就是说,它包含每个已安装软件包的 autoload
中 composer.json
字段的值:
"packages": [
{
"name": "some/package",
"version": "x.y.z",
"type": "library",
"autoload": {
"psr-4": {
"SomePackage\\": "./src/"
}
}
}
]
(请注意,
autoload
对象是从composer.json
的some/package
复制的)
一个包可能会更改它的自动加载信息(例如,如果您在本地开发一个包,您可能决定将源代码目录重命名为其他名称,因此您将更改包的
autoload.psr-4
中的 composer.json
字段)
但是,进行此类更改后,您的
composer.lock
将保持不变
composer 似乎使用
composer.lock
中的自动加载信息进行自动加载,因此,在我的示例中,它会尝试通过旧路径加载类(在重命名源代码文件夹之前)
作为我当前的解决方案,我手动更改了
composer.lock
中的自动加载信息以匹配最新的。我想有更好的方法,仔细更新composer.lock