Symfony 5 - 在类别 url 中显示 id 和 slug 并在更新 slug 时通过 id 找到它

Posted

技术标签:

【中文标题】Symfony 5 - 在类别 url 中显示 id 和 slug 并在更新 slug 时通过 id 找到它【英文标题】:Symfony 5 - Display id and slug in category url and find it by id when slug is updated 【发布时间】:2021-05-01 07:12:39 【问题描述】:

我的类别 url 同时包含 id 和 slug,例如 https://myapp.com/category/56-category-name(数据库中的 id 字段 = 56 和 slug 字段 = 类别名称),当更新类别名称时,数据库中的 slug 字段会更新,但 id 仍然相同。 我想显示我的类别,只要 id 正确,当然显示正确的 url。在这种情况下,我认为 SEO 仍然正确。

这里是我的展示方法:

/**
 * @Route("/category/id-slug", name="category_show", requirements="id"="\d+")
 */
public function show(CategoryRepository $categoryRepository, $slug, $id): Response


    $category = $categoryRepository->find($id);
    if($category->getSlug() !== $slug) 
        return $this->redirectToRoute('category_show', [
            'id' => $id,
            'slug' => $category->getSlug()
        ]);
    
    return $this->render('category/show.html.twig', [
        'category' => $category
    ]);

如果给定的 id 存在于 DB 中,它可以工作,否则我得到一个错误 在 null 上调用成员函数 getSlug()。我可以抛出 NotFoundException,但我认为这种方法会使用多次查询。

所以请帮助我以更高的灵活性和性能正确地完成这些工作。 如果我想在帖子网址中显示类别以及https://myapp.com/56-category-name/23-post-title 怎么办??

提前致谢

【问题讨论】:

您好,如果我理解您的问题,可以尝试在您的存储库中创建一个自定义方法,例如“findByIdOrSlug”,您对此有何看法? 【参考方案1】:

这是我发现对我的应用有好处的:

在我创建的 CategoryController.php 中,显示方法:

/**
 * @Route("/id-slug", name="category_show", requirements="id"="\d+")
 */
public function show(CategoryRepository $categoryRepository, $slug = null, $id): Response


    $category = $categoryRepository->find($id);
    
    if (!$category) 
        throw new NotFoundHttpException();
    

    if($category->getSlug() !== $slug) 
        return $this->redirectToRoute('category_show', [
            'id' => $id,
            'slug' => $category->getSlug()
        ]);
    
    return $this->render('category/show.html.twig', [
        'category' => $category
    ]);

在我的索引模板中显示 category_show 链接:

<a href=" path('category_show', 'slug': category.slug, 'id': category.id) ">show</a>

在我创建的 ArticleController.php 中,显示方法:

/**
 * @Route("/category/id-slug", name="article_show", requirements="id"="\d+")
 */
public function show(ArticleRepository $articleRepository, $slug = null, $id, $category = null): Response

    $article = $articleRepository->find($id);
    
    if (!$article) 
        throw new NotFoundHttpException();
    
    
    $cat = $article->getCategory()->getId() . '-' . $article->getCategory()->getSlug();

    if($article->getSlug() !== $slug || $cat !== $category) 
        return $this->redirectToRoute('article_show', [
            'id' => $id,
            'slug' => $article->getSlug(),
            'category' => $cat
        ]);
    
    return $this->render('article/show.html.twig', [
        'article' => $article,
    ]);

在我的索引模板中显示 article_show 链接:

<a href=" path('article_show', 'category': article.category.id ~ '-' ~ article.category.slug, 'slug': article.slug, 'id': article.id) ">show</a>

对我来说,这解决了我的问题。但是,如果我们可以改进流程,我还是买家。

谢谢

【讨论】:

【参考方案2】:

使用findOneBy()并检查结果是否为null

/**
 * @Route("/category/id-slug", name="category_show", requirements="id"="\d+")
 * @Route("/id-slug/idArticle-postSlug", name="article_show", requirements="idArticle"="\d+")
 */
public function show(CategoryRepository $categoryRepository, $slug, $id, $idArticle = false, $postSlug = false ): Response


    $category = $categoryRepository->findOneBy(['id'=>$id]);
    if(is_null($category))
      throw new NotFoundHttpException(); //404, nothing found
    else
      //Category found.
      if($idArticle) //  https://myapp.com/56-category-name/23-post-title
         //Article route, put your logic here 
      else //https://myapp.com/category/56-category-name 
        // Category route, logic here
        if($category->getSlug() !== $slug) 
           return $this->redirectToRoute('category_show', [
              'id' => $id,
              'slug' => $category->getSlug()
           ]);
        
        return $this->render('category/show.html.twig', [
          'category' => $category
        ]);
      
    

【讨论】:

它有效。但如果我想在帖子网址中显示类别以及myapp.com/56-category-name/23-post-title 怎么办?? @bahahmadou94 现在检查代码。我添加了第二条路线。 感谢您的帮助?

以上是关于Symfony 5 - 在类别 url 中显示 id 和 slug 并在更新 slug 时通过 id 找到它的主要内容,如果未能解决你的问题,请参考以下文章

在 Symfony 5 中使用 GET 参数生成 URL

Symfony 5 / 请求响应:使用 Ajax 获取数据

Symfony2 url层次结构

Symfony 5 和 Doctrine,找不到使用 3 个相关实体获取结果的方法

Symfony 5 easyadmin 3 与 ManyToOne 关系的实体 - 不保存在“多”端

带有多个表的 Symfony sfDoctrinePager