我正在使用zend框架构建一个应用程序。
问题是,如何在非rest应用程序中使用zend_rest_控制器的相同控制器逻辑。
例如,假设twitter是用zend框架编写的。他们可能会使用zend_rest_控制器和api的路由。然而,他们的网站将使用什么(显然使用相同的api逻辑)?他们是否会编写一个全新的应用程序来触发rest请求?这不是超载吗?
[编辑]
如果web应用程序通过某个http_客户端类调用api来获取数据,则会向服务器发出另一个请求(这会导致性能降低并减慢响应速度)。我不想再提出另一个请求,我想使用与api中相同的业务逻辑。
谢谢,
静脉

最佳答案

新答案:
我想出了一个似乎很有效的模式。它解决了您的所有问题:
以下是我的缩小版本:
首先我们需要自己的控制器。该联系人将有一个服务,在该服务中,如果不定义服务,则代理向服务发送任何动作请求:

abstract class App_Rest_Controller extends Zend_Controller_Action
{
    /**
     * @var App_Rest_Service_Abstract
     */
    protected $_service;

    public function __call($methodName, $args)
    {
        if ('Action' == substr($methodName, -6)) {
            $action = substr($methodName, 0, strlen($methodName) - 6);
            return $this->_service()->$action();
        }

        return parent::__call($methodName, $args);
    }
}

现在是服务的时候了。我们扩展了action helper抽象,以便:
我们可以直接访问请求对象
我们可以很容易地从任何控制器调用服务
这将充当应用程序和数据实际存储之间的中间环节。
abstract class App_Rest_Service_Abstract extends Zend_Controller_Action_Helper_Abstract
{
    /*
     * @var App_Rest_Storage_Interface
     */
    protected $_storage;
    public function __call($methodName, $args)
    {
        if (!method_exists($this->getStorage(), $methodName)) {
            throw new App_Rest_Service_Exception(sprintf('The storage does not have the method "%s"', $methodName));
        }

        switch ($methodName) {
            case 'get':
            case 'put':
            case 'delete':
                //if id param isnot set, throw an exception
                if (FALSE === ($id = $this->getRequest()->getParam('id', FALSE))) {
                    throw new  App_Rest_Service_Exception(sprintf('Method "%s" expects an id param, none provided', $methodName));
                }
                $iterator = $this->getStorage()->$methodName($id, $this->getRequest()->getParams());
                break;
            case 'index':
            case 'post':
            default:
                //if index, post or not a tradition RESTful request, the function must expect the first and only argument to be an array
                $iterator =  $this->getStorage()->$methodName($this->getRequest()->getParams());
                break;
        }


        return $this->_getResult($iterator);
    }

    protected function _getResult($iterator)
{ /*
       * write your own, in my case i make a paginator and then
       *  either return it or send data via the json helper
       *
      /*
}

现在是界面。这将完成存储、修改和返回数据的实际工作。使用它作为接口的好处是,无论您在模型层使用什么,都可以轻松地实现它。我创建了一个抽象存储,它只是有一个zend_表单(用于验证)和一个zend_db_表用于实际数据。但是你也可以在任何对象上实现它。
interface App_Rest_Storage_Interface extends Zend_Validate_Interface
{
    public function index(array $params = NULL);

    public function get($id, array $params = NULL);

    public function post(array $params);

    public function put($id, array $params);

    public function delete($id, array $params);

}

现在在你网站的任何地方运行。假设你有一个“客户”服务。在任何控制器内部
$customer = $this->_helper->helper->customers->get(1);

其他任何地方(例如说视图助手):
Zend_Controller_Action_HelperBroker::getStaticHelper('customers')->get(1)

我希望这能有帮助。它对我很有用。

关于php - Zend框架 Restful Web服务逻辑用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5831433/

10-09 18:48
查看更多