我想在Laravel项目中找到所有模型的列表,数据库表作为备份。
我想这样做来构建一个仪表板,显示所有模型中的数据随时间变化的方式,I.E。如果有用户模型,则在过去90天内每天添加或修改了多少用户。
答案 0 :(得分:8)
我会浏览你的文件系统并从你的模型文件夹中取出所有的php文件。我将我的模型保存在app / Models文件夹中,如下所示:
$path = app_path() . "/Models";
function getModels($path){
$out = [];
$results = scandir($path);
foreach ($results as $result) {
if ($result === '.' or $result === '..') continue;
$filename = $path . '/' . $result;
if (is_dir($filename)) {
$out = array_merge($out, getModels($filename));
}else{
$out[] = substr($filename,0,-4);
}
}
return $out;
}
dd(getModels($path));
我刚尝试了这个,它吐出了我所有模型的完整文件路径。您可以剥离字符串,使其仅显示命名空间和模型名称,如果这就是您要查找的内容。
答案 1 :(得分:6)
我想提出一种不同的方法,使用PHP reflection而不是依靠所有模型都驻留在名为Model的名称空间或目录中。
下面的代码示例收集所有应用程序类,验证它们是否实际上扩展了Eloquent Model类并且不是抽象的。
/**
* Converts value to slug
* @customfunction
*/
function slugify(value) {
/*
* Convert the the vs in a range of cells into slugs.
* @customfunction
*/
let slug = '';
slug = value.substring(0, 100).toLowerCase();
slug = slug.replace(/[^\w\s-]/g, '');
slug = slug.replace(/\s+/g, '-');
Logger.log(slug);
return slug;
}
答案 2 :(得分:4)
请注意,这可能会错过在引导期间未在范围内的模型。请参阅下面的编辑。
有一种方法可以在不重复文件系统的情况下加载声明的模型。由于大多数模型都是在引导后声明的,因此您可以致电get_declared_classes
并过滤模型的回报'像这样的名称空间(我的类在\App\Models
名称空间中):
$models = collect(get_declared_classes())->filter(function ($item) {
return (substr($item, 0, 11) === 'App\Models\\');
});
编辑: 感谢@ ChronoFish的评论,我再次看了一下这个方法,实际上并没有在所有情况下提升所有模型。
例如,在服务提供商的引导生命周期的早期阶段,这根本不起作用。但即使它正在工作,也可能会错过一些模型,具体取决于您的项目结构,因为并非所有类都在范围内。对于我的测试项目,所有模型都已加载,但在更复杂的应用程序中,可能会错过大量的类。
感谢您的评论!
我目前正在使用这样的东西:
$appNamespace = Illuminate\Container\Container::getInstance()->getNamespace();
$modelNamespace = 'Models';
$models = collect(File::allFiles(app_path($modelNamespace)))->map(function ($item) use ($appNamespace, $modelNamespace) {
$rel = $item->getRelativePathName();
$class = sprintf('\%s%s%s', $appNamespace, $modelNamespace ? $modelNamespace . '\\' : '',
implode('\\', explode('/', substr($rel, 0, strrpos($rel, '.')))));
return class_exists($class) ? $class : null;
})->filter();
$modelNamespace
适用于那些为其模型设置不同文件夹和命名空间的人,强烈建议这样做。那些只使用Laravel默认值的人可以将其留空,但是然后将拉入app目录中的所有类,而不仅仅是Eloquent模型。然后,您可能必须使用反射来确保您只获得模型......
答案 3 :(得分:1)
根据题目回答:
<?php
use Illuminate\Support\Facades\File;
/**
* Get Available models in app.
*
* @return array $models
*/
public static function getAvailableModels()
{
$models = [];
$modelsPath = app_path('Models');
$modelFiles = File::allFiles($modelsPath);
foreach ($modelFiles as $modelFile) {
$models[] = '\App\\' . $modelFile->getFilenameWithoutExtension();
}
return $models;
}
答案 4 :(得分:0)
这是我的解决方案。不打算在子文件夹中搜索模型。
<?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);
}
答案 5 :(得分:0)
答案 6 :(得分:0)
我正在寻找可读的东西,所以,我制作了这段代码,可以获取所有模型名称,并且您可以根据需要设置格式。
<?php
function getModelNames(): array
{
$path = app_path('Models') . '/*.php';
return collect(glob($path))->map(fn ($file) => basename($file, '.php'))->toArray();
}
答案 7 :(得分:-1)
一种方法是使用Standard PHP Library (SPL)
递归列出目录中的所有文件,您可以创建如下函数。
function getModels($path, $namespace){
$out = [];
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
$path
), \RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
/**
* @var \SplFileInfo $item
*/
if($item->isReadable() && $item->isFile() && mb_strtolower($item->getExtension()) === 'php'){
$out[] = $namespace .
str_replace("/", "\\", mb_substr($item->getRealPath(), mb_strlen($path), -4));
}
}
return $out;
}
getModels(app_path("Models/"), "App\\Models\\");