Validation 如何避免创建已作为路由存在的段塞“;Symfony 4“;

Validation 如何避免创建已作为路由存在的段塞“;Symfony 4“;,validation,routes,symfony4,slug,Validation,Routes,Symfony4,Slug,我的实体页面由slug标识。我还可以在页面控件中查看页面: class PageController extends AbstractController { /** * @Route("/{slug}", name="fronend_page") */ public function show(Page $page) { return $this->render("font_end/page/show.html.twig", [

我的实体页面由slug标识。我还可以在页面控件中查看页面:

class PageController extends AbstractController
{
   /**
    * @Route("/{slug}", name="fronend_page")
    */
   public function show(Page $page)
   {
       return $this->render("font_end/page/show.html.twig", [
           "page" => $page,
       ]);
   }
}
我正在寻找一种好的做法,在不使用前缀将slug保存到数据库之前验证slug(检查路由中是否存在) 例如:

路由存在:
@route(“/blog”)

在创建slug之前检查blog是否存在:
/{slug}=/blog


谢谢

您可以使用
uniquentity
注释来检查slug的唯一性

例如,在实体中,使用
slug
字段添加
uniquentity
注释

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @UniqueEntity("slug")
 */
class Page
{
    /**
     * @ORM\Column(type="string", length=255, unique=true)
     * @Assert\NotBlank
     */
    private $slug;

    public function __construct(string $slug)
    {
        $this->slug = $slug;
    }
}
然后,您可以在控制器中创建一些服务或进行验证

   /**
    * @Route("/{slug}")
    */
   public function show($slug, ValidatorInterface $validator)
   {
       $page = new Page($slug);
       $errors = $validator->validate($author);

       if (count($errors) > 0) {
           // handle errors
       }

       // save entity 
   }
更新:

对于检查已有的路由,您可能可以执行以下操作

public function isRouteExist(string $slug): bool
{
    /** @var Symfony\Component\Routing\RouterInterface $router */
    $routes = array_filter(array_map(function (\Symfony\Component\Routing\Route $route) {
        if (!$route->compile()->getVariables()) {
            return $route->getPath();
        }

        return null;
    }, $router->getRouteCollection()->all()));

    return in_array(sprintf('/%s', $slug), $routes, true);
}

我创建了一个验证符号:

class ContainsCheckSlugValidator extends ConstraintValidator
{

   private $router;

   public function __construct(UrlGeneratorInterface $router)
   {
       $this->router = $router;
   }

   public function validate($value, Constraint $constraint)
   {
       if (!$constraint instanceof ContainsCheckSlug) {
           throw new UnexpectedTypeException($constraint, ContainsCheckSlug::class);
       }

       // custom constraints should ignore null and empty values to allow
       // other constraints (NotBlank, NotNull, etc.) take care of that
       if (null === $value || "" === $value) {
           return;
       }
       $routes = $this->router->getRouteCollection()->all();
       $routes = array_map(function($route){
           return $route->getPath();
       },$routes);
       if (in_array(sprintf("/{_locale}/%s/", $value), $routes, true)) {
           $this->context->buildViolation($constraint->message)
               ->setParameter("{{ string }}", $value)
               ->addViolation();
       }
   }
}

谢谢@Ihor_Kostrov:)

谢谢Ihor,但我想检查slug是否存在路由,而不是slug假设我们有route:route(“/blog”),并且我们有一个页面系统,其中route:route(“/{slug}”)在创建页面时,它们可能具有相同的名称“blog”。我正在寻找一种方法来检查slug与现有路线更新的答案。