我知道已经提供了一些其他解决方案,但我想提供更多解释以及稍微不同的建议。 Pipe 的响应在正确的轨道上并且有效,但出于您的目的,我不会只为每辆车生成一个随机令牌,我会在每辆 SEO 友好的汽车上绑定一个 slug。
例如,在您的汽车表中,您将拥有:
+-------+--------------+
| id | slug |
+-------+--------------+
| 1 | ford-150 |
| 2 | cadillac-cts |
+-------+--------------+
然后您的实体将具有相应的变量和 Doctrine 注释,如下所示:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Car
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="slug", type="string", length=50, nullable=false)
*/
private $slug;
}
现在您在 Twig 中生成的链接将如下所示:
<a href="{{ path('rent', {'slug': car.slug}) }}">
那么你的控制器/路由可以这样定义:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class RentController extends Controller
{
/**
* @Route("/rent/{slug}", name="rent")
*/
public function rentAction(Car $car)
{
// logic here
}
}
这里 Symfony 使用 ParamConverter 和您的 Car $car type hint 来自动使用 slug 属性并找到与该 slug 匹配的相应 Car 实体。
它本质上是以下操作的快捷方式,您也可以这样做,而不是使用参数转换器:
/**
* @Route("/rent/{slug}")
*/
public function rentAction($slug)
{
$em = $this->getDoctrine()->getManager();
$car = $em->getRepository('AppBundle:Car')->findOneBySlug($slug);
// ...
}
这将允许您保留对用户有意义的友好 URL,同时完全隐藏 ID。