Проблема с сохранением массивов через update_user_meta
Я пишу функцию, которая добавляет ID в массив и сохраняет его в usermeta. $_GET['auction']
содержит post_id
.
Вот сама функция:
$reminders = get_user_meta( $current_user->ID, "reminders" );
print_r( $reminders );
if( in_array( $_GET['auction'], $reminders ) ) {
echo "Ошибка: Аукцион уже в списке";
} else {
array_push( $reminders, intval( $_GET['auction'] ) );
if ( update_user_meta( $current_user->ID, "reminders", $reminders ) ) {
echo "Успешно";
} else {
echo "Ошибка: Не удалось обновить пользовательские метаданные";
}
}
print_r( $reminders );
Результат после добавления первого аукциона:
Array ( )
Успешно
Array ( [0] => 7 )
Результат после добавления второго аукциона:
Array ( [0] => Array ( [0] => 7 ) )
Успешно
Array ( [0] => Array ( [0] => 7 ) [1] => 73 )
Результат после добавления третьего аукциона:
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) )
Успешно
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) [1] => 0 )
Обратите внимание, что добавление нового элемента в массив через array_push
работает корректно. Но когда массив сохраняется в usermeta, а затем извлекается снова, последний элемент помещается в отдельный массив, создавая бесконечномерный массив. Я хотел бы сохранить массив одномерным.
Есть ли способ использовать update_user_meta
и get_user_meta
без изменения структуры массива?

У меня была такая же проблема, и я решил её с помощью этого небольшого кода, который помещает все новые значения в один массив, сохраняемый как метаданные пользователя:
//Где $access_key - следующее (добавляемое) значение
$get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
$current_access_keys = $get_access_keys_from_wp[0];
$new_access_keys = array();
$new_access_keys[]=$access_key;
foreach($current_access_keys as $key => $value){
$new_access_keys[]=$value;
}
delete_user_meta( $user_id, 'wsm_capability');//Очищаем метаданные...
update_user_meta( $user_id, 'wsm_capability', $new_access_keys);
Массив перед сохранением/обновлением для мета-ключа (из get_user_meta):
Array
(
[0] => access_9
)
Результирующий массив (после обновления метаданных) с добавлением значения 'access_5':
Array
(
[0] => access_5
[1] => access_9
)
Если вам нужно добавить новое значение в конец массива, используйте вместо этого:
//Где $access_key - следующее (добавляемое) значение
$get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
$current_access_keys = $get_access_keys_from_wp[0];
$new_access_keys = array();
foreach($current_access_keys as $key => $value){
$new_access_keys[]=$value;
}
$new_access_keys[]=$access_key;
Затем обновите метаданные...
Брайан

Давно не использовал эту функцию, но, думаю, твоя проблема в том, что ты добавляешь массив в массив. Так что проверь, является ли intval($_GET['auction'])
массивом:
echo '<pre>';
print_r(intval($_GET['auction']));
echo '</pre>';
Правка #1: Возможно, тебе нужно получить значение из этого массива, а затем добавить его с помощью array_push. Например, что-то вроде array_push( $reminders, $_GET['auction'][0]) );
— если ты добавляешь только одно значение. Также можно сделать так: $reminders[] = $_GET['auction'][0];
, чтобы добавить его в конец массива.
Правка #2: Судя по коду ядра: да. update_user_meta()
— это просто алиас для update_metadata()
, который принимает ID + значение и сохраняет его в базе данных как массив.
// Из /wp-includes/meta.php ~ строка 135
$where = array( $column => $object_id, 'meta_key' => $meta_key );
if ( !empty( $prev_value ) ) {
$prev_value = maybe_serialize($prev_value);
$where['meta_value'] = $prev_value;
}

Похоже, проблема была в сериализации/десериализации массива, поэтому я переписал функцию, используя строку с разделителями-запятыми:
$reminders = get_user_meta($current_user->ID,"reminders",TRUE);
if(is_int(strpos($reminders,$_GET['auction']))) {
echo "Ошибка: Аукцион уже в списке";
} else {
$reminders .= ",".intval($_GET['auction']);
if(substr($reminders,0,1) == ",") { //Удаляем ведущую запятую, если она есть
$reminders = substr($reminders,1,strlen($reminders)-1);
}
if(update_user_meta($current_user->ID,"reminders",$reminders)) {
echo "Успешно";
} else {
echo "Ошибка: Не удалось обновить метаданные пользователя";
}
}

Привет @Jarred, у тебя в итоге получилось реализовать это? У меня похожая задача для моего сайта. У меня есть пользовательские мета-данные в виде чекбоксов (массив), которые нужно обновить для каждого пользователя (1500+ пользователей). И мне нужен способ массового обновления каждого пользователя, назначая им разные варианты выбора. Ваше решение кажется подходящим, но я не уверен, как реализовать выбор разных опций для каждого отдельного пользователя. Я бы хотел поработать с вашим примером, но мне нужна помощь в адаптации его под мою задачу - сделать уникальный выбор для каждого пользователя и затем обновить.

Ответ Шона был правильным, но, по моему мнению, требует дополнительных пояснений. Вы можете поместить массив в запись пользовательских метаданных, но при его извлечении вам все равно нужно извлекать его с параметром single, установленным в true, иначе вы получите массив массивов. Вот мой код:
$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);
//проверим, был ли уже обработан этот новый заказ
if(in_array($_GET["oid"], $past_orders))
{
echo '<p>Этот заказ уже был обработан.</p>';
//отладка
//var_dump($past_orders);
}
else
{
//добавляем номер заказа в массив прошлых заказов и сохраняем его
//если список пуст, инициализируем его как пустой массив
if($past_orders == '')
{
$past_orders = array();
}
//добавляем новый заказ в список
array_push($past_orders, $_GET["oid"]);
//добавляем новый список в базу данных
update_user_meta($order_userID, 'qr-replacement-orders', $past_orders);
echo '<p>Ваша карта была приобретена и будет отправлена вам по почте. Спасибо!</p>';
//отладка: подтверждение работы
//$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);
//var_dump($past_orders);
}
