通过配置的方式重写某个Yii2 文件 或第三方扩展文件 [ 2.0 版本 ]
介绍一种比较好的用Yii2 classMap的方式重写的方法
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文件的前提下,重写任何文件了
FancyEcommerce.com 原文链接: 通过配置的方式重写某个Yii2 文件 或第三方扩展文件
下面是代码举例说明的详细步骤:
下面是我写的一个类,内容如下:
<?php
/**
* FecShop file.
*
* [@link](/member/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';
}
}
- 然后我在controller中对这个类的静态方法进行了调用:
<?php
/**
* FecShop file.
*
* [@link](/member/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](/member/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](/member/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 ,这样会报错的。
- 我添加Yii::classMap 数组的值的新的My类的文件路径
Yii::$classMap['fecshop\app\appfront\helper\test\My'] = ['@appfront/helper/My.php'];
然后调用后,发现调用的是新的My类。
需要注意的是,新的类的名字必须和之前的类的名字一样,否则会出错,另外,namespace要一致,一样。
我们希望通过配置文件的方式,这样比较方面,我们可以这样做。
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 ,这里不多写了。
Fecshop 深圳
最后登录:2024-08-13
在线时长:73小时36分
- 粉丝157
- 金钱2381
- 威望490
- 积分8011
共 3 条评论
最后,推荐一下我的Fecshop ,开源商城,github地址:https://github.com/fancyecommerce/yii2_fecshop
演示地址:http://fecshop.appfront.fancyecommerce.com/
截止到2016-11-12号,产品,分类,首页,评论,用户中心,搜索,多语言,多货币 等功能已经做完,除了购物车和支付部分,其他的基本都已经完成,关注fecshop的 在等2-3个月,也就是明年2,3月份,版本已经就可以出来,2017年4,5月份在把手机web 做一下,预计到明年5月份,后台,pc前台,手机web前台 ,命令控制台 这几个入口 基本可以完善,多谢大家关注和你们的Star,谢谢,我会坚持把他写好。
作者QQ:2358269014
geili 给力啊 楼主!
来学习fecshop吧,哈哈
在了 已转粉!
请教一个问题:


我安装了一个数据库备份模块
我想要更改里面的视图,只能直接更改vendor下的源码吗 有没有别的方式?
1,通过Yii2的controllerMap,重写controller,然后在重写后的controller中,执行新的view路径文件
'backup' => [ /** * Yii2 controllerMap 重写机制。 */ 'controllerMap' => [ 'category' => 'appfront\local\local_modules\Catalog\controllers\CategoryController', ], ... ]