Categories
PHP

Common PHP error messages

Error Levels

The possible php error levels and their meanings are as follows. For a full discussion of errors and handling of errors, see “Error Reporting and Debugging.”
Errors generally come in three different levels:

  • Notices Generated at runtime, these are situations where the PHP interpreter noticed an inconsistency or other oddity that, though syntactically correct, may or may not make conceptual sense. In fact these may end up being bugs in your code as PHP may interpret what you meant as something different from what the code is supposed to do. This includes E_STRICT, E_USER_NOTICE, and E_NOTICE.
  • Warnings Generated at runtime, these are nonfatal errors that do not cause script execution to end. This includes E_WARNING, E_CORE_WARNING, E_COMPILE_WARNING, and E_USER_WARNING.
  • Errors Often referred to as fatal errors, these are problems that cause script execution to stop. They can be generated at any stage of PHP execution, including initialization, parsing, and execution. This includes E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, and E_USER_ERROR.

Output Result: A Blank Page

Unfortunately it is all too common for you to just receive a blank page back when you try to run a page of code. Usually this is a combination of any of the other errors described in following sections and the fact that you don’t have enough error reporting turned on.
On your development web servers you should make sure that you have errors being displayed to the screen and E_ALL (or preferably E_STRICT) set as the error level to display. Also make sure that startup errors are displayed as well; otherwise, some initial parsing errors may be hidden from you. This will ensure that you will see any and all errors that will ever happen and should keep you from seeing the dreaded blank page.
The lines that you need to add to your php.ini configuration file to make sure that these are turned on are as follows:
display_errors = On
display_startup_errors = On
error_reporting = E_ALL | E_STRICT

If you do not have access to your php.ini file, you can still turn on most of the error reporting inside your code itself, via the following PHP commands:
ini_set(‘display_errors’, / = true);
error_reporting(E_ALL | E_STRICT);

Notice: Use of undefined constant asdf – assumed ‘asdf’

This is a fairly common error, caused by using a raw word where PHP was expecting a string. PHP is nice in these cases and assumes that you meant to use a string instead. A line of code as simple as the following can cause this error:
$var = asdf;

Realize that although sometimes this is okay, in many situations this can cause problems. Having a computer decide for you how something should be determined isn’t usually a good idea. When you see this error, look for the word in question and you will find it. Typically this will be either because you forgot to surround the word with quotes because you meant to use it as a string or it is actually a variable name and you forgot to place a $ in front of it.

Notice: Undefined variable: asdf

This error means exactly what it says. You tried to use a variable that was not yet defined. This often happens when you have a variable that you might increment at any point but never initialized to a starting value, such as zero. So the following code might be a sample culprit:
$asdf++;

The other shortcut operators such as “+=”, “-=”, “.=”, and so on are also frequently to blame. It is true that PHP guarantees you that an uninitialized variable will be equal to NULL. However it’s always a good thing to declare variables to have specific default values before you just use them. Think of the preceding example; what if some other programmer were to edit your code, not realizing it, and reuse the $asdf variable before your line of code. Now you will be incrementing from where the other programmer left off.
It is just good programming practice to make sure that all your variables are initialized before use. You can do this at the top of your page, or function, easily with a run-on assignment line such as the following, which sets four variables at once to be equal to an empty string:
$jen = $harry = $heather = $ron = ”;

Notice: Undefined index: asdf

This error is similar to the previous error; however, it relating specifically to an array index instead. The array existed, but that index didn’t. This can happen during loops of counting. Or it quite often happens when you are trying to access the superglobal arrays and the value you thought existed, didn’t. Such as
if ($_GET[‘asdf’] > 3) { echo ‘Yes’; }

Although you can always make sure that variables your application creates are set, there is still an issue with any variables that may appear in the superglobal arrays. A particular key may or may not be set in a superglobal due to a number of factors, such as whether a PHP script is running from a web server. Therefore you need to make sure that the value really exists before trying to access it. This is best accomplished via the isset() function. So the preceding line of code could be rewritten as
if (isset($_GET[‘asdf’]) && ($_GET[‘asdf’] > 3)) { echo ‘Yes’; }

Again, PHP guarantees that you will receive a NULL for your troubles if you don’t check it first, but again, it is always safer to specifically test for all cases. It leads to cleaner coding practices.

Parse error: syntax error, unexpected T_STRING

Parse error: syntax error, unexpected T_VARIABLE

Parse error: syntax error, unexpected T_IF and so on

These errors and all like them are essentially the same. They are the compiler complaining that it found one type of language construct when it didn’t expect to see it. This is almost always caused by a typo in the code such as:

if $asdf = 2) { echo '2'; }

In this case the opening parenthesis for the if statement was forgotten, and therefore it gives the T_VARIABLE version of this error because it saw the “$” when it wasn’t expecting one.
Any such error message that includes a word that begins with T_, is referring to a token, an internal representation of a language construct. For example, T_VARIABLE is the token used by PHP to indicate a variable. Similarly, T_STRING is the token representing a string, and so on. Many tokens are available, not all of which have obvious names. If faced with a token string that is not clear to you, you can find the list of tokens at http://php.net/tokens.
In general these can be some of the toughest errors to track down because often the line number that the error claims to be on is far away from the actual error. Also the parsing engine stops immediately when it comes on one of these errors; therefore, you may fix one to find another and another. In general the best way of fixing these errors is instead to just avoid them.
Try running your code regularly as you are coding it to find such errors early before your code gets so large that it becomes difficult to track down the issue.

Parse error: syntax error, unexpected $end

