【问题标题】:HOW TO LOOP PHP'S PDO BIND PARAM如何循环 PHP 的 PDO 绑定参数
【发布时间】:2018-09-12 06:42:55
【问题描述】:

我现在正在创建我自己的查询生成器,并且我坚持使用 PDO 的准备好的语句。是否可以循环 PDO 的 BindParam。我使用 foreach() 完成了它,但它不能仅在循环执行的最后一个数据上工作。

$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";

$array = array(":a"=>"10002345", "Josh");
$stmt = $conn->prepare($sql); 

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

$stmt->execute();

它只绑定循环执行的最后一个数据。

【问题讨论】:

  • 另外请提及数组中的所有键,因为缺少 :b
  • “它只适用于循环执行的最后一个数据” - 请澄清这是什么意思。
  • 我的意思是没有正确绑定
  • 我认为你覆盖了 bind 的参数,你还必须在 for 循环中执行 $stmt->execute();
  • 那么我需要把execute()放在循环里面吗?

标签: php mysql pdo bindparam


【解决方案1】:

最好在查询中使用? 占位符并将数据数组传递给execute

$sql = "SELECT * FROM users WHERE id = ? OR fname = ?";
$array = array("10002345", "Josh"); // you don't even need keys here
$stmt = $conn->prepare($sql); 
$stmt->execute($array);

【讨论】:

  • 为什么使用?“更好”?您甚至可以将命名参数传递给execute()
【解决方案2】:

只是偶然发现了这个,但仅供将来参考......

首先,我将假设您的示例应该读取$array = array(":a"=>"10002345", ":b"=>"Josh");,因为即使您的:b 密钥不存在也会出现问题。


在这一点上:

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

您还没有“passed by reference”。 $value 应修改为&$value

foreach($array as $key => &$value ) {
    $stmt->bindParam($key, $value);
}

这是因为bindParam 方法签名要求值是变量引用:

public function bindParam ($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) {}

(注意$variable之前的&)。


原始查询(无&)的最终结果是所有:params 都将设置为原始循环中$value 的最后一次迭代中的值。

所以,结果

$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";

$array = array(":a"=>"10002345", ":b"=>"Josh");

$stmt = $conn->prepare($sql); 

foreach($array as $key => $value ) {
    $stmt->bindParam($key, $value);
}

$stmt->execute();

应该是SELECT * FROM users WHERE id = 'Josh' OR fname = 'Josh'


使用命名参数 (:param) 比位置参数 (?) 具有优势,因此值得为准备好的语句保留该选项,而不是“最好使用 ? 占位符”的公认答案,事实并非如此。

【讨论】:

  • 应该是接受者的答案,但要注意命名参数的数量。通过循环使用动态槽不能很好地处理静态数量的命名参数。我的意思是,有时,参数/值数组可能会比查询中的命名参数计算更多或更少的值..
【解决方案3】:

在我的数据库抽象层中,我使用以下实用函数:

/**
 * getFieldList return the list with or without PK column
 * @param bool $withID - true when including parameter
 */
static protected function getFieldList( $withID = false )
{
    if( $withID )
        $result = '`' . static::getTableName( ) . '`' .
            '.`' . static::getPrimaryKeyName( ) . '`, ';
    else
        $result = '';

    return $result .= '`' . static::getTableName( ) . '`.' . 
        '`' . implode( '`, `'.static::getTableName( ) . '`.`', static::getFieldNames( ) ) . '`';
}

/**
 * getFieldPlaceholders - 
 * @return string - all PDO place holders prefixed :
 */
static protected function getFieldPlacholders( )
{
    return ':' . implode( ',:', static::getFieldNames( ) );
}

/**
 * getUpdateList - SQL updates section
 * @return string
 */
static private function getUpdateList( )
{
    $result = array( );
    foreach( static::getFieldNames( ) as $field ) {
        if( $field === static::getPrimaryKeyName() ) continue;
        $result[] = '`' . $field . '`=:' . $field;
    }
    return implode( ',', $result );
}

/**
 * Bind the fields to PDO placeholdes
 * @param PDOStatement $stmt statement that the fields are bound to
 * @return void
 */
protected function bindFields( $stmt )
{
    foreach( array_keys($this->fields) as $field ) {
        if( $field === static::getPrimaryKeyName() ) continue;
        $stmt->bindParam( ':' . $field, $this->fields[$field] );

        // echo $field . '->' . $this->fields[$field] . '<br>';
    }
}
/**
 * Bind the fields to the placeholders
 * @param PDOStatement $stmt - that the fields are bind to
 * @return void
 */
protected function bindColumns( $stmt, $withID = false )
{
    if( $withID )
        $stmt->bindColumn( static::getPrimaryKeyName(), $this->ID );
    foreach( static::getFieldNames() as $fieldname )
    {
        $stmt->bindColumn( $fieldname, $this->fields[$fieldname] );
    }   
}

/**
 * parseResultset
 * Set the values of the select results, resets dirty (object is in sync)
 * @param mixed[] $result - associative array
 */
protected function parseResultset( $result )
{
    foreach( $result as $field=> $value ) {
        if( $field === static::getPrimaryKeyName() )
            $this->ID = $value;
        $this->fields[$field] = $value;
    }
    $this->dirty = array();
}

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 2020-09-05
    • 2018-05-02
    • 2017-01-29
    • 2012-03-23
    • 1970-01-01
    • 2011-03-23
    相关资源
    最近更新 更多