movephp/classloader

Movephp框架的扩展自动加载器

v1.0.2 2017-11-26 18:42 UTC

This package is auto-updated.

Last update: 2024-09-25 20:16:20 UTC


README

Build Status Coverage Status

扩展Autoloader用于Movephp框架

这是一个创建应用程序类映射的机制。它扫描指定的目录以寻找 *.php 文件,并列出所有找到的类(包括抽象类、接口和特性)。对于每个类,也定义了命名空间、父类、使用的接口和特性、子类。

获取到的数据数组可以用于常规的自动加载,也可以用于搜索和分析类映射。

例如,可以找到所有具有指定父类树的类,或者可以找到所有使用特定特性的类等。

这允许快速分析应用程序代码并执行预处理。

目录

安装

推荐安装方式是使用 Composer。请将以下指令添加到您的 composer.json 文件中

"require": {
    "movephp/classloader": "~1.0"
}

快速入门

快速入门示例代码

include_once('vendor/autoload.php');
use Movephp\ClassLoader\{Autoload, Map};
$autoload = new Autoload(
    new Map\Map()
);
$autoload->setScanPaths(__DIR__ . '/src', __DIR__ . '/vendor');
$autoload->makeMap();
var_dump($autoload->map()->classes());

自动加载器

可以通过 $autoload->register() 方法注册从构建的映射中自动加载类函数。

建议使用缓存(PSR-6)作为类加载库的自动加载器。

$cachePool = new Symfony\Component\Cache\Adapter\FilesystemAdapter();
$autoload = new Autoload(
    new Map\Map(),
    $cachePool
);
$autoload->setScanPaths(__DIR__ . '/src', __DIR__ . '/vendor');
$autoload->makeMap();
$autoload->register();

使用缓存时,类映射只生成一次,后续请求将快速从缓存中恢复数据。

默认情况下,库使用键 movephp_classloader 从传递的 CachePool 获取 CacheItem。为了避免可能的冲突,可以在 Autoload 类的构造函数中将命名空间作为第三个参数传递:$autoload = new Autoload($map, $cachePool, 'mynamespace') - 在这种情况下,用于获取 CacheItem 的键将是 mynamespace_movephp_classloader

更新映射

在开发环境或项目开发中可能需要更新类映射

$cachePool = new Symfony\Component\Cache\Adapter\FilesystemAdapter();
$autoload = new Autoload(
    new Map\Map(),
    $cachePool
);
$autoload->setScanPaths(__DIR__ . '/src', __DIR__ . '/vendor');
$autoload->makeMap();
if (...some_сondition_here...) {
    $autoload->updateMap();
}
$autoload->register();

另一种更慢的方法是完全清除缓存并重新生成映射

$cachePool = new Symfony\Component\Cache\Adapter\FilesystemAdapter();
if (...some_сondition_here...) {
    $cachePool->clear();
}
$autoload = new Autoload(
    new Map\Map(),
    $cachePool
);
$autoload->setScanPaths(__DIR__ . '/src', __DIR__ . '/vendor');
$autoload->makeMap();
$autoload->register();

扫描设置

除了使用 $autoload->setScanPaths() 方法指定应扫描哪些文件/目录外,还存在两个额外的方法

  • $autoload->setExcludingPaths(string ...$excludePaths) - 排除指定的文件和目录(以及其所有内容)的扫描过程。对于包含测试的目录来说,使用这个功能是有意义的。
  • $autoload->setOverridePaths(string ...$overridePaths) - 如果在扫描项目时发现具有相同名称的多个类(包括命名空间),将会引发错误。但是,该方法允许指定包含替换其他扫描文件中同名类的类和目录。在这种情况下不会发生错误,而来自 $overridePaths 的类将被添加到映射中。

特殊情况

Composer包

在扫描项目文件时,特别关注 composer.json 文件。如果在找到这样的文件时它包含 autoload 指令,则只会扫描其中描述的目录和文件。

在找到的Composer包中的其他文件将被跳过,因为它们可能只需要用于测试或仅是垃圾。

PHPUnit和Composer库

以下情况下,类不会包含在类映射中,并且既不能用于自动加载也不能用于分析

  • 如果类是 phpUnit 测试,即它或其任何一个父类继承自 PHPUnit_Framework_TestCasePHPUnit\Framework\TestCase
  • 如果类是 Composer 库的一部分,即它在 Composer 命名空间或其任何子命名空间 Composer\... 中定义。

可能存在错误的类

类将被包含在类图中,但在以下情况下不会自动加载:

  • 如果类的文件代码中存在 exit()(或 die())操作符,且不在类体内,即在文件连接到应用时可能被调用。
  • 如果类继承自不在公共类图中的类,或者不是 PHP 的内置类。这也适用于使用的特性和接口。

此类将获得特殊的标记 $item->isSafeInclude() === false,这意味着加载包含此类的文件可能会导致错误或脚本意外终止。然而,此类将存在于类图中,并可供分析使用。

搜索和分析类

可以通过方法 $autoload->map() 获取形成的类图对象 Map\Map。如果您不需要自动加载和缓存功能,可以直接使用类 Map\Map 及其方法 scan()

$map = new Map\Map();
$map->scan([__DIR__ . '/src', __DIR__ . '/vendor']);

方法 Map\Map::classes() 返回类图中所有类的完整列表,以 Map\Item 对象的数组形式。

使用方法 Map\Map::find() 可以在类图中根据指定参数进行搜索。以下是一个搜索实现 MyNamespace\MyInterface 接口且不是抽象类的示例,以及这些类的子类。

$map->find(Map\Item::TYPE_CLASS, MyNamespace\MyInterface::class);

方法 find() 也返回 Map\Item 对象的数组。

Map\Item 对象(类图元素)具有许多用于获取关于所代表类各种信息的属性访问器方法。

API参考

Movephp\ClassLoader\Autoload

这是库的主要类。用于根据类图执行自动加载器功能,以及管理类图对象和其缓存。

构造函数

__construct(Movephp\ClassLoader\Map\MapInterface $cleanMap, Psr\Cache\CacheItemPoolInterface $cachePool = null, string $cacheKeyNamespace = '')

方法

Movephp\ClassLoader\Map\Map

此类的对象代表类图,用于其构建(扫描项目文件)和搜索。

构造函数

__construct(string $itemClass = '')

方法

方法 find() 参数 $type 的可能值:

  • Movephp\ClassLoader\Map\ItemInterface::TYPE_CLASS
  • Movephp\ClassLoader\Map\ItemInterface::TYPE_ABSTRACT
  • Movephp\ClassLoader\Map\ItemInterface::TYPE_INTERFACE
  • Movephp\ClassLoader\Map\ItemInterface::TYPE_TRAIT
  • 或者这些常数的任何组合(Movephp\ClassLoader\Map\ItemInterface::TYPE_ANY 是它们的总和)。

Movephp\ClassLoader\Map\Item

此类的对象代表类图中的一个元素:在扫描过程中找到的类、接口或特性。

方法

待办事项

  • 使在指定扫描和排除扫描的目录和文件时使用特殊符号 *? 成为可能;
  • 配置扫描文件的扩展名(默认为 *.php);
  • 避免直接调用文件系统函数(使用 Flysystem 或类似库)。