替换 Yii2 核心类

问题描述

我希望使用我创建的扩展版本覆盖认的 Model \yii\base\Model 类。为了争论,可以说我在 backend\components\Model

我尝试将这两个都放在引导配置文件中,但没有任何变化 - 它继续使用旧类

Yii::$container->set('yii\base\Model','backend\components\Model');
Yii::$classMap['yii\base\Model'] = 'backend\components\Model';

在后端\模型文件中:

<?PHP

namespace backend\components;


use Yii;
use yii\base\InvalidConfigException;
use yii\base\UserException;
use yii\helpers\ArrayHelper;

class Model extends \yii\base\Model
{
   /**
     * Adds a new error to the specified attribute.
     * @param string $attribute attribute name
     * @param string $key attribute index
     * @param string $error new error message
     */
    public function addCustomError($attribute,$key,$error = '')
    {
        $this->_errors[$attribute][$key][] = $error;
    }
}

我还尝试使用以下方法将其添加配置文件中:

 'container' => [
        'deFinitions' => [
            'yii\base\model'=>
            ['class'=>'backend\components\model']
        ]
    ],

无论我做什么 - 当我创建一个新的 ActiveRecord 时,它仍然拥有相同的 yii\base\model 类。

我花了一个下午的大部分时间试图解决这个问题,并且浏览了 Yii 文档以及 StackOverflow 上已有的问题。似乎有一个反复出现的主题,即 Container 函数不起作用,人们转向 ClassMap 函数 - 但似乎两者都不起作用。

感谢您的帮助。

解决方法

如果您使用容器来实例化被覆盖的类(如 Yii::$container->get('yii\base\Model');),则通过容器覆盖会起作用。如果你有 class MyModel extends \yii\base\Model 你没有使用容器,yii\base\Model 无论如何都会被用作基类,因为这是 PHP 的工作方式,框架无法改变它。如果您想这样做,您至少有 4 个选择:

  1. 首选:只需将 class MyModel extends \backend\components\Model 用于您的模型,并避免替换 hacky 类。
  2. Desperate 1:将 vendor/yiisoft/yii2/base/Model.php 复制到 overridden/Model.php,更改其源代码,并覆盖自动加载配置以将 overridden/Model.php 用于 yii\base\Model - 添加:
    Yii::$classMap['yii\base\Model'] = __DIR__ . '/../overridden/Model.php';
    
    要么
    require __DIR__ . '/../overridden/Model.php';
    
    require __DIR__ . '/../vendor/autoload.php';
    require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php
    
    您需要在框架更新后将 vendor/yiisoft/yii2/base/Model.php 中的所有更改同步到您的副本。通常这应该是最后的手段,因为很容易忘记它并获得完全意外的行为。
  3. Desperate 2:直接使用 cweagans/composer-patches 修补 vendor/yiisoft/yii2/base/Model.php。这比第二种选择更容易维护,但一段时间后仍然可能令人惊讶。此外,在某些时候,您的补丁程序可能会在框架更新后发生冲突,需要了解正在发生的事情的人对此进行查看。
  4. Desperate 3:fork yiisoft/yii2 并做任何你想做的事——它现在是你的框架。对于大型且活跃的项目,它可能非常有用,但在其他情况下,您最终可能会得到完全过时的框架,因为没人关心从上游获取更改。