【问题标题】:Symfony2 Create a Post calls ShowActionSymfony2 创建一个帖子调用 ShowAction
【发布时间】:2015-01-13 11:30:27
【问题描述】:

我正在将我的旧网站代码“移植”到新的 Symfony2.6 中。我有一个控制器来呈现表单并像在博客中一样创建帖子。然后,一旦它有效,它就会在第二个控制器中提交(POST 方法)。当我调用路由来初始化控制器时,由于某种原因我忽略了它,它也调用了 ShowAction($slug),并且它失败了,因为它尚未创建它的帖子,因此它没有任何 $slug 参数。为什么要调用这个 showAction?尽管我输入 url 只是为了显示表单。

这是开始失败的行的错误日志:

1. in src/Blog/BlogBundle/Services/PostManager.php at line 80
2. at PostManager ->findBySlug ('create_post') in src/Blog/BlogBundle/Controller PostController.php at line 55  
3. at PostController ->ShowAction ('create_post')
4. at call_user_func_array (array(object(PostController), 'ShowAction'), array('create_post')) in app/bootstrap.php.cache at line 3020

我不想调用 ShowAction。

这是控制器代码:

 /**
    * Show a Post
   *
 * @param string $slug
 *
 * @throws NotFoundHttpException
 * @return array
 *
 * @Route("/{slug}")
 * @Template()
 */
public function ShowAction($slug)
{
    $post = $this->getPostManager()->findBySlug($slug);
    $form_comment = $this->createForm(new CommentType());

    return array(
        'post' => $post,
        'form_comment' => $form_comment->createView()
    );
}

/**
 * Displays a form to create a new Post entity.
 *
 * @Route("/new_post", name="_blog_backend_post_new")
 * @Template()
 */
public function newAction()
{
    $form = $this->createForm(new PostType(), new PostModel(new Post()));

    return array(
        'form' => $form->createView(),
    );
}

/**
 * Creates a new Post entity.
 *
 * @Route("/create_post", name="_blog_backend_post_create")
 * @Method("POST")
 * @Template("BlogBundle:Backend/Post:new.html.twig")
 */
public function createAction()
{
    $request = $this->getRequest();
    $em = $this->getDoctrine()->getManager();

    $form = $this->createForm(new PostType(), new PostModel(new Post()));
    $formHandler = new PostHandler($form, $request, new Post(), $em);
    if ($formHandler->process()) {
        return $this->redirect($this->generateUrl('_blog_backend_post'));
    }

    return array(
        'form' => $form->createView(),
    );
}

我不知道是否有必要,但这里是涉及的模板:
* @Template("BlogBu​​ndle:Backend/Post:new.html.twig"):

{% extends "::base.html.twig" %}

{% block content %}
    <form class="well" action="{{ url('_blog_backend_post_create') }}" method="post" {{ form_enctype(form) }}>
        {% include 'BlogBundle:Backend/Post:edit.form.html.twig' with {'form': form } %}
    </form>
{% endblock %}

BlogBu​​ndle:Backend/Post:edit.form.html.twig:

{% if form_errors(form) %}
<div class="alert alert-block alert-error fade in form-errors">
    {{ form_errors(form) }}
</div>
{% endif %}
<p>
<label for="">Title</label>
{% if form_errors(form.title) %}
<div class="alert alert-block alert-error fade in form-errors">
    {{ form_errors(form.title) }}
</div>
{% endif %}
{{ form_widget(form.title, { 'attr': {'class': 'w100'} }) }}
</p>
<p>
<label for="">Body</label>
{% if form_errors(form.body) %}
<div class="alert alert-block alert-error fade in form-errors">
    {{ form_errors(form.body) }}
</div>
{% endif %}
{{ form_widget(form.body, { 'attr': {'class': 'w100'} }) }}
</p>
<p>
<button class="btn" type="submit">Save</button>
<a class="btn" href="{{ url('_blog_backend_post') }}">Cancel</a>
</p>
{{ form_rest(form) }}

我缺少什么以及如何纠正它?提前谢谢你。

【问题讨论】:

  • 为什么新建/编辑表单不用同一个函数,提交后还要处理?
  • 我想改进它,旧的在这种情况下没有用。但是我现在使用的是相同的,所以我认为问题出在控制器中,它首先调用 showAction 而不仅仅是 newAction
  • 创建一个处理新建和编辑操作的单一路由。如果 "$slug" 为 null,则创建新对象,否则更新当前对象

标签: forms symfony redirect controller render


【解决方案1】:

路由器匹配第一个可能的路由,在本例中为“/{slug}”,其中 slug="create_post"。

至少有两种解决方案,第一种是最简单的,第二种是我推荐的:

  • 将您的 showAction 剪切/粘贴到文件底部,在这种情况下,路由器将首先将 /create_post 与 createAction 匹配

  • 您可以像这样排除:@Route("/{slug}", requirements={"slug" = "^(?&lt;!create_post).+"})

【讨论】:

  • 错误说明 /create_post 是问题所在。那么为什么 /new_post 似乎有效?
  • 那是因为我首先阅读了这个:“尽管我输入了 url 只是为了显示表单。”,这就是“new_post”。不过谢谢,我改对了
  • 如果用户输入/new_post,你认为会发生什么?
  • 感谢您的帮助。我蛞蝓干扰了新的行动。我添加了新要求及其现在的工作。然而它奇怪的是它在以前的 symfony 版本中工作。谢谢!
【解决方案2】:

问题是您发布到 /create_post 又匹配路由 /{slug}。 slug 被设置为“create_post”。使用 Symfony 2 路由器,第一场比赛获胜,因此您的 showAction 方法被调用。

考虑将 ShowAction 路径设置为:'/show/{slug}'。

或者您可以将 ShowAction 移至控制器文件的底部。这有点危险,因为您可能会忘记并稍后添加不同的操作。但无论哪种方式都可以。

【讨论】:

    猜你喜欢
    • 2021-03-02
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多