根据官方解释,我想创建我的自定义MySQL函数ROUND((,它可以接受(不是强制性的(另一个参数。
到目前为止,我已经这样做了:
<?php
namespace HQF'Bundle'PizzasBundle'DQL;
use 'Doctrine'ORM'Query'AST'Functions'FunctionNode;
use 'Doctrine'ORM'Query'Lexer;
class MysqlRound extends FunctionNode
{
public $simpleArithmeticExpression;
public function getSql('Doctrine'ORM'Query'SqlWalker $sqlWalker)
{
return 'ROUND(' . $sqlWalker->walkSimpleArithmeticExpression(
$this->simpleArithmeticExpression
) . ')';
}
public function parse('Doctrine'ORM'Query'Parser $parser)
{
$lexer = $parser->getLexer();
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
但是如何实现ROUND(XX)
可以,ROUND(XX, YY)
也可以的事实呢?
您需要声明第二个参数,并像这样使用Lexer
:
namespace HQF'Bundle'PizzasBundle'DQL;
use 'Doctrine'ORM'Query'AST'Functions'FunctionNode;
use 'Doctrine'ORM'Query'Lexer;
class MysqlRound extends FunctionNode
{
private $firstExpression = null;
private $secondExpression = null;
public function parse('Doctrine'ORM'Query'Parser $parser)
{
$lexer = $parser->getLexer();
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstExpression = $parser->ArithmeticPrimary();
// parse second parameter if available
if(Lexer::T_COMMA === $lexer->lookahead['type']){
$parser->match(Lexer::T_COMMA);
$this->secondExpression = $parser->ArithmeticPrimary();
}
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql('Doctrine'ORM'Query'SqlWalker $sqlWalker)
{
// use second parameter if parsed
if (null !== $this->secondExpression){
return 'ROUND('
. $this->firstExpression->dispatch($sqlWalker)
. ', '
. $this->secondExpression->dispatch($sqlWalker)
. ')';
}
return 'ROUND(' . $this->firstExpression->dispatch($sqlWalker) . ')';
}
}
编辑
这里已经编写了许多Doctrine2扩展。所有这些都归功于@beberlei的伟大工作。有许多函数可用(IFELSE
、IFNULL
、NULLIF
、COS
、ACOS
等(,但并非所有函数都可用(缺少ROUND
、GREATEST
或LEAST
,但如果需要,您仍然可以自己编写它们。(
我还在这里找到了GREATEST
实现https://raw.githubusercontent.com/rodgermd/mura-show.com/master/src/Rodger/GalleryBundle/DoctrineExtension/Greatest.php(c(rodgermd@github:
namespace Rodger'GalleryBundle'DoctrineExtension;
use Doctrine'ORM'Query'Lexer,
Doctrine'ORM'Query'AST'Functions;
class Greatest extends Functions'FunctionNode {
protected $firstExpression, $secondExpression;
public function getSql('Doctrine'ORM'Query'SqlWalker $sqlWalker)
{
return sprintf("GREATEST(%s, %s)",
$this->firstExpression->dispatch($sqlWalker),
$this->secondExpression->dispatch($sqlWalker));
}
public function parse('Doctrine'ORM'Query'Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER); // (2)
$parser->match(Lexer::T_OPEN_PARENTHESIS); // (3)
$this->firstExpression = $parser->ArithmeticPrimary(); // (4)
$parser->match(Lexer::T_COMMA); // (5)
$this->secondExpression = $parser->ArithmeticPrimary(); // (6)
$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
}
}