Zend:重定向后是否可以发送视图变量?

时间:2009-03-25 11:37:40

标签: php zend-framework

如何在完成重定向后发送其他视图参数(例如$ this-> _redirect-> gotoSimple();)?

例如,假设我有一个Edit操作,它将用户重定向到Error操作处理程序,我希望能够向其视图发送自定义的详细错误消息。为了更清楚地说明,流程将是:

  1. 在编辑视图(例如,http://localhost/product/edit)中,用户提交了令人讨厌的内容
  2. 在editAction()中,失败检查会触发重定向到我的错误视图/操作处理程序(以便我的URL读取为http://localhost/error/index
  3. Error / index.phtml采用“errorMessage”视图变量来显示自定义错误消息,而editAction()需要一种方法将一些值传递给“errorMessage”视图变量
  4. 快速代码段可能如下所示:

    public function editAction() {
        //DO THINGS...
    
        // Upon failure
        if($fail) {
            $this->_redirector->gotoUrl('/error/index');
            //TODO: I need to be able to do something like
            //      $errorView->errorMessage = "Generic error";
        }
    }
    

    非常感谢任何解决方案,甚至其他更好的实现方法。

5 个答案:

答案 0 :(得分:5)

不要将gotoURL()用于内部重定向。使用gotoSimple()。我最多需要4个参数:

gotoSimple($action, 
           $controller = null, 
           $module = null, 
           array $params = array())

在你的情况下,它将是:

$this->_redirector->gotoSimple('index',
                               'error',
                                null,
                                array('errorMessage'=>$errMsg));

有关详细信息,请参阅Redirector Zend_Controller_Action_Helper

答案 1 :(得分:4)

我还没有看到任何动作(editAction)访问另一个动作的视图(errorView)。对于错误处理的特殊情况,我的想法是使用异常。为不同的错误情况抛出不同的异常,在错误处理程序操作中,您可以根据异常类型决定向用户显示的内容:

// file: ProductContorller.php
public function editAction() {
    // some code
    if ($badThing) {
         throw new Exception('describe the bad thing',$errorCode);
    }
    if ($badThing2) {
         throw new Exception('describe the other bad thing',$errorCode2);
    }
}

// file: ErrorController.php
public function errorAction() {
     $error = $this->_getParam('error_handler');
     $exception = $error->exception; // the original Exception object thrown by some code
     $code = $exception->getCode();
     switch ($code ) {
          // decide different things for different errors
     }
}

有关错误处理的更多信息,Zend Framework quick start是一个很棒的教程。

对于其他情况,您可以使用某些消息传递机制在这两个操作之间进行通信。使用flashMessenger动作助手是我想到的第一件事:

// file: ProductContorller.php
public function editAction() {
    // some code
    if ($badThing) {
         $this->_helper->flashMessenger->addMessage('error1');
         $this->_redirect('error');
    }
    if ($badThing2) {
         $this->_helper->flashMessenger->addMessage('error2');
         $this->_redirect('error');
    }
}

// file: ErrorController.php
public function errorAction() {
     $errors = $this->_helper->flashmessenger->getMessages();
     if ( in_array('error1',$errors) ) {
       // do something
     } // elseif ( ...
}

虽然请记住flashMessenger使用会话,因此会话和很可能的cookie将参与此消息传递过程。

答案 2 :(得分:3)

执行此操作的标准方法是使用基于会话的商店来显示您要显示的消息。通常有一个基于视图的助手FlashMessenger

  

FlashMessenger帮助程序允许您   传递用户可能传递的消息   需要看下一个请求。至   实现这一点,FlashMessenger使用   要存储的Zend_Session_Namespace   用于将来或下一个请求的消息   恢复。这通常是个好主意   如果你打算使用Zend_Session   或Zend_Session_Namespace,你   用Zend_Session :: start()初始化   在你的bootstrap文件中。 (见   Zend_Session文档了解更多信息   有关其用法的详细信息。)

答案 3 :(得分:1)

浏览此链接..它解释了如何在_redirect

之前设置视图变量

http://www.rmauger.co.uk/2009/06/creating-simple-extendible-crud-using-zend-framework/

答案 4 :(得分:0)

我将添加此内容以提供有关FlashMessenger类如何工作的更多信息(我有一些问题可以搞清楚)。

我在某处读到了应该使用

在Bootstrap.php中启动会话
Zend_Session::start();

..但我的代码没有这个,所以我怀疑会话已经开始了。

我们在一个控制器对象中,正在调用一个动作方法。然后发生了一些事情,比如插入或编辑数据库,真的。

我们现在设置一条或多条消息。我使用以下语法。

$this->_helper->FlashMessenger("Message in a bottle.");

完全相同
$this->_helper->FlashMessenger->addMessage("Message in a bottle.");

这会在会话中设置一条消息,您可以通过调用

直接检查
print_r($this->_helper->FlashMessenger->getMessages());
die();

现在有一个重定向到一个新的url(基本上是一个新的请求),在处理请求的控制器+动作内部,我们将消息添加到视图中,如下所示:

$this->view->flashMessages = $this->_helper->FlashMessenger->getMessages();

我们现在可以选择输出这些消息的位置。我们可以在“属于”某个控制器的视图中执行此操作,因此可以

views/scripts/index/index.phtml

这里的缺点是你必须将输出消息的代码添加到使用它的每个视图中。那不是DRY

在我看来,优秀的解决方案如下。在您定义应用程序基本布局的文件中输出这些消息。那可能是

layouts/scripts/index.phtml

我在那里写了下面的代码。

<?php if( isset($this->flashMessages) && !empty($this->flashMessages) ){ ?>
    <ul id="messages">            
        <?php foreach( $this->flashMessages as $message ){?>
            <li>
                <?php echo $message;?>
            </li>    
        <?php } ?>
    </ul>
<?php } ?>