Php PDO bindParam合并到一个语句中?

Php PDO bindParam合并到一个语句中?,php,mysql,pdo,Php,Mysql,Pdo,有没有办法把这些bindParam语句放到一个语句中 $q = $dbc -> prepare("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)"); $q -> bindParam(':username', $_POST['username']); $q -> bindParam(':email', $_POST['email']); $q ->

有没有办法把这些bindParam语句放到一个语句中

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)");
$q -> bindParam(':username', $_POST['username']);
$q -> bindParam(':email', $_POST['email']);
$q -> bindParam(':password', $_POST['password']);
$q -> execute();
在可能的情况下,我使用了之前准备好的mysqli,我切换到PDO以获得assoc_阵列支持。在PDO的php.net网站上,它在单独的行上显示它们,在我看到的所有示例中,它都在单独的行上

可能吗?

页面上的示例2是您想要的:

$sth->execute(array(':calories' => $calories, ':colour' => $colour));
您可能还想看看其他示例。对于问号参数,它将是:

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) VALUES (?, ?, ?)");
$q->execute(array($_POST['username'], $_POST['email'], $_POST['password']));
如果只有这些列,您可以编写:

$q = $dbc -> prepare("INSERT INTO accounts VALUES (?, ?, ?)");
$q->execute(array($_POST['username'], $_POST['email'], $_POST['password']));

helper函数是一个函数,它可以帮助您避免在每次运行查询时编写大量重复代码。
这就是所谓的“编程”,在这个网站上几乎没有,至少在“PHP”标签下是这样。
虽然许多peiople认为编程代表复制/粘贴手动示例中的代码块,但它有点不同。 虽然这很难学,但确实值得,特别是如果你致力于网络开发的话

正如你所看到的,没有被接受的答案对你没有真正的帮助,因为你仍然需要写一些类似的东西

