【问题标题】:How to implement Zend routing with Ajax如何使用 Ajax 实现 Zend 路由
【发布时间】:2011-03-18 14:22:23
【问题描述】:

我是 zend 的新手,我找不到在 zend 中实现 Ajax 的方法。

在一般的 php 中,很容易发出 ajax 请求并在我们页面的所需部分显示响应。但是来到zend,我不知道该怎么做。

假设在我的索引控制器的 index.phtml 文件中,我有一个按钮,当我点击它时,我必须向特定的控制器和动作发出 ajax 请求,并在我的页面中加载相关控制器动作的视图。

但我无法理解的是如何为 ajax 请求指定 url 以及路由是如何工作的。

目前,我发出 ajax 请求以静态加载视图,如下所示:

xmlhttp.open("GET","../application/views/scripts/register/register.phtml",true);

仅供参考,我在我的应用程序中使用正则表达式路由,那么使用 curl 路由请求会更好吗?

【问题讨论】:

    标签: php ajax zend-framework


    【解决方案1】:

    首先,您不直接请求视图。您需要请求特定的控制器操作,例如

    /register/register
    

    Zend 带有一个很棒的动作助手,叫做AjaxContext。此帮助器允许您根据请求类型 (XmlHttpRequest) 和 format 参数以不同的视图进行响应,从而禁用通常存在的任何布局。

    要进行设置,请在控制器的 init() 方法中放置类似的内容

    public function init()
    {
        $this->_helper->ajaxContext->addActionContext('register', 'html')
                                   ->initContext();
    }
    

    然后,添加一个带有ajax 后缀的视图脚本,例如register/register.ajax.phtml

    构造您的 AJAX GET 请求以包含 format=html 参数,例如

    xmlhttp.open('GET', '/register/register/format/html', true);
    

    xmlhttp.open('GET', '/register/register?format=html', true);
    

    返回的是register.ajax.phtml的渲染内容,没有任何布局。

    【讨论】:

      【解决方案2】:

      除了其他答案所述之外,还有一个 URL 视图辅助函数可用于调用控制器上的特定操作。因此,您可以使用$this->url(array('controller' => 'your_controller', 'action' => 'your_action'), 'default', true); 获取“your_controller”控制器上“your_action”操作的链接(使用默认路由)。如果你定义了一个,你也可以指定一个特定的路由而不是“默认”。

      因此,对于您的示例,您将在视图 phtml 文件中使用类似以下内容(如果您使用的是默认路由):

      xmlhttp.open("GET","<?php echo $this->url(array('controller' => 'register', 'action' => 'register'), 'default', true);?>");
      

      更多信息请参考Zend Framework - View Helpers

      【讨论】:

        【解决方案3】:

        您永远不应该直接请求视图。那是错误的。请求 URI 如下:

        xmlhttp.open("GET","/register/register");
        

        这意味着“我正在寻找默认模块、注册控制器和注册操作”,或者换句话说,RegisterController::registerAction()。

        同理:

        xmlhttp.open("GET","/default/register/register");
        

        同理,默认模块可以省略。

        Zend Framework 知道在哪里查找视图脚本(除非您使用一些不寻常的目录结构)。

        您可以只创建一个空白布局并将其用于您的 ajax 控制器操作(或者 Phil 建议,AjaxContent 可能更适合此操作)。

        【讨论】:

          【解决方案4】:

          我将在这里写一个几乎完整的“如何”指南,以在 Zendframework 3 中实现 AJAX 调用。 我们需要:

          1. 路由声明
          2. 控制器
          3. 一些 javaScript(不在范围内,也许我会在其他地方展示它)

          路由声明:

          <?php
          // editing a module.config.php in your project
          // typical lines:
          namespace Ajax2l; // my ajax module name
          use Zend\Router\Http\Segment;
          // ...
          'router' => [
            // ... other routes
            'ajax2lsajaxcall'    => [
              'type'    => Segment::class,
              'options' => [
                  'route' => '/ajax2l/ajaxrequest[/:action][/:garbage]',
                  // the :action wildcard is a place to have extra parameters
                  // the :garbage wildcard is a place to send random strings
                  //      to ensure you break cache to get real process for
                  //      all your calls, since every call will be different
                  'defaults' => [
                      'controller' => Controller\AjaxController::class,
                      'action'     => 'ajaxrequest'                        
                  ]
              ],
              'may_terminate' => true,
              'child_routes'  => [
                // other ajax routes if needed
              ]
          ],
          // I only use one ajax route and one controller for all my sites' ajax 
          // calls because they fire small db actions and reflect them on small
          // parts of my pages. So I think I do not need a route and a controller
          // for each ajax call. Instead, I use a Library and some services to get
          // sets of elementary components and to perform tasks.
          

          控制器 我的 Ajax2l 模块位于“myzend_project/module”目录下。

          <?php
          // Filename: /module/Ajax2l/src/Controller/AjaxController.php
          namespace Ajax2l\Controller
          
          use Zend\Mvc\Controller\AbstractActionController;
          use Zend\View\Model\ViewModel;
          // No more components are needed
          
          class AjaxController extends AbstractActionController {
            public function ajaxrequestAction(){
              $request = $this->getRequest();
              $content = $request->getContent();
              $isHttpRequest = $this->ifIsValidHttpRequest();
              // if you have a real ajax call you must disable the normal output
              $viewmodel = new ViewModel();
              $viewmodel->setTerminal($is_xmlhttprequest);
              // If not an Ajax call (perhaps from untrusted eyes) serve a forgiven
              // page message
              if(!$isHttpRequest){
                return $this->forgivenPage();
              }
              // Now prepare a response and responds
              $requestParams = $this->preProcessRequest($content);
              // call the logics to process your params
              $output = $this->processRequestParams($requestParams);
              // and send a response
              $response = $this->getResponse();
              $response->setContent($output);
              return $response;
            }
          
            private function ifIsValidHttpRequest($content){
              // I use a small token string to verify if posted data matches 
              // perhaps not the proper way but is fast and works
              $token = 'my_secure_visitor_session_token_identifier';
              return (strpos($content, $token) > 2) ? 1 : 0;
              // the validation is simplified here it has some more
              // complex logics. To ensure validation of requesting source
            }
          
            private function preProcessRequest($content){
              // The logics to know what to do
              // ...
              // here you can identify and set properly the post params
            }
          
            function processRequestParams($requestParams){
              // some logics to process your data
              // ...
              // some logics to create a Json output
              // ...
              return $jsonObject;
            }
          
            protected function forgivenPage(){
              $view = new ViewModel([]);
              // set a forgiven message page as output
              $view->setTemplate('ajax2l/messages/forgiven.phtml');
              // note: the views directory uses lowercase for module names
              return $view;
            }
          }
          

          希望对您有所帮助。我浪费了很多时间阅读 zend ajax 却没有结果。所以我希望我是最后一个在这个话题上浪费时间的人。

          路易斯

          【讨论】:

            猜你喜欢
            • 2012-03-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多