2013-03-18 3 views
1

Итак, я передаю массивы значений, которые будут меняться при использовании в методе, который затем вставляет их в базу данных. Моя проблема заключается в том, как связаны параметры.Вставка нескольких значений в MySQL с помощью PHP

public function insertValues($table, $cols, $values) 
{ 
    $mysqli = new mysqli(DBHOST, DBUSER, DBPASSWORD, DBDATABASE); 

    $colString = implode(', ', $cols); // x, x, x 
    $valString = implode(', ', array_fill(0, count($values), '?')); // ?, ?, ? 

    $sql = "INSERT INTO $table ($colString) VALUES($valString)"; 
    if (!$stmt = $mysqli->prepare($sql)) 
     echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error; 

    // THIS IS THE PROBLEM AREA 
    foreach ($values as $v) 
     if (!$stmt->bind_param('s', $v)) 
      echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error; 

    if (!$stmt->execute()) 
     echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error; 

    $stmt->close(); 
    $mysqli->close(); 
} 

Мне нужен способ, чтобы связать все параметры сразу я думаю, и не один, в то время, но я не могу понять, полезный способ сделать это. Любая помощь будет принята с благодарностью.

+0

В чем проблема? Основываясь на чтении документации, то, что вы делаете, должно быть правильным, хотя мне самому не нужно ее проверять. – siride

+1

Вы можете связать несколько var за один раз, но поскольку вы не знаете числа var в вашем случае, лучшим способом является итерация. Ваше решение работает хорошо? Если нет, попытались ли написать 'foreach ($ values ​​as $ index => $ v)', а затем связать '$ stmt-> bind_param ('s', $ values ​​[$ index])'? – MatRt

ответ

3

Я нашел ответ на проблему, которую вы ищете на PHP.net (http://php.net/manual/en/mysqli-stmt.bind-param.php). Я вставив его здесь для удобства, вся заслуга человека, идущего по электронной почте Nick9v^AT^-remove- -dot- Hotmail ком

При работе с динамическим числом значений полей при подготовке Я считаю этот класс полезным.

[Примечание редактора: изменен BindParam :: добавить(), чтобы принять $ значение по ссылке и тем самым предотвратить предупреждение в более новых версиях PHP.]

<?php 
class BindParam{ 
    private $values = array(), $types = ''; 

    public function add($type, &$value){ 
     $this->values[] = $value; 
     $this->types .= $type; 
    } 

    public function get(){ 
     return array_merge(array($this->types), $this->values); 
    } 
} 
?> 

Использование довольно просто. Создайте экземпляр и используйте метод add для заполнения. Когда вы будете готовы выполнить, просто используйте метод get.

<?php 
$bindParam = new BindParam(); 
$qArray = array(); 

$use_part_1 = 1; 
$use_part_2 = 1; 
$use_part_3 = 1; 

$query = 'SELECT * FROM users WHERE '; 
if($use_part_1){ 
    $qArray[] = 'hair_color = ?'; 
    $bindParam->add('s', 'red'); 
} 
if($use_part_2){ 
    $qArray[] = 'age = ?'; 
    $bindParam->add('i', 25); 
} 
if($use_part_3){ 
    $qArray[] = 'balance = ?'; 
    $bindParam->add('d', 50.00); 
} 

$query .= implode(' OR ', $qArray); 

//call_user_func_array(array($stm, 'bind_param'), $bindParam->get()); 

echo $query . '<br/>'; 
var_dump($bindParam->get()); 
?> 

Это получает вам результат, который выглядит примерно так:

SELECT * FROM пользователей WHERE hair_color =? OR age =? ИЛИ баланс =? массив (4) {[0] => строка (3) "sid" 1 => строка (3) "красный" [2] => int (25) [3] => float (50)}

0

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

Проще всего было бы составить массив с типами и параметрами, а затем передать его в bind_param с вызовом call_user_func_array, например:

$params = array(); 
$types = ''; 

foreach ($values as $k => $v) 
{ 
    $types .= 's'; 
    $params[] = &$values[$k]; 
} 

$bind_params = array_merge(array($types), $params); 

if (!call_user_func_array(array($stmt, 'bind_param'), $bind_params)) 
    // ... 

Обратите внимание, что bind_param ожидает переменные, передаваемые по ссылка не по значению, иначе это будет пара строк, строящих массив со значениями, а не цикл foreach.

Смежные вопросы