18

Every time a POST value is not equal to the list of values set in an array will return: Undefined Index error, I made an if statement but is not working.

Here's the if statement:

 if ($products[$_POST['product']] == $_POST['product']) {
do everything;}
else {
echo "This item is not available";
}

EDIT2:

Seen the current situation avoiding the warning wont help much because I'm dealing with several factors, for example a list of items in a Shopping Cart, if the invalid product is not removed, it will be added to the shopping list session.

This is the full script:

<?php

session_start();

//Getting the list
 $_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();    

 //stock    
 $products = array(      
     'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,       
     'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,      
     'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,      
     'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,    
 );    

if( isset($_POST['product']) ){


     //Saving the stuff    
     $new_item = array(      
         'item' => $_POST['product'],       
         'quantity' => $_POST['quantity'],     
         'code' => $_POST['code'],      
         'price' => $products[$_POST['product']] * $_POST['quantity'],    

     );



    $new_product = true;    
    foreach($_SESSION['list'] as $key => $item) {      
        if ($item['item'] == $new_item['item']) {        
        $_SESSION['list'][$key]['quantity'] += $new_item['quantity'];        
        $_SESSION['list'][$key]['price'] = $products[$new_item['item']] * $new_item['quantity'];        
        $new_product = false;
        }    
    }   

    if ($new_product) {      
        $_SESSION['list'][] = $new_item;        
    }    

    /*if ($new_item['item'] != $products[$new_item['item']]) {
        echo "This item is not available";}*/

    //listing    
    echo  "<b>SHOPPING LIST</b></br>";    
    foreach($_SESSION['list'] as $key => $item) {       
        echo 'Product .'. $key. ' '. $item['item'], ' ', $item['quantity'], ' units: ', $item['price']. '<br />';    
        }

}

else {
echo "This item is not available";
}

echo "</br> <a href='index.html'>Return to index</a> </br>";

//Printing session
var_dump($_SESSION);

session_destroy();

