PHP正则表达式获取SQL语句中的表名

有一个SQL语句集合,里面可能有selectselect ... left joinupdatedeleteinsert

要从这语句集合中获取到所有的表名,该如何做呢?

代码如下,

<?php

class SqlLog
{
    // SQL语句
    private static $sql = [];

    // UPDATE 正则条件
    private static $updateExpression = '/UPDATE[\\s`]+?(\\w+)[\\s`]+?/is';

    // INSERT 正则条件
    private static $insertExpression = '/INSERT\\s+?INTO[\\s`]+?(\\w+)[\\s`]+?/is';

    // DELETE 正则条件
    private static $deleteExpression = '/DELETE\\s+?FROM[\\s`]+?(\\w+)[\\s`]+?/is';

    // SELECT 正则条件
    private static $selectExpression = '/((SELECT.+?FROM)|(LEFT\\s+JOIN|JOIN|LEFT))[\\s`]+?(\\w+)[\\s`]+?/is';

    /**
     * @return array 返回查询操作的所有表名
     */
    public static function selectTableNames()
    {
        return self::getTableNames(self::$selectExpression);
    }

    /**
     * @return array 返回更新操作的所有表名
     */
    public static function updateTableNames()
    {
        return self::getTableNames(self::$updateExpression);
    }

    /**
     * @return array 返回插入操作的所有表名
     */
    public static function insertTableNames()
    {
        return self::getTableNames(self::$insertExpression);
    }

    /**
     * @return array 返回删除操作的所有表名
     */
    public static function deleteTableNames()
    {
        return self::getTableNames(self::$deleteExpression);
    }

    /**
     * 根据正则表达式获取所有操作的表名
     * @param $expression
     * @return array
     */
    public static function getTableNames($expression)
    {
        $sqlString = implode(PHP_EOL, self::$sql);
        preg_match_all($expression, $sqlString, $matches);

        return array_unique(array_pop($matches));
    }

    /**
     * 根据sql获取表名、操作
     * @param $sql string SQL语句
     */
    public static function setSql($sql)
    {
        self::$sql[] = $sql;
    }

    /**
     * 获取SQL语句
     * @return array SQL语句集合
     */
    public static function getSql()
    {
        return self::$sql;
    }
}

使用姿势:

<?php
$sql = "select count(*) as count from order as a left join user as b on a.user_id = b.user_id where a.title like '%衣服%'";
SqlLog::setSql($sql);
var_dump(Sql::Log::selectTableNames());

会打印出两张表:orderuser

5 条评论

a
anna says: 回复

很不错,学习了

小米 says: 回复

不错,收藏了

M
Murara says: 回复

没有考虑到[,]形式的join查询-

M
Murara says:

以及update/delete语句的join

1
1111 says: 回复

where 条件 排序识别 group by 等各个值分解出来比较好重组

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

昵称 *