为将表添加到MySQL(PHP)准备的语句
这段代码可以工作并将表添加到我的数据库中。我的问题是如何用事先准备好的声明来保护它为将表添加到MySQL(PHP)准备的语句,php,mysql,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
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 ";
}
尽管允许用户创建表是否是一个好的计划值得怀疑,但要回答您的问题: 首先,确保变量不包含任何奇怪的字符。虽然是MySQL,但您可能只需要普通的字母和数字:
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将其视为标识符,请在backticks中引用它
$sql = "CREATE TABLE `$MyServer` (...etc..."
CREATE TABLE index(…等…
将在MySQL中引发错误,因为index
是一个关键字
CREATE TABLE `index` (...etc...
不会,因为它被标记为标识符。我猜您正在考虑如何避免通过示例程序中的
$MyServer
变量向查询中注入SQL
不能使用参数化值在SQL中命名表(或数据库或列)。必须执行程序中显示的变量替换
不过,在将$MyServer
变量用于替代之前,可以使用php对其进行清理
例如:
您可以这样做,或者类似的操作。这要求变量以字母开头,然后最多再包含七个字母或数字字符。如果变量不匹配,则抛出异常
if (!preg_match('^/[A-Za-z][A-Za-z0-9]{0,7}$/', $MyServer)) {
throw new Exception ('username unsuitable for use as a table name');
}
老实说,通过从
$\u POST
获取数据,您在这里真正打开了SQL注入的大门
除非您的用户名已经存储在数据库中,并且没有导致SQL注入的特殊字符(如引号),否则您的方法是绝对不可行的
编辑:我在上面看到两个答案,这是对我所说的赞美,你可以使用这两个答案中的一个(O.Jones是我的首选)
如果您希望代码更符合PDO过程(绑定PDO值以避免SQL注入),为什么不创建一个包含列(username、saved_username)的表,并且您可以使用PDO语句有效地与该表中的信息交互
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";
}
例如,要插入数据,您只需执行以下操作:
$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();
保护什么?你想保护什么?你的意思是如何避免sql注入以及允许用户基于
$POST
变量创建表?可能不是最好的计划。你至少要清理/清除表名。我想保护它不受注入的影响。你为什么要允许用户在e数据库?对我来说听起来像是糟糕的计划~如果$\u POST['username']='fred;drop database;';
?我仍然无法理解为什么您会认为(每个用户)有多个表比结构正确的数据库模式更好