PHP: Undefined index even after checking IsSet
Asked Answered
D

3

5

I have read the other questions, none have answered nor helped me.

Here is my issue, I have an object/array which contains a property which is also an object/array.

I have successfully accessed similar properties before via:

$variable[propertyObject][property]

However, I have been receiving the error Notice: Undefined index lately.

Here is the code:

$extensionData = $data['Data'];
echo '<p>' . isset($extensionData['Calories']) ? $extensionData['Calories'] : '' . '</p>';

However, that still throws the same error. Even when I check:

isset($extensionData['Calories']), it always resolves to 1/True which means the property should exist, so how can the index be undefined?

And when I do a var_dump or print_r of $extensionData, this is what I get:

Array
(
    [Calories] => 295
    [WebDesktopImage] => https://clutch-asset-management.s3.amazonaws.com/elevation-burger/IMG_0760-Edit.jpg
    [WebMobileImage] => https://clutch-asset-management.s3.amazonaws.com/elevation-burger/IMG_0760-Edit.jpg
    [WebDescription] => BLT image
)
Dev answered 10/5, 2017 at 18:44 Comment(6)
Put (parentheses) around your ternary operation. It's probably messing things around.Classroom
@NiettheDarkAbsol thanks but that didn't work, worst part is that it passes isset but then suddenly says it's an undefined indexDev
Is this in a loop? Try writing isset($extensionData['Calories']) var_dump($extensionData['Calories']); before the echo statement.Lynd
Instead of trying it inline, I declared a variable at the beginning of the function and that somehow resolved it, very weird.Dev
@Dev Please see my answer belowFe
For future reference, this should help. You already have some answers that show it, but basically it's because . has higher precedence than ?:.Cold
F
12

The ternary expression:

isset($extensionData['Calories']) ? $extensionData['Calories'] : ''

is OK when used stand-alone like this:

echo isset($extensionData['Calories']) ? $extensionData['Calories'] : '';

$tmp_var = isset($extensionData['Calories']) ? $extensionData['Calories'] : '';

return isset($extensionData['Calories']) ? $extensionData['Calories'] : '';

because it is equivalent to the expected:

if(isset($extensionData['Calories']))
{
    // use $extensionData['Calories']
}
else
{
    // use empty string ''
}

but, when used in string concatenation then you need parenthesis in order to confine the scope of the comparison so that the leading string is not part of the comparison

echo '<p>' . (isset($extensionData['Calories']) ? $extensionData['Calories'] : '') . '</p>';

Doing (wrong way):

echo '<p>' . isset($extensionData['Calories']) ? $extensionData['Calories'] : '' . '</p>';

is equivalent to

if('<p>' . isset($extensionData['Calories'])) // The leading string is used in the comparison and the result of isset() (boolean) is appended to the string so 100% of the time this example will be true because of how loose comparisons work
{
    echo $extensionData['Calories']; // Produces Undefined index error
}
else
{
    echo '' . '</p>';
}

In conclusion:

When in doubt, add parenthesis.

When not in doubt, add parenthesis anyways because the code will be more legible when you have to re-visit it in 6 months. Most text editors have parenthesis and bracket match highlighting so adding parenthesis is a very beneficial way to declare and later see the operation's intended behavior.

See Operator Precedence if you come across someone's cryptic code and need help figuring out what on Earth they were thinking and/or failed to consider.

Fe answered 10/5, 2017 at 18:55 Comment(2)
You are a life saver, how come this answer did not get many upvotes ?Starchy
@KhanShahrukh I'm glad you found this useful. As for the upvotes, Stack Overflow works in mysterious ways :-pFe
S
1

The following code will evaluate to True and thus your isset() query is negated:

echo '<p>' . isset($extensionData['Calories'])

This will return True because the string '<p>' is true.

Try this:

echo '<p>' . ( isset($extensionData['Calories']) ? $extensionData['Calories'] : '' ) . '</p>';
Shovelnose answered 10/5, 2017 at 18:56 Comment(0)
A
1

The problems is in your ternary operation. Your isset() with ternary operator is a bitty messy, you're not defining the scope when concatenating with a string. You need to add parenthesis to you ternary operation and isolate the string from the operation. The ifstatement for your code is the same as

if('<p>'. isset($extensionData['Calorie']))
{
   echo $extensionData[´Calorie´];
}
else 
{
  echo ''.'</p>';
}

I reccomend you to put it in a variable in order to organize your code better

$extensionData = $data['Data'];
$varCalorie = (isset($extensionData['Calories']) ? $extensionData['Calories'] : ''); 
echo '<p>'. $varCalorie . '<p/>'; 

The above would be identical to

if (isset($extensionData['Calories'])) {
    $varCalorie = $extensionData['Calories'];
    echo '<p>'. $varCalorie . '<p/>'; 
} else {
    $varCalorie = '';
    echo '<p>'. $varCalorie . '<p/>'; 
}

You can also do

echo isset($extensionData['Calories']) ? $extensionData['Calories'] : '';
return isset($extensionData['Calories']) ? $extensionData['Calories'] : '';
Aixlachapelle answered 10/5, 2017 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.