按 Table 名称查找 Eloquent Class

Find Eloquent Class by Table Name

我目前正在围绕遗留数据库 Laravel/Eloquent 包装并建立关系,但是我 运行 遇到了一些现有系统动态特性的问题。一些关系是在数据库本身中定义的,这意味着 table_a 中的项目可以与任意数量的其他 table 相关,具体取决于存储的指令。

这包括 table 个存储在说明中的名称。

我当前的 objective 是找到为 table X 构建的 Eloquent Model class。

一些注意事项:

也许我只是希望 Laravel 在内存中的某个地方保留所有 Eloquent classes 的清单,我可以利用它,但这可能是一厢情愿的想法。

有什么妙招吗?

根据 miken32 的建议研究反射,我能够编译样本片段并向 BaseModel 添加功能 class。这可能不是我的最终实现,但它满足了我的需要。

<?php

namespace App\Models;

use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;

abstract class BaseModel extends Model
{
    public static function tableName(): string
    {
        return with(new static)->getTable();
    }

    public static function getClassMetadata(): Collection
    {
        return Cache::rememberForever('model:eloquent:metadata',function(){
            return collect(File::allFiles(app_path()))->map(function ($item){
                $path = $item->getRelativePathName();
                return sprintf('\%s%s', Container::getInstance()->getNamespace(),
                    strtr(substr($path, 0, strrpos($path, '.')), '/', '\'));
            })->filter(function ($class){
                $valid = false;
                if (class_exists($class)) {
                    $reflection = new \ReflectionClass($class);
                    $valid = $reflection->isSubclassOf(BaseModel::class) && !$reflection->isAbstract();
                }
                return $valid;
            })->map(function ($class){
                $reflection = new \ReflectionClass($class);
                return [
                    'fqcn' => $class,
                    'table' => $reflection->getMethod('tableName')->invoke(null)
                ];
            })->values();
        });
    }
}