Symfony Custom DoctrineFunctions始终返回null

时间:2017-04-13 03:56:24

标签: php symfony doctrine

我在Symfony上编写了一个简单的自定义学说函数,它根据实体的bithdate计算AGE。这是我的功能:

class AgeFunction extends FunctionNode
{
    private $birthDate;

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->birthDate = $parser->ArithmeticPrimary();
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        $bday = $this->birthDate->dispatch($sqlWalker);
        $currDate = DateFormatter::formatDate(new \DateTime());

        return "TIMESTAMPDIFF(YEAR, {$bday}, '{$currDate}')";
    }
}

以下是我如何使用它:

public function getAge()
{
    $qb = $this->createQueryBuilder('s')
        ->select('AGE(s.dateOfBirth)')
        ->orderBy('s.id', 'DESC');

    dump($qb->getQuery()->getResult());
}

这是生成的查询:

  

SELECT TIMESTAMPDIFF(YEAR,s0_.date_of_birth,' 2017-04-13')AS sclr_0 FROM suspect s0_ ORDER BY s0_.id DESC;

我认为这里的错误是s0_.date_of_birth永远不会得到实际值,因为当我手动更换它时效果很好。

那我该怎么做呢?感谢。

1 个答案:

答案 0 :(得分:1)

也许你最初还是想做别的事,但是对我而言,业务要求似乎很奇怪,因为你只是想要获得最后一个人的年龄。无论如何,让我暂时忽略它,专注于你需要的东西。我检查了下面的例子并且工作正常。

<强> DQL

namespace My\Bundle\Product\APIBundle\Entity\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;

class TimestampDiff extends FunctionNode
{
    public $value;

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->value = $parser->StringPrimary();
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }

    public function getSql(SqlWalker $sqlWalker)
    {
        return sprintf(
            'TIMESTAMPDIFF(YEAR, %s, %s)',
            $this->value->dispatch($sqlWalker),
            date('Y-m-d')
        );
    }
}

<强> REPOSITORY

public function findAge()
{
    $qb = $this->createQueryBuilder('s')
        ->select('TIMESTAMPDIFF(s.dateOfBirth) AS Age')
        ->orderBy('s.id', 'DESC')
        ->setMaxResults(1);

    return $qb->getQuery()->getResult(Query::HYDRATE_SIMPLEOBJECT);
}

拨打

$p = $this->suspectRepository->findAge();

注册 (我的设置不同,因此您可以查看下面的链接以使其适用于您的设置)

# app/config.yml

doctrine:
    dbal:
      default_connection: hello
      connections:
        hello:
          driver: "%database_driver%"
          host:   "%database_host%"
          ....
        ....
    orm:
        default_entity_manager: hello

        entity_managers:
            hello:
                dql:
                    string_functions:
                        TIMESTAMPDIFF: My\Bundle\Product\APIBundle\Entity\DQL\TimestampDiff
                connection: hello
                ....

<强> RESULT

SELECT
TIMESTAMPDIFF(YEAR, s0_.date_of_birth, 2017-04-13) AS sclr_0
FROM suspect s0_
ORDER BY s0_.id DESC
LIMIT 1