This question already has answers here:
"Notice: Undefined variable", "Notice: Undefined index", "Warning: Undefined array key", and "Notice: Undefined offset" using PHP
(29 answers)
Closed 9 years ago.
I understand there are many posts on this issue. I have looked at the many many posts but for some reason I can seem to find an answer!
Any help will be very much appreciated. I am fairly new to PHP so I apologise if I say anything incorrectly.
I am trying to create a basic basket system using an array. I keep getting an error undefined index on line $_SESSION['cart'][$app_ID]++; The funny thing is it all functions correctly! I want to solve the error and not just turn off the error reporting.
if(isset($_GET['id'])){
$app_ID = $_GET['id']; //the item id from the URL
$action = $_GET['action']; //the action from the URL
$total = 0;
if (isset($app_ID)){
switch($action) {
case "add":
$_SESSION['cart'][$app_ID]++;
break;
case "remove":
$_SESSION['cart'][$app_ID]--;
if($_SESSION['cart'][$app_ID] == 0) unset($_SESSION['cart'][$app_ID]);
break;
case "empty":
unset($_SESSION['cart']); //unset the whole cart, i.e. empty the cart.
break;
Thanks guys and gals.
You should use isset($_SESSION['cart'][$app_ID]) and maybe isset( $_SESSION['cart']) before, everywhere.
Generally you must make sure that and array index is present before referencing it. You can do this either with isset(), or writing code where that condition is inevitable (e.g. adding the index somewhere earlier).
The other part of your question, I suppose, is why your code works. The explanation is easy. When you reference a non-existent index, the notice you observed is emitted (in non-production environments) but that does not stop the program. Since there is nothing to be used, null is returned for that array value. So the value is assumed to be null, and ++ takes values, as integers, and null is converted to the integer 0, and then raised by one. Since ++ is an operator that writes, it will create the array item for you. Since $a++ is defined as $a=$a+1 it's easy to see that what you've written is $_SESSION['cart'][$app_ID]=$_SESSION['cart'][$app_ID]+1 which is in turn $_SESSION['cart'][$app_ID]=null+1 where null+1 is executed as 0+1 yielding 0, so 0 is assigned to (the formerly missing) array item. Hope this helps see clear. ;)
to use $_SESSION you must call session_start () first before send any header information
I hope this help you,
Cheers,
session_start(); // at the top
case "add":
if (isset( $_SESSION['cart'][$app_ID] )){
$_SESSION['cart'][$app_ID]++;
} else {
$_SESSION['cart'][$app_ID] = 1;
}
break;
It's worth to mention, that it's merely a Notice, not an error. You basically must check for array index existence and initialize it before referencing it.
if (isset($app_ID)) {
switch($action) {
case "add":
if (!isset($_SESSION['cart']) {
$_SESSION['cart'] = array();
}
if (!isset($_SESSION['cart'][$app_ID]) {
$_SESSION['cart'][$app_ID] = 0;
}
$_SESSION['cart'][$app_ID]++;
break;
case "remove":
if (isset($_SESSION['cart'] && isset($_SESSION['cart'][$app_ID]) {
$_SESSION['cart'][$app_ID]--;
if ($_SESSION['cart'][$app_ID] <= 0) {
unset($_SESSION['cart'][$app_ID]);
}
}
break;
case "empty":
unset($_SESSION['cart']); //unset the whole cart, i.e. empty the cart.
break;
}
}
I've also changed == 0 in remove to <= 0 just to be safe.
Related
This question already has answers here:
Notice: Undefined index when trying to increment an associative array in PHP
(6 answers)
Closed 4 months ago.
I want to increment a value of an array, which is potentially not existing yet.
$array = [];
$array['nonExistentYet']++; // Notice
Problem
This leads to a NOTICE.
Attempt
I found a way to do this, but its kinda clunky:
$array = [];
$array['nonExistentYet'] = ($array['nonExistentYet'] ?? 0) + 1;
Question
Is there a more human readable/elegant way to do this?
well i guess a more readable way would be to use if..else as,
$arr = [];
if(array_key_exists('nonExistentYet', $arr)) {
$arr['nonExistentYet'] += 1;
}
else {
$arr['nonExistentYet'] = 1;
}
If this is used often, you can define a little helper method, which also uses an interesting side effect...
function inc(&$element) {
$element++;
}
$array = [];
inc($array['nonExistentYet']);
print_r($array);
gives...
Array
(
[nonExistentYet] => 1
)
with no warning.
As you can see the function defines the parameter as &$element, if this value doesn't exist, then it will be created, so the function call itself will create the element and then it will just increment it.
My standard implementation for this is:
if (isset($array['nonExistentYet']))
$array['nonExistentYet']++;
else
$array['nonExistentYet'] = 1;
But this is one of the rarely scenarios where I use the # operator to suppress warnings, but only if I have full control over the array:
#$array['nonExistentYet']++;
Generally, it is not good to suppress warnings or error messages!
What you ask is a little vague,
Either the variable exists and you increment it, or it does not exist in this case you create it.
In another case suppose that you want to do it in a for loop, in this case you do not have to worry about the existence of the variable.
One way is ternary operator, which checks if array value exists:
$array['iDoNotExistYet'] = empty($array['iDoNotExistYet']) ? 1 : ++$array['iDoNotExistYet'];
Other one would be just rewriting it to if and else condition.
This question already has answers here:
Notice: Undefined index when trying to increment an associative array in PHP
(6 answers)
Closed 4 months ago.
I have a foreach loop, inside of which I am building a big multi-dimensional array and doing lots of incriminating, like this:
$totalCosts['sawn']['materials'] += $sawnMaterialsCost;
On the first iteration of the loop, the key 'materials' is not set, so it throws an undefined index notice (not terrible, but annoying).
I can fix that by defining it before the loop like this:
$totalCosts['sawn']['materials'] = '0.00';
BUT, I have many keys I am filling by incrementing, and I don't like having to set each variable/key to '0' for every one before looping. Is there a better way to do this so the first iteration of the loop checks for a value and sets it to 1 if not found?
$totalCosts['sawn']['materials'] = ($totalCosts['sawn']['materials'] ?? 0) + $sawnMaterialsCost;
??, an operator introduced in PHP 7, uses the left-hand operand if defined and not null, otherwise the right-hand operand.
The performance cost of ?? is negligible, unless you are doing millions of comparisons. On an Amazon c3.medium, I measured each at ~250ns more than a static assignment. On a loop of 10,000,000 that's a half-second penalty.
perf.code.
Yes - first check if it exists, and if not, create it.
foreach($something as $key) { //e.g. $key = 'materials'
if (!isset($totalCosts['sawn'][$key])) $totalCosts['sawn'][$key] = 0;
$totalCosts['sawn'][$key] += $sawnMaterialsCost;
}
Well, I don't think there is a solution way more compact than this:
foreach(...) {
if(!isset($totalCosts['sawn'][$yourkey]))
$totalCosts['sawn'][$yourkey] = 0.00;
$totalCosts['sawn'][$yourkey]+=$sawnMaterialsCost;
}
Using the ternary operator is one way you can accomplish this.
$totalCosts['sawn']['materials'] = !empty($totalCosts['sawn']['materials']) ? $totalCosts['sawn']['materials'] + $sawnMaterialsCost : $sawnMaterialsCost;
This way you won't try adding to a non-existent value.
I have been trying to create a very simple shopping cart and I'm having a problem with my $_SESSION array. This is for a school project and I'm trying to make it as simple as possible.
The error I'm getting is:
Notice: Undefined index: cart in C:\xampp\htdocs\Final\menu.php on
line 31
Notice: Undefined offset: 5 in C:\xampp\htdocs\Final\menu.php on
line 31
if(isset($_GET['id'])){
$product_id = $_GET['id'];
$_SESSION['cart'][$product_id]++;
print_r($_SESSION);
print "<br>";
print_r($_GET);
}
Once I've added more than one item to a particular product_id, the error goes away. This is the way the tutorial I read explained to add items to the cart. Any suggestions?
Looks like $_SESSION['cart'] does not yet exist. Since it's going to be an array, instantiate it first with:
if(!array_key_exists('cart', $_SESSION)) $_SESSION['cart'] = array();
Since you have not yet assigned anything to $_SESSION['cart'][$product_id], you'll get this type of error when trying to increment it. You may want to try:
$_SESSION['cart'][$product_id] = (array_key_exists($product_id, $_SESSION['cart'])) ? $_SESSION['cart'][$product_id] +1 : 1;
or as an if statement:
if(array_key_exists($product_id, $_SESSION['cart'])) $_SESSION['cart'][$product_id]++;
else $_SESSION['cart'][$product_id] = 1;
When you do $_SESSION['cart'][$product_id]++; you are actually doing:
$_SESSION['cart'][$product_id] = $_SESSION['cart'][$product_id] + 1;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generates warning if they keys do not exist yet
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assigns without problems if they keys do not exist yet
The assignment with newly created keys is not the problem, the warning is generated by php trying to get the actual value of $_SESSION['cart'][$product_id].
To solve this you should properly initialize the variable:
$_SESSION['cart'][$product_id] = isset($_SESSION['cart'][$product_id])
? $_SESSION['cart'][$product_id]++
: 1;
I get Notice: Undefined index: sesStatus warning and I am able to fix this warning when its just a variable, but this is part of a code and I am not sure how to fix the warning.
Her is the code that its doing it on.
case $_SESSION['sesStatus']=='e_logged':
$cc_section = $cc_emp;
$sidecol = $sc_employer;
break;
Replace case $_SESSION['sesStatus']=='e_logged':
with
case isset($_SESSION['sesStatus']) && $_SESSION['sesStatus']=='e_logged':
Assuming all else is well, I'd start by testing for the existence of the key with isset(). Also, testing for equality in the case statement is unusual.
<?php
if(isset($_SESSION['sesStatus'])) {
switch($_SESSION['sesStatus']) {
case 'e_logged':
$cc_section = $cc_emp;
$sidecol = $sc_employer;
break;
}
}
If accessing an undefined index of a null reference, PHP does not throw any errors.
<?php
$array = &$foo['bar'];
if ($array['stuff']) echo 'Cool'; // No PHP notice
$array['thing'] = 1; // Array created; $foo['bar']['thing'] == 1
$array['stuff']; // PHP notice
If $array wasn't a reference PHP would have complained on the first line.
Why doesn't it for references? Do I need bother with isset for null references, or is PHP complaining internally and not letting me know?
In your code $array is null. The following code will not give you a notice either:
$b = null;
if ($b['stuff']) echo 'cool';
This is strange, this comment in the documentation points to that fact.
You must raise your error reporting level. Your example $array['stuff'] will throw warnings about index not found. I often combine a test for key in with the evaluation so as to prevent those warnings:
if( array_key_exists("blah",$arr) && strlen($arr['blah']) > 0 ) {
; // do stuff here
}
I often combine variables in with array names because anytime I have to cut-n-paste copy code to the next section to do the same-ish thing, I'd rather make an array of variable names and then iterate through the variable names. The most absurd condition is when I have billing and shipping data to manipulate, where I'll have an array variable name $BorS or just $BS and then at the top, set $BorS="shipping"; and end up with really interesting statements like:
${$BorS."data"}[${$BorS."_addr1"}]=$input_array[$BorS."_address_line_1"];
Why not just do:
$array = array();