首页 > 解决方案 > 雄辩的选择使用了错误的类?

问题描述

上下文:尝试从数据库表中扩展 Laravel 模型。models链接到 的表App\Models\BootableModelApp\Models\User扩展了这个类。

我有以下代码:

<?php
    class BootableModel extends Model
    {
        protected $table = 'models';

        protected $fillable = [
            'name',
            'class',
            'table',
        ];

        public function __construct(array $attributes = [])
        {
            $this->bootFromDatabase();
            parent::__construct($attributes);
        }

        private function bootFromDatabase()
        {
            $class = static::class;
            $bModClass = self::class;
            Log::debug($class);
            Log::debug($bModClass);
            //$bootableModel = DB::table('models')->where('class', $class)->first();
            $bootableModel = $bModClass::where('class', $class)->first();
            if(!$bootableModel) {
                return;
            }
            Log::debug($bootableModel->id);

调试$bModClass显示App\Models\BootableModel按预期(selfvs static),但由于某种原因$bModClass::where正在尝试查询users表。使用直接引用App\Models\BootableModel::class不会改变这一点,所以这不是self::class问题所在。调试输出作为证明:

[2021-02-21 17:33:39] local.DEBUG: App\Models\User
[2021-02-21 17:33:39] local.DEBUG: App\Models\BootableModel

它永远不应该尝试访问User::where(),因此,它永远也不应该尝试使用User::$table任何一个,但不知何故它确实如此。

Laravel 是在做一些奇怪的反射,还是这是正常的 PHP 行为?有没有解决的办法?

更新:

我找到了一种解决方法,但我不满意这是正确/唯一的解决方案:

        public function __construct(array $attributes = [])
        {
            parent::__construct($attributes);
            static::bootFromDatabase();
        }

        public static function bootFromDatabase()
        {
            $class = static::class;
            $bModClass = self::class;
            if($class === $bModClass) {
                return;
            }

标签: phplaravelinheritanceeloquent

解决方案


你有没有试过self::where(...)代替$bModClass::where(...)

类似情况:

class Base {
    public static function where()
    {
        return 'where from base';
    }
    
    public static function getName()
    {
        return self::where();
    }
}

class User extends Base {
    public static function where()
    {
        return 'where from user';
    }
}

echo User::getName();

输出:where from base


推荐阅读