关于service文件中为什么要设置protected的action方法,而不是直接使用public的普通方法

问题咨询 · dotatong · 于 4年前 发布 · 1630 次阅读

如题,关于service文件中为什么要设置protected的action方法,而不是直接使用public的普通方法。

例如有如下service

<?php

namespace fecshop\services;

class Test extends Service
{
	protected function actionHello(){
		return 'world';
	}
}

使用的时候需要这样调用

Yii::$service->test->hello();

那为什么,不直接将actionHello方法改为

public function hello(){
	return 'world';
}

请问,这两种写法具体有哪些区别,有哪些影响?

共收到 2 条回复 问题提问
haikou#14年前 1 个赞

读源码就可以读懂的

1.service类都是继承于父类 @fecshop/services/Service.php ,也就是文件:https://github.com/fecshop/yii2_fecshop/blob/master/services/Service.php

2.打开这个文件可以看到里面有一个魔术方法

/**
     * 通过call函数,去调用actionXxxx方法。
     */
    public function __call($originMethod, $arguments)
    {
        if (isset($this->_callFuncLog[$originMethod])) {
            $method = $this->_callFuncLog[$originMethod];
        } else {
            $method = 'action'.ucfirst($originMethod);
            $this->_callFuncLog[$originMethod] = $method;
        }
        if (method_exists($this, $method)) {
            $this->beginCall($originMethod, $arguments);
            $return = call_user_func_array([$this, $method], $arguments);
            $this->endCall($originMethod, $arguments);

            return $return;
        } else {
            throw new InvalidCallException('fecshop service method is not exit.  '.get_class($this)."::$method");
        }
    }

譬如Yii::$service->order->getxxxx(), 如果找不到函数,就会调用魔术方法__call,去找 actionGetxxxx函数,找到后执行这个函数

这样设置的目的是想在每一次调用services,系统都可以记录

$this->beginCall($originMethod, $arguments);
$return = call_user_func_array([$this, $method], $arguments);
$this->endCall($originMethod, $arguments);

这是为了调试加入的,也是这个设计初衷,您如果二次开发,直接定义public方法即可,不需要按照actionGetxxx来定义

也就是如果定义public的方法,不会走这个魔术方法过程,进行不会将这个调用,以及各个service函数的耗时打印出来。

dotatong#24年前 0 个赞

@haikou #1楼 明白了,非常感谢您!

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