“Notice: Undefined variable”, “Notice: Undefined i

2020-01-22 07:18发布

I'm running a PHP script and continue to receive errors like:

Notice: Undefined variable: my_variable_name in C:\wamp\www\mypath\index.php on line 10

Notice: Undefined index: my_index C:\wamp\www\mypath\index.php on line 11

Line 10 and 11 looks like this:

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

What is the meaning of these error messages?

Why do they appear all of a sudden? I used to use this script for years and I've never had any problem.

How do I fix them?


This is a General Reference question for people to link to as duplicate, instead of having to explain the issue over and over again. I feel this is necessary because most real-world answers on this issue are very specific.

Related Meta discussion:

28条回答
虎瘦雄心在
2楼-- · 2020-01-22 08:00

These errors occur whenever we are using a variable that is not set.

The best way to deal with these is set error reporting on while development.

To set error reporting on:

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

On production servers, error reporting is off, therefore, we do not get these errors.

On the development server, however, we can set error reporting on.

To get rid of this error, we see the following example:

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

We can initialize the variables to NULL before assigning their values or using them.

So, we can modify the code as:

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

This will not disturb any program logic and will not produce Notice even if $test does not have value.

So, basically, its always better to set error reporting ON for development.

And fix all the errors.

And on production, error reporting should be set to off.

查看更多
可以哭但决不认输i
3楼-- · 2020-01-22 08:01

Notice: Undefined variable

From the vast wisdom of the PHP Manual:

Relying on the default value of an uninitialized variable is problematic in the case of including one file into another which uses the same variable name. It is also a major security risk with register_globals turned on. E_NOTICE level error is issued in case of working with uninitialized variables, however not in the case of appending elements to the uninitialized array. isset() language construct can be used to detect if a variable has been already initialized. Additionally and more ideal is the solution of empty() since it does not generate a warning or error message if the variable is not initialized.

From PHP documentation:

No warning is generated if the variable does not exist. That means empty() is essentially the concise equivalent to !isset($var) || $var == false.

This means that you could use only empty() to determine if the variable is set, and in addition it checks the variable against the following, 0, 0.0, "", "0", null, false or [].

Example:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

Test the above snippet in the 3v4l.org online PHP editor

Although PHP does not require a variable declaration, it does recommend it in order to avoid some security vulnerabilities or bugs where one would forget to give a value to a variable that will be used later in the script. What PHP does in the case of undeclared variables is issue a very low level error, E_NOTICE, one that is not even reported by default, but the Manual advises to allow during development.

Ways to deal with the issue:

  1. Recommended: Declare your variables, for example when you try to append a string to an undefined variable. Or use isset() / !empty() to check if they are declared before referencing them, as in:

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';
    

    This has become much cleaner as of PHP 7.0, now you can use the null coalesce operator:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Set a custom error handler for E_NOTICE and redirect the messages away from the standard output (maybe to a log file):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  3. Disable E_NOTICE from reporting. A quick way to exclude just E_NOTICE is:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Suppress the error with the @ operator.

Note: It's strongly recommended to implement just point 1.

Notice: Undefined index / Undefined offset

This notice appears when you (or PHP) try to access an undefined index of an array.

Ways to deal with the issue:

  1. Check if the index exists before you access it. For this you can use isset() or array_key_exists():

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. The language construct list() may generate this when it attempts to access an array index that does not exist:

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');
    

Two variables are used to access two array elements, however there is only one array element, index 0, so this will generate:

Notice: Undefined offset: 1

$_POST / $_GET / $_SESSION variable

The notices above appear often when working with $_POST, $_GET or $_SESSION. For $_POST and $_GET you just have to check if the index exists or not before you use them. For $_SESSION you have to make sure you have the session started with session_start() and that the index also exists.

Also note that all 3 variables are superglobals and are uppercase.

Related:

查看更多
别忘想泡老子
4楼-- · 2020-01-22 08:01

WHY IS THIS HAPPENING?

Over time, PHP has become a more security-focused language. Settings which used to be turned off by default are now turned on by default. A perfect example of this is E_STRICT, which became turned on by default as of PHP 5.4.0.

