用于向MySQL添加表的准备语句(PHP)

时间:2017-08-05 13:59:57

标签: php mysql

此代码可以工作并将表添加到我的数据库中。我的问题是我如何用准备好的陈述来保护它。

 require "conn.php";
    $MyServer =($_POST["username"]);
        $sql = ("CREATE TABLE $MyServer (
            id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
            username VARCHAR(30) NOT NULL
            )");
        if($conn->query($sql) === TRUE){
            echo "Table created successfully";
        }

我正在使用MySQLi。 我试过这个并没有添加表格。

$MyServer =($_POST["username"]);
    if (!preg_match('^/[A-Za-z][A-Za-z0-9]{0,7}$/', $MyServer)) {
       throw new Exception ('username unsuitable for use as a table name');
    }
    $sql = ("CREATE TABLE `$MyServer` (
        id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
        username VARCHAR(30) NOT NULL
        )");
    if($conn->query($sql) === TRUE){
        echo "Table created successfully";
    } else {
        echo "Table is not created successfully ";
    }

3 个答案:

答案 0 :(得分:1)

我想您正在考虑如何通过示例程序中的$MyServer变量来避免SQL注入查询。

您不能使用参数化值来命名SQL中的表(或数据库或列)。您必须执行程序中显示的变量替换。

您可以使用php来清理$MyServer变量,然后再将其用于替换。

例如:How to check, if a php string contains only english letters and digits?

你可以这样做,或类似的东西。这要求变量以字母开头,然后包含多达七个字母或数字字符。如果变量不匹配,则抛出异常。

if (!preg_match('^/[A-Za-z][A-Za-z0-9]{0,7}$/', $MyServer)) {
     throw new Exception ('username unsuitable for use as a table name');
}

答案 1 :(得分:0)

虽然让用户创建表格是一个好计划是否值得怀疑,但回答你的问题:

首先,确保您的变量不包含任何奇怪的字符。虽然MySQL allows (a subset of) unicode characters,你可能只需要普通的字母和数字:

if (
    !preg_match('/^[a-z0-9]+$/i', $MyServer)
    || preg_match(/^[0-9]+$/, $MyServer) // Identifiers may begin with a digit but unless quoted may not consist solely of digits.
    || strlen($MyServer) > 64 // Limit of table-name length
) {
    // Insert your own error handling
    die('Not allowed');
}

其次,要确保SQL将其视为标识符,请在反引号中引用它

$sql = "CREATE TABLE `$MyServer` (...etc..."

CREATE TABLE index (...etc...会在MySQL中引发错误,因为index是关键字

CREATE TABLE `index` (...etc...

不会,因为它被标记为标识符。

答案 2 :(得分:0)

老实说,通过从$_POST获取数据,您实际上是在开放SQL注入。

除非您的用户名已经存储在您的数据库中,并且没有会导致SQL注入的特殊字符(例如引号),否则您的方法肯定不行。

编辑:我看到上面的两个答案,赞美我所说的,你可以使用这两个答案中的一个(O.琼斯是我的首选)。

如果您希望您的代码更符合PDO过程(绑定PDO值以避免SQL注入),为什么不创建一个包含列(username,saved_username)的表,并且您可以与该表中的信息进行交互有效地使用PDO声明。

例如,您需要做的就是插入数据:

$query = 'INSERT INTO table (username, saved_username) VALUES (:username, :username_to_save)';
$stmt->bindParam(':username', $_POST['username']);
$stmt->bindParam(':username_to_save', $_POST['username_to_save']);
$stmt->execute()

并选择数据:

$query = 'SELECT * FROM table WHERE username = :username';
$stmt->bindParam(':username', $_POST['username']);
$stmt->execute()
$users_saved_usernames = $stmt->fetchAll();