【问题标题】:PHP/PDO: Prepared statements don't work when creating a table?PHP/PDO:创建表时准备好的语句不起作用?
【发布时间】:2010-09-08 08:17:15
【问题描述】:

当我使用 PDO 准备好的语句,并使用它将表名插入查询失败时,一个简单的示例:

$stmt = $dbh->prepare("CREATE TABLE ? (id foo, int bar,...)");
$stmt->execute(Array('table_foobar'));

它所做的只是将? 替换为'table_foobar',单引号不允许为我创建表格!

我最终需要在准备好的语句的顶部执行sprintf 以添加预定义的表名。

我到底错过了什么?

【问题讨论】:

  • 认为表名不能被参数化。我会看看我是否可以得到任何硬文档
  • 我也从未见过参数类型转换(id foo 等)。

标签: php mysql pdo prepared-statement


【解决方案1】:

我在手册中找不到任何明确的内容,但查看用户贡献的注释,参数的使用仅用于实际的 ,而不是表名、字段名等。

应该(并且可以)使用普通的字符串连接。

$tablename = "tablename";
$stmt = $dbh->prepare("CREATE TABLE `$tablename` (id foo, int bar,...)");

【讨论】:

  • 当有人声称“准备好的陈述是 100% 安全的”时,这就是我一直在谈论的(并且把每个人都烦死了,呵呵)
  • @Col true - 如果您 需要 使用动态表名,则应该以某种方式对其进行转义 - 如果我没看错的话,PDO 没有明确的 escape功能更多!因为,好吧,你不再需要那个了。因为,这就是您的参数化查询。
  • 我一直使用sprintf,因为我在define 中定义了表名,所以我将其更改为要使用的变量。
【解决方案2】:

如果您正在动态创建表,这很可能意味着您不了解关系数据库的思想,因此做错了。
只需在应用程序设置时从现成的转储中创建所有表,不要在运行时创建任何表。

根本不需要使用动态表名。

【讨论】:

  • 好点,尽可能遵循,但我可以看到动态表名称的一个用例:允许用户指定前缀 appname_tablename 以将多个安装/应用程序整合到一个的可再发行应用程序数据库 - 有时在托管环境中是必需的。
  • 这是应用程序设置的一部分,我纯粹是指要由网站管理员设置的表名,不幸的是选择了定义,因此需要 sprintf 的问题。现在使用变量修复。
  • 正确的是,一开始就构建所有表,而不是动态构建。但这是更一般的情况。例如,使用 select 语句,您也会遇到此问题。 SELECT * FROM ? 也不起作用,所以如果他不动态创建表,问题甚至会持续存在:)
  • @faileN SELECT * FROM ? 也表示糟糕的设计。但是ORDER BY ? 是更明智的情况。硬编码所有可能的选项是解决方案。
猜你喜欢
  • 2011-11-10
  • 1970-01-01
  • 2018-01-24
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多