This error is related to the errors mentioned previously but worth mentioning separately. The $end in that statement refers to the end of the file, meaning that it hit the end of the file when it was still expecting something. Ninety-nine percent of the time this means that you are missing a “}” in your code. You will have to scan your entire file to find out where it is missing.
This error can also be generated by bad syntax related to the Heredoc construct, <<<. Recall that Heredoc defines a block of a PHP script to be interpreted the same way as a double-quoted string. The Heredoc syntax requires that the ending delimiter must be the first item on a line, without any other character, including whitespace, preceding it. Often, due to typos or editors that attempt to do automatic code formatting, this syntax is violated, resulting in this error.

Parse error: syntax error, unexpected ‘=’, expecting ‘;’

This error also is related to the preceding errors, but sometimes PHP knows that it was specifically expecting something, such as an “;”. In that case PHP adds that to the error message. How to debug it is the same; however, it is often easier because if PHP knows exactly what it is looking for, it usually is closer to the line in which it claims the error was.

Fatal error: Maximum execution time of 60 seconds exceeded

The heart of what causes this error can vary, but the overall trigger is the same. PHP has a limit built in for how long any script can run. This is to prevent a badly written page from running forever and stealing all resources from the web server. This error simply means that your page took too long to run. It’s easy to simulate this, just start a loop that will never end:
while(true);

If this happens it tends to mean one of two things. First, you may have ended up with an infinite loop in your code without realizing it. Check all the loops in your code to make sure that they actually end. If so, your code is simply taking too long to run. You can either try to speed it up, or increase the amount of time PHP has to execute. You can do this from within your code by using the function set_time_limit() and passing it the number of seconds that you want to allow your script to run.
It resets the time limit at that point, meaning that you can call it multiple times, and you could even call it during each iteration of a loop, giving a certain amount of time for that specific iteration to run.

Warning: Cannot modify header information – headers already sent

This is a specific error and therefore easy to fix. Simply put, you cannot output anything to the browser before any calls to header() because all HTTP header information must be sent before content. Therefore the following code causes this error:
foreach(range(1,10000) as $i) { echo $i; }
header(‘Content-type: text/plain’);

All that you need to do to fix this is make sure that all that calls to header() are before any output. Similarly any other functions that use HTTP header information would also have to be first, such as the setting of cookies, or starting a PHP session.
Note
PHP has a configuration parameter called output_buffering that tells PHP to send only so many bytes at a time. When this is enabled, it is possible to send up to one buffer’s worth of data before calling header() because no data has been sent to the client yet. This is functionality that typically shouldn’t be relied on because the configuration can change from server to server. If you need to check whether the headers have already been sent, you can call headers_sent().

Alternatively, if you absolutely must send a header in the middle of your page, the best solution is to use the output buffering commands ob_start() at the top of your script and ob_end_flush() at the bottom. This causes your entire page to be buffered before sending it, making it possible to set a header at any time during the page creation.

Warning: Wrong parameter count for foo()

This is a fairly simple error. In this case we didn’t pass the right number of parameters to a specific function or method:
foo($asdf);

The error gives you the correct line number and you only need to determine what options you are missing, or what extra ones you used. Make sure to check that you didn’t forget a comma.

Fatal error: Call to undefined function foo2()

You called a function that does not exist. Most likely this is the result of a typo such as
foo2(‘ ‘, $asdf);

However you will need to check carefully; it might happen because you forgot to include the file that has the function in it. Whatever the cause, you need to point this line of code to the correct function name, or make sure that the function really exists.

Fatal Error: Cannot redeclare foo()

This error can occur at any point during script execution and means exactly what it says: You attempted to define a function that was already defined. This often is the result of a script including a number of libraries, one of which also includes the same library script. As standard practice, you should include any code that contains function or class definitions using the include_once or require_once constructs. These constructs first check to see whether the specified file has already been referenced. If so, the file is not read in again.

'Coz sharing is caring
Categories
PHP

PHP Array with Numeric key or string type

I have a PHP array that has numeric keys as a string type.
But when I try and access them, PHP is giving me an undefined index error.

$a = (array)json_decode('{"1":1,"2":2}');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);

Output:

array (size=2)
    '1' => int 1
    '2' => int 2

boolean false

boolean false

ERROR: E_NOTICE: Undefined offset: 1
null

ERROR: E_NOTICE: Undefined offset: 1
null

Now the issue is “How do I access these values”?

Let’s start our environment, $obj equals the object notation of a decoded string:

php > $obj = json_decode('{"1":1,"2":2}');

php > print_r($obj);
stdClass Object
(
    [1] => 1
    [2] => 2
)

php > var_dump( $obj );
object(stdClass)#1 (2) {
  ["1"]=>
  int(1)
  ["2"]=>
  int(2)
}

If you want to access the strings, we know the following will fail:

php > echo $obj->1;

Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1

Accessing the object variables
You can access it like so:

php > echo $obj->{1};
1

Which is the same as saying:

php > echo $obj->{'1'};
1

Accessing the array variables
The issue with arrays is that the following return blank, which is the issue with typecasting.

php > echo $obj[1];
php >

If you typecast it back, the object is once again accessible:

php > $obj = (object) $obj;
php > echo $obj->{1};
1

Here is a function which will automate the above for you:

function array_key($array, $key){
    $obj = (object) $array;
    return $obj->{$key};
}

Example usage:

php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1

php > echo array_key($obj, 2);
2

If you want array, set the second parameter of json_decode to true.

$a = json_decode('{"1":1,"2":2}', true);

when you cast a std object to array, numeric string key doesn’t cast to number. Here is an example.

$obj = new stdClass;
$obj->{'1'} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
'Coz sharing is caring