Php 原则:如何添加带有可选参数的自定义函数?

Php 原则:如何添加带有可选参数的自定义函数?,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,按照官方的解释,我想创建我的自定义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 $sim

按照官方的解释,我想创建我的自定义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);
    }
}

您需要声明第二个参数,并像这样使用
Lexer

namespace HQF\Bundle\PizzasBundle\DQL;
使用\doctor\ORM\Query\AST\Functions\FunctionNode;
使用\doctor\ORM\Query\Lexer;
类MysqlRound扩展了FunctionNode
{
private$firstExpression=null;
private$secondExpression=null;
公共函数解析(\doctor\ORM\Query\Parser$Parser)
{
$lexer=$parser->getLexer();
$parser->match(Lexer::T_标识符);
$parser->match(Lexer::T_OPEN_括号);
$this->firstExpression=$parser->ArithmeticPrimary();
//分析第二个参数(如果可用)
如果(Lexer::T_COMMA==$Lexer->lookahead['type']){
$parser->match(Lexer::T_逗号);
$this->secondExpression=$parser->arithmetricprimary();
}
$parser->match(Lexer::T_CLOSE_括号);
}
公共函数getSql(\doctor\ORM\Query\SqlWalker$SqlWalker)
{
//如果已解析,请使用第二个参数
if(null!=$this->secondExpression){
返回“轮('
.$this->firstExpression->dispatch($sqlWalker)
. ', '
.$this->secondExpression->dispatch($sqlWalker)
. ')';
}
返回'ROUND('.$this->firstExpression->dispatch($sqlWalker)。');
}
}
编辑
已经编写了许多Doctrine2扩展。所有的荣誉都归功于@beberlei的伟大工作。有许多函数可用(
IFELSE
IFNULL
NULLIF
COS
ACOS
,等等),但并非所有函数都缺少(
ROUND
grest
LEAST
),但如果需要,您仍然可以自己编写它们。)

我在这里也发现了
最大的
实现(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)
    }
}

对不起,我没看到那一点。现在可以正常工作了:)啊哈,实际上我今天也做了类似的事情:)非常感谢你的出色编辑。如果在圆函数(最后一行)之前有一个
,那将是绝对完美的。)
我正试图做同样的事情,并将我的工作建立在您的和官方函数的基础上,如以下文件:
vendor/doctor/orm/lib/doctor/orm/Query/AST/functions/LocateFunction.php
基于本文,我试图在MySQL查询中实现这一点<代码>错误:预期为已知函数,得到“COS”
。DQL似乎不知道ROUND,但也知道SIN(),COS()。。。和弧度()<代码>(天哪)天哪这不是完整的实现。最伟大的是多重数函数,可以接受任意数量的参数,而不仅仅是两个参数。下面是完整的impl: