2017-04-13 4 views
0

Ich schreibe eine einfache benutzerdefinierte Doktrin-Funktion auf Symfony, die AGE berechnet, wenn das Bithdatum der Entität angegeben wird. Hier ist meine Funktion:Symfony Custom DoctrineFunctions gibt immer null zurück

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}')"; 
    } 
} 

Und hier ist, wie ich es verwendet:

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

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

Dies ist die Abfrage erzeugt:

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

Ich denke, was hier falsch ist s0_.date_of_birth bekommt nie den tatsächlichen Wert, da, wenn ich ersetzen es gut funktioniert manuell.

Also wie kann ich das tun? Vielen Dank.

+0

Zeigt die produzierte Abfrage ein Ergebnis, wenn Sie es direkt in Ihrem SQL-Client (wie phpmyadmin) ausführen? Ich habe es in einer meiner Datenbanken getestet und die Abfrage scheint korrekt zu sein. –

+0

Ich bin ein bisschen neugierig, warum das Zeitalter mit der Doktrin und nicht mit PHP zu tun hat? – goto

Antwort

1

Vielleicht versuchen Sie ursprünglich, etwas anderes zu tun, aber die Geschäftsanforderungen scheinen mir komisch, weil Sie versuchen, nur das Alter der letzten Person zu bekommen. Lassen Sie mich das jetzt einfach ignorieren und konzentrieren Sie sich auf das, was Sie brauchen. Ich habe das Beispiel unten überprüft und hat gut funktioniert.

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); 
} 

ANRUF

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

RE Gister(Mein Setup ist anders, so dass Sie Links unten überprüfen können, um es für das Setup funktioniert)

# 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 
+0

Ich mache das später und melde mich bei Ihnen für das Ergebnis :) Danke. – iamjc015

+0

und die getAge() - Funktion ist nur ein Test, um die DoctrineFunction für andere Funktionen zu verwenden. – iamjc015

Verwandte Themen