De ce primesc erori "undefined_index" în WordPress?

23 iun. 2011, 13:14:20
Vizualizări: 19.2K
Voturi: 4

Bună, mă lovesc de aceeași problemă și nu înțeleg de ce. Sigur e ceva simplu, dar continuu să primesc erori de index nedefinit pentru toate aceste variabile.

function meta_genus_species() {
    global $post;

    if (isset($post)) {
        $custom = get_post_custom($post->ID);
    }

    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>Gen:</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>Etimologie:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology)) { echo $etymology; } ?></textarea></p>
<label>Familie:</label>
<input name="family" value="<?php if(isset($family)) { echo $family; } ?>" />
<label>Denumiri comune:</label>
<input name="common_names" value="<?php if(isset($common_names)) { echo $common_names; } ?>" />
    <?php
}

Primesc această eroare pentru fiecare variabilă:

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

Idei?

2
Comentarii

care linie de cod este linia 207?

Scott Scott
23 iun. 2011 13:24:10

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

turbonerd turbonerd
23 iun. 2011 14:25:26
Toate răspunsurile la întrebare 3
2

Este o eroare comună în PHP, care apare de obicei când încerci să accesezi un element dintr-un array folosind o cheie inexistentă;

$array = array( 'hello' => 'world' );
echo $array['foobar']; // index nedefinit

Ar trebui să verifici mai întâi existența cheii folosind isset( $array['foobar'] );

ACTUALIZARE: În acest caz, aș folosi o buclă care să inițializeze variabilele pentru tine, verificând în același timp existența indexului.

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

echo $genus; // afișează valoarea lui $custom['genus'][0] dacă există, altfel un șir gol
23 iun. 2011 13:23:26
Comentarii

Sugerezi să folosesc isset pe fiecare linie, gen (pseudo) isset($custom[genus]) > $genus=$custom[genus]? Sigur, asta e un mod infernal de complicat de a face lucrurile. Am crezut (și asta e prima dată când întâlnesc această problemă) că folosirea isset pe $post și apoi pe $custom ar însemna că acele variabile nu sunt setate/nu există dacă nu există date în $post?

turbonerd turbonerd
23 iun. 2011 14:25:12

Deloc - dar în orice caz, nu ar trebui niciodată să presupui că X există. Vezi răspunsul meu actualizat :)

TheDeadMedic TheDeadMedic
23 iun. 2011 14:52:54
5

Deja apelezi isset() de fiecare dată când afișezi datele pe ecran.

De ce să nu sări peste această 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];
}

și să faci asta când afișezi un input:

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

Atribuirile suplimentare de variabile nu sunt necesare și generează notificări aici.

Apropo...

Trebuie să-ți escape output-ul înainte de a-l afișa într-un formular:

<label>Genus:</label>
<input name="genus" value="<?php if(isset($genus)) { echo esc_attr( $genus ); } ?>" />
<label>Species:</label>
<input name="species" value="<?php if(isset($species)) { echo esc_attr( $species ); } ?>" />
<p><label>Etymology:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology)) { echo esc_textarea( $etymology ); } ?></textarea></p>
<label>Family:</label>
<input name="family" value="<?php if(isset($family)) { echo esc_attr( $family ); } ?>" />
<label>Common Names:</label>
<input name="common_names" value="<?php if(isset($common_names)) { echo esc_attr( $common_names ); } ?>" />
23 iun. 2011 15:58:16
Comentarii

Da, nu mă deranjează să scăp de escapare până nu am codul funcțional.. :) M-am gândit să o fac așa cum ai sugerat, dar sunt un pic obsedat de estetica codului și, Doamne iartă-mă, ce urât arată! Mulțumesc.

turbonerd turbonerd
23 iun. 2011 16:32:00

Presupun că suntem diferiți atunci... Nu mă deranjează să afișez pe ecran decât dacă datele sunt escapare și nu introduc niciodată complexitate inutilă doar pentru a face codul să arate "frumos".

mfields mfields
23 iun. 2011 16:39:22

LOL! IMO cred că site-urile hack-uite cu linkuri farmaceutice în subsol sunt mai urâte decât acel cod. ;)

John P Bloch John P Bloch
23 iun. 2011 16:45:33

Nu te agăța de faptul că $custom["genus"][0] este "mai urât" decât $genus. Codul lui @mfields este, în rest, exact la fel ca al tău, dar nu va returna o eroare. Scrie cât cod ai nevoie pentru a-ți face treaba, nu mai mult, nu mai puțin.

EAMann EAMann
23 iun. 2011 17:12:50

Heh, după cum subliniază EAMann, nu escaparea o văd ca fiind urâtă - mă refeream la $custom["genus"][0] în loc de $genus. Cu siguranță nu sugerez că nu aș escapa datele pentru că le-ar face mai urâte.. :)

turbonerd turbonerd
23 iun. 2011 17:41:38
1

O alternativă, care a ieșit dintr-o discuție pe Twitter legată de acest articol, este să schimbați modul în care obțineți datele. get_post_custom() returnează un array de array-uri și este ceea ce vă cauzează probleme. Aș recomanda să folosiți în schimb 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>Genul:</label>
<input name="genus" value="<?php if(isset($genus[0])) { echo esc_attr( $genus[0] ); } ?>" />
<label>Specia:</label>
<input name="species" value="<?php if(isset($species[0])) { echo esc_attr( $species ); } ?>" />
<p><label>Etimologie:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology[0])) { echo esc_attr( $etymology ); } ?></textarea></p>
<label>Familia:</label>
<input name="family" value="<?php if(isset($family[0])) { echo esc_attr( $family ); } ?>" />
<label>Denumiri comune:</label>
<input name="common_names" value="<?php if(isset($common_names[0])) { echo esc_attr( $common_names ); } ?>" />
    <?php
}

O alternativă mai bună la valorile personalizate ar fi utilizarea meta datelor personalizate. Puteți defini acestea ca fiind unice, astfel încât atunci când extrageți meta datele din baza de date, veți obține o singură valoare în loc de un array indexat cu un singur membru. Doar ceva de luat în considerare.

23 iun. 2011 17:10:00
Comentarii

Mulțumesc EAMann. Voi cerceta valorile personalizate/meta când ajung acasă și apoi voi analiza această abordare.

turbonerd turbonerd
23 iun. 2011 17:43:02