wpdb->insert - множественная вставка записей за один раз
После создания таблицы 'settings-table' мне нужно добавить в неё несколько записей.
Вот как я делаю это сейчас, но это не лучший способ, поэтому мне нужен более эффективный метод, так как я буду добавлять больше записей в таблицу.
ПРИМЕР 1
$wpdb->insert('settings-table', array('option_name' => 'name-1',
'option_value' => 'val-1',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-1'
));
$wpdb->insert('settings-table', array('option_name' => 'name-2',
'option_value' => 'val-2',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-2'
));
$wpdb->insert('settings-table', array('option_name' => 'name-1',
'option_value' => 'val-3',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-3'
ОБНОВЛЕНИЕ
Этот вариант работает (приветствуются любые другие лучшие решения)
$wpdb->query("INSERT INTO settings-table
(`option_name`, `option_value`, `option_created`, `option_edit`, `option_user`)
VALUES
('name-1', 'val-1', current_time('mysql'), current_time('mysql'), 'user-1'),
('name-2', 'val-2', current_time('mysql'), current_time('mysql'), 'user-2'),
('name-3', 'val-3', current_time('mysql'), current_time('mysql'), 'user-3')")

$wpdb->query("INSERT INTO settings-table
(option_name, option_value, option_created, option_edit, option_user)
VALUES
('name-1', 'val-1', current_time('mysql'), current_time('mysql'), 'user-1'),
('name-2', 'val-2', current_time('mysql'), current_time('mysql'), 'user-2'),
('name-3', 'val-3', current_time('mysql'), current_time('mysql'), 'user-3')")
В запросе, который вы опубликовали, имена столбцов не должны быть заключены в кавычки.

Функция $wpdb->insert не поддерживает вставку нескольких записей за один вызов. Вам нужно перебрать данные, подготовить их для вставки и затем использовать $wpdb->insert в цикле, вставляя записи по одной.
Вместо этого мы можем подготовить INSERT-запрос следующим образом и выполнить его всего один раз.
Например, если нужно вставить 100 записей, при использовании $wpdb->insert потребуется выполнить 100 INSERT-запросов. Если же использовать приведённый ниже код, потребуется выполнить всего 1 INSERT-запрос.
Надеюсь, это поможет.
function do_insert($place_holders, $values) {
global $wpdb;
$query = "INSERT INTO settings-table (`option_name`, `option_value`, `option_created`, `option_edit`, `option_user`) VALUES ";
$query .= implode( ', ', $place_holders );
$sql = $wpdb->prepare( "$query ", $values );
if ( $wpdb->query( $sql ) ) {
return true;
} else {
return false;
}
}
$data_to_be_inserted = array( array(
'option_name' => 'name-1',
'option_value' => 'val-1',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-1'
),
array(
'option_name' => 'name-2',
'option_value' => 'val-2',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-2'
),
array(
'option_name' => 'name-1',
'option_value' => 'val-3',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-3'
));
$values = $place_holders = array();
if(count($data_to_be_inserted) > 0) {
foreach($data_to_be_inserted as $data) {
array_push( $values, $data['option_name'], $data['option_value'], $data['option_created'], $data['option_edit'], $data['option_user']);
$place_holders[] = "( %s, %s, %s, %s, %s)";
}
do_insert( $place_holders, $values );
}

Я разработал это решение, которое расширяет класс wpdb
, чтобы использовать его внутренние функции обработки данных:
<?php
class wpdbx extends wpdb {
public function __construct() {
parent::__construct(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
}
public function insert_multiple($table, $data, $format = null) {
$this->insert_id = 0;
$formats = array();
$values = array();
foreach ($data as $index => $row) {
$row = $this->process_fields($table, $row, $format);
$row_formats = array();
if ($row === false || array_keys($data[$index]) !== array_keys($data[0])) {
continue;
}
foreach($row as $col => $value) {
if (is_null($value['value'])) {
$row_formats[] = 'NULL';
} else {
$row_formats[] = $value['format'];
}
$values[] = $value['value'];
}
$formats[] = '(' . implode(', ', $row_formats) . ')';
}
$fields = '`' . implode('`, `', array_keys($data[0])) . '`';
$formats = implode(', ', $formats);
$sql = "INSERT INTO `$table` ($fields) VALUES $formats";
$this->check_current_query = false;
return $this->query($this->prepare($sql, $values));
}
}
global $wpdbx;
$wpdbx = new wpdbx();
?>
Затем вы можете использовать это следующим образом:
<?php
global $wpdbx;
$results = $wpdbx->insert_multiple(
'settings-table',
array(
array(
'option_name' => 'name-1',
'option_value' => 'val-1',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-1'
),
array(
'option_name' => 'name-2',
'option_value' => 'val-2',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-2'
),
array(
'option_name' => 'name-1',
'option_value' => 'val-3',
'option_created'=> current_time('mysql'),
'option_edit' => current_time('mysql'),
'option_user' => 'user-3'
)
)
);
?>

Это также будет работать
$nameArray = array("name-1", "name-2", "name-3");
$valueArray = array("val-1", "val-2" , "val-3");
$userArray = array("user-1" , "user-2", "user-3");
$maxRow= count($nameArray); // можно использовать count любого массива
$setting_values = array();
$time = current_time('mysql');
for($x=0;$x<$maxRow; $x++){
$SettingContext = [
'option_name' => "'" . $nameArray[$x] . "'",
'option_value' => "'" . $valueArray[$x] . "'",
'option_created' => "'" . $time . "'",
'option_edit' => "'" . $time . "'",
'option_user' => "'" . $userArray[$x] . "'"
];
$setting_values[] = "(" . implode(',', $SettingContext) . ")";
}
$settingSubmit = implode(',', $setting_values);
$setting_save = $wpdb->query("
INSERT INTO setting
(option_name, option_value, option_created,option_edit, option_user)
VALUES " . $settingSubmit
);
