Problema con l'archiviazione di array usando update_user_meta

29 mar 2011, 07:50:39
Visualizzazioni: 15K
Voti: 5

Sto scrivendo una funzione che aggiunge un numero ID a un array e inserisce l'array nei usermeta. $_GET['auction'] è il post_id.

Ecco la funzione:

$reminders = get_user_meta( $current_user->ID, "reminders" );
print_r( $reminders );
if( in_array( $_GET['auction'], $reminders ) ) {
    echo "Errore: Asta già presente nella lista";
} else {
    array_push( $reminders, intval( $_GET['auction'] ) );
    if ( update_user_meta( $current_user->ID, "reminders", $reminders ) ) {
        echo "Successo";
    } else {
        echo "Errore: Impossibile aggiornare i metadati utente";
    }
}
print_r( $reminders );

Ecco l'output dopo aver aggiunto un'asta:

Array ( ) 
Successo
Array ( [0] => 7 ) 

Ecco l'output dopo aver aggiunto due aste:

Array ( [0] => Array ( [0] => 7 ) ) 
Successo
Array ( [0] => Array ( [0] => 7 ) [1] => 73 )

Ecco l'output dopo aver aggiunto tre aste:

Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) ) 
Successo
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) [1] => 0 )

Nota che aggiungere un nuovo elemento all'array usando array_push funziona correttamente. Ma quando l'array viene archiviato nei usermeta e poi recuperato nuovamente, l'ultimo elemento nell'array viene inserito in un array a sé stante, creando un array a dimensioni infinite. Preferirei mantenere questo array monodimensionale.

Esiste un modo per utilizzare update_user_meta e get_user_meta senza che modifichino la struttura del mio array?

0
Tutte le risposte alla domanda 5
0

Ho avuto lo stesso problema. Aggiungere "true" a "get_user_meta" ha funzionato per me. Ad esempio:

DA:

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

A:

$reminders = get_user_meta($current_user->ID,"reminders",true);
30 ott 2011 03:15:44
0

Ho avuto lo stesso problema e l'ho risolto con questo piccolo snippet, che inserisce tutti i nuovi valori in un singolo array salvato come metadato dell'utente:

//Dove $access_key è il valore successivo (aggiunto)

$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');//Svuota i metadati...
update_user_meta( $user_id, 'wsm_capability', $new_access_keys);

Array prima del salvataggio/aggiornamento per la meta key (da get_user_meta):

Array
(
    [0] => access_9
)

Array risultante (dopo l'aggiornamento dei metadati) aggiungendo il valore 'access_5':

Array
(
    [0] => access_5
    [1] => access_9
)

Se hai bisogno che il nuovo valore venga aggiunto alla fine dell'array, fai invece così:

//Dove $access_key è il valore successivo (aggiunto)    
$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;

Poi aggiorna i metadati...

Bryan

25 feb 2012 02:38:03
2

Non ho utilizzato la funzione per un bel po' di tempo, ma immagino che il tuo problema sia che stai inserendo un array in un array. Quindi controlla se intval($_GET['auction']) è un array:

echo '<pre>';
print_r(intval($_GET['auction']));
echo '</pre>';

Modifica #1: Potresti dover ottenere il valore da quell'array e poi inserirlo con array_push. Quindi qualcosa come array_push( $reminders, $_GET['auction'][0]) ); - se stai aggiungendo solo un singolo valore. Potresti anche fare qualcosa come $reminders[] = $_GET['auction'][0]; per aggiungerlo alla fine del tuo array.

Modifica #2: Dando un'occhiata al file core: sì. update_user_meta() è solo un alias di update_metadata() che prende l'ID + il valore e lo inserisce nel database come array.

// Da /wp-includes/meta.php ~ riga 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 mar 2011 16:13:30
Commenti

var_dump($_GET['auction']) mostra: string(1) "7". Sembra che update_user_meta serializzi automaticamente i dati. Potrebbe questo causare un problema?

Jarred Jarred
29 mar 2011 19:40:46

Vedi Modifica #2 ... :)

kaiser kaiser
29 mar 2011 19:46:08
1

Sembrava che il problema fosse con la serializzazione/desserializzazione dell'array, quindi ho semplicemente riscritto la funzione per utilizzare una stringa separata da virgole:

        $reminders = get_user_meta($current_user->ID,"reminders",TRUE);
        if(is_int(strpos($reminders,$_GET['auction']))) {
            echo "Errore: L'asta è già presente nella lista";
        } else {
            $reminders .= ",".intval($_GET['auction']);
            if(substr($reminders,0,1) == ",") { //Rimuove la virgola iniziale se esiste
                $reminders = substr($reminders,1,strlen($reminders)-1);
            }
            if(update_user_meta($current_user->ID,"reminders",$reminders)) {
                echo "Successo";
            } else {
                echo "Errore: Impossibile aggiornare i metadati utente";
            }
        }
29 mar 2011 20:13:51
Commenti

Ciao @Jarred, alla fine hai risolto? Ho un'esigenza simile per il mio sito web. Ho delle opzioni di checkbox nei metadati utente (un array) che devo aggiornare per ogni utente (più di 1500 utenti). E ho bisogno di un modo per aggiornare ogni utente, assegnando loro selezioni diverse, ma su larga scala. La nostra soluzione sembra possa funzionare, ma non sono sicuro di come implementare la scelta di opzioni diverse per ogni singolo utente. Vorrei lavorare con il tuo esempio, ma ho bisogno di aiuto per personalizzarlo in base alla mia necessità, che sarebbe fare selezioni uniche per ogni utente e poi aggiornare.

user1893 user1893
21 ott 2011 19:17:34
0

La risposta di Shaun era corretta ma sento che necessita di maggiori chiarimenti. Puoi inserire un array in una voce di meta utente, ma quando lo recuperi devi comunque recuperarlo con l'argomento single impostato su true altrimenti otterrai un array di array. Ecco il mio codice:

$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);

//verifica se questo nuovo ordine è già stato processato
if(in_array($_GET["oid"], $past_orders))
{
     echo '<p>Questo ordine è già stato processato.</p>';
    //debug
    //var_dump($past_orders);   
}
else
{
      //aggiungi il numero dell'ordine all'array degli ordini passati e memorizzalo
     //se la lista è vuota, inizializzala come array vuoto
     if($past_orders == '')
     {
        $past_orders = array();
     }
     //aggiungi il nuovo ordine alla lista
    array_push($past_orders, $_GET["oid"]);

    //aggiungi la nuova lista al DB
    update_user_meta($order_userID, 'qr-replacement-orders', $past_orders);

    echo '<p>La tua carta è stata acquistata e ti verrà inviata via posta. Grazie!</p>';                       

    //debug: conferma che ha funzionato
    //$past_orders = get_user_meta($order_userID, 'qr-replacement-orders', true);
    //var_dump($past_orders);   
}
8 mar 2012 22:35:57