【问题标题】:How to use prepared statements in this query?如何在此查询中使用准备好的语句?
【发布时间】:2009-12-22 13:47:44
【问题描述】:

我是 PHP 和 PDO 的新手,我尝试在这里使用准备好的语句。经过1小时的尝试,我放弃了。或者我的教程太糟糕了。

编辑:

这在没有准备好的语句的情况下完美地工作:

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name="root"');
    //$prepared->bindParam('foo', 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

但这对于准备好的语句根本不起作用。这样做时得到一个完全空白的页面:

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name=:foo');
    $prepared->bindParam('foo', 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

foo 应该替换为 root。但是,它没有。

【问题讨论】:

  • 您似乎接受了一个错误的答案,而忽略了真正的答案(您在 bindParam $prepared-&gt;bindParam(':foo', 'root') 中缺少一个 :)

标签: php pdo prepared-statement


【解决方案1】:

在绑定时也尝试在名称中使用冒号:

$prepared->bindParam(':foo', 'root');

正如文档中所做的那样:http://php.net/manual/en/pdostatement.bindparam.php

【讨论】:

  • 我很确定这是正确的答案,应该被接受。其他答案让 PDO 与 MySQLi 混淆。
【解决方案2】:

你的bindParam 的第二个参数必须是一个变量,否则你会得到一个致命错误。所以,

$value='root';
$prepared->bindParam('foo', $value);

或:

$prepared->bindValue('foo', 'root');


很容易弄清楚何时显示错误消息:

if ($in_development) ERROR_REPORTING(E_ALL);
// ... code

【讨论】:

    【解决方案3】:

    您不能将参数用于表名和列名之类的东西,它只能用于数据,而不是用于完全动态的查询

    这应该可行:

    $prepared = $dbh->prepare('SELECT * from sy_navigation_point WHERE Foo=:whatever');
    $prepared->bindParam('whatever', 'Bar');
    

    编辑:这应该是真正的解决方案。

    通过查看documentation,很明显该模式必须是:

    $prepared = $dbh->prepare('SELECT * from sy_navigation_point WHERE Foo=:whatever');
    $prepared->bindParam('whatever', $value);
    

    然后你做:

    $value = 'Bar';
    $prepared->execute();
    

    【讨论】:

    • 不起作用:我一做任何参数绑定就会得到一个空白页
    • 我用更好的例子更新了我的问题。它不起作用。
    • 不起作用,但答案被接受了吗?解决方案是什么?
    • Prepared Statements 不是为了防止 SQL 注入。它们被发明用于解析 SQL 语句并构建执行计划一次,然后使用不同的值多次执行它,因此首先发送“原始”查询,然后独立地发送所有数据。这可以防止 SQL 注入是一种副作用,但不是本意。 (特别是因为它不适用于所有领域,例如动态字段名称等)
    • 此答案似乎不适用于该问题,可能是因为它已被编辑。
    【解决方案4】:

    http://www.php.net/manual/en/pdo.prepare.php 那里的评论者说它不适用于关键字、表名、视图名和字段名 所以你需要$prepared = $dbh-&gt;prepare('SELECT * from ' . $table);

    因为它只对列变量有效。

    【讨论】:

    • 我用更好的例子更新了我的问题。它甚至对列变量也不起作用。
    【解决方案5】:

    您不能在 MySQL 准备好的语句中绑定表,您只能绑定值。来自the manual

    但是,它们不允许用于标识符(例如表名或列名), 或指定二元运算符的两个操作数,例如 = 等号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-05-02
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      相关资源
      最近更新 更多