Furthermore, according to PHP documentation, by default, E_NOTICE is disabled in php.ini. PHP docs recommend turning it on for debugging purposes. However, when I download PHP from the Ubuntu repository–and from BitNami's Windows stack–I see something else.

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

Notice that error_reporting is actually set to the production value by default, not to the "default" value by default. This is somewhat confusing and is not documented outside of php.ini, so I have not validated this on other distributions.

To answer your question, however, this error pops up now when it did not pop up before because:

  1. You installed PHP and the new default settings are somewhat poorly documented but do not exclude E_NOTICE.

  2. E_NOTICE warnings like undefined variables and undefined indexes actually help to make your code cleaner and safer. I can tell you that, years ago, keeping E_NOTICE enabled forced me to declare my variables. It made it a LOT easier to learn C, were not declaring variables is much bigger of a nuisance.

WHAT CAN I DO ABOUT IT?

  1. Turn off E_NOTICE by copying the "Default value" E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED and replacing it with what is currently uncommented after the equals sign in error_reporting =. Restart Apache, or PHP if using CGI or FPM. Make sure you are editing the "right" php.ini. The correct one will be Apache if you are running PHP with Apache, fpm or php-fpm if running PHP-FPM, cgi if running PHP-CGI, etc. This is not the recommended method, but if you have legacy code that's going to be exceedingly difficult to edit, then it might be your best bet.

  2. Turn off E_NOTICE on the file or folder level. This might be preferable if you have some legacy code but want to do things the "right" way otherwise. To do this, you should consult Apache2, Nginx, or whatever your server of choice is. In Apache, you would use php_value inside of <Directory>.

  3. Rewrite your code to be cleaner. If you need to do this while moving to a production environment or don't want someone to see your errors, make sure you are disabling any display of errors, and only logging your errors (see display_errors and log_errors in php.ini and your server settings).

To expand on option 3: This is the ideal. If you can go this route, you should. If you are not going this route initially, consider moving this route eventually by testing your code in a development environment. While you're at it, get rid of ~E_STRICT and ~E_DEPRECATED to see what might go wrong in the future. You're going to see a LOT of unfamiliar errors, but it's going to stop you from having any unpleasant problems when you need to upgrade PHP in the future.

WHAT DO THE ERRORS MEAN?

Undefined variable: my_variable_name - This occurs when a variable has not been defined before use. When the PHP script is executed, it internally just assumes a null value. However, in which scenario would you need to check a variable before it was defined? Ultimately, this is an argument for "sloppy code". As a developer, I can tell you that I love it when I see an open source project where variables are defined as high up in their scopes as they can be defined. It makes it easier to tell what variables are going to pop up in the future and makes it easier to read/learn the code.

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index - This occurs when you try to access a value in an array and it does not exist. To prevent this error, perform a conditional check.

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

Another option is to declare an empty array at the top of your function. This is not always possible.

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(additional tip)

  • When I was encountering these and other issues, I used NetBeans IDE (free) and it gave me a host of warnings and notices. Some of them offer very helpful tips. This is not a requirement, and I don't use IDEs anymore except for large projects. I'm more of a vim person these days :).
查看更多
SAY GOODBYE
5楼-- · 2020-01-22 08:02

In a very Simple Language.
The mistake is you are using a variable $user_location which is not defined by you earlier and it doesn't have any value So I recommend you to please declare this variable before using it, For Example:


$user_location = '';
Or
$user_location = 'Los Angles';
This is a very common error you can face.So don't worry just declare the variable and Enjoy Coding.

查看更多
放荡不羁爱自由
6楼-- · 2020-01-22 08:02

undefined index means in an array you requested for unavailable array index for example

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

undefined variable means you have used completely not existing variable or which is not defined or initialized by that name for example

<?php print_r($myvar); ?>

undefined offset means in array you have asked for non existing key. And the solution for this is to check before use

php> echo array_key_exists(1, $myarray);
查看更多
闹够了就滚
7楼-- · 2020-01-22 08:05

The best way for getting input string is:

$value = filter_input(INPUT_POST, 'value');

This one-liner is almost equivalent to:

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

If you absolutely want string value, just like:

$value = (string)filter_input(INPUT_POST, 'value');
查看更多
登录 后发表回答