编辑器:自动加载疑难解答



我提交这个问题是因为我一直在搜索在 Composer 中对自动加载进行故障排除的主题,似乎找不到任何简单的东西。我向库中添加了几个类,然后在项目中引用了它们。项目找不到类。以下是相关事实:

• 我已经在项目中使用该库一段时间了。

• 我仔细检查了库中类的代码文件中的命名空间声明:

namespace LibraryPackageSubpackage;
class Widget { ...

• 我仔细检查了为库和实例化别名的use语句:

use LibraryPackageSubpackage as Subpackage;
$e = new SubpackageWidget();

•对于笑容,我更改了别名:

use LibraryPackageSubpackageWidget as Widget;
$e = new Widget();

•为了获得更多的笑容,我尝试了直接参考:

$e = new LibraryPackageSubpackageWidget();

•我还确保composer update并确保文件确实在那里,在正确的路径上:

composer update
find . -name Widget.php
./vendor/organization/library/Package/Subpackage/Widget.php

• 作为健全性检查,我添加了对同一库中另一个项目的引用,但在不同的子包中。

$f = new LibraryPackage2Widget2(); // this works fine

•作为绝对的最后手段,我将引用单独放在PHP文件中并运行它。

require_once __DIR__.'/vendor/autoload.php';
$e = new LibraryPackageSubpackageWidget();

• 为了获得好处,我编写了一个单元测试来检查库vendor文件夹中的每个文件:

class AutoloadTest extends PHPUnitFrameworkTestCase
{
public function classDataProvider()
{
$data = array();
$path = realpath('organization/library/Package/');
$directory_iterator = new RecursiveDirectoryIterator($path);
$iterator_iterator = new RecursiveIteratorIterator($directory_iterator);
foreach ($iterator_iterator as $iterator_result) {
$real_path = $iterator_result->getRealPath();
if (substr($real_path, -4, 4) != '.php') {
continue;
}
$split = explode('organization/library/Package/', $real_path);
$processed_path = substr($split[1], 0, -4);
$class_fqname = sprintf('Library%s', str_replace("/", '\', $processed_path));
$data[]  = array($class_fqname);
}
return $data;
}
public function test($class_name)
{
$assertion = class_exists($class_name) || trait_exists($class_name) || interface_exists($class_name);
$this->assertTrue($assertion, "$class_name is not recognized as a class, trait or interface.");
}
}

我的问题是:

  1. 最有可能的罪魁祸首是什么?
  2. 如何使用 Composer 来获取有关它正在尝试的路径的跟踪信息?有没有办法给作曲家提供一条路径,让它告诉我它是否可以解决它?

无关的反斜杠。

namespace LibraryPackageSubpackage;
^ oops!

删除此反斜杠解决了问题。

最终,我编写的单元测试帮助我找到并解决了问题。因此,对于我问题的第二部分,我将提供我编写的测试类。提供程序接收要扫描的路径和文件所属的命名空间对。它扫描给定的路径并查找该命名空间中的类。测试检查断言每个限定类名对应于一个类、特征或接口。(当然,需要自动加载器来加载类。

abstract class AutoloadTestBase extends PHPUnitFrameworkTestCase
{
public function pathProvider()
{
$data = array();
foreach ($this->directories() as $directory_specification) {
list($path, $namespace) = $directory_specification;
if (empty($path)) {
continue;
}
$directory_iterator = new RecursiveDirectoryIterator($path);
$iterator_iterator = new RecursiveIteratorIterator($directory_iterator);
foreach ($iterator_iterator as $iterator_result) {
$real_path = $iterator_result->getRealPath();
$split1 = explode($path.'/', $real_path);
if (count($split1) < 2) {
continue;
}
$success = preg_match('/^(.+).php$/', $split1[1], $split2);
if (!$success || substr($split2[1], 0, 5) == 'Tests') {
continue;
}
$class_fqname = sprintf('%s%s', $namespace, str_replace("/", '\', $split2[1]));
$data[] = array($class_fqname);
}
}
return $data;
}
/**
* @dataProvider pathProvider
*/
public function test($class_name)
{
$assertion = class_exists($class_name) || trait_exists($class_name) || interface_exists($class_name);
$this->assertTrue($assertion, "$class_name is not recognized as a class, trait or interface.");
}
}
class AutoloadTest extends AutoloadTestBase
{
protected function directories()
{
return array(
array('Package1/Subpackage1','Library1Package1Subpackage1'),
array('vendor/organization2/package2/Subpackage2','Library2Package2Subpackage2')
);
}
}

相关内容

  • 没有找到相关文章

最新更新