【问题标题】:How does the method syntax "public function direct(){}" work in PHP?方法语法“public function direct(){}”在 PHP 中是如何工作的?
【发布时间】:2011-05-02 19:20:38
【问题描述】:

我目前正在学习 Zend Framework,遇到了以下语法。

class Zend_Controller_Action_Helper_Redirector extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * Perform a redirect to an action/controller/module with params
     *
     * @param  string $action
     * @param  string $controller
     * @param  string $module
     * @param  array  $params
     * @return void
     */
    public function gotoSimple($action, $controller = null, $module = null, array $params = array())
    {
        $this->setGotoSimple($action, $controller, $module, $params);

        if ($this->getExit()) {
            $this->redirectAndExit();
        }
    }

    /**
     * direct(): Perform helper when called as
     * $this->_helper->redirector($action, $controller, $module, $params)
     *
     * @param  string $action
     * @param  string $controller
     * @param  string $module
     * @param  array  $params
     * @return void
     */
    public function direct($action, $controller = null, $module = null, array $params = array())
    {
        $this->gotoSimple($action, $controller, $module, $params);
    }
}

在 Zend Framework 中,可以使用以下语法调用此类中的 direct() 方法:

$this->_helper->redirector('index','index');

重定向器是 _helper 对象中的一个对象(!),它位于控制器对象内部,我们在其中调用方法。这里的语法糖是你可以将参数传递给对象而不是方法,我们可以这样写:

$this->_helper->redirector->gotoSimple('index','index');

..当然,这一切都很好。

这是我的问题:这个 direct() 方法在 OO PHP 中是标准的吗?或者这个功能是内置在 Zend 框架中的吗? 我找不到这方面的任何文档。

谢谢!

【问题讨论】:

    标签: php oop zend-framework syntactic-sugar


    【解决方案1】:

    它是 Zend 框架中内置的功能。

    Controller 实例中的$_helpers 属性包含一个Action_HelperBroker 实例。此实例实现PHP's magic __call method。当您调用该实例上不存在的方法时,它将尝试使用方法名称来获取同名的帮助程序并在其上调用direct()(如果可能)。请参阅下面的代码。

    来自Zend_Controller_Action

    /**
     * Helper Broker to assist in routing help requests to the proper object
     *
     * @var Zend_Controller_Action_HelperBroker
     */
    protected $_helper = null;
    

    来自Zend_Controller_Action_HelperBroker

    /**
     * Method overloading
     *
     * @param  string $method
     * @param  array $args
     * @return mixed
     * @throws Zend_Controller_Action_Exception if helper does not have a direct() method
     */
    public function __call($method, $args)
    {
        $helper = $this->getHelper($method);
        if (!method_exists($helper, 'direct')) {
            require_once 'Zend/Controller/Action/Exception.php';
            throw new Zend_Controller_Action_Exception('Helper "' . $method . '" does not support overloading via direct()');
        }
        return call_user_func_array(array($helper, 'direct'), $args);
    }
    

    Helper Broker 还实现了神奇的__get 方法,因此当您尝试访问不存在的属性时,代理将使用属性名称作为getHelper() 的参数

    /**
     * Retrieve helper by name as object property
     *
     * @param  string $name
     * @return Zend_Controller_Action_Helper_Abstract
     */
    public function __get($name)
    {
        return $this->getHelper($name);
    }
    

    请注意,魔术方法并不是要替代适当的 API。虽然您可以使用它们如上所示,调用更详细的

    $this->_helper->getHelper('redirector')->gotoSimple('index','index');
    

    通常是更快的选择。

    【讨论】:

    • 此外,您可以在此处阅读有关帮助程序(和 direct 方法)的信息:devzone.zend.com/article/3350
    • 在您的编辑之后:您谈到更长的语法是更快的替代方案,我们说得更快还是可以忽略不计?好的,这当然取决于,但这就像用变量解析双引号字符串还是连接单引号字符串和变量的比较?
    • @Niels 这是一个 µ 优化,如果你只有几个这样的调用也没关系。但如果你有很多这样的电话,它可能会产生影响。 ViewHelpers 使用了类似的技术,例如在 View 中调用 $this->helperName() 将使用魔术方法来查找和调用帮助程序。在我当前的项目中,我们的页面在呈现页面时会对 ViewHelpers 进行数百次调用。无论我是直接调用助手还是通过魔术方法调用助手,都会有所不同。另见stackoverflow.com/questions/3330852/…
    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 2011-02-12
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2020-02-22
    相关资源
    最近更新 更多