PHP 和 SQL 解析

Posted

技术标签:

【中文标题】PHP 和 SQL 解析【英文标题】:PHP and SQL Parsing 【发布时间】:2009-07-02 20:23:05 【问题描述】:

假设我有一个表 DDL 查询数组,我想获取正在创建的每个表的名称。提取表名的最佳方法是什么?

例如:

$ddl = array(
    'CREATE TABLE tableOne ...',
    'CREATE TABLE tableTwo ...',
    'CREATE TABLE tableThree ...'
);

foreach($ddl as $tableDef) 
    $tableName = [???];
    echo $tableName;

这只是一个简化的案例,但我想知道如何解析表名。假设它是“CREATE TABLE”之后的任何内容是否安全?有什么特殊情况需要注意吗?

【问题讨论】:

【参考方案1】:

mysql 支持 CREATE TABLE IF NOT EXISTS foobar,您必须考虑到这一点。以下代码应该可以解决问题:

foreach ($ddl as $tableDef) 
    if (preg_match("/^CREATE\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF NOT EXISTS\s+)?([^\s]+)/i", $tableDef, $matches)) 
        $tableName = $matches[1];
    

【讨论】:

【参考方案2】:

如果你控制了数组...

$ddl = array(
    'tableOne' => 'CREATE TABLE tableOne ...',
    'tableTwo' => 'CREATE TABLE tableTwo ...',
    'tableThree' => 'CREATE TABLE tableThree ...'
);

foreach ($ddl as $tablename => $sql)  ... 

或者一个正则表达式:

foreach ($ddl as $sql) 
    if (preg_match('/CREATE(\s+|\s+TEMPORARY\s+).*\s+TABLE(\s+|\s+IF NOT EXISTS\s+)(\w[\w\d_]*)\s/imU', $sql, $match)) 
        echo $match[3];
    

【讨论】:

【参考方案3】:

根据MySQL docs,CREATE TABLE 调用的基本形式是

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...)
    [table_options]
    [partition_options]

因此,您需要考虑单词 TEMPORARY 和字符串 IF NOT EXISTS 的可能性。我相信表名也有可能被反引号引用以防它包含任何有趣的字符(不过我可能错了)。

这是一个正则表达式的第一次尝试:

/CREATE\s+(TEMPORARY\s+)*TABLE\s+(IF NOT EXISTS\s+)*(.*?)\s+/gi

【讨论】:

以上是关于PHP 和 SQL 解析的主要内容,如果未能解决你的问题,请参考以下文章

代码收藏系列--php--加载sql文件并解析成数组

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

我用的php+sql+apache集成环境,我能直接用IP访问域名A解析但是发现有时候用域名不能访问为啥??

错误查询SQL在PHP中解析XML

Atitit.sql ast 表达式 语法树 语法 解析原理与实现 java php c#.net js

mysql工作流程