Подтвердить что ты не робот

PDO bindParam в одно утверждение?

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

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

4b9b3361

Ответ 1

Пример 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']));

Ответ 2

Вспомогательная функция - это функция, которая помогает избежать написания букета повторяющегося кода каждый раз, когда вы хотите запустить запрос.
Это называется "программирование", и на этом сайте почти нет его, по крайней мере, в теге "PHP".
Хотя многие люди полагают, что программирование означает копирование/склеивание кусков кода из ручных примеров, оно несколько отличается. Хотя трудно учиться, но действительно стоит того, особенно если вы посвящаете себя веб-разработке.

Как вы можете видеть, ни один принятый ответ не помог вам, поскольку вам все равно нужно написать что-то вроде

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

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

Но будучи программистом, вы можете использовать возможности программирования. A цикл, например, один из операторов программирования в краеугольном камне.
Каждый раз, когда вы видите повторения, вы знаете, что должен быть цикл.

например, вы можете настроить список полей, называя их только один раз. И пусть программа сделает все остальное.

Скажем, такая функция, как эта

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, так и массив данных. Программный. Итак, ваш код станет не более, чем этими тремя короткими строками:

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

Ответ 3

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

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

$q->execute($_POST);

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

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

Ответ 5

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