查询生成器或调用本身有什么问题?
What is wrong in the Query Builder or in the call itself?
我在存储库中有此功能:
public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select(array('su', 'p', 'ps', 'c'))
->from('AppBundle:SolicitudUsuario', 'su')
->leftJoin('su.producto_solicitud', 'ps')
->leftJoin('ps.producto', 'p')
->leftJoin('su.constancias', 'c')
->where('su.id = ?', $solicitudUsuario)
->andWhere('ps.id = ?', $productoSolicitud);
return $builder->getResult();
}
我正尝试从我的控制器调用它,如下所示:
$result = $em->getRepository("AppBundle:Constancia")->buscarConstanciaProducto(
(int) $request->query->get('id'), // this gets 18
$productoSolicitud->getId() // this gets 25
);
但是我得到这个错误:
Warning: get_class() expects parameter 1 to be object, integer given
哪里出了问题?
这是完整的 StackTrace:
[1] Symfony\Component\Debug\Exception\ContextErrorException: Warning: get_class() expects parameter 1 to be object, integer given
at n/a
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
at Symfony\Component\Debug\ErrorHandler->handleError('2', 'get_class() expects parameter 1 to be object, integer given', '/var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php', '92', array('arg' => '18', 'this' => object(Andx)))
in line
at get_class('18')
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
at Doctrine\ORM\Query\Expr\Base->add('18')
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 74
at Doctrine\ORM\Query\Expr\Base->addMultiple(array('su.id = ?', '18'))
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 63
at Doctrine\ORM\Query\Expr\Base->__construct(array('su.id = ?', '18'))
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 871
at Doctrine\ORM\QueryBuilder->where('su.id = ?', '18')
in /var/www/html/project.dev/src/Sencamer/AppBundle/Entity/Repository/ConstanciaRepository.php line 23
at AppBundle\Entity\Repository\ConstanciaRepository->buscarConstanciaProducto('18', '25')
in /var/www/html/project.dev/src/Sencamer/AppBundle/Controller/Comunes/ListadoController.php line 96
at AppBundle\Controller\Comunes\ListadoController->getConstanciaProductosSolicitudAction(object(Request))
in line
at ReflectionMethod->invokeArgs(object(ListadoController), array(object(Request)))
in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 63
at CG\Proxy\MethodInvocation->proceed()
in /var/www/html/project.dev/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php line 120
at JMS\SecurityExtraBundle\Security\Authorization\Interception\MethodSecurityInterceptor->intercept(object(MethodInvocation))
in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 58
at CG\Proxy\MethodInvocation->proceed()
in /var/www/html/project.dev/app/cache/dev/jms_diextra/proxies/Sencamer-AppBundle-Controller-Comunes-ListadoController.php line 30
at EnhancedProxy72c8de70_7ca524686d92d76741252b9b0630ee44b00c6576\__CG__\AppBundle\Controller\Comunes\ListadoController->getConstanciaProductosSolicitudAction(object(Request))
in line
at call_user_func_array(array(object(ListadoController), 'getConstanciaProductosSolicitudAction'), array(object(Request)))
in /var/www/html/project.dev/app/bootstrap.php.cache line 3022
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
in /var/www/html/project.dev/app/bootstrap.php.cache line 2984
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
in /var/www/html/project.dev/app/bootstrap.php.cache line 3133
at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
in /var/www/html/project.dev/app/bootstrap.php.cache line 2377
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
in /var/www/html/project.dev/web/app_dev.php line 20
您的问题似乎是 where()
,以这种方式使用,需要类似 additional 表达式。
/**
* Specifies one or more restrictions to the query result.
* Replaces any previously specified restrictions, if any.
*
* <code>
* $qb = $em->createQueryBuilder()
* ->select('u')
* ->from('User', 'u')
* ->where('u.id = ?');
*
* // You can optionally programatically build and/or expressions
* $qb = $em->createQueryBuilder();
*
* $or = $qb->expr()->orx();
* $or->add($qb->expr()->eq('u.id', 1));
* $or->add($qb->expr()->eq('u.id', 2));
*
* $qb->update('User', 'u')
* ->set('u.password', md5('password'))
* ->where($or);
* </code>
*
* @param mixed $predicates The restriction predicates.
*
* @return QueryBuilder This QueryBuilder instance.
*/
public function where($predicates)
{
if ( ! (func_num_args() == 1 && $predicates instanceof Expr\Composite)) {
$predicates = new Expr\Andx(func_get_args());
}
return $this->add('where', $predicates);
}
[来自 vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder
]
和add()
方法是
/**
* @param mixed $arg
*
* @return Base
*
* @throws \InvalidArgumentException
*/
public function add($arg)
{
if ( $arg !== null && (!$arg instanceof self || $arg->count() > 0) ) {
// If we decide to keep Expr\Base instances, we can use this check
if ( ! is_string($arg)) {
$class = get_class($arg);
if ( ! in_array($class, $this->allowedClasses)) {
throw new \InvalidArgumentException("Expression of type '$class' not allowed in this context.");
}
}
$this->parts[] = $arg;
}
return $this;
}
[来自 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base
]
所以,对我来说,使用 where('foo.id', $someVariable);
的唯一方法是将 表达式 作为第二个参数传递,如下所示
$qb->where('su.id = ?1', $qb->expr()->eq('su.somethingElse', '?2'));
等于
$qb->where('su.id = ?1')
->andWhere('su.somethingElse = ?2');
所以,回到你的问题,如果你想设置参数,你应该修改查询的构建过程如下
public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select(array('su', 'p', 'ps', 'c'))
->from('AppBundle:SolicitudUsuario', 'su')
->leftJoin('su.producto_solicitud', 'ps')
->leftJoin('ps.producto', 'p')
->leftJoin('su.constancias', 'c')
->where('su.id = ?1')
->andWhere('ps.id = ?2')
->setParameter(1, $solicitudUsuario)
->setParameter(2, $productoSolicitud)
->getQuery() //don't forget this step
;
return $builder->getResult();
}
我在存储库中有此功能:
public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select(array('su', 'p', 'ps', 'c'))
->from('AppBundle:SolicitudUsuario', 'su')
->leftJoin('su.producto_solicitud', 'ps')
->leftJoin('ps.producto', 'p')
->leftJoin('su.constancias', 'c')
->where('su.id = ?', $solicitudUsuario)
->andWhere('ps.id = ?', $productoSolicitud);
return $builder->getResult();
}
我正尝试从我的控制器调用它,如下所示:
$result = $em->getRepository("AppBundle:Constancia")->buscarConstanciaProducto(
(int) $request->query->get('id'), // this gets 18
$productoSolicitud->getId() // this gets 25
);
但是我得到这个错误:
Warning: get_class() expects parameter 1 to be object, integer given
哪里出了问题?
这是完整的 StackTrace:
[1] Symfony\Component\Debug\Exception\ContextErrorException: Warning: get_class() expects parameter 1 to be object, integer given
at n/a
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
at Symfony\Component\Debug\ErrorHandler->handleError('2', 'get_class() expects parameter 1 to be object, integer given', '/var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php', '92', array('arg' => '18', 'this' => object(Andx)))
in line
at get_class('18')
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
at Doctrine\ORM\Query\Expr\Base->add('18')
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 74
at Doctrine\ORM\Query\Expr\Base->addMultiple(array('su.id = ?', '18'))
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 63
at Doctrine\ORM\Query\Expr\Base->__construct(array('su.id = ?', '18'))
in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 871
at Doctrine\ORM\QueryBuilder->where('su.id = ?', '18')
in /var/www/html/project.dev/src/Sencamer/AppBundle/Entity/Repository/ConstanciaRepository.php line 23
at AppBundle\Entity\Repository\ConstanciaRepository->buscarConstanciaProducto('18', '25')
in /var/www/html/project.dev/src/Sencamer/AppBundle/Controller/Comunes/ListadoController.php line 96
at AppBundle\Controller\Comunes\ListadoController->getConstanciaProductosSolicitudAction(object(Request))
in line
at ReflectionMethod->invokeArgs(object(ListadoController), array(object(Request)))
in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 63
at CG\Proxy\MethodInvocation->proceed()
in /var/www/html/project.dev/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php line 120
at JMS\SecurityExtraBundle\Security\Authorization\Interception\MethodSecurityInterceptor->intercept(object(MethodInvocation))
in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 58
at CG\Proxy\MethodInvocation->proceed()
in /var/www/html/project.dev/app/cache/dev/jms_diextra/proxies/Sencamer-AppBundle-Controller-Comunes-ListadoController.php line 30
at EnhancedProxy72c8de70_7ca524686d92d76741252b9b0630ee44b00c6576\__CG__\AppBundle\Controller\Comunes\ListadoController->getConstanciaProductosSolicitudAction(object(Request))
in line
at call_user_func_array(array(object(ListadoController), 'getConstanciaProductosSolicitudAction'), array(object(Request)))
in /var/www/html/project.dev/app/bootstrap.php.cache line 3022
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
in /var/www/html/project.dev/app/bootstrap.php.cache line 2984
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
in /var/www/html/project.dev/app/bootstrap.php.cache line 3133
at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
in /var/www/html/project.dev/app/bootstrap.php.cache line 2377
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
in /var/www/html/project.dev/web/app_dev.php line 20
您的问题似乎是 where()
,以这种方式使用,需要类似 additional 表达式。
/**
* Specifies one or more restrictions to the query result.
* Replaces any previously specified restrictions, if any.
*
* <code>
* $qb = $em->createQueryBuilder()
* ->select('u')
* ->from('User', 'u')
* ->where('u.id = ?');
*
* // You can optionally programatically build and/or expressions
* $qb = $em->createQueryBuilder();
*
* $or = $qb->expr()->orx();
* $or->add($qb->expr()->eq('u.id', 1));
* $or->add($qb->expr()->eq('u.id', 2));
*
* $qb->update('User', 'u')
* ->set('u.password', md5('password'))
* ->where($or);
* </code>
*
* @param mixed $predicates The restriction predicates.
*
* @return QueryBuilder This QueryBuilder instance.
*/
public function where($predicates)
{
if ( ! (func_num_args() == 1 && $predicates instanceof Expr\Composite)) {
$predicates = new Expr\Andx(func_get_args());
}
return $this->add('where', $predicates);
}
[来自 vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder
]
和add()
方法是
/**
* @param mixed $arg
*
* @return Base
*
* @throws \InvalidArgumentException
*/
public function add($arg)
{
if ( $arg !== null && (!$arg instanceof self || $arg->count() > 0) ) {
// If we decide to keep Expr\Base instances, we can use this check
if ( ! is_string($arg)) {
$class = get_class($arg);
if ( ! in_array($class, $this->allowedClasses)) {
throw new \InvalidArgumentException("Expression of type '$class' not allowed in this context.");
}
}
$this->parts[] = $arg;
}
return $this;
}
[来自 vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base
]
所以,对我来说,使用 where('foo.id', $someVariable);
的唯一方法是将 表达式 作为第二个参数传递,如下所示
$qb->where('su.id = ?1', $qb->expr()->eq('su.somethingElse', '?2'));
等于
$qb->where('su.id = ?1')
->andWhere('su.somethingElse = ?2');
所以,回到你的问题,如果你想设置参数,你应该修改查询的构建过程如下
public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select(array('su', 'p', 'ps', 'c'))
->from('AppBundle:SolicitudUsuario', 'su')
->leftJoin('su.producto_solicitud', 'ps')
->leftJoin('ps.producto', 'p')
->leftJoin('su.constancias', 'c')
->where('su.id = ?1')
->andWhere('ps.id = ?2')
->setParameter(1, $solicitudUsuario)
->setParameter(2, $productoSolicitud)
->getQuery() //don't forget this step
;
return $builder->getResult();
}