Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Undefined index even after checking IsSet

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
)
like image 556
AnimaSola Avatar asked May 10 '17 18:05

AnimaSola


3 Answers

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.

like image 106
MonkeyZeus Avatar answered Oct 24 '22 00:10

MonkeyZeus


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>';
like image 31
OnNIX Avatar answered Oct 23 '22 23:10

OnNIX


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'] : '';
like image 1
Diéfani Favareto Piovezan Avatar answered Oct 24 '22 00:10

Diéfani Favareto Piovezan