Проблема с сохранением массивов через update_user_meta

29 мар. 2011 г., 07:50:39
Просмотры: 15K
Голосов: 5

Я пишу функцию, которая добавляет 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 без изменения структуры массива?

0
Все ответы на вопрос 5
0

У меня была такая же проблема. Добавление "true" к "get_user_meta" помогло. Например:

БЫЛО:

$reminders = get_user_meta($current_user->ID,"reminders");

СТАЛО:

$reminders = get_user_meta($current_user->ID,"reminders",true);
30 окт. 2011 г. 03:15:44
0

У меня была такая же проблема, и я решил её с помощью этого небольшого кода, который помещает все новые значения в один массив, сохраняемый как метаданные пользователя:

//Где $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;

Затем обновите метаданные...

Брайан

25 февр. 2012 г. 02:38:03
2

Давно не использовал эту функцию, но, думаю, твоя проблема в том, что ты добавляешь массив в массив. Так что проверь, является ли 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;
}
29 мар. 2011 г. 16:13:30
Комментарии

var_dump($_GET['auction']) выводит: string(1) "7". Похоже, что update_user_meta автоматически сериализует данные. Может ли это вызывать проблему?

Jarred Jarred
29 мар. 2011 г. 19:40:46

Смотрите Исправление #2 ... :)

kaiser kaiser
29 мар. 2011 г. 19:46:08
1

Похоже, проблема была в сериализации/десериализации массива, поэтому я переписал функцию, используя строку с разделителями-запятыми:

        $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 "Ошибка: Не удалось обновить метаданные пользователя";
            }
        }
29 мар. 2011 г. 20:13:51
Комментарии

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

user1893 user1893
21 окт. 2011 г. 19:17:34
0

Ответ Шона был правильным, но, по моему мнению, требует дополнительных пояснений. Вы можете поместить массив в запись пользовательских метаданных, но при его извлечении вам все равно нужно извлекать его с параметром 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);   
}
8 мар. 2012 г. 22:35:57