Perché ricevo errori "undefined_index" in PHP? Risoluzione

23 giu 2011, 13:14:20
Visualizzazioni: 19.2K
Voti: 4

Ok, mi sto sbattendo la testa contro il muro qui. Sono sicuro che sia qualcosa di incredibilmente semplice, ma continuo a ricevere errori di indice non definito per tutte queste variabili.

function meta_genus_species() {
    global $post;

    // Verifica se il post è settato
    if (isset($post)) {
        $custom = get_post_custom($post->ID);
    }

    // Verifica se $custom è settato e contiene i campi richiesti
    if (isset($custom)) {
        $genus = $custom["genus"][0];
        $species = $custom["species"][0];
        $etymology = $custom["etymology"][0];
        $family = $custom["family"][0];
        $common_names = $custom["common_names"][0];
    }

    ?>
<label>Genere:</label>
<input name="genus" value="<?php if(isset($genus)) { echo $genus; } ?>" />
<label>Specie:</label>
<input name="species" value="<?php if(isset($species)) { echo $species; } ?>" />
<p><label>Etimologia:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology)) { echo $etymology; } ?></textarea></p>
<label>Famiglia:</label>
<input name="family" value="<?php if(isset($family)) { echo $family; } ?>" />
<label>Nomi comuni:</label>
<input name="common_names" value="<?php if(isset($common_names)) { echo $common_names; } ?>" />
    <?php
}

Ricevo questo errore per ogni variabile:

Notice: Undefined index: genus in [...]sf-species-profiles.php on line 207

Qualche idea?

2
Commenti

quale riga di codice è la riga 207?

Scott Scott
23 giu 2011 13:24:10

$genus = $custom["genus"][0];

turbonerd turbonerd
23 giu 2011 14:25:26
Tutte le risposte alla domanda 3
2

È un errore comune in PHP, che si verifica solitamente quando si tenta di accedere a un elemento di un array con una chiave inesistente:

$array = array( 'hello' => 'world' );
echo $array['foobar']; // indice non definito

Dovresti prima verificare l'esistenza della chiave con isset( $array['foobar'] );

AGGIORNAMENTO: In questo caso, inserirei un ciclo che imposta le variabili automaticamente, verificando nel contempo l'esistenza dell'indice.

foreach ( array( 'genus', 'species', 'etymology', 'family', 'common_names' ) as $var )
    $$var = isset( $custom[ $var ][0] ) ? $custom[ $var ][0] : '';

echo $genus; // stampa il valore di $custom['genus'][0] se impostato, altrimenti una stringa vuota
23 giu 2011 13:23:26
Commenti

Stai suggerendo di usare isset su ogni riga, tipo (pseudo) isset($custom[genus]) > $genus=$custom[genus]? Di sicuro è un modo terribilmente prolisso di fare le cose. Avevo l'impressione (ed è la prima volta che incontro questo problema) che usando isset su $post e poi anche su $custom significasse che quelle variabili non sono impostate/non esistono a meno che non ci siano dati in $post?

turbonerd turbonerd
23 giu 2011 14:25:12

Nient'affatto - ma in ogni caso, non dovresti mai dare per scontato che X esista. Vedi la mia risposta aggiornata :)

TheDeadMedic TheDeadMedic
23 giu 2011 14:52:54
5

Stai già chiamando isset() ogni volta che stampi i dati sullo schermo.

Perché non saltare direttamente questa parte:

if (isset($custom)) {
    $genus = $custom["genus"][0];
    $species = $custom["species"][0];
    $etymology = $custom["etymology"][0];
    $family = $custom["family"][0];
    $common_names = $custom["common_names"][0];
}

e fare così quando stampi un input:

<label>Genere:</label>
<input name="genus" value="<?php if( isset( $custom["genus"][0] ) ) { print $custom["genus"][0]; } ?>" />

Le assegnazioni extra di variabili non sono necessarie e stanno causando la generazione di notice qui.

A proposito...

