PHP中的动态逻辑表达式解析/评估?

12

我需要在一些 PHP 页面上评估任意复杂的用户自定义逻辑表达式。假设表单字段是主要变量,则需要:

  • 用字段值替换“变量”;
  • 通过符号,名称(如eq,lt,le,ge,gt)处理比较运算符,最少包括==,<,<=,>= 和 >;
  • 通过名称、符号(如!,&&,|| 和 ^^)处理布尔运算符not、and、or和可能的xor;
  • 处理字符串和数字的字面值;
  • 是纯文本而不是XML(例如,“firstname ==''or lastname ==''”);并且
  • 具有合理的性能。

以前我写过递归下降解析器,可以构建表达式树并执行此类操作,但我不想在 PHP 中进行这项任务,因此我希望有一些现成的内容可以为我提供部分帮助。

有什么建议吗?


2
我可以问一下,你是否成功创建了一个简单表达式解析函数而不使用eval? - buggedcom
6个回答

12
自从这个问题被提出以来已经过去了很长时间,我碰巧正在寻找一个用于PHP的表达式解析器。我选择使用Symfony 2.4中的ExpressionLanguage组件。它可以通过packagist从composer安装,无需任何依赖项。 < p > < code > composer require symfony/expression-language


2
我在stackoverflow和谷歌上评估了几乎所有提到的ExpressionParsers。最终我选择了这个。 - larrydahooster
1
仅提供链接的回答很容易受到破坏,最好将其作为评论发表。 - mickmackusa

3

请查看create_function,它可以从传递的字符串参数创建匿名函数,我不确定它的性能如何,但它非常灵活...


哦,不错。我不是PHP专家,所以我不知道create_function。谢谢你告诉我。 - cletus
2
值得注意的是,自 PHP 7.2.0 起已经弃用该语法。 - Rico Humme
2
请提供一个更具教育性的答案,而不仅仅是手册链接。 - mickmackusa

1

如果我正确理解了问题,您希望用户使用非PHP编写函数,然后由PHP解释它?

如果是这样,您可以简单地获取他们的字符串并将“lt”替换为“<”,将“gt”替换为“>”,然后执行eval()。

我有一种预感问题并不是这么简单,但如果是,则eval()可以完成任务。当然,这样就会让您面临任何类型的攻击。


谢谢你的回答。事实上,答案可能就是那么简单。我不是PHP专家,Java更是我的强项。这些表达式都不是来自外部世界,而是全部来自内部配置。 - cletus
eval 的问题在于它执行传递给它的任意 PHP 代码。传统上,存在注入攻击的问题。例如,用户可以传递代码,该代码将被插入并在与生产代码相同的环境中执行。根据用户的聪明程度或恶意程度,该代码可能会造成混乱和不良副作用。您必须非常小心和聪明地检查/替换器,以能够过滤掉任意 PHP 中所有潜在问题。 - Dennis

0

看一下我的中缀转后缀示例,我认为你可以相对容易地将其移植到PHP。它只使用了一个数组和一些开关。没有树。只需要一个堆栈来运行后缀结果。


1
仅提供链接的答案容易变得脆弱,最好作为评论来提供。 - mickmackusa

0

1
仅提供链接的答案容易变得脆弱,最好作为评论来提供。 - mickmackusa

-1
你可以尝试使用我的评估器类(https://github.com/djfm/Evaluator),它可以处理算术表达式(目前只支持算术表达式),并且你也可以使用变量。所有主要的PHP运算符都已实现。

1 == 1 && 2 == 2 返回0。我本来期望它返回1。 解析后的表达式是:((1 == (1 && 2)) == 2) 这似乎不对。 - ds00424
1
仅提供链接的回答容易变得脆弱,最好作为评论来提供。 - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接