使用MySQLi安全地创建动态表

时间:2014-03-24 20:56:46

标签: php mysql mysqli prepared-statement

我希望能够为自定义用户调查创建动态表...就像调查猴子一样......我将如何创建类似的东西?

因为我想让用户能够创建调查,具有不同数量的文本字段和不同的选项字段......我需要为每个调查创建一个自定义表。

这样的事情会成为可能吗?

<?php

$table_name = 'survey_'.$_POST['surveyid'];

$query = 'CREATE TABLE ? (
            `responseid` INT NOT NULL AUTO_INCREMENT,
            `textarea1` TEXT NULL,
            `textarea2` TEXT NULL,
            `textarea3` VARCHAR(255) NULL,
            `drop_down1` VARCHAR(255) NULL,
            `drop_down2` VARCHAR(255) NULL,
            `bool1` BIT NULL,
            `bool2` BIT NULL,
        PRIMARY KEY (`responseid`))';

if($stmt = $mysqli->prepare($query)){
    $stmt->bind_param('s', $table_name);
    $stmt->execute();
    $stmt->close();
}else die("Failed to prepare");

?>

以上示例返回"Failed to prepare",因为我不认为我可以准备一个表名...还有另外一个使用mysqli的工作吗?

if(ctype_digit($_POST['surveyid']) && $_POST['surveyid']>0){

    $table_name = 'survey_'.$_POST['surveyid'];

    $query = 'CREATE TABLE '.$table_name.' (
            `responseid` INT NOT NULL AUTO_INCREMENT,
            `textarea1` TEXT NULL,
            `textarea2` TEXT NULL,
            `textarea3` VARCHAR(255) NULL,
            `drop_down1` VARCHAR(255) NULL,
            `drop_down2` VARCHAR(255) NULL,
            `bool1` BIT NULL,
            `bool2` BIT NULL,
        PRIMARY KEY (`responseid`))';

我知道我可以尝试消毒$_POST['surveyid'](就像我上面所做的那样)但我更愿意在可能的情况下做好准备。

2 个答案:

答案 0 :(得分:1)

$table_name = 'survey_'.$_POST['surveyid'];

不要执行上述操作。如果您在任何SQL字符串中直接包含$ _GET或$ _POST数据,黑客很容易利用您的网站。

但是您不能使用参数作为表名。参数取代单个标量值 only You can prepare CREATE TABLE但您无法使用参数作为标识符(例如表格名称)。

最佳做法是确保您的表名符合规则,例如只有数字字符串的前导部分,最多为MySQL表名的最大长度:

$table_name = 'survey_' . strspn(trim($_POST['surveyid']), '0123456789', 0, 56);

如果您对surveyid有其他规则,那么您可以使用preg_replace():

$table_name = 'survey_' . preg_replace('^(\w+)', '$1', trim($_POST['surveyid']));

答案 1 :(得分:0)

可以准备像&#34; CREATE TABLE&#34;这样的数据定义语言语句。我无法在MySQL文档中找到解释这一点的参考,但我确实在PHP documentation site上找到了一个很好的解释。