如何循环 PHP 的 PDO 绑定参数
HOW TO LOOP PHP'S PDO BIND PARAM
我目前正在创建我自己的查询构建器,我坚持使用 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();
它只绑定循环执行的最后一个数据。
最好在查询中使用 ?
占位符并将数据数组传递给 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);
只是偶然发现了这个,但仅供将来参考...
首先,我将假设您的示例应显示为 $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
) 比位置参数 (?
) 有优势,因此值得为准备好的语句保留该选项,而不是 "it's better to use ?
placeholders" 接受的答案,事实并非如此。
在我的数据库抽象层中,我使用了以下实用函数:
/**
* 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();
}
我目前正在创建我自己的查询构建器,我坚持使用 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();
它只绑定循环执行的最后一个数据。
最好在查询中使用 ?
占位符并将数据数组传递给 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);
只是偶然发现了这个,但仅供将来参考...
首先,我将假设您的示例应显示为 $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
) 比位置参数 (?
) 有优势,因此值得为准备好的语句保留该选项,而不是 "it's better to use ?
placeholders" 接受的答案,事实并非如此。
在我的数据库抽象层中,我使用了以下实用函数:
/**
* 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();
}