0

In the course of learning PHP, I've been following this series on youtube: So far, its been really smooth sailing. I'm using VS Code 1.21.1, I just installed PHP 7, and am running XAMPP 7.2.3 (only running Apache so far), and viewing the output in Chrome, all in Windows 7. The code in the completed tutorial looks like this

<form action="index.php" method="GET">
        Name:<br><input type="text" name="name"><br>
        Age:<br><input type="text" name="age" size="5"><br><br>
        <input type="submit" value="Submit">
    </form>

<?php

    $name = $_GET['name'];
    $age = $_GET['age']; 
if(isset($name) && isset($age) && !empty($name) && !empty($age)) {
    echo 'I am '.$name.' and I am '.$age.' years of age.';
} else {
    echo 'Please type something.';
}

?>

This never worked for me.

Tutorial 22 Undefined index screenshot

The if(isset) statement towards the end of the code is supposed to avoid the "undefined index" error, but never did for me. I ended up trying quite a few fixes, including adding in PHPCS linting, in case there was something new and exciting I was missing. The first 9 errors led me to discover an entire world of things the tutorial missed (and maybe most were just warnings... but still...)

My (partial?) solution was lifted from a different youtube video, where a name was given to the submit button and ONLY that field was tested against (in the tutorial, the test is also that the fields aren't blank. This solution does NOT check for that.) Note there is also a ton of other boilerplate added in trying to solve all of the linted issues, none of which solved the issue... but the question remains, why does THIS work to avoid the invalid index issues, but the one in the tutorial did not?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="index.php" method="GET" enctype="form-data/multipart">
        Name:<br><input type="text" name="name"><br>
        Age:<br><input type="text" name="age" size="5"><br><br>
        <input type="submit" name="submit" value="Submit">
    </form>

<?php
/**
 * MyClass File Doc Comment
 *
 * PHP Version 7
 * 
 * @category MyClass
 * @package  MyPackage
 * @author   A N Other <another@gmail.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://www.holygenericboilerplatebatman.com/
 */

if (isset($_GET['submit'])) { // It's before the variables, so it works?
    $name = $_GET['name'];
    $age = $_GET['age']; 

    echo 'I am '.$name.' and I am '.$age.' years old.';
} else {
    echo 'Please type something.';
}

?>

    </body>
</html>

The only obvious difference i can see is having the if(isset) statement placed before the variables are declared, but using the one from the tutorial in that position made the page load properly, but then NOT render the entered name and age below the form like it's supposed to. The URL would update with the PHP entries, but the page would still say "Please type something" instead of switching to the other line of text with the variables filled in.

I don't understand the difference between the approaches enough to know what I'm supposed to be learning! :S

The other thing I noticed in all my reading/attempts is that 99% of all undefined index error suggestions are focused on the '$_POST' method, not '$_GET' including here on SO. As a result, I don't believe this is a duplicate question. Is this something else I'm missing that's obvious? Thanks in advance!

Dustin Kreidler
  • 168
  • 1
  • 9
  • I *have* checked what looked like the truly authoritative answers here, including this one which seems encyclopedic: https://stackoverflow.com/questions/4261133/php-notice-undefined-variable-notice-undefined-index-and-notice-undef and I just tried to use the PHP 7 null coalesce operator, which also made the page APPEAR correctly, but then still fail to actually render the completed text after submission. – Dustin Kreidler Mar 31 '18 at 04:02

4 Answers4

0

In your first code, it shows those errors becuase $_GET['name'] and $_GET['age'] are undefined.

To define them in your case, you need to submit the form first. As you will see after you submit the form, your browser adress bar url will appear like - index.php?name=john&age=23 - that's how those $_GET variables are defined and their values set.

When the form is not submitted, then the url will not change, no $_GET variables defined and you'll get error notices when you prematurely use them like you're doing in your first code.

Anyway, even if those $_GET variables aren't defined like usual, you can still prevent those error notices by using the function isset() to check if they are set or not before attempting to use them.

Replace:

$name = $_GET['name'];
$age = $_GET['age']; 

With:

$name = "John Doe"; // default values
$age = "24";

if( isset( $_GET['name'] ) ) {
   $name = $_GET['name'];
}

if( isset( $_GET['age'] ) ) {
   $age = $_GET['age'];
}
Karlo Kokkak
  • 3,674
  • 4
  • 18
  • 33
  • The only thing I don't like is the need to seed the values (with them then showing on the page when it first loads), but other than that, the answer makes sense. Thanks! – Dustin Kreidler Mar 31 '18 at 14:57
0

You have to check isset before you assign it to variable. change your php script as below:

<?php

if(isset($_GET['name']) && isset($_GET['age']) && !empty($_GET['name']) && !empty($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
    echo 'I am '.$name.' and I am '.$age.' years of age.';
} else {
    echo 'Please type something.';
}

?>
B. Desai
  • 16,414
  • 5
  • 26
  • 47
  • This worked, thanks! Do you have any idea why the code (as presented in the first example) was NOT throwing the undefined index error for the presenter? Some change in any of the included technologies from when he posted it in September? – Dustin Kreidler Mar 31 '18 at 14:46
0

Try this

$name = $_GET['name'] ?? false;
$age = $_GET['age'] ?? false; 
if($name && $age) {

Using null coalesce ?? PHP7+

I just installed PHP 7,

I notice you are using PHP7+ so we can use the new features (I need the practice anyway)

Now you get the undefined Index notice, because as it says your trying to access something that doesn't exist. There are various ways to check this that won't issue the error. Each is a bit different and here are the 2 most common ways.

  • empty checks if a variable is falsy, it could be set or not set.
    • eg. returns true on any false value such as 0, '', [], null and when not set.
  • isset checks if a variable is set
    • eg. returns false when not set, otherwise returns true even on falsy values, except for null

Using empty can be very problematic because of PHP's loose typing. Many things in PHP evaluate out to be false or empty (AKA falsy), some of which may be perfectly valid inputs. A simple example is the value 0 or an empty string '' each of which may be perfectly acceptable. However, these are both considered to be empty or false (when not using === which does type checking).

Using isset return boolean true when a variable is defined and not null. In other words, and unlike empty, isset will return true on any falsy values except null.

There are also various ways to use isset in conditional logic. The new ?? null coalesce returns the first non-null value from the list (left to right), using the same check that isset does. Therefor, we would say it equivalent to isset.

This new operator has a few advantages over checking isset with "more" traditional conditional blocks.

Some examples

Using long hand if conditions, can bloat your code if you have a lot of inputs to check or many alternative values you can substitute.

if(isset($foo))
   $var = $foo;
elseif(isset($bar))
   $var = $bar;
elseif(isset($biz))
   $var = $biz;
else
   $var = false;

Ternary format({condition} ? true : false;) is an improvement on that, but you can only do one true and one false resolution at a time. You can nest them, but that becomes unreadable really fast:

$var = isset($foo) ? $foo : isset($bar) ? $bar : isset($biz) ? $biz : false;

In PHP7+ we were blessed with the ?? null coalesce opperator and we can do the same thing as shown in the 2 examples above, with just this:

$var = $foo ?? $bar ?? $biz ?? false;

All of these are roughtly equivalent, and it's very easy to see the attraction of using the new null coalesce operator.

Hope that helps explain it. I'm still getting used to the ?? myself as we haven't started using PHP7 in production at my work. Don't worry it will be soon as we just did a compatibility run through and "fix up" ... :)

ArtisticPhoenix
  • 21,464
  • 2
  • 24
  • 38
0

Actually, on the original question, this is how it works correctly, staying in PHP 5.6 , and staying at the original tutorial:

if (isset($_GET['name']) && isset($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
}

if (isset($name) && isset($age) && !empty($name) && !empty($age)) {
    echo 'I am '.$name. ' and I am ' .$age. ' old';
  } else {
  echo 'Please type something';
}

Or more clearly:

if (isset($_GET['name']) && isset($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
}

if (!empty($name) && !empty($age)) {
    echo 'I am '.$name. ' and I am ' .$age. ' old';
  } else {
  echo 'Please type something';
}
Zollie
  • 1,171
  • 7
  • 14