lorisleiva / lody
将文件和类作为Laravel中的懒集合加载。
Requires
- php: ^8.0
- illuminate/contracts: ^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^9.0
- pestphp/pest: ^1.20|^2.34
- phpunit/phpunit: ^9.5.10|^10.5
README
将文件和类作为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::files
或Lody::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');