Doctrine Querybuilder 不 return 完全匹配
Doctrine Querybuilder doesnt return exact matches
我有 api 端点,应该 return 一个用户基于他的 id : user/{id}
.
在我的控制器中,我有以下代码:
/**
* @Api\Get("user/{id}")
* @SWG\Parameter(name="id", type="string", in="path", required=true)
*/
public function getUser(Request $request, string $id) {
$user = $this->getDoctrine()->getManager()->getRepository('App\Entity\User')->findUser($id);
return $this->view($user);
}
在我的存储库中,我有以下代码:
public function findUser(string $id) {
$qb = $this->createQueryBuilder('a');
$qb->andWhere($qb->expr()->eq('a.id',':id'))->setParameter('id',$id);
return $qb->getQuery()->getOneOrNullResult();
}
在获取 user/4
时工作正常,但在获取 user/4ruqbu
时也工作正常。
我只想在 user/4
上获得用户,在 user/4ruqbu
上没有结果。它应该 return 完全匹配。我认为问题在于 id 参数是一个字符串。如果我将它更改为 int 它正在工作,但是如果我尝试 user/4eiugq
.
我会得到一个错误而不是没有结果
有办法解决吗?
您的路由接受您的 id
参数的任何字符串,这意味着任何值都将进入您的存储库方法。然后,如果您尝试使用以数字值开头的字符串作为整数,您将得到该整数。
在 3v4l.org:
上亲自尝试
var_dump((int)'4ruqbu'); // output: int(4)
您可以使用 parameters validation 使用正则表达式:
/**
* @Api\Get("user/{id<\d+>}")
*/
public function getUser(Request $request, int $id) {
// ...
}
现在对于 /user/4ruqbu 这样的 URI 应该会失败,因为它不符合路由要求。
一些改进:
如果您安装了 sensio/framework-extra-bundle you can benefit of the ParamConverter 并将 string $id
替换为用户:
public function getUser(User $user, Request $request)
{
// ...
}
避免使用 $this->getDoctrine()
等获取与 Doctrine 相关的服务。改用自动装配。
如果您需要 Entity Manager 到 save/update/remove 实体,请将 Doctrine\ORM\EntityManagerInterface
参数添加到您的控制器方法。如果您需要使用存储库查询实体,请添加一个使用其 class 输入的参数,例如 App\Repository\UserRepository
在您的情况下:
// Example of controller method fetching services by autowiring:
public function myAction(EntityManagerInterface $em, UserRepository $userRepo)
{
// ...
}
我有 api 端点,应该 return 一个用户基于他的 id : user/{id}
.
在我的控制器中,我有以下代码:
/**
* @Api\Get("user/{id}")
* @SWG\Parameter(name="id", type="string", in="path", required=true)
*/
public function getUser(Request $request, string $id) {
$user = $this->getDoctrine()->getManager()->getRepository('App\Entity\User')->findUser($id);
return $this->view($user);
}
在我的存储库中,我有以下代码:
public function findUser(string $id) {
$qb = $this->createQueryBuilder('a');
$qb->andWhere($qb->expr()->eq('a.id',':id'))->setParameter('id',$id);
return $qb->getQuery()->getOneOrNullResult();
}
在获取 user/4
时工作正常,但在获取 user/4ruqbu
时也工作正常。
我只想在 user/4
上获得用户,在 user/4ruqbu
上没有结果。它应该 return 完全匹配。我认为问题在于 id 参数是一个字符串。如果我将它更改为 int 它正在工作,但是如果我尝试 user/4eiugq
.
有办法解决吗?
您的路由接受您的 id
参数的任何字符串,这意味着任何值都将进入您的存储库方法。然后,如果您尝试使用以数字值开头的字符串作为整数,您将得到该整数。
在 3v4l.org:
var_dump((int)'4ruqbu'); // output: int(4)
您可以使用 parameters validation 使用正则表达式:
/**
* @Api\Get("user/{id<\d+>}")
*/
public function getUser(Request $request, int $id) {
// ...
}
现在对于 /user/4ruqbu 这样的 URI 应该会失败,因为它不符合路由要求。
一些改进:
如果您安装了 sensio/framework-extra-bundle you can benefit of the ParamConverter 并将 string $id
替换为用户:
public function getUser(User $user, Request $request)
{
// ...
}
避免使用 $this->getDoctrine()
等获取与 Doctrine 相关的服务。改用自动装配。
如果您需要 Entity Manager 到 save/update/remove 实体,请将 Doctrine\ORM\EntityManagerInterface
参数添加到您的控制器方法。如果您需要使用存储库查询实体,请添加一个使用其 class 输入的参数,例如 App\Repository\UserRepository
在您的情况下:
// Example of controller method fetching services by autowiring:
public function myAction(EntityManagerInterface $em, UserRepository $userRepo)
{
// ...
}