【问题标题】:PDOStatement->bindParam doesn't workPDOStatement->bindParam 不起作用
【发布时间】:2017-07-02 09:14:47
【问题描述】:

$query->bindParam 有点问题。它不会将占位符更改为值。

$options 是一个数组:

$options['where'] = [
    'id'    => [ 1, 2, 3 ],
    'title' => [ 'some', 'title' ]
];
$fields = '*';
$where_clauses = []; /* define empty error which could be filled with where clauses */
/* if it is a separte blog, only posts posted by it's admin should be got */
if ( Main::$current_blog_id !== 1 )
    $where_clauses[] = '`author_id` IN(' . $this->blog->admin_id . ')';

/* if options have been passed */
if ( ! empty( $options ) ) {
    /* if there are "where" options */
    if ( ! empty( $options['where'] ) ) {
        $placeholder_number = 1; /* define placeholder number */
        $placeholders       = []; /* create array with placeholders 'placeholder_number' => 'value' */
        foreach ( $options['where'] as $field_name => $values ) {
            $field_values = []; /* values that will be used to create "IN" statement */

            /* fill $fild_values array with values */
            foreach ( $values as $value ) {
                $placeholder = ':' . $placeholder_number; /* create placeholder */

                $field_values[] = $placeholder; /* add placeholder to field values */

                $placeholders[ $placeholder ] = $value; /* add placeholer with it's value to common placeholders array */

                $placeholder_number++; /* increase placeholder number */
            }

            /* turn $fields_values array into string */
            $field_values = implode( ', ', $field_values );

            /* create clause and put it into $where_clauses */
            $where_clauses[] = '`' . $field_name . '` IN(' . $field_values . ')';
        }
    }
}

/* if where statement is empty */
$where_clauses =
    ! empty( $where_clauses ) ?
    implode( ' AND ', $where_clauses ) :
    1;

$query = Main::$data_base->pdo->prepare(
    'SELECT ' . $fields . ' ' .
    'FROM `posts` ' .
    'WHERE ' . $where_clauses . ' ' .
    'LIMIT ' . $posts_quantity . ';'
);

/* if there are placeholders in the query */
if ( ! empty( $placeholders ) ) {
    foreach ( $placeholders as $placeholder => $value )
        $query->bindParam( $placeholder, $value, PDO::PARAM_STR );
}

$query->execute();
$posts = $query->fetchAll( PDO::FETCH_ASSOC );

var_dump( $query );

return
    ! empty( $posts ) ?
    $posts :
    [];

在所有这些之后,我打印的查询看起来像:

SELECT * FROM `posts` WHERE `id` IN(:1, :2, :3) AND `title` IN(:4, :5) LIMIT 15;

【问题讨论】:

  • 你可能应该阅读一些关于 php 如何处理数组的教程

标签: php mysql database pdo


【解决方案1】:

您需要定义绑定,例如...

 Array ( ':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title' )

另外你的选择不正确...

"SELECT * FROM posts WHERE id IN(:1, :2, :3) AND title IN(:4, :5) LIMIT 15;"

你必须在里面放 AND 而不是 &&。

【讨论】:

  • 对不起,我将此字符串突出显示为代码,但实际上它是打印的数组,因此它在代码中具有相同的视图
  • 更新了对 SELECT 语句的更正
  • 即使使用 AND 也不起作用。但是查询是正确的,因为如果我硬写代码,查询就会成功处理
  • 我把故障描述改了,你能看到吗?
【解决方案2】:

PDOStatement::bindParam 不会修改您传递给PDO::prepare 的查询字符串。它会在执行语句并将查询发送到 SQL 服务器时将占位符替换为您绑定到它的变量的值。

这应该是你想要的:

$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query); // $db contains the connection to the database
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
foreach ($placeholders as $placeholder => $value) {
  $statement->bindValue($placeholder, $value, PDO::PARAM_STR);
}
$statement->execute();

请注意,我使用了 PDOStatement::bindValue 并且修改了您的 SQL 查询字符串(and 而不是 &&)。

你也可以这样做:

$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query);
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
$statement->execute($placeholders);

docs 中了解PDOStatement::execute

【讨论】:

  • 我把故障描述改了,你能看到吗?
  • 您的var_dump 打印的是什么确切?我想这不仅仅是查询字符串?
  • object(PDOStatement)#13 (1) { ["queryString"]=> string(80) "SELECT * FROM posts WHERE id IN(:1, :2, :3 ) AND title IN(:4, :5) 限制 15;" }
  • 这是完全正确的。使用 perpared 语句,您将永远无法看到最终的查询字符串。我编辑了我的答案以使其更清楚。
  • 面部护理。它确实可以正常工作,但是我在查询中看到了占位符并认为有问题。谢谢你,很抱歉偷了时间。
猜你喜欢
  • 1970-01-01
  • 2014-09-11
  • 2019-03-19
  • 2010-09-23
  • 2014-01-02
  • 2015-06-23
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多