【问题标题】:Symfony 4 routing from DB来自数据库的 Symfony 4 路由
【发布时间】:2018-06-03 15:06:11
【问题描述】:

我正在使用 Symfony 4 创建一个简单的 CMS。可以在其中创建页面。创建页面时,会调用 Doctrine EvenSubscriber。此订阅者创建一个 PageRoute。

<?php
#src/Doctrine/EvenListener 

/**
 * PageRouteSubscriber
 */

namespace App\Doctrine\EventListener;


use App\Controller\PageController;
use App\Entity\Page;
use App\Entity\Route;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

/**
 * Class PageRouteSubscriber
 * @package App\Doctrine\EventListener
 */
class PageRouteSubscriber implements EventSubscriber {
    /**
     * Returns an array of events this subscriber wants to listen to.
     * @return array
     */
    public function getSubscribedEvents() {
        return [
            'postPersist',
            'postUpdate',
        ];
    }

    public function postPersist(LifecycleEventArgs $args){
        $this->index($args);
    }

    public function postUpdate(LifecycleEventArgs $args){
        $this->index($args);
    }

    public function index(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        if($entity instanceof Page){
            $route = new Route();
            $route->setController(PageController::class);
            $route->setRouteContentId(get_class($entity) . '#' . $entity->getId());
            $route->setLocale($entity->getLocale());
            $route->setSlug($entity->getSlug());

            $entityManager = $args->getObjectManager();
            $entityManager->persist($route);
            $entityManager->flush();
        }
    }
}

所以当页面被创建时,也会创建一个路由。请参阅图像以获取数据库页面和路由示例。

页面

路线

我不知道这是在数据库中存储路由和页面的最佳方式。 因为他们都有相同的蛞蝓。我在想,只在路由表中设置 slug。并且每个实体根据路由表中的所有 slug 检查唯一的 slug(如果可能的话?)。

对于路由:我现在不知道如何 grep 路由并将它们与 Symfony Route Collection 一起使用。也可以像 Symfony 一样缓存路由并在名为:srcDevDebugProjectContainerUrlGenerator 的大文件上创建

当我的路线正常工作时,我可以创建前端菜单。页面菜单项与页面耦合的地方。该页面有一条路线。使用这条路线可以创建菜单 url(是正确的思维方式吗?)。

【问题讨论】:

  • RE 缓存路由:我假设您使用 DynamicRouter。该路由器的重点是路由存储在数据库中并在运行时查询。每次编辑其中一个路由时都需要重新构建缓存文件,这将非常低效。
  • 如果您可以从内容生成路由而无需手动交互,您可以查看 cmf 路由包的路由提供程序 - 您可以从您的内容动态生成它们,而不需要存储数据库中的单独路由。

标签: symfony doctrine-orm routing url-routing symfony-cmf


【解决方案1】:

我认为您应该避免在数据库中存储类名。如果您更改名称空间,那么它们将不再起作用。而且我不明白您为什么需要路由表?

您可以像大多数 CMS 一样执行此操作:只需使用页面实体中的 slug,然后让 symfony param converter 处理其余部分,或手动加载。

/**
 * @Route("/page/{slug}")
 * @ParamConverter("page")
 */
public function showAction(Page $page)
{
}

您可以通过网址like this 获取语言环境。

对于您的菜单,您只需创建一个“菜单”实体并添加与您的页面实体的关系或在其中硬核一个 slug/url 字段。

【讨论】:

  • 路由表可用于在 slug 更改时重写 url。需要控制器来将路由映射到控制器和操作。
  • 还阅读了一些关于 Symfony CMF 路由和自定义路由加载器的内容。哪个更好用?
【解决方案2】:

在现实中要解决过去类似的问题,您需要采取一些步骤。我的需要是没有前缀的路线(所以没有/article/{slug},但只有{slug},而且我有很多这样的路线,所以DB看起来更合适。

  • 存储路由 - 我有路由表,我在其中存储要匹配的 url、目标控制器和要传递的参数(我不能在路由中包含 ID)
  • 在您的情况下 - 文章将具有 route_id 作为其属性之一。这也将解决路由的生成问题,因为您将通过关联从数据库中获取它们
  • 创建新路线时,我检查了是否存在具有请求名称的路线,如果存在,我在末尾添加了递增数字。
  • 然后我在正常路由的末尾有一个通用路由来匹配所有/*,我连接到内核事件,如果匹配此路由并且我在我的数据库中找到 mu 当前请求 - 我已将请求修改为指向我的数据库记录控制器

这可以很容易地扩展,例如跟踪更改历史(假设您有第一篇文章(slug:/first-article),然后您将其重命名为第二篇文章(slug 更改:/second-article)在这里您可以轻松跟踪此更改并进行正确的重定向。

【讨论】:

    【解决方案3】:

    你不需要在数据库中存储路由,看看 CMF 路由器组件,你可以使用动态路由器根据 slug (https://symfony.com/doc/master/cmf/bundles/routing/dynamic.html) 路由任何 cms 页面,然后使用链路由器 (@987654322 @) 与标准 SF 路由器一起使用。

    【讨论】:

      猜你喜欢
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      相关资源
      最近更新 更多