PDO bindParam в одно утверждение? - PullRequest
13 голосов
/ 16 апреля 2011

Есть ли способ, которым я могу поместить эти операторы 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.На веб-сайте php.net для PDO он показывает их в отдельных строках, и во всех примерах, которые я видел, он находится в отдельных строках.

Возможно ли это?

Ответы [ 5 ]

22 голосов
/ 16 апреля 2011

Пример 2 на странице execute - это то, что вам нужно:

$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']));
4 голосов
/ 31 июля 2014

Ваш здравый смысл совершенно прав, что целью кодирования является сохранение набора текста ... но его решение не помогает с битом 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...));

Предварительно очистив ваши значения, конечно.

4 голосов
/ 16 апреля 2011

вспомогательная функция - это функция, которая помогает вам избежать написания множества повторяющихся кодов каждый раз, когда вы хотите выполнить запрос.
Это называется «программирование», и на этом сайте его практически нет, по крайней мере, под тегом «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); 
}

имея массив имен полей, он может создать для вас оператор вставки и массив данных. Программный. Итак, ваш код становится не более чем этими 3 короткими строками:

$fields = array('username', 'email', 'password');
$stmt = $dbh->prepare("INSERT INTO accounts SET ".pdoSet($fields,$values));
$stmt->execute($values);
3 голосов
/ 04 ноября 2013

+ 1 Мэтью Флашену за принятый ответ, но я покажу вам еще один совет. Если вы используете параметры SQL с именами, совпадающими с записями в $ _POST, вы можете воспользоваться тем, что $ _POST уже является массивом:

$q->execute($_POST);

Имена параметров SQL имеют префикс двоеточия (:), а ключи в массиве $ _POST - нет. Но современные версии PDO объясняют это - вам больше не нужно использовать префиксы двоеточия в ключах в массиве, который вы передаете execute ().

Но вы должны быть осторожны, чтобы каждый мог добавить дополнительные параметры к любому веб-запросу, и вы должны получить только подмножество параметров $ _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 голос
/ 27 августа 2012

Лично я предпочитаю использовать функцию-обертку для всего 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).

Код, который я использую для создания этой функции-оболочки, выглядит следующим образом:

/**
* 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 до одной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...