PHP PDO语法问题?

时间:2014-06-26 17:33:53

标签: php mysql pdo

我在使用这段代码时出现问题,但无法找到任何错误:

$query = "CREATE TABLE ? (? INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(?), ? VARCHAR(30), ? VARCHAR(50), ? TIMESTAMP, ? VARCHAR(50), ? DECIMAL(15, 2), ? DECIMAL(3, 2), ? VARCHAR(255))";
$array = array($table_name, $id, $id, $a_title, $c_title, $date_updated_title, $s_title, $ds_title, $ps_title, $u_title);

    try {
        $results = db_query($db, $query, $array); // db_query() is my PDO function to query the database. This function works fine elsewhere.
        echo($table_name . " create successfully!");
    } catch (PDOException $e) {
        echo('<br />Could not create table "' . $table_name . '".');
        return false;
        error($e); //error() is my function to write errors to my log, and works fine elsewhere.
    }

当我在浏览器中运行时,它会返回我捕获的异常&#39;无法创建表&#34;名称&#34;。&#39;但是,我在日志中看不到任何错误,因此我不知道它是否是语法问题,或者是什么。

当我自己进行查询,并将问号替换为实际值,并将其转储到PHPMyAdmin中时,它会创建表格。我不确定这里的问题是什么。我在另一个网站上用PDO取得了合理的成功,但我还是比较新的。有什么想法吗?

感谢您的帮助!

[编辑]自尝试使用此查询以来我已经

"CREATE TABLE $a_title (? INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(?), ? VARCHAR(30), ? VARCHAR(50), ? TIMESTAMP, ? VARCHAR(50), ? DECIMAL(15, 2), ? DECIMAL(3, 2), ? VARCHAR(255))";

我尝试过单引号和双引号。我还从数组中删除了$ table_name变量。仍然会出现语法错误,并且不确定原因。

1 个答案:

答案 0 :(得分:3)

来自@DCoder的评论是正确的。您可以使用查询参数 only ,通常可以放置 单个字符串文字,日期文字或数字文字。

您不能将查询参数用于:

  • 表名

    错误:SELECT * FROM ?

  • 列名

    错误:SELECT * FROM table WHERE ? = 1234

  • 值列表

    错误:SELECT * FROM table WHERE column IN (?)

    虽然您可以将IN()与参数占位符列表一起使用,但每个标量值都有一个。

  • SQL运算符,表达式或关键字

    错误:SELECT * FROM table WHERE column ? 'value' AND ? ORDER BY column ?

对于这些情况,如果您希望动态内容成为查询的一部分,则在调用prepare() 之前,内容必须是查询的一部分。

但这意味着你要回到将变量插入到SQL查询字符串中,我们被告知它的SQL注入风险是禁止的。

解决方案是使用过滤和白名单来确保内容不包含某些不安全的内容。例如,如果它是一个动态表名,除去你想要保留的字符以外的任何字符,然后还要分隔表名,以防有人为其表命名为“table”或“order”之类的保留字。

$table = preg_replace("/[^\w]/", "", $table);
$sql = "CREATE TABLE `{$table}` ( ... )";

重新评论:

是的,列名也不受限制。正如我在顶部所说,参数仅用于标量值。

您还需要了解三种不同类型的引号的适当用法。