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
In reply to ""Why do they appear all of a sudden? I used to use this script for years and I've never had any problem."
It is very common for most sites to operate under the "default" error reporting of "Show all errors, but not 'notices' and 'deprecated'". This will be set in php.ini and apply to all sites on the server. This means that those "notices" used in the examples will be suppressed (hidden) while other errors, considered more critical, will be shown/recorded.
The other critical setting is the errors can be hidden (i.e. display_errors
set to "off" or "syslog").
What will have happened in this case is that either the error_reporting
was changed to also show notices (as per examples) and/or that the settings were changed to display_errors
on screen (as opposed to suppressing them/logging them).
Why have they changed?
The obvious/simplest answer is that someone adjusted either of these settings in php.ini, or an upgraded version of PHP is now using a different php.ini from before. That's the first place to look.
However it is also possible to override these settings in
and any of these could also have been changed.
There is also the added complication that the web server configuration can enable/disable .htaccess directives, so if you have directives in .htaccess that suddenly start/stop working then you need to check for that.
(.htconf / .htaccess assume you're running as apache. If running command line this won't apply; if running IIS or other webserver then you'll need to check those configs accordingly)
Summary
error_reporting
and display_errors
php directives in php.ini has not changed, or that you're not using a different php.ini from before.error_reporting
and display_errors
php directives in .htconf (or vhosts etc) have not changederror_reporting
and display_errors
php directives in .htaccess have not changederror_reporting
and display_errors
php directives have been set there.Using a ternary is simple, readable, and clean:
Pre PHP 7
Assign a variable to the value of another variable if it's set, else assign null
(or whatever default value you need):
$newVariable = isset($thePotentialData) ? $thePotentialData : null;
PHP 7+
The same except using Null Coalescing Operator. There's no longer a need to call isset()
as this is built in, and no need to provide the variable to return as it's assumed to return the value of the variable being checked:
$newVariable = $thePotentialData ?? null;
Both will stop the Notices from the OP question, and both are the exact equivalent of:
if (isset($thePotentialData)) {
$newVariable = $thePotentialData;
} else {
$newVariable = null;
}
If you don't require setting a new variable then you can directly use the ternary's returned value, such as with echo
, function arguments, etc:
Echo:
echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';
Function:
$foreName = getForeName(isset($userId) ? $userId : null);
function getForeName($userId)
{
if ($userId === null) {
// Etc
}
}
The above will work just the same with arrays, including sessions etc, replacing the variable being checked with e.g.:
$_SESSION['checkMe']
or however many levels deep you need, e.g.:
$clients['personal']['address']['postcode']
Suppression:
It is possible to suppress the PHP Notices with @
or reduce your error reporting level, but it does not fix the problem, it simply stops it being reported in the error log. This means that your code still tried to use a variable that was not set, which may or may not mean something doesn't work as intended - depending on how crucial the missing value is.
You should really be checking for this issue and handling it appropriately, either serving a different message, or even just returning a null value for everything else to identify the precise state.
If you just care about the Notice not being in the error log, then as an option you could simply ignore the error log.
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.
Probably you were using old PHP version until and now upgraded PHP thats the reason it was working without any error till now from years. until PHP4 there was no error if you are using variable without defining it but as of PHP5 onwards it throws errors for codes like mentioned in question.
Try these
Q1: this notice means $varname is not defined at current scope of the script.
Q2: Use of isset(), empty() conditions before using any suspicious variable works well.
// recommended solution for recent PHP versions
$user_name = $_SESSION['user_name'] ?? '';
// pre-7 PHP versions
$user_name = '';
if (!empty($_SESSION['user_name'])) {
$user_name = $_SESSION['user_name'];
}
Or, as a quick and dirty solution:
// not the best solution, but works
// in your php setting use, it helps hiding site wide notices
error_reporting(E_ALL ^ E_NOTICE);
Note about sessions:
When using sessions, session_start();
is required to be placed inside all files using sessions.
http://php.net/manual/en/features.sessions.php
For undesired and redundant notices, one could use the dedicated @ operator to »hide« undefined variable/index messages.
$var = @($_GET["optional_param"]);
isset?:
or ??
super-supression however. Notices still can get logged. And one may resurrect @
-hidden notices with: set_error_handler("var_dump");
if (isset($_POST["shubmit"]))
in your initial code.@
or isset
only after verifying functionality.Fix the cause first. Not the notices.
$_GET
/$_POST
input parameters, specifically if they're optional.And since this covers the majority of such questions, let's expand on the most common causes:
$_GET
/ $_POST
/ $_REQUEST
undefined inputFirst thing you do when encountering an undefined index/offset, is check for typos:
$count = $_GET["whatnow?"];
Secondly, if the notice doesn't have an obvious cause, use var_dump or print_r to verify all input arrays for their curent content:
var_dump($_GET);
var_dump($_POST);
//print_r($_REQUEST);
Both will reveal if your script was invoked with the right or any parameters at all.
Alternativey or additionally use your browser devtools (F12) and inspect the network tab for requests and parameters:
POST parameters and GET input will be be shown separately.
For $_GET
parameters you can also peek at the QUERY_STRING in
print_r($_SERVER);
PHP has some rules to coalesce non-standard parameter names into the superglobals. Apache might do some rewriting as well.
You can also look at supplied raw $_COOKIES
and other HTTP request headers that way.
More obviously look at your browser address bar for GET parameters:
http://example.org/script.php?id=5&sort=desc
The name=value
pairs after the ?
question mark are your query (GET) parameters. Thus this URL could only possibly yield $_GET["id"]
and $_GET["sort"]
.
Finally check your <form>
and <input>
declarations, if you expect a parameter but receive none.
<input name=FOO>
id=
or title=
attribute does not suffice.method=POST
form ought to populate $_POST
.method=GET
(or leaving it out) would yield $_GET
variables.action=script.php?get=param
via $_GET and the remaining method=POST
fields in $_POST alongside.If you are employing mod_rewrite, then you should check both the access.log
as well as enable the RewriteLog to figure out absent parameters.
$_FILES
$_FILES["formname"]
.enctype=multipart/form-data
method=POST
in your <form>
declaration.$_COOKIE
$_COOKIE
array is never populated right after setcookie()
, but only on any followup HTTP request.