duankan6894 2016-12-30 05:02
浏览 30
已采纳

扩展表达语言

I'm attempting to extend Symfony's Expression Language component so that I can use PHP's absolute value (abs) function within my expressions.

I've extended the base class and created a separate provider class for the abs function as outlined in the documentation, but the values that my class is receiving / returning isn't what I am expecting it to.

The expression that I'm trying to evaluate is as follows:

abs(result.getDate().getTimestamp() - match.getDate().getTimestamp()) <= 86400

For example, if the result object had a timestamp of 1483100536 and the match object a timestamp of 1483014137, then you'd expect the absolute value to be 86399 and therefore for the expression to evaluate to true. However, if you use the code as it is below then the expression eventually evaluates to false as the $int value which get's passed into the evaluator function of the provider class isn't something that PHP's absolute function can handle.

The $int variable in the compiler function receives:

 ($result->getDate()->getTimestamp() - $match->getDate()->getTimestamp())

The $int variable in the evaluator function receives:

  1. [
  2. "result" => Result {#1754}
  3. "match" => Match {#2161}
  4. ]`

Now I don't truly know the inner workings of Symfony's Expression Language, but you'd like to think that it would subtract the two inner values from each other before then passing that to the outer function and then finally comparing it against the given integer.

Is there something that I need to change in my class to enable a custom function to handle expressions within itself?

Extended Base Class

  1. namespace AppBundle\Service\ExpressionLanguage;
  2. use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
  3. class ExpressionLanguage extends BaseExpressionLanguage
  4. {
  5. public function __construct($cache = null, array $providers = [])
  6. {
  7. // prepend the default provider to let users override it easily
  8. array_unshift($providers, new StringExpressionLanguageProvider());
  9. parent::__construct($cache, $providers);
  10. }
  11. }

Provider Class

When adding / registering a new function it is expected to have the following parts:

  • Name - The name of the function in an expression.
  • Compiler - A function executed when compiling an expression using the function.
  • Evaluator - A function executed when the expression is evaluated.

Class

  1. namespace AppBundle\Service\ExpressionLanguage;
  2. use Symfony\Component\ExpressionLanguage\ExpressionFunction;
  3. use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
  4. class StringExpressionLanguageProvider implements ExpressionFunctionProviderInterface
  5. {
  6. public function getFunctions()
  7. {
  8. return [
  9. new ExpressionFunction('abs', function ($int) {
  10. return sprintf('(is_int(%1$d) ? abs(%1$d) : %1$d)', $int);
  11. }, function ($int) {
  12. if (!is_int($int)) {
  13. return $int;
  14. }
  15. return abs($int);
  16. }),
  17. ];
  18. }
  19. }

展开全部

  • 写回答

1条回答 默认 最新

  • dongqintong8972 2016-12-30 07:35
    关注

    There is a difference between the parameters of the evaluator and compiler functions:

    Compiler:  function ($value) { }
    Evaluator: function (array $variables, $value) { }
    

    As you can see, the evaluator receives a list of all available variables as the first argument. That's exactly what you discovered in the dump of $int. A fix is easy in this case, just make sure the parameters are correct:

    new ExpressionFunction('abs', function ($int) {
        return sprintf('(is_int(%1$d) ? abs(%1$d) : %1$d)', $int);
    }, function (array $variables, $int) {
        if (!is_int($int)) {
            return $int;
        }
    
        return abs($int);
    }),
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 爱快路由器端口更改错误导致无法访问
  • ¥20 安装catkin时遇到了如下问题请问该如何解决呢
  • ¥15 VAE模型如何输出结果
  • ¥15 编译python程序为pyd文件报错:{"source code string cannot contain null bytes"
  • ¥20 关于#r语言#的问题:广义加行模型拟合曲线后如何求拐点
  • ¥15 fluent设置了自动保存后,会有几个时间点不保存
  • ¥20 激光照射到四象线探测器,通过液晶屏显示X、Y值
  • ¥50 数据库开发问题求解答
  • ¥15 安装anaconda时报错
  • ¥15 小程序有个导出到插件方式,我是在分包下引入的插件,这个export的路径对吗,我看官方文档上写的是相对路径
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部