将SQL查询中的SELECT子句解析为PHP数组

4

这更多是用于在将查询发送到服务器之前分析PHP中的查询。为什么要这样做非常复杂,所以我宁愿不谈论原因。

在PHP中,我需要将字段选择存储到PHP数组中。以此查询为例:

SELECT user_id,username,DATE(join_datetime) as join_date, (SELECT COUNT(1) FROM foobar WHERE foonum IN (5,4,6) and user_id = users.user_id) as myfoo_count 
FROM users 
WHERE user_id = 123

在这种情况下,我需要将user_id、username、DATE(join_datetime)作为join_date、(SELECT COUNT(1) FROM foobar WHERE foonum IN (5,4,6) and user_id = users.user_id) 作为myfoo_count存储到一个由逗号(,)分隔的数组中。这样我就可以得到:
array (
  [1] => 'user_id',
  [2] => 'username',
  [3] => 'DATE(join_datetime) as join_date',
  [4] => '(SELECT COUNT(1) FROM foobar WHERE foonum IN (5,4,6) and user_id = users.user_id) as myfoo_count'
)

我已经完成了查询字段的提取,但是我在尝试通过逗号拆分字段时遇到了困难。主要问题在于子查询也可能包含逗号(请参见示例)。

2
好的,这与那无关。这是一个需要我写一本小说才能解释清楚的情况。这不是糟糕的设计或懒惰,只是我不想用项目中不必要的细节来让每个人感到无聊。 - David
1
X-Ref: PHP中的SQL解析器? - hakre
David,任何对于在PHP中使用解析器处理声明性语言的有用性表示怀疑的人都不值得争论。请注意,我编写了X-Ref中提到的PHP SQL解析器。 - Justin Swanhart
3个回答

7

如果将来有人遇到这个问题,已经有人费力地编写了一个PHP中的SQL解析器

目前,它支持SELECT、INSERT、UPDATE、DELETE和REPLACE语句。


5
您需要编写一个解析器,几乎和MySQL的查询解析器一样复杂(用YACC/Bison为C编写)。这不是一个正则表达式或简单的字符串操作。这是一种非正则语言,您无法在没有实际解析器的情况下进行解析。
您也不能仅仅通过遍历字符串来查找逗号和括号,SQL比那要复杂得多。您需要在表达式内部进行表达式、函数调用、条件逻辑等操作,而且所有这些操作都可以任意嵌套,并且有大量逗号和括号。
如果您真的想使用PHP完成此任务,那么您将面临巨大的挑战。
参考链接:http://dev.mysql.com/doc/refman/5.0/en/expressions.html

1
正如第二个答案中所提到的,我为PHP编写了一个实际的SQL解析器,因为我需要解析和重写用于分片的SQL。它被称为PHP-SQL-parser。http://code.google.com/p/php-sql-parser该解析器被SugarCRM使用,并可作为Drupal插件等提供。它非常彻底。 - Justin Swanhart
1
随着Google Code的消失,PHP-SQL-parser源代码现在在Github上得到维护:https://github.com/greenlion/PHP-SQL-Parser - dregad
@JustinSwanhart 我很想使用这个解析器,但我无法通过Docker容器在我的系统上配置它运行。看起来这个仓库也已经被放弃了。 - oxwilder
看起来这个仓库被放弃了?我几天前刚推送了一个新版本,其中包括多个贡献者的PR,包括为PHP 8.1更新。很多人在使用它。我不确定你遇到了什么问题,但文档解释了如何设置库。 - Justin Swanhart

0

我正在尝试这个:

https://github.com/greenlion/PHP-SQL-Parser

可能有效

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