$sth->execute(array(':username' => $_POST['username'], 
                    ':email' => $_POST['email']
                    ':password' => $_POST['password']);
表中的字段数是原来的字段数的两倍,这与最初的方法没有多大区别,但仍然需要将每个字段名写四次

但是作为一名程序员,你可以使用编程的能力。一个循环,例如-一个基础编程操作符。
每次你看到重复,你就知道应该有一个循环

例如,可以设置字段列表,只命名一次。 让一个程序来完成剩下的工作

比如,像这样的函数

function pdoSet($fields, &$values, $source = array()) {
  $set = '';
  $values = array();
  if (!$source) $source = &$_POST;
  foreach ($fields as $field) {
    if (isset($source[$field])) {
      $set.="`$field`=:$field, ";
      $values[$field] = $source[$field];
    }
  }
  return substr($set, 0, -2); 
}
给定一个字段名数组,它可以为您生成insert语句和数据数组。以编程方式。因此,您的代码不超过以下3行:

$fields = array('username', 'email', 'password');
$stmt = $dbh->prepare("INSERT INTO accounts SET ".pdoSet($fields,$values));
$stmt->execute($values);

就我个人而言,我更喜欢为所有pdo使用包装器函数,这大大简化了所需的代码

例如,要运行绑定查询(嗯,所有我的查询),我要执行以下操作:

$iterable_resultset = query("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)", array(':username'=>'bob', ':email'=>'bob@example.com', ':password'=>'bobpassword'));
请注意,sql不仅只是一个字符串,而且实际上是一个可重用的字符串,因为如果您想在sql之后执行类似的插入(不适用于这种情况,但适用于其他sql用例),您可以简单地将sql作为字符串传递,并更改要传递的变量数组

我用于创建此包装函数的代码如下所示:

/**
* Run bound queries on the database.
*
* Use: query('select all from players limit :count', array('count'=>10));
* Or: query('select all from players limit :count', array('count'=>array(10, PDO::PARAM_INT)));
*
* Note that it returns foreachable resultset object unless an array is specifically requested.
**/
function query($sql, $bindings=array(), $return_resultset=true) {
DatabaseConnection::getInstance(); // Gets a singleton database connection
$statement = DatabaseConnection::$pdo->prepare($sql); // Get your pdo instance, in this case I use a static singleton instance.  You may want to do something simpler.

foreach ($bindings as $binding => $value) {
if (is_array($value)) {
$first = reset($value);
$last = end($value);
// Cast the bindings when something to cast to was sent in.
$statement->bindParam($binding, $first, $last);
} else {
$statement->bindValue($binding, $value);
}
}

$statement->execute();

if ($return_resultset) {
return $statement; // Returns a foreachable resultset
} else {
// Otherwise returns all the data an associative array.
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
}

// Wrapper to explicitly & simply get a multi-dimensional array.
function query_array($sql_query, $bindings=array()) {
return query($sql_query, $bindings, false); // Set return_resultset to false to return the array.
}

如评论中所述,您可能希望使用自己的方法来设置数据库连接并获取初始化的pdo,但通常它允许将绑定的sql缩减为一行。

+1向Matthew Flaschen寻求可接受的答案,但我将向您展示另一个技巧。如果使用与$\u POST中的条目名称相同的SQL参数,则可以利用$\u POST已经是一个数组这一事实:

$q->execute($_POST);
SQL参数名称的前缀是冒号(
),但$\u POST数组中的键不是。但是PDO的现代版本说明了这一点——您不再需要在传递给execute()的数组中的键中使用冒号前缀

但是您应该注意,任何人都可以向任何web请求添加额外的参数,并且您应该只获得与查询中的参数匹配的$u POST参数的子集

$q = $dbc -> prepare("INSERT INTO accounts (username, email, password) 
  VALUES (:username, :email, :password)");
$params = array_intersect_key($_POST, array("username"=>1,"email"=>1,"password"=>1));
$q->execute($params);

你的常识是完全正确的,编码的目的是为了节省打字。。。但他的解决方案对BindParams一点都没有帮助。我在网上找不到关于这个的任何其他信息,所以这里有一个我最终说服它工作的东西——我希望它对某些人有用

//First, a function to add the colon for each field value.
function PrepareString($array){
//takes array (title,author);
//and returns the middle bit of pdo update query :title,:author etc 
    foreach($array as $k =>$v){
        $array[$k]=':'.$v;
    }
    return implode(', ', $array);
}
然后

function PdoInsert($table_name,$array){

    $db = new PDO(); //however you create your own pdo

 //get $fields and $vals for statement
    $fields_vals=array_keys($array);
    $fields=implode(',',$fields_vals);
    $vals=PrepareString($fields_vals);
    $sql = "INSERT INTO $table_name($fields)    VALUES ($vals)";  

    $qwe=$db->prepare($sql);


    foreach ($array as $k =>$v ){
      //add the colon to the key
      $y=':'.$k;
        //god knows why it doesn't like $qwe->bindParam($y,$v,PDO::PARAM_STR);
        // but it really doesn't! So we refer back to $array.
        //add checks for different binding types here 
(见附件)

然后您可以通过执行以下操作插入任何内容

PdoInsert('MyTableName',array('field1'=>$value1,'field2'=>$value2...));

当然,之前已经对您的值进行了清理。

谢谢您,还有最后一个问题,我有一个SELECT查询,其中只包含一个占位符:电子邮件,是否最好将其存储在数组中,将bindParam代码行从等式中删除,但是数组将只存储1个变量,因为我只有一个占位符:email,哪个更好?@Basic,不管怎样,我倾向于使用数组。我还喜欢什么?占位符。但是,这两种方法都是主观的。是否需要assoc_阵列支持?你不是指命名的占位符吗?只是好奇,你会一直这样使用它吗?没有助手函数之类的?我今天才开始使用PDO,我不知道什么是助手函数,如果你能解释一下的话?不是你要求的,但是不要将明文密码保存到数据库中。(看起来你的代码就是这么做的。也许我错了,但建议对未来的读者有用。)真棒的答案!我会试试这个:)我从不复制和粘贴,但我比你低几级。atm:P如果你使用
占位符,你根本不需要重复字段名,我确实提到过(我推荐的示例中显示了这一点)。@Matthew
占位符只占四分之一。请不要把时间浪费在评论上。在现实生活中,只需一段代码就可以生成简洁且可用的代码。@Basic好的,不要复制/粘贴,我们称之为“将所有东西放在一起”。就像乐高积木一样,一直都是相同的代码块,一个接一个。无意冒犯,但PHP在大多数书籍和答案中的出现方式并不是编程方式。我是唯一一个在这篇文章中发现@Col.Shrapnel有点粗鲁和对抗性的人吗?看在上帝的份上,冷静点,伙计。
PdoInsert('MyTableName',array('field1'=>$value1,'field2'=>$value2...));