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

Posted

技术标签:

【中文标题】将 SQL 查询的 SELECT 子句解析为 PHP 数组【英文标题】:Parse SELECT clause of SQL queries into a PHP array 【发布时间】:2011-06-25 12:25:27 【问题描述】:

这更多地用于分析 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) as join_date, (SELECT COUNT(1) FROM foobar WHERE foonum IN (5,4,6) and user_id = users.user_id) as 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'
)

我已经提取了查询的字段部分,但我坚持尝试用逗号分解字段。主要问题是子查询中也可能包含逗号(参见示例)。

【问题讨论】:

好吧,这与它无关。这种情况需要我看一本小说来解释原因。它的设计或懒惰都不错,我只是不想让每个人都对项目的不需要的细节感到厌烦。 X-Ref: SQL parser in PHP? 大卫,任何怀疑解析器在 PHP 中的声明性语言的有用性的人都不值得争论。注意,我编写了 X-Ref 中引用的 PHP SQL 解析器。 【参考方案1】:

对于以后遇到这个问题的人来说,已经有人费心写了SQL parser in PHP。

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

【讨论】:

【参考方案2】:

您必须编写一个几乎与 mysql 的查询解析器一样复杂的解析器(用 YACC/Bison for C 编写)。它不会是一个正则表达式或一个小的字符串操作。这是一种非常规语言,如果没有实际的解析器,您将无法解析它们。

您也不能只遍历字符串查找逗号和括号,SQL 比这复杂得多。您在表达式、函数调用、条件逻辑等中都有表达式。所有这些都可以用逗号和括号任意嵌套。

http://dev.mysql.com/doc/refman/5.0/en/expressions.html

如果你真的想用 PHP 来做这件事,那么你有一个很大的工作要做。

【讨论】:

如第二个答案所述,我为 PHP 编写了一个实际的 SQL 解析器,因为我需要解析和重写 SQL 以进行分片。它被称为 PHP-SQL 解析器。 code.google.com/p/php-sql-parser SugarCRM 使用解析器,可用作 Drupal 插件等。这是非常彻底的。 随着 Google 代码的消亡,PHP-SQL-parser 源代码现在保存在 Github github.com/greenlion/PHP-SQL-Parser

以上是关于将 SQL 查询的 SELECT 子句解析为 PHP 数组的主要内容,如果未能解决你的问题,请参考以下文章

SQL 语句的解析过程

sql语句解析顺序和执行顺序

linq to sql select和where的区别

C#操作sql时注意点

T-SQL All-At-Once 操作解析

SQL查询where子句太长