2017-02-05 18 views
2

Я использую PDO для вставки данных в таблицу. Проблема в том, что есть много столбцов, что означает, что запрос очень длинный.Как я могу написать меньше кода с помощью bindParam?

Это код, который я в настоящее время:

$stmt = $con->prepare("INSERT INTO table (crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges) VALUES (:crisps, :biscuits, :chocolate, :cakes, :smarties, :yogurts, :apples, :oranges)"); 
$stmt->bindParam(':crisps', $crisps); 
$stmt->bindParam(':biscuits', $biscuits); 
$stmt->bindParam(':chocolate', $chocolate); 
$stmt->bindParam(':cakes', $cakes); 
$stmt->bindParam(':smarties', $smarties); 
$stmt->bindParam(':yogurts', $yogurts); 
$stmt->bindParam(':apples', $apples); 
$stmt->bindParam(':oranges', $oranges); 
$stmt->execute(); 

Есть более простой способ, а не имея другой строки кода для каждого значения?

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

foreach(value) { 
    $stmt->bindParam(':value', $value); 
} 
+0

Передайте параметры 'execute()'. –

+0

Подобный вопрос http://stackoverflow.com/questions/25996358/pdo-query-giving-no-results/25996641#25996641 –

+0

'Что-то вроде этого возможно? 'Да. В точку. Вы начали отвечать на свой вопрос, теперь следуйте/исследуйте этот ответ и посмотрите, куда он ведет вас .... – Martin

ответ

3

Вы можете использовать ? идентификатор и покормить значения в следующем порядке:

$stmt = $con->prepare(" 
    INSERT INTO table 
    (crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges) 
    VALUES 
    (?, ?, ?, ?, ?, ?, ?, ?) 
"); 

$stmt->execute([$crisps, $biscuits, $chocolate, $cakes, $smarties, $yogurts, $apples, $oranges]); 

Это экономит довольно много коды уже, :named параметров имеют свою область применения, но вы не можете использовать их в комбинации с ?.


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

Для именованных параметров создать массив следующим образом:

$list = [ 
    ':crisps' => $crisps, 
    ':biscuits' => $biscuits, 
    # etc 
]; 

foreach($list as $k => $v){ 
    $stmt->bindValue($k, $v); 
} 

$stmt->execute(); 

И это для ? индексированных параметров:

$list = [ 
    $crisps, 
    $biscuits, 
    #etc 
] 

foreach($list as $k => $v){ 
    $stmt->bindValue($k+1, $v); 
} 

$stmt->execute(); 

Пожалуйста, обратите внимание, что я изменил метод от bindParam() до bindValue() как в ваш код не имеет смысла использовать этот метод.

В этом случае возникает вопрос об использовании bindValue(), потому что этот дополнительный метод только для того, чтобы он мог присвоить значение определенному типу, используя параметр 3th, который вы ничего не делаете.

Таким образом, в сущности, вы можете избежать этого foreach петли все-вместе путем подачи $list в execute() метод непосредственно:

$stmt->execute($list); 

Если вы действительно хотите использовать bindParam(), то просто добавьте опорный символ перед именем переменной :

$list = [ 
    ':cakes' => &$cakes 
]; 
+0

Спасибо за предложение. Я мог бы попробовать использовать '?', Но мне бы очень понравилось, если бы я мог использовать 'foreach', как я предложил в своем вопросе. –

+1

Ну, ваш foreach можно использовать, но вам нужно построить этот массив, который все еще берет строки кода. –

+0

Этот ответ кажется слишком сфокусированным на том, что SQL является INSERT и ярлыками синтаксиса, чем 'INSERT'. Что происходит в SQL-запросе 'UPDATE' или' SELECT'? Также имея неопознанные '?'- шаг назад, а не вперед в ссылках на переменные. – Martin

1

Ну ваш Еогеасп можно использовать, но вам нужно построить этот массив, который до сих пор занимает строки кода
- Марк Бейкер.

Это очень верно.


Примечание: Пожалуйста read here, почему я использую BindValue, а не BindParam. Благодаря Xorifelse для напоминания.

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

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

так:

$save['crisps'] = $crisps; 
$save['biscuits'] = $buiscuits; 
... 

Это заменить автономные переменные ($crisps и т.д.) с коллекцией (массив) переменных, с ключом массива является имя ссылки.

Тогда

foreach($save as $key=>$value){ 
    $stmt->bindValue(":".$key, $value); 
} 
unset($key,$value); 

ПРИМЕЧАНИЕ: Я не поставить в любой чистки безопасности или проверки процедур здесь, как это несколько выходит за рамки, но я рекомендую делать так (в preg_replace или аналогичный), чтобы обеспечить недопустимые символы предварительно удаляются из значения ключа.

Пример:

$key = preg_replace("/[^a-z]/i","",$key); 

Вы уверены, что мне нужно заранее определенный массив как таковой? Может ли это быть упрощено больше, поскольку $ v всегда будет таким же, как $ k, только с $ перед ним (если вы понимаете, что я имею в виду)?
- Codesee

Проблема с этим, как ваши переменные не собираются в массив или объект, как подразумевается код, чтобы узнать, какие переменные вы хотите добавить в INSERT SQL? Вам все равно нужна строка кода для каждого из них.

+0

Что-то я пропустил, а затем, прежде чем создать свой ответ, 'bindParam()'! = 'BindValue()', поэтому определение массива, как вы делали, отрицает использование 'bindParam()' – Xorifelse

+0

@Xorifelse Извините, что я не понимая вашу ссылку? ah wait, вы говорите, что, поскольку это 'BindParam', он не будет принимать значения, переданные по ссылке? О да ... Я забыл, что .... ffs – Martin

+0

Я пропустил что-то, что мне пришлось пересмотреть старые ответы/комментарии. Итак ... у вас [есть свой ответ] (https://stackoverflow.com/questions/42050924/how-can-i-write-less-code-with-bindparam/42051086#comment79705335_42052445) о том, почему. (Некоторое спортивное поведение на @yourcommensense будет оценено) – Xorifelse

0

Xorifelse уже mede эту тему ясно, поэтому я могу сделать только небольшое дополнение. в PHP вы всегда можете найти нечетную функцию, которая может помочь вам сделать что-то экстравагантное.

Так что, если вы предпочитаете использовать именованные заполнители, вы можете держать с ними, но по-прежнему использовать ярлык с Execute():

$stmt = $con->prepare("INSERT INTO table (crips, biscuits, chocolate, cakes, smarties, yogurts, apples, oranges) VALUES (:crisps, :biscuits, :chocolate, :cakes, :smarties, :yogurts, :apples, :oranges)"); 
$stmt->execute(compact('crisps', 'biscuits', 'chocolate', 'cakes', 'smarties', 'yogurts', 'apples', 'oranges')); 

Но лично я предпочел бы позиционные заполнителей.

+0

Я не уверен, почему это получило пониженное голосование, 'extract()' с флагом 'EXTR_REFS' и' compact() 'идут рука об руку. Его можно отлично использовать с bindParam(). – Xorifelse