?>
Gabriel
  • 305
  • 1
  • 3
  • 7
  • Possible duplicate of [PHP: "Notice: Undefined variable" and "Notice: Undefined index"](http://stackoverflow.com/questions/4261133/php-notice-undefined-variable-and-notice-undefined-index) – kenorb Dec 18 '15 at 10:32
  • Use if( isset($yourvariable ) ) to avoide index error in php – shaz3e Aug 18 '18 at 12:00

10 Answers10

32

With PHP 7, the null coalescing operator can be used to deal with optional request variables. You can change your $_POST['product'] reference to $_POST['product'] ?? null which will resolve to null (rather than throwing the warning) if 'product' is not a valid key in the post array. If you wanted to check both the $_POST and $_GET arrays for a value, you would use $_POST['product'] ?? $_GET['product'] ?? null.

Garland Pope
  • 3,242
  • 1
  • 25
  • 19
26

I'm a bit confused by your code. It looks like your array has the same key and value, so:

$products['saucepan'] = 'saucepan'

Perhaps you are trying to do this, which will check whether the product exists in the products array:

if(isset($_POST['product']) && array_key_exists($_POST['product'], $products))
{
  // do stuff
}
else
{
  echo "This item is not available";
}
matiit
  • 7,969
  • 5
  • 41
  • 65
Dan Blows
  • 20,846
  • 10
  • 65
  • 96
12
@$_POST['product']

(with an @) will return the same thing as :

$product = (isset($_POST['product'])) ? $_POST['product'] : null;

Shorter is sweeter !! 4 times less code ! Easier to read and understand.

The @ symbol is the error control operator (AKA the "silence" or "shut-up" operator). It makes PHP suppress any error messages (notice, warning, fatal, etc.).

But beware not to use @ for any other thing, as it would make your code so much harder to debug!

(this will answer your question before the edit)

Cedric
  • 5,135
  • 11
  • 42
  • 61
  • This doesn’t seem like a good answer. Silencing errors is never the right approach. – Evan Hendler Jul 21 '18 at 15:22
  • 3
    @EvanHendler checking for isset first then evaluing the value is no better than the ' @ ' ! But for other things, silencing errors isn't a great thing to do - that is especially why I warn people about it in the answer. – Cedric Jul 22 '18 at 09:21
  • 1
    I've gotta go with Cedric on this one, the `@` operator has a very limited use, up til now I have used it only on `@session_start()` (which throws an annoying notice for apparently no functional reason), the succinctness of `$var = @$_POST['var']` is way too nice to throw it in the 'never suppress errors' basket. – Abraham Brookes Mar 20 '19 at 22:04
  • @EvanHendler Silencing errors is never right approach, but silencing notices is a different story. Notices might help with finding cause of follow-up error but if my code is fine with getting null instead of expected value this mandatory array_key_exists() might pollute code in PHP quite extensively making it harder to comprehend. – Thomas Urban May 20 '19 at 08:20
  • 1
    man! you just made my day, i've been looking for this thing for a log time. – tinyCoder Jul 11 '19 at 20:49
  • STRONGLY agree with @EvanHendler. Silencing errors/notices is never the correct approach. Programming is not about reducing lines of code or line length. Clean code is about being clear. Code == Communication. The (slightly) longer version that uses `isset` clearly communicates what you're doing, what you're expecting and why. The error suppression version communicates nothing and may get in the way of debugging. – catchdave Jan 20 '20 at 21:36
9

You should first check to see if $_POST['product'] is set with isset(), like:

if( isset($_POST['product']) ){
    // Do something with $_POST['product']
}

That should suppress the warning.

cmptrgeekken
  • 8,052
  • 3
  • 29
  • 35
3

You could also try

$product = (isset($_POST['product'])) ? $_POST['product'] : null;

This will set $product to the $_POST value if it exists, or to null if not. Then you could try

if ($product) {
  do_something();
}

or access your array with

$products[$product];

I feel this way it makes your code that little bit easier on the eyes..

Zac
  • 12,637
  • 21
  • 74
  • 122
sunny
  • 31
  • 1
1

You can just use a ?? to set set a default value if your value is not set.

$_POST['product'] ?? "No product";

Etta
  • 339
  • 4
  • 10
1

I think this is the most elegant and readable way of doing it, it is not a one-liner but readable nevertheless.

$product = $_POST['product'] ?? null;
if(empty($product)){
 // $product was not set in the request. Interrupt, throw error or deal with it here
}

// At this point $product is set, continue as normal

Remote
  • 11
  • 2
0
if (isset($products[$_POST['product']]) && $products[$_POST['product']] == $_POST['product']) 

the isset() function will help you avoid the warning

Ibu
  • 42,752
  • 13
  • 76
  • 103
0
if(isset($products[$_POST['product']) && $products[$_POST['product'] != "")

Note that a vriable can be empty but also "set" so the what comes after the && is necessary.

fatnjazzy
  • 6,070
  • 12
  • 57
  • 83
  • You could use `if(empty($products[$_POST['product']))` which will also check whether the value is null or 0. – Dan Blows Apr 30 '11 at 05:35
  • 2
    @Blowski : if index 0 valid for $product then? – Gaurav Apr 30 '11 at 05:38
  • @Gaurav Fair point. I would check the $_POST['product'] first and then use `array_key_exists()` as in my answer. – Dan Blows Apr 30 '11 at 05:42
  • Thanks fatnjazzy, however since I'm using a SESSION the invalid value will be re-used, thus stopping the event would be much more effective, can you check for a minute my recently EDITED question? – Gabriel Apr 30 '11 at 05:45
0

you can check whether the index 'product' is defined in the same if statement ..

if (isset($_POST['product']) && $products[$_POST['product']] == $_POST['product']) {
    do everything;
}
else {
    echo "This item is not available";
}
naiquevin
  • 7,588
  • 12
  • 53
  • 62