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)
{
    // ...
}