将文件和类作为Laravel中的懒集合加载。

资助包维护!
lorisleiva

v0.5.0 2024-03-13 12:08 UTC

This package is auto-updated.

Last update: 2024-09-13 13:31:48 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

将文件和类作为Laravel中的懒集合加载。

安装

composer require lorisleiva/lody

使用

Lody允许您获取提供的路径(或路径数组)中相对于您应用程序基础路径的所有现有PHP类。它返回一个自定义的LazyCollection,具有有用的方法,以便您可以进一步根据您自己的要求筛选类。例如,以下代码将递归地获取给定路径中所有非抽象的Node实例,并为每个实例进行注册。

use Lorisleiva\Lody\Lody;

Lody::classes('app/Workflow/Nodes')
    ->isNotAbstract()
    ->isInstanceOf(Node::class)
    ->each(fn (string $classname) => $this->register($classname));

如果您想要所有文件而不是现有的PHP类,您可以使用Lody::files代替。

use Lorisleiva\Lody\Lody;

Lody::files('app/Workflow/Nodes')
    ->each(fn (SplFileInfo $file) => $this->register($file));

配置

解析路径

当向Lody::filesLody::classes方法提供路径时,Lody将自动假定这些路径位于您的应用程序根目录中,除非它们以斜杠开头,在这种情况下它们将保持不变。

您可以通过在您的服务提供者之一上调用Lody::resolvePathUsing方法来配置此逻辑。以下示例提供了默认逻辑。

Lody::resolvePathUsing(function (string $path) {
    return Str::startsWith($path, DIRECTORY_SEPARATOR) ? $path : base_path($path);
});

解析类名

当使用Lody::classes方法时,Lody将根据PSR-4约定将您的文件名转换为类名。例如,如果您的文件名是app/Models/User.php,并且您已将App命名空间映射到app目录在您的composer.json文件中,则它将解析为App\Models\User

默认情况下,类名解析会考虑您在vendor/composer/autoload_psr4.php文件中定义的每个PSR-4映射。这意味着它甚至可以正确解析位于您的供应商目录中的类。

如果您的PSR-4自动加载文件位于其他位置,您可以通过在您的服务提供者之一上调用Lody::setAutoloadPath方法来配置它。

Lody::setAutoloadPath('my/custom/autoload_psr4.php');

或者,您可以通过调用Lody::resolveClassnameUsing方法完全覆盖此逻辑。以下示例为Laravel应用程序提供了一个有用的示例。

Lody::resolveClassnameUsing(function (SplFileInfo $file) {
    $classnameFromAppPath = str_replace(
        ['/', '.php'],
        ['\\', ''],
        Str::after($file->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)
    );

    return app()->getNamespace() . $classnameFromAppPath;
});

在不使用Laravel的情况下使用Lody

Lody与Laravel配合使用,因为我们可以使用base_path方法访问项目的根目录。

但是,如果您希望在不使用Laravel的情况下使用Lody,您只需显式使用Lody::setBasePath方法提供应用程序的基本路径即可。

// Assuming this is executed at the root of your project.
Lody::setBasePath(__DIR__);

参考

Lody

// All return an instance of FileLazyCollection (see below).
Lody::files('app/Actions');
Lody::files(['app/Auth/Actions', 'app/Billing/Actions']);
Lody::files('app/Actions', recursive: false); // Non-recursively.
Lody::files('app/Actions', hidden: true); // Includes dot files.
Lody::filesFromFinder(Finder::create()->files()->in(app_path('Actions'))->depth(1)); // With custom finder.

// All return an instance of ClassnameLazyCollection (see below).
Lody::classes('app/Actions');
Lody::classes(['app/Auth/Actions', 'app/Billing/Actions']);
Lody::classes('app/Actions', recursive: false); // Non-recursively.
Lody::classesFromFinder(Finder::create()->files()->in(app_path('Actions'))->depth(1)); // With custom finder.

// Registering custom resolvers.
Lody::resolvePathUsing(fn(string $path) => ...);
Lody::resolveClassnameUsing(fn(SplFileInfo $file) => ...);

FileLazyCollection

// Transforms files into classnames and returns a `ClassnameLazyCollection`.
// Note that these can still be invalid classes. See `classExists` below.
Lody::files('...')->getClassnames();

ClassnameLazyCollection

// The `classExists` rejects all classnames that do not reference a valid PHP class.
Lody::files('...')->getClassnames()->classExists();

// Note that this is equivalent to the line above.
Lody::classes('...');

// Filter abstract classes.
Lody::classes('...')->isAbstract();
Lody::classes('...')->isNotAbstract();

// Filter classes based on inheritance.
Lody::classes('...')->isInstanceOf(SomeClassOrInterface::class);
Lody::classes('...')->isNotInstanceOf(SomeClassOrInterface::class);

// Filter classes based on traits.
Lody::classes('...')->hasTrait(SomeTrait::class);
Lody::classes('...')->hasTrait(SomeTrait::class, recursive: false); // Don't include recursive traits.
Lody::classes('...')->doesNotHaveTrait(SomeTrait::class);
Lody::classes('...')->doesNotHaveTrait(SomeTrait::class, recursive: false); // Don't include recursive traits.

// Filter classes based on method it contains or not.
Lody::classes('...')->hasMethod('someMethod');
Lody::classes('...')->hasStaticMethod('someMethod'); // Ensures the method is static.
Lody::classes('...')->hasNonStaticMethod('someMethod'); // Ensures the method is non-static.
Lody::classes('...')->doesNotHaveMethod('someMethod');