Devi eseguire l'escape dell'output prima che venga stampato in un form:

<label>Genere:</label>
<input name="genus" value="<?php if(isset($genus)) { echo esc_attr( $genus ); } ?>" />
<label>Specie:</label>
<input name="species" value="<?php if(isset($species)) { echo esc_attr( $species ); } ?>" />
<p><label>Etimologia:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology)) { echo esc_textarea( $etymology ); } ?></textarea></p>
<label>Famiglia:</label>
<input name="family" value="<?php if(isset($family)) { echo esc_attr( $family ); } ?>" />
<label>Nomi comuni:</label>
<input name="common_names" value="<?php if(isset($common_names)) { echo esc_attr( $common_names ); } ?>" />
23 giu 2011 15:58:16
Commenti

Sì, di solito non mi preoccupo di fare l'escape finché non ho del codice funzionante.. :) Avevo pensato di farlo nel modo che hai suggerito, ma sono un po' maniacale dell'estetica del codice e, santo cielo, che brutto che è! Grazie.

turbonerd turbonerd
23 giu 2011 16:32:00

Immagino che siamo diversi allora... Io non mi preoccupo di stampare a schermo a meno che i dati non siano protetti e non introduco mai complessità inutili per far sembrare il codice "carino".

mfields mfields
23 giu 2011 16:39:22

LOL! IMHO penso che i siti hackerati con link farmaceutici nel footer siano più brutti di quel codice. ;)

John P Bloch John P Bloch
23 giu 2011 16:45:33

Non fissarti sul fatto che $custom["genus"][0] sia "meno elegante" di $genus. Il codice di @mfields è altrimenti esattamente uguale al tuo, ma non restituirà un errore. Scrivi tutto il codice che ti serve per portare a termine un lavoro, niente di più, niente di meno.

EAMann EAMann
23 giu 2011 17:12:50

Eh, come sottolinea EAMann, non è l'escape che vedo come poco elegante - mi riferivo a $custom["genus"][0] piuttosto che a $genus. Di certo non sto suggerendo che non farei l'escape dei dati perché li rende meno eleganti.. :)

turbonerd turbonerd
23 giu 2011 17:41:38
1

Un'alternativa, emersa da una discussione su Twitter riguardo a questo post, è cambiare il modo in cui ottieni i tuoi dati. get_post_custom() restituisce un array di array ed è ciò che ti sta causando problemi. Consiglierei invece di usare get_post_custom_values():

function meta_genus_species() {
    global $post;

    $genus = get_post_custom_values( 'genus', $post->ID );
    $species = get_post_custom_values( 'species', $post->ID );
    $etymology = get_post_custom_values( 'etymology', $post->ID );
    $family = get_post_custom_values( 'family', $post->ID );
    $common_names = get_post_custom_values( 'common_names', $post->ID );

    ?>
<label>Genere:</label>
<input name="genus" value="<?php if(isset($genus[0])) { echo esc_attr( $genus[0] ); } ?>" />
<label>Specie:</label>
<input name="species" value="<?php if(isset($species[0])) { echo esc_attr( $species ); } ?>" />
<p><label>Etimologia:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology[0])) { echo esc_attr( $etymology ); } ?></textarea></p>
<label>Famiglia:</label>
<input name="family" value="<?php if(isset($family[0])) { echo esc_attr( $family ); } ?>" />
<label>Nomi comuni:</label>
<input name="common_names" value="<?php if(isset($common_names[0])) { echo esc_attr( $common_names ); } ?>" />
    <?php
}

Un'alternativa migliore ai valori personalizzati sarebbe usare i meta personalizzati. Puoi definirli come unici, così quando recuperi i meta personalizzati dal database avrai un singolo valore invece di un array indicizzato con un solo membro. Solo qualcosa da considerare.

23 giu 2011 17:10:00
Commenti

Grazie EAMann. Ricercherò i valori personalizzati/meta quando sarò a casa e poi valuterò questo approccio.

turbonerd turbonerd
23 giu 2011 17:43:02