关于fecshop中 appfront->config->fecshop_local_services中的php文件和@fecshop->services中的php文件的关系

问题咨询 · xiaobeibei · 于 3年前 发布 · 1615 次阅读

第一个common中的service,第二个是fecshop中的service这两种service都被index.php给作为config初始化了。 如图: 试问:比如common->config->fecshop_local_services->Product.php和fecshop -> services->Product.php有什么关联关系?第一个Product.php返回的是第二个php文件的实例吗? 他们会同时存在于$config中吗?

共收到 9 条回复
Fecmall#13年前 0 个赞

这个是Yii2的容器注入,原理就是:吧一个类和一个配置数据扔给容器,容器给生成一个对象。

配置:common\config\fecshop_local_services\Product.php

类:@fecshop\services\Product.php

容器方法,也就是:Yii::createObject($service);

所有的service都继承于 [@fecshop](/member/fecshop)\services\Service 在这个类里面可以看到如下代码:

protected function getChildService($childServiceName)
    {
        if (!$this->_childService[$childServiceName]) {
            $childService = $this->childService;
            if (isset($childService[$childServiceName])) {
                $service = $childService[$childServiceName];
                $this->_childService[$childServiceName] = Yii::createObject($service);
            } else {
                throw new InvalidConfigException('Child Service ['.$childServiceName.'] is not find in '.get_called_class().', you must config it! ');
            }
        }

        return $this->_childService[$childServiceName];
    }

原理为使用php的魔术方法 __get() ,在上面的类中你可以看到这个魔术方法调用了 getChildService($childServiceName) , 这个函数里面调用了 Yii::createObject($service); 这个容器函数,来生成相应的对象。

上面说的就是容器生成的原理,Yii2的组件就是这个原理搞的,按照Yii::$app->xxxxx,进行调用组件,组件是单例模式,

fecshop参考了Yii2组件的原理,Yii::$service->xxxx 的方式调用service

对于每一个service的配置,一共有几个配置文件,在初始化的时候合并

@fecshop//config/services/Product.php : 这个配置文件是yii2对services的默认配置。

@common/config/fecshop_local_services/Product.php :如果你想全局重写Product services , 可以在 这个配置文件中更改配置

@appfront/config/fecshop_local_services/Product.php :如果你在单个入口重写 Product services,譬如在appfront中重写,您可以在 这个文件中更改配置,如果Product.php不存在,您可以新建一个配置文件。

这三个配置文件是有优先级的,高优先级的配置会覆盖低优先级的配置, @appfront @common [@fecshop ,优先级由高到低,

原理为:打开@app/web/index.php 可以看到代码:(@app 统称,代指 @appfront @apphtml5等)

$config = yii\helpers\ArrayHelper::merge(
        require(__DIR__.'/../../common/config/main.php'),
        require(__DIR__.'/../../common/config/main-local.php'),
        require(__DIR__.'/../config/main.php'),
        require(__DIR__.'/../config/main-local.php'),
        // fecshop services config
        require(__DIR__.'/../../vendor/fancyecommerce/fecshop/config/fecshop.php'),
        // fecshop module config
        require(__DIR__.'/../../vendor/fancyecommerce/fecshop/app/appfront/config/appfront.php'),

        // thrid part confing

        // common modules and services.
        require(__DIR__.'/../../common/config/fecshop_local.php'),

        // appadmin local modules and services.
        require(__DIR__.'/../config/fecshop_local.php')

    );

也就是配置会在初始化的时候合并,通过yii\helpers\ArrayHelper::merge() 函数合并, 高优先级的会覆盖低优先级的,通过配置覆盖的方式来实现功能的重写。

还有什么疑问,在下面留言。

Fecmall#23年前 0 个赞

这个部分的文档不够完善,回头完善一下。

可以参看这个链接,看一下index.php的初始化工作:http://www.fecshop.com/doc/fecshop-guide/develop/cn-1.0/guide-fecshop-init-index.html

Fecmall#33年前 0 个赞

关于fecshop的配置结构的介绍,可以看这个文档:

http://www.fecshop.com/doc/fecshop-guide/instructions/cn-1.0/guide-fecshop_config_construction.html

xiaobeibei#43年前 0 个赞

那么fecshop\services目录下的所有定义的Service类就是所有config目录下中service的描述?不知道我描述的准不准确

xiaobeibei#53年前 0 个赞

好想有点明白了工作的流程了,原理还是不是很懂

Fecmall#63年前 0 个赞

@xiaobeibei #5楼 容器注入, 上面写了,根据类和配置,生成一个单例模式的对象,放到Yii::$service的一个属性(这个属性是数组)里面,__get()方法会到这个属性里面取之前生成的对象,取不到就会生成,你先了解下yii框架把。

xiaobeibei#73年前 0 个赞

请问 Terry有相关文章吗?http://www.yiichina.com/tutorial/112 我只找到这个不知是否准确

Fecmall#83年前 0 个赞

@xiaobeibei #7楼 知道原理就行了,那个是探究原理的代码

可以很简单的理解原理就行了,譬如:

配置:common\config\fecshop_local_services\Product.php

类:@fecshop\services\Product.php

容器方法:Yii::createObject($service);

容器的作用就是实例化类,生成一个对象,然后利用配置中的数组数据,对对象的属性依次赋值,就这么个原理,如果想了解本质,可以看看你发的那个文章。

xiaobeibei#93年前 0 个赞

谢谢

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Your Site Analytics