【问题标题】:PHP PDO + Prepare StatementPHP PDO + 准备语句
【发布时间】:2011-12-30 02:55:39
【问题描述】:
$sql='SELECT phrase,english FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['languagepage']));

上面的代码运行良好。但是我需要将另一个变量放入准备语句中。我尝试了以下方法,但似乎不起作用:

$sql='SELECT phrase,? FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['language'],$_POST['languagepage']));

我知道 $_POST['language'] (通过打印它)只包含单词“english”。 是否可以在选择的这一部分中放置一个准备变量?

谢谢

【问题讨论】:

  • 语法似乎没有错误,你得到了什么错误代码?
  • 没有错误——而是从数据库中取回值,它只是给了我英语这个词。这是数据库中列的变量和标题中的值...
  • 例如:{"free":"english","meetsingles":"english","searchprofiles":"english"} 但它应该有不同的值,其中单词英语是......

标签: php pdo


【解决方案1】:

查询参数只能代替常量值——不能代替列名。

所有列和表必须在您准备查询时命名,您不能将选择列推迟到后续执行步骤。

当您希望用户输入确定列名时,请使用白名单地图将用户输入限制为有效选择。地图数组的键是合法的用户输入。映射数组的值是您要在 SQL 查询中使用的字符串,在本例中是列名。

$lang_col_map = array(
  "DEFAULT" => "english",
  "en"      => "english",
  "es"      => "spanish"
);
$lang_col = $lang_col_map[ $_POST["language"] ] ?: $lang_col_map[ "DEFAULT" ];

$sql='SELECT phrase,$lang_col FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); 
$pds->execute(array($_POST['languagepage']));

这样你可以确保只有 $lang_col_map 中的值可以成为 SQL 查询的一部分,如果用户试图在 http 请求中发送任何棘手的东西,它会被忽略,因为它不匹配任何键地图。所以查询不会受到 SQL 注入的影响。

请参阅我的演示文稿SQL Injection Myths and Fallacies 了解更多信息。

【讨论】:

  • 按照设计,所有问题/查询都应该在被问到之前就知道。
【解决方案2】:

Prepared 语句仅支持数据库支持的值的参数。

在您的第二个陈述中,第一个“?”是列名的占位符,而不是值。

您必须改用动态 SQL 语句。 为此,您必须防止 SQL 注入。

$language_authorized = array('english', 'french', 'spanish');
$language = $_POST['language'];
if (in_array($language_authorized, $language)) {
  $sql='SELECT phrase,'.$language.' FROM static_site_language WHERE page=?;';
  $pds = $database->pdo->prepare($sql);
  $pds->execute(array($_POST['languagepage']));
}

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 2014-04-19
    • 2013-04-21
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2010-12-19
    • 2016-09-10
    相关资源
    最近更新 更多