createDb.sql
create database `:name` ;
我正在尝试此文件以创建数据库。
$createSql = file_get_contents('createDb.sql');
$stmt = $db->prepare($createSql);
$stmt->bindValue(':name', $dbName);
$stmt->execute();
问题是,我得到了数据库名称的额外引用。例如,如果$ dbName = trash,则新创建的数据库名为'trash'(不带重音,但带引号)。我可以摆脱报价吗?
答案 0 :(得分:0)
在任何情况下,对查询的静态部分(SELECT
,INSERT INTO
数据库名称,...)使用占位符认真会降低准备的安全性陈述给你。这是因为准备好的陈述的本质。
以下是它们的工作原理(简单表示):
SELECT * from db.tbl WHERE field = ?
此字符串被发送到DB,准备好准备。在准备好语句之后,您可以使用生成的资源并将实际值发送到DB服务器以与此语句一起使用:
<stmt> + 123
值通过不同协议发送,然后正确转义,并插入预处理语句以保证正确转义。
现在将它应用于你的情况,假设它甚至可以工作:
CREATE DATABASE ?
无论接下来会传递什么价值,都不应该过多地逃避,因为:
CREATE DATABASE 'foobar'
不是有效的SQL,但是:
CREATE DATABASE IF NOT EXISTS foobar
也应被接受,因为是有效的SQL,在某些方面,它比你当前使用的简单的create语句更优选。 /> 在这一点上,我们甚至没有讨论 options 而不是指定(charset,collation,table specific options ...)那些呢?
真的,最好的办法是重构,重新思考,并且问自己是否想要动态创建数据库。
9/10,甚至99.99999%的次数,你最好创建表格。即便如此,您可能不希望为表名使用变量,除非它们至少被正确消毒。
但顺便说一句,如果你想继续你正在做的事情,并且不有这些引用,你应该这样做:
$dbName = str_replace(' ', '_', strtolower(trim($dbName)));//remove spaces, trim
$dbName = preg_replace('/^\d*|[^a-z0-9]/','',$dbName);//remove leading digits and non alf-num chars
$db->query('CREATE DATABASE '.$dbName);
使用输入123foo% bar 3
,这将创建一个名为foo_bar3
的数据库。
一些有趣的链接: