DESCRIBE表时PDO异常

时间:2018-09-19 17:53:53

标签: php mysql pdo

我遇到了错误:

  

SQLSTATE [42000]:语法错误或访问冲突:1064您有一个   您的SQL语法错误;检查与您的手册相对应的手册   MySQL服务器版本,可在“ mytable”附近使用正确的语法   第1行

当我使用调用以下函数时

$fields = Table::getFieldsForTable('mytable');

如果我将:t硬编码为我的表名,则代码可以正常执行。

 public static function getFieldsForTable ($table ) {
            $sql = 'DESCRIBE :t';

            try {
                /**
                 * @var $db \PDO
                 */
                $db = static::getDB();
                $stmt = $db->prepare($sql);

                $stmt->bindValue(':t', $table, PDO::PARAM_STR);

                $stmt->execute();

                return $stmt->fetchAll(PDO::FETCH_ASSOC);
            } catch (\PDOException $e){
                echo "PDO ERROR" . $e->getMessage();
            }
        }

我在项目的其他部分中反复使用了相同的代码段,但在这里看不到我做错了什么。

有帮助吗?

2 个答案:

答案 0 :(得分:1)

仅因为表名或列名不能用PDO中的参数替换-这只是其工作方式的基本限制。

查看重复问题的答案: Can PHP PDO Statements accept the table or column name as parameter?

https://stackoverflow.com/a/15990488/180733 是一个很好的解释。

如果您担心接受任意表名的安全性,请考虑使用SHOW TABLES预先提取所有表名,然后使用{{1}针对该列表验证建议的表名}。

答案 1 :(得分:0)

bindValuePDO::FETCH_ASSOC引用字符串,就好像它是您要用于插入或选择等的值一样。只需连接字符串

$sql="DESCRIBE ".$table;. 

为了安全起见,请开发仅检测有效表名的正则表达式,例如像这样

preg_match('/^[a-zA-Z]{1}[a-zA-Z_]{1,18}$/',$table);

或与白名单匹配,例如可接受的表格数组