Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Right, I'm banging my head against a wall here. I'm sure it's something incredibly simple but I keep getting undefined index errors on all of these variables.

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>Genus:</label>
<input name="genus" value="<?php if(isset($genus)) { echo $genus; } ?>" />
<label>Species:</label>
<input name="species" value="<?php if(isset($species)) { echo $species; } ?>" />
<p><label>Etymology:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology)) { echo $etymology; } ?></textarea></p>
<label>Family:</label>
<input name="family" value="<?php if(isset($family)) { echo $family; } ?>" />
<label>Common Names:</label>
<input name="common_names" value="<?php if(isset($common_names)) { echo $common_names; } ?>" />
    <?php
}

I get this for every variable:

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

Any ideas?

share|improve this question
    
which line of code is line 207? –  Brady Jun 23 '11 at 10:24
    
$genus = $custom["genus"][0]; –  dunc Jun 23 '11 at 11:25
add comment

3 Answers 3

up vote 5 down vote accepted

It's a common PHP error, usually when you try to access an array member with a non-existent key;

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

You should check for the key first with isset( $array['foobar'] );

UPDATE: In this case, I would chuck in a loop that sets-up the variables for you, checking for the index in the process.

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

echo $genus; // prints value of $custom['genus'][0] if set, otherwise empty
share|improve this answer
    
Are you suggesting I use isset on every line, such as (pseudo) isset($custom[genus]) > $genus=$custom[genus]? Surely that's a hellishly long-winded way of doing things. I was under the impression (and this is the first time I've encountered this problem) that using isset on $post then also $custom would mean that those variables aren't set/don't exist unless there is data in $post? –  dunc Jun 23 '11 at 11:25
1  
Not at all - but either way, you should never assume X exists. See my updated answer :) –  TheDeadMedic Jun 23 '11 at 11:52
    
Fantastic, thanks buddy. –  dunc Jun 23 '11 at 12:52
add comment

You are already calling isset() each time you are printing the data to the screen.

Why not just skip this part:

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];
}

and do this when you print an input:

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

The extra variable assignments are not needed and are causing notices to be generated here.

BTW ...

You need to escape your output before it is printed in a form:

<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 ); } ?>" />
share|improve this answer
    
Yeah, I don't bother escaping until I've got working code.. :) I did contemplate doing it the way you've suggested, but I'm a bit of a code-aesthetics freak and dear Lord that looks ugly! Thank you. –  dunc Jun 23 '11 at 13:32
1  
I guess we are different then ... I don't bother printing to the screen unless I the data is escaped and I never introduce unnecessary complexity make code look "pretty". –  mfields Jun 23 '11 at 13:39
1  
LOL! IMHO I think hacked sites with pharmaceutical links in the footer are uglier than that code. ;) –  John P Bloch Jun 23 '11 at 13:45
    
Don't get hung up on $custom["genus"][0] being "uglier" than $genus. @mfields' code is otherwise exactly the same as yours, but it won't return an error. Write as much code as you need to in order to get a job done, no more, no less. –  EAMann Jun 23 '11 at 14:12
    
Heh, as EAMann points out, it isn't the escaping that I see as ugly - it's $custom["genus"][0] rather than $genus that I was referring to. I'm most certainly not suggesting that I wouldn't escape data because it made it ugly.. :) –  dunc Jun 23 '11 at 14:41
add comment

An alternative, which has come out of a Twitter discussion on this post, is to change how you're getting your data. get_post_custom() returns an array of arrays and is what's causing you headaches. I would recommend using get_post_custom_values() instead:

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>Genus:</label>
<input name="genus" value="<?php if(isset($genus[0])) { echo esc_attr( $genus[0] ); } ?>" />
<label>Species:</label>
<input name="species" value="<?php if(isset($species[0])) { echo esc_attr( $species ); } ?>" />
<p><label>Etymology:</label><br />
<textarea cols="50" rows="5" name="etymology"><?php if(isset($etymology[0])) { echo esc_attr( $etymology ); } ?></textarea></p>
<label>Family:</label>
<input name="family" value="<?php if(isset($family[0])) { echo esc_attr( $family ); } ?>" />
<label>Common Names:</label>
<input name="common_names" value="<?php if(isset($common_names[0])) { echo esc_attr( $common_names ); } ?>" />
    <?php
}

A better alternative to custom values would be to use custom meta. You can define these as unique, then when you get the custom meta back out of the DB you'll have one value rather than an indexed array with only one member. Just something to consider.

share|improve this answer
    
Thanks EAMann. I'll research custom values/meta when I get home then contemplate that approach. –  dunc Jun 23 '11 at 14:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.