Как использовать $wpdb->insert для вставки нескольких строк
Как использовать $wpdb->insert
для вставки нескольких строк. Вот мой код:
for($i=0; $i<=$urlCount; $i++) {
$stat = $wpdb->insert(
'WP_URLS',
array(
'POSTID' => $post->ID,
'URL' => $_POST['url'.$i]
)
);
}
Этот код работает только для первой вставки (т.е. когда $i = 0
, когда значение равно url_0
). Иногда количество URL может быть больше 100, а иногда равно нулю. Поэтому вместо написания кода 100 раз, я просто хочу иметь простой цикл, который будет работать для любого количества записей. Вот почему я выбрал цикл.
Спасибо за помощь.
Структура таблицы:
CREATE TABLE WP_URLS (
POSTID BIGINT NOT NULL,
URL VARCHAR(254)
);

Полагаю, проблема довольно простая. Вы не показали весь код, но я предполагаю, что проблема в том, что вы сохраняете вставку по какой-то неизвестной причине как string
в переменную с именем $stat
. Каждый раз, когда вы заполняете переменную новым запросом, вы перезаписываете её. Вместо этого вам следует использовать $stat .= $wpdb->insert( ...и т.д... )
, чтобы дополнять строку. Не забудьте установить переменную в пустую строку перед циклом, чтобы можно было дополнять: $stat = ''
.
Другой — на мой взгляд, лучший — способ заключается в использовании массива. Причина: так легче отлаживать код. И, пожалуйста, прочтите комментарий в коде.
$stats = array();
for( $i = 0; $i <= $urlCount; $i++ )
{
$stats[] = array(
'POSTID' => $post->ID,
// вы действительно получаете **ВСЕ** свои URL как "url1", "url2" и т.д.
// через форму, отправленную методом $_POST?
'URL' => filter_var(
$_POST["url{$i}"],
FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED
)
);
}
foreach ( $stats as $stat )
$wpdb->insert( 'WP_URLS', $stat );

Хотя есть принятый ответ, он работает с отдельными запросами для каждой вставки.
Это может быть лучшее решение для вставки данных всего одним запросом:
<?php
/**
* Метод для вставки нескольких строк в указанную таблицу
*
* Пример использования:
*
* $insert_arrays = array();
* foreach($assets as $asset) {
*
* $insert_arrays[] = array(
* 'type' => "multiple_row_insert",
* 'status' => 1,
* 'name'=>$asset,
* 'added_date' => current_time( 'mysql' ),
* 'last_update' => current_time( 'mysql' ));
*
* }
*
* wp_insert_rows($insert_arrays);
*
*
* @param array $row_arrays
* @param string $wp_table_name
* @return false|int
*
* @author Ugur Mirza ZEYREK
* @source http://stackoverflow.com/a/12374838/1194797
*/
function wp_insert_rows($row_arrays = array(), $wp_table_name) {
global $wpdb;
$wp_table_name = esc_sql($wp_table_name);
// Создаем массивы для реальных значений и плейсхолдеров
$place_holders = [];
$row = implode(', ', array_keys($row_arrays));
$values = array_values($row_arrays);
foreach (array_values($row_arrays) as $key => $param) {
if(is_numeric($param)) {
if($key == 0){
array_push($place_holders, " '%d'");
} else {
array_push($place_holders, ", '%d'");
}
} else {
if($key == 0){
array_push($place_holders, " '%s'");
} else {
array_push($place_holders, ", '%s'");
}
}
}
$params = implode('', $place_holders);
$query = "INSERT INTO {$wp_table_name} (" . $row . ") VALUES (" . $params . ")";
if($wpdb->query($wpdb->prepare($query, $values))){
return true;
} else {
return false;
}
}

Я бы предложил поменять порядок аргументов и поставить неявно требуемый аргумент первым: $table_name
. Также в большинстве случаев можно напрямую использовать $wpdb->table_name
. Кроме того, с точки зрения читаемости, возможно, стоит разместить INSERT INTO {$wp_table_name} (
после цикла foreach
, чтобы было понятно, что происходит в каком порядке (цикл, строки запроса, построение массива VALUES
, затем присваивание и вставка. Что касается аргументов prinft
: Существует больше, чем просто string/int. Также могут возникнуть проблемы с нестандартными строками и режимом SQL strict
.
