通过配置的方式重写某个Yii2 文件 或第三方扩展文件

1.我需要重写某个Yii的类方法,譬如:yii\helpers\ArrayHelper

我需要新建一个类,继承,然后覆盖这个类的方法。
如果我的系统都成型了,然后我在调用这个类的地方,需要将

use yii\helpers\ArrayHelper

改成

use xxxxxx\yii\helpers\ArrayHelper

2.现在用classMap

Yii::$classMap['yii\helpers\ArrayHelper'] = '@xxxxxx/yii/helpers/ArrayHelper.php';

直接就行了,对yii的文件不需要改动,调用的地方也不用改动。

可能是我在做fecshop考虑重写的事情,看到这个,真的豁然开朗的感觉,
这样可以在不改动yii2文件,和不改动我的fecshop文件的前提下,重写任何文件了

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面是代码举例说明的详细步骤:

  1. 下面是我写的一个类,内容如下:
<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My
{
  
  public static function test(){
    echo 'this is my first test php file';
  }
  
}

2. 然后我在controller中对这个类的静态方法进行了调用:

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\modules\Customer\controllers;
use Yii;
use fec\helpers\CModule;
use fec\helpers\CRequest;
use fecshop\app\appfront\modules\AppfrontController;
use fecshop\app\appfront\helper\test\My;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class AccountController extends AppfrontController
{
  
  public function actionLogin()
    {
    My::test();
    exit;
  }
}

然后我在很多地方对My::test进行了调用,然后我想对这个My类的test的内容进行重写,但是前提是My这个文件是库包文件,我不能直接进行修改,否则,以后的升级会出现问题,那么我需要用一个类继承这个My类,然后重写test()方法,然后在各个调用My::test()的地方修改use部分,改成新的类的namespaces,这种方式的坏处是修改量大,对于维护起来很费劲,下面介绍另外一种方法,通过在Yii::classMap中配置:

Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';

官网部分的介绍为:

http://www.yiiframework.com/doc-2.0/guide-helper-overview.html#customizing-helper-classes

下面是代码步骤:

1.原来的类的内容为:

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My
{
  
  public static function test(){
    echo 'this is my first test php file';
  }
  
}

2.我写一个新类: 文件路径为: appfront/helper/My.php ,我想让controller调用的类为下面的类

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My{
  
  public static function test(){
    echo 'this is my appfront test php file';
  }
  
}

注意:namespace和上面的那个My类的要一样,而不是按照 appfront/helper/My.php 写成 namespace appfront\helper  ,这样会报错的。

3. 我添加Yii::classMap  数组的值的新的My类的文件路径

Yii::$classMap['fecshop\app\appfront\helper\test\My'] = ['@appfront/helper/My.php'];

然后调用后,发现调用的是新的My类。

4. 需要注意的是,新的类的名字必须和之前的类的名字一样,否则会出错,另外,namespace要一致,一样。

5. 我们希望通过配置文件的方式,这样比较方面,我们可以这样做。

5.1 在app/config/下面添加文件 YiiClassMap.php ,内容如下:

<?php
return [
  'fecshop\app\appfront\helper\test\My' => '@appfront/helper/My.php',   
  
];

在web/index.php的代码

$application = new yii\web\Application($config);   上面添加代码:

/**
 * yii class Map Custom
 * 
 */ 
$yiiClassMap = require(__DIR__ . '/../config/YiiClassMap.php');
if(is_array($yiiClassMap) && !empty($yiiClassMap)){
  foreach($yiiClassMap as $namespace => $filePath){
    Yii::$classMap[$namespace] = $filePath;
  }
}

这样,通过上面的配置文件,就可以把classMap执行了,以后如果添加classMap,直接在文件

app/config/YiiClassMap.php 文件里面的数组中添加一条数据就可以了。

您也可以把yii2的库包文件,yii2的某个扩展库包里面的几个文件,通过这种方式进行重写。这个是非常非常非常方便的,尤其对于你写了一个扩展,让大家用,你的扩展需要升级,因此别人不能直接动你的库包文件,不然升级后,修改的会被覆盖,通过这种方式就可以解决这个问题。

总之,这个功能是更好的进行文件重写。

 

对于Yii2的自动加载的原理,可以参看:http://www.digpage.com/autoload.html,这里不多写了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注