Php Zend framework 2:重定向toRoute短路未触发

Php Zend framework 2:重定向toRoute短路未触发,php,redirect,zend-framework2,Php,Redirect,Zend Framework2,通常情况下,这不是我会问的问题,因为我认为我遗漏了一些愚蠢的东西,但在调试过程中,我发现了一些非常奇怪的行为,真的让我感到困惑 为了描述发生(可疑)错误的设置:我有一个基本的CRUD控制器(或者在我的情况下是首选的NERD),其中我有四个操作: 新的 编辑 阅读 删除 read、edit和delete操作需要一个对象,比如blogpost,并且需要提供由/post/read/[:id]之类的路由调用的url。在这些操作中,我要做的第一件事是检查(a)id参数是否已设置,以及(b)id是否对应

通常情况下,这不是我会问的问题,因为我认为我遗漏了一些愚蠢的东西,但在调试过程中,我发现了一些非常奇怪的行为,真的让我感到困惑

为了描述发生(可疑)错误的设置:我有一个基本的CRUD控制器(或者在我的情况下是首选的NERD),其中我有四个操作:

  • 新的
  • 编辑
  • 阅读
  • 删除
read、edit和delete操作需要一个对象,比如blogpost,并且需要提供由
/post/read/[:id]
之类的路由调用的url。在这些操作中,我要做的第一件事是检查(a)id参数是否已设置,以及(b)id是否对应于数据库中存储的有效实体(我使用Doctrine 2作为映射器)。如果(a)或(b)失败,我立即返回并重定向到索引操作:

 return $this->redirect()->toRoute('post/index');
我在同一控制器中的单独公共函数中执行检查,以防止代码重复

守则: 问题消失,应用程序整齐地重定向。然而,这毫无意义。该行只调用控制器中实例化表单的公共函数,就我所知,这应该没有任何效果。更糟糕的是,如果我从那一行中删除
->bind()
调用,旧问题又回来了。因此,我所能理解的是,这些操作之间的区别似乎是调用
validatePostId()
和返回视图之间没有任何额外的代码,这其实并不重要

编辑: 更新,如果我直接使用
readAction()
中的
validatePostId()
函数的代码,问题也会消失:

public function readAction()
{
    $post_id = $this->params()->fromRoute('id');
    $post    = $this->validatePostId($post_id);

    if (!$post_id) {
        $this->flashMessenger()->addErrorMessage('Invalid post id');
        return $this->redirect()->toRoute('post');
    }

    $post = $this->getBlogService()->getPostById($post_id);

    if ($post == NULL) {
        $this->flashMessenger()->addErrorMessage('Invalid post id');
        return $this->redirect()->toRoute('post');
    }

    return array(
        'post' => $post
    );
}

在控制器中调用
$this->redirect()
的行为不会自动重定向到新位置,它只会返回一个
响应
对象,然后需要从控制器操作返回该对象以缩短请求

由于您正在从另一个函数返回
redirect()
调用的结果,因此需要首先测试该调用的结果是否是
响应
对象,并在控制器操作中处理它

<?php

namespace Blog\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\Controller\Plugin\FlashMessenger as FlashMessenger;

use Zend\Stdlib\ResponseInterface as Response;

class PostController extends AbstractActionController
{

    public function readAction()
    {
        $post_id = $this->params()->fromRoute('id');
        $post    = $this->validatePostId($post_id);

        // check to see if post validation returned a Response 
        if ($post instanceof Response) {
            // redirect...
            return $post;
        }

        return array(
            'post' => $post
        );
    }

    /**
     * Checks if $id from url is set and tries to find the corresponding post
     */
    public function validatePostId($post_id)
    {        
        if (!$post_id) {
            $this->flashMessenger()->addErrorMessage('Invalid post id');
            return $this->redirect()->toRoute('post');
        }

        $post = $this->getBlogService()->getPostById($post_id);

        if ($post == NULL) {
            $this->flashMessenger()->addErrorMessage('Invalid post id');
            return $this->redirect()->toRoute('post');
        }

        return $post;
    }
}

我想知道如何测试empty()而不是==NULL。
empty()
没有什么区别最近的编辑表明$post=$this->getBlogService()->getPostById($post\u id)中出现了问题;在原始代码中,如果您在返回之前使用var_dump($post_id)和var_dump($post),并且它们都仍然为空,那么我就被难住了。可能重定向后出现了问题,即路线(“post”)走到哪里+1对于你的头像,btwWell,这让我们两个人,
var\u dump($post)
就在返回转储
NULL
之前(显然,如果开始时它不应该输入
)。谢谢你的评论,我只是想。。。如果在构造函数中进行验证,会发生什么?或者在另一个类中进行验证,并将已验证的post对象注入$this->post?我还注意到,您首先说明了到“post/index”的路由,但其他示例说明了到“post”的路由。对不起,希望我能帮上更多的忙。很有帮助的解释,谢谢。我在您建议的操作中更改了检查
$post
是否是响应的一个实例,以检查它是否是一个对象并且是否有效
public function readAction()
{
    $post_id = $this->params()->fromRoute('id');
    $post    = $this->validatePostId($post_id);

    if (!$post_id) {
        $this->flashMessenger()->addErrorMessage('Invalid post id');
        return $this->redirect()->toRoute('post');
    }

    $post = $this->getBlogService()->getPostById($post_id);

    if ($post == NULL) {
        $this->flashMessenger()->addErrorMessage('Invalid post id');
        return $this->redirect()->toRoute('post');
    }

    return array(
        'post' => $post
    );
}
<?php

namespace Blog\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\Controller\Plugin\FlashMessenger as FlashMessenger;

use Zend\Stdlib\ResponseInterface as Response;

class PostController extends AbstractActionController
{

    public function readAction()
    {
        $post_id = $this->params()->fromRoute('id');
        $post    = $this->validatePostId($post_id);

        // check to see if post validation returned a Response 
        if ($post instanceof Response) {
            // redirect...
            return $post;
        }

        return array(
            'post' => $post
        );
    }

    /**
     * Checks if $id from url is set and tries to find the corresponding post
     */
    public function validatePostId($post_id)
    {        
        if (!$post_id) {
            $this->flashMessenger()->addErrorMessage('Invalid post id');
            return $this->redirect()->toRoute('post');
        }

        $post = $this->getBlogService()->getPostById($post_id);

        if ($post == NULL) {
            $this->flashMessenger()->addErrorMessage('Invalid post id');
            return $this->redirect()->toRoute('post');
        }

        return $post;
    }
}