<?php
use Illuminate\Database\Eloquent\Model;
function getModels(?string $path = null): array
{
$path = $path ?? app_path();
// Se obtienen los archivos en el directorio, sin subdirectorios.
$files = File::files($path);
// Se obtienen los nombres sin rutas ni extensiones.
$filenames = array_map(function ($file): string {
$pathinfo = pathinfo($file);
return $pathinfo['filename'];
}, $files);
$namespace = "\App";
// Se conservan aquellos que sean modelos.
$mapped = array_map(
function ($filename) use ($namespace): ?string {
$class = "{$namespace}\\{$filename}";
if (!class_exists($class)) {
return null;
}
$object = new $class;
if (!$object instanceof Model) {
return null;
}
return $class;
},
$filenames
);
// Se filtran los que no son modelos.
$models = array_filter($mapped);
return array_values($models);
}
9条答案
按热度按时间qvtsj1bj1#
我想建议一种不同的方法,使用PHP reflection,而不是依赖于所有模型都驻留在名为Model的名称空间或目录中。
下面的代码示例收集了所有的应用程序类,验证它们是否实际上扩展了EloquentModel类,并且不是抽象的。
oewdyzsn2#
我会浏览你的文件系统,从models文件夹中取出所有的php文件。我把我的模型保存在app/Models文件夹中,所以类似这样:
我刚试过这个,它吐出了我所有模型的完整文件路径。您可以剥离字符串,使其只显示名称空间和模型名称(如果这是您正在寻找的)。
00jrzges3#
有一种方法可以加载声明的模型,而无需迭代文件系统。由于大多数模型都是在引导后声明的,你可以调用
get_declared_classes
并像这样过滤模型命名空间的返回值(我的类在\App\Models
命名空间中):正如@ChronoFish所提到的,这种方法并不能在所有情况下提取所有模型。
例如,这在 Bootstrap 生命周期的早期阶段根本不起作用,如在服务提供商中。但即使它在工作,它也可能会错过一些模型,这取决于项目的结构,因为并非所有类都在范围内。在我的测试项目中,加载了所有模型,但在更复杂的应用程序中,可能会遗漏大量的类。
感谢您的评论!
我目前正在使用这样的东西:
$modelNamespace
是为那些有一个独特的文件夹和命名空间的模型,这是强烈推荐的,或者谁正在使用Laravel 8+,这是新的默认值。那些只使用Laravel 7或更低版本的默认值的人可以将此留空,但随后将拉入应用程序目录中的所有类,而不仅仅是Eloquent模型。在这种情况下,你可以通过像这样过滤列表来确保你只得到模型:
falq053o4#
根据主题答案:
x8diyxa75#
我正在寻找一些可读的东西,所以,我做了这个代码,得到所有模型的名称,你可以格式化你想要的。
fjaof16o6#
一种方法是使用
Standard PHP Library (SPL)
递归地列出目录中的所有文件,您可以使用下面的函数。u5rb5r597#
你也可以尝试这样来解决这个问题:
https://gist.github.com/mohammad425/231242958edb640601108bdea7bcf9ac
zqdjd7g98#
这就是我的解决方案。不用于搜索子文件夹中的模型。
c0vxltue9#
我认为这样更好更简单(不使用反射类)