PDO bindParam 到一个语句中?

发布于 2024-11-01 21:06:04 字数 479 浏览 1 评论 0原文

有没有一种方法可以将这些 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_array支持。在 PDO 的 php.net 网站上,它在单独的行上显示它们,并且在我看到的所有示例中,它都是在单独的行上。

是否可以?

Is there a way I can put these bindParam statements into one statement?

$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();

I was using mysqli prepared before where it was possible, I switched to PDO for assoc_array support. On the php.net website for PDO it shows them on seperate lines, and in all examples I have seen it is on seperate lines.

Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼眸里的那抹悲凉 2024-11-08 21:06:04

execute 页面上的示例 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']));

Example 2 on the execute page is what you want:

$sth->execute(array(':calories' => $calories, ':colour' => $colour));

You may want to look at the other examples too. With question mark parameters, it would be:

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

If those are the only columns, you can just write:

$q = $dbc -> prepare("INSERT INTO accounts VALUES (?, ?, ?)");
$q->execute(array($_POST['username'], $_POST['email'], $_POST['password']));
信仰 2024-11-08 21:06:04

辅助函数是一个可以帮助您避免每次要运行查询时编写一堆重复代码的函数。
这就是所谓的“编程”,而这个网站上几乎没有任何此类内容,至少在“PHP”标签下是这样。
虽然许多人认为编程代表从手动示例中复制/粘贴代码块,但它有些不同。
尽管它很难学习,但确实值得,特别是如果您致力于网络开发。

正如您所看到的,没有接受的答案对您没有真正的帮助,因为您仍然需要

$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); 
}

被赋予一组字段名称,它可以为您生成插入语句和数据数组。以编程方式。所以,你的代码就只剩下这三行:

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

helper function is a function that makes you help to avoid writing bunch of repetitive code every time you want to run a query.
This is called "programming" and there is almost none of it on this site, at least under "PHP" tag.
While many peiople thinks that programming stands for copy/pasting chunks of code from manual examples, it's somewhat different.
Although it's hard to learn but really worth it, especially if you're devoting yourself to web-developing.

As you can see, no accepted answer did no real help for you, as you still have to write something like

$sth->execute(array(':username' => $_POST['username'], 
                    ':email' => $_POST['email']
                    ':password' => $_POST['password']);

as many times as many fields in your table, which makes not much difference from your initial approach, still makes you write each field name FOUR times.

But being a programmer, you can use powers of programming. A loop, for example - one of cornerstone programming operators.
Every time you see repetitions, you know there should be a loop.

for example, you can set up a list of fields, naming them only once.
And let a program do the rest.

Say, such a function like this one

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); 
}

being given an array of field names, it can produce both insert statement and data array for you. Programmatically. So, your code become no more than these 3 short lines:

$fields = array('username', 'email', 'password');
$stmt = $dbh->prepare("INSERT INTO accounts SET ".pdoSet($fields,$values));
$stmt->execute($values);
浅黛梨妆こ 2024-11-08 21:06:04

您的常识是完全正确的,编码的目的是节省打字...但他的解决方案对 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 

(请参阅PDO::PARAM_INT 在bindParam 中很重要?

        $qwe->bindParam($y,$array[$k],PDO::PARAM_STR);

    }
    if ($qwe->execute()==true){
        return $db->lastInsertId();  
    }
    else {
        return  $db->errorCode();
    }
}

然后,您可以通过

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

预先清理您的值来插入任何内容。

Your Common Sense is totally right that the aim of coding is to save typing... but his solution doesn't help with the BindParams bit. I couldn't find anything else about this online, so here's something I finally just persuaded to work - I hope it's useful for someone!

//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);
}

Then...

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 

(see PDO::PARAM_INT is important in bindParam?)

        $qwe->bindParam($y,$array[$k],PDO::PARAM_STR);

    }
    if ($qwe->execute()==true){
        return $db->lastInsertId();  
    }
    else {
        return  $db->errorCode();
    }
}

Then you can insert anything by doing

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

Having previously sanitized your values of course.

冰火雁神 2024-11-08 21:06:04

+1 给 Matthew Flaschen 接受的答案,但我会告诉你另一个提示。如果您使用的 SQL 参数的名称与 $_POST 中的条目相同,则可以利用 $_POST 已经是一个数组的事实:

$q->execute($_POST);

SQL 参数名称以冒号为前缀 (:)但 $_POST 数组中的键不是。但现代版本的 PDO 考虑到了这一点 - 您不再需要在传递给execute() 的数组的键中使用冒号前缀。

但您应该小心,任何人都可以向任何 Web 请求添加额外的参数,并且您应该仅获取与查询中的参数匹配的 $_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);

+1 to Matthew Flaschen for the accepted answer, but I'll show you another tip. If you use SQL parameters with names the same as the entries in $_POST, you could take advantage of the fact that $_POST is already an array:

$q->execute($_POST);

The SQL parameter names are prefixed with a colon (:) but the keys in the $_POST array are not. But modern versions of PDO account for this - you no longer need to use colon prefixes in the keys in the array you pass to execute().

But you should be careful that anyone can add extra parameters to any web request, and you should get only the subset of $_POST params that match parameters in your query.

$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);
那小子欠揍 2024-11-08 21:06:04

就我个人而言,我更喜欢对所有 pdo 使用包装函数,这可以大大简化所需的代码。

例如,要运行绑定查询(好吧,我的所有查询),我这样做:

$iterable_resultset = query("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)", array(':username'=>'bob', ':email'=>'[email protected]', ':password'=>'bobpassword'));

请注意,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被削减为只有一行。

Personally, I prefer to use a wrapper function for all of pdo, which simplifies the code necessary substantially.

For example, to run bound queries (well, all my queries), I do this:

$iterable_resultset = query("INSERT INTO accounts (username, email, password) VALUES (:username, :email, :password)", array(':username'=>'bob', ':email'=>'[email protected]', ':password'=>'bobpassword'));

Note that not only is the sql simply a string, but it's actually a reusable string, as you can simply pass the sql as a string and change the array of variables to pass in if you want to perform a similar insert right after that one (not applicable to this situation, but applicable to other sql use cases).

The code that I use to create this wrapper function is as below:

/**
* 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.
}

As noted in the comments, you'd want to use your own method for setting up a database connection and getting an initialized pdo, but in general it allows your bound sql to be cut down to just a single line.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文