PDO PHP вставляется в БД из ассоциативного массива

У меня есть такой массив

$a = array( 'phone' => 111111111, 'image' => "sadasdasd43eadasdad" ); 

Когда я делаю var-dump, я получаю это ->

  { ["phone"]=> int(111111111) ["image"]=> string(19) "sadasdasd43eadasdad" } 

Теперь я пытаюсь добавить это в БД, используя инструкцию IN –

  $q = $DBH->prepare("INSERT INTO user :column_string VALUES :value_string"); $q->bindParam(':column_string',implode(',',array_keys($a))); $q->bindParam(':value_string',implode(',',array_values($a))); $q->execute(); 

Проблема, с которой я столкнулась, заключается в том, что implode возвращает строку. Но столбец «телефон» является целым числом в базе данных, а также массив хранит его как целое. Поэтому я получаю ошибку SQL, так как мой последний запрос выглядит так:

 INSERT INTO user 'phone,image' values '111111111,sadasdasd43eadasdad'; 

Это неправильный запрос. Есть ли способ обойти это.

Мои имена столбцов динамически основаны на том, что пользователь хочет вставить. Поэтому я не могу использовать заполнители, такие как : phone и : image, поскольку я не всегда могу получить значения для этих двух столбцов. Пожалуйста, дайте мне знать, если есть способ обойти это. в противном случае мне придется определять несколько функций для каждого типа обновления.

Благодарю.

В прошлый раз, когда я проверил, было невозможно подготовить заявление, в котором затронутые столбцы были неизвестны во время подготовки, – но эта вещь, похоже, работает – может быть, ваша система базы данных более прощающая, чем те, которые я использую (в основном postgres)

То, что явно неверно, – это оператор implode (), так как каждая переменная должна обрабатываться им самостоятельно, вам также нужна скобка вокруг списка полей в инструкции insert.

Чтобы вставить пользовательские поля, я думаю, вам нужно сделать что-то вроде этого (по крайней мере, так, как я это делаю);

 $fields=array_keys($a); // here you have to trust your field names! $values=array_values($a); $fieldlist=implode(',',$fields); $qs=str_repeat("?,",count($fields)-1); $sql="insert into user($fieldlist) values(${qs}?)"; $q=$DBH->prepare($sql); $q->execute($values); 

Если вы не можете доверять именам полей в $ a, вы должны сделать что-то вроде

 foreach($a as $f=>$v){ if(validfield($f)){ $fields[]=$f; $values[]=$v; } } 

Если validfields – это функция, которую вы пишете, которая проверяет каждое имя поля и проверяет, действительно ли она (быстро и грязно, создавая ассоциативный массив $ valfields = array ('name' => 1, 'email' => 1, 'phone' = > 1 … и затем проверяет значение $ valfields [$ f] или (как я бы предпочел), выбирая имена полей с сервера)

Параметры SQL-запроса могут использоваться только там, где в противном случае вы указывали бы буквальное значение .

Поэтому, если бы вы могли видеть, что вы вставляете строковый литерал, литерал даты или числовой литерал в эту позицию в запросе, вы можете использовать параметр.

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

Для этих случаев вам все равно придется интерполировать содержимое в строку SQL, поэтому у вас есть некоторый риск внедрения SQL. Способ защиты от этого – с помощью белого списка имен столбцов и отклонения любого ввода, который не соответствует «белым спискам».

Потому что все другие ответы позволяют SQL-инъекции . Для ввода пользователя вам необходимо фильтровать разрешенные имена полей:

 // change this $fields = array('email', 'name', 'whatever'); $fieldlist = implode(',', $fields); $values = array_values(array_intersect_key($_POST, array_flip($fields))); $qs = str_repeat("?,",count($fields)-1) . '?'; $q = $db->prepare("INSERT INTO events ($fieldlist) values($qs)"); $q->execute($values); 

Фактически вы можете иметь поля :phone и :image связанные с нулевыми значениями заранее. Структура таблицы в любом случае исправлена, и вы, вероятно, должны получить этот путь.


Но ответ на ваш вопрос может выглядеть так:

 $keys = ':' . implode(', :', array_keys($array)); $values = str_repeat('?, ', count($array)-1) . '?'; $i = 1; $q = $DBH->prepare("INSERT INTO user ($keys) VALUES ($values)"); foreach($array as $value) $q->bindParam($i++, $value, PDO::PARAM_STR, mb_strlen($value)); 

Я оценил ответ MortenSickel, но я хотел использовать именованные параметры, чтобы быть в безопасности:

  $keys = array_keys($a); $sql = "INSERT INTO user (".implode(", ",$keys).") \n"; $sql .= "VALUES ( :".implode(", :",$keys).")"; $q = $this->dbConnection->prepare($sql); return $q->execute($a); 

Я знаю, что на этот вопрос уже давно дан ответ, но я нашел его сегодня и внес небольшой вклад в дополнение к ответу @MortenSickel.

Следующий класс позволит вам вставить или обновить ассоциативный массив в таблицу базы данных. Для получения дополнительной информации о MySQL PDO посетите: http://php.net/manual/en/book.pdo.php

 <?php class dbConnection { protected $dbConnection; function __construct($dbSettings) { $this->openDatabase($dbSettings); } function openDatabase($dbSettings) { $dsn = 'mysql:host='.$dbSettings['host'].';dbname='.$dbSettings['name']; $this->dbConnection = new PDO($dsn, $dbSettings['username'], $dbSettings['password']); $this->dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } function insertArray($table, $array) { $fields=array_keys($array); $values=array_values($array); $fieldlist=implode(',', $fields); $qs=str_repeat("?,",count($fields)-1); $sql="INSERT INTO `".$table."` (".$fieldlist.") VALUES (${qs}?)"; $q = $this->dbConnection->prepare($sql); return $q->execute($values); } function updateArray($table, $id, $array) { $fields=array_keys($array); $values=array_values($array); $fieldlist=implode(',', $fields); $qs=str_repeat("?,",count($fields)-1); $firstfield = true; $sql = "UPDATE `".$table."` SET"; for ($i = 0; $i < count($fields); $i++) { if(!$firstfield) { $sql .= ", "; } $sql .= " ".$fields[$i]."=?"; $firstfield = false; } $sql .= " WHERE `id` =?"; $sth = $this->dbConnection->prepare($sql); $values[] = $id; return $sth->execute($values); } } ?> 

Использование класса dbConnection:

 <?php $dbSettings['host'] = 'localhost'; $dbSettings['name'] = 'databasename'; $dbSettings['username'] = 'username'; $dbSettings['password'] = 'password'; $dbh = new dbConnection( $dbSettings ); $a = array( 'phone' => 111111111, 'image' => "sadasdasd43eadasdad" ); $dbh->insertArray('user', $a); // This will asume your table has a 'id' column, id: 1 will be updated in the example below: $dbh->updateArray('user', 1, $a); ?>