Errors are an inevitable part of software development, and PHP is no exception. Whether you are building small scripts or enterprise-level applications, knowing how PHP handles errors - and how to manage them - can save you hours of debugging.
Types of Errors in PHP
Broadly speaking, PHP errors are divided into fatal and non-fatal errors. Fatal errors will immediately stop the execution of your script, while non-fatal errors allow execution to continue, though they can still lead to unintended behavior.
Fatal Errors
Fatal errors are critical problems that prevent your code from running. These usually point to serious issues like syntax problems or undefined functions.
- E_PARSE (Parse Error)
A parse error occurs when PHP encounters invalid syntax. Since parsing happens before execution, PHP won't even start running your code.
// Missing semicolon after echo statement echo "Hello, world!" echo "This line will never run."; // Parse error: syntax error, unexpected token "echo", expecting "," or ";"
- E_ERROR (Fatal Runtime Error)
A runtime fatal error occurs when the code tries to do something impossible, such as calling a non-existent function or running out of memory. This will immediately halt the script.
// Attempting to call a function that doesn't exist nonExistentFunction(); echo "This line will never run."; // Fatal error: Uncaught Error: Call to undefined function nonExistentFunction()
From PHP 7 onwards, these are thrown as Error exceptions, so you can catch them:
try { nonExistentFunction(); } catch (Error $e) { echo "Caught fatal error: " . $e->getMessage(); } // Caught fatal error: Call to undefined function nonExistentFunction()
Non-Fatal Errors
Non-fatal errors are warnings or notices that don't stop execution but indicate something is wrong or risky. Ignoring them can lead to subtle bugs.
- E_WARNING (Warning)
A warning indicates a problem but does not stop the script. Warnings often occur when working with external resources (files, database connections).
// Trying to open a non-existent file $file = fopen("nonexistent.txt", "r"); echo "Script continues running."; // Warning: fopen(nonexistent.txt): Failed to open stream: No such file or directory
- E_NOTICE (Notice)
Notices were historically emitted for minor problems that are less urgent than warnings, such as accessing an undefined variable. However, the PHP 8.x release cycle has promoted the most common notices into warnings in recognition that they're still likely to cause problems in your program. There are now few notices remaining and it's best to treat them similarly to warnings.
- E_DEPRECATED (Deprecated)
Deprecated errors trigger when you run code that won't work in a future PHP version, such as calling a function that's planned to be removed. You don't need to fix these errors immediately, but they'll have to be dealt with before you upgrade to the next major PHP release.
Setting the PHP Error Reporting Level
You can configure which error levels are reported by calling the error_reporting() function or setting the error_reporting config value in your php.ini file. The value must be an integer that's calculated as a bitmask of the PHP error level constants discussed above.
// Report all errors except Notices and Deprecations error_reporting(E_ALL & E_NOTICE & E_DEPRECATED);
It's common practice to reduce PHP's error reporting level in production environments. This helps stop your logs becoming too noisy. However, it's best to have all errors reported during development so you can easily find and fix possible issues with your code. Notices and deprecations don't usually require urgent attention, but you should still be aware that they're being emitted.
Debugging Common PHP Errors
Now we've discussed PHP's built-in error types, let's look at some of the most regularly seen real-world errors. This isn't an exhaustive list of errors you could encounter, but it should give you an effective starting point for diagnosing common problems.
- Undefined Variable
Undefined variable warnings are emitted when you use a variable that doesn't exist in your code's scope. It's often caused by code similar to the following:
if (file_exists("/demo")) { $demo = "file"; } echo $demo; // Warning: Undefined variable $demo
In the example, the $demo variable is only defined if the file_exists("/demo") function returns true.
- Cannot Use Object as Array
Cannot use object of type ... as array errors mean that you've tried to use an instance of a class as an array. It's easy to make this mistake when you're refactoring older applications that used to store data in associative arrays, but which now use classes instead.
class User { public function __construct( public readonly string $username, public readonly bool $active = true ) {} } $myUser = new User("demo"); echo ($myUser["active"] ? "active" : "inactive"); // Fatal error: Uncaught Error: Cannot use object of type User as array
In this example, although the User class has a property called active, it can't be accessed using array syntax. This is a fatal error so it will halt your application.
- Cannot Modify Header Information
The Cannot modify header information - headers already sent warning is a common frustration when you're manually assembling HTTP responses. It occurs when you try to set a response header after you've already emitted some body data:
echo "Hello World!"; header("Demo-Header: foobar"); // PHP Warning: Cannot modify header information - headers already sent
The problem is that HTTP responses require their headers to be sent ahead of their body content. PHP's echo statement writes to the body, so in this example the headers have already been closed and sent before the header() function is called.
- Undefined Array Key
Undefined array key warnings are some of the most commonly encountered PHP errors. They occur when you try to access an array index that isn't actually set:
$list = ["a", "b", "c"]; echo $list[3]; // Warning: Undefined array key 3 $assoc = ["a" => "x", "b" => "y", "c" => "z"]; echo $assoc["d"]; // Warning: Undefined array key "d"
To prevent this error from occurring, you must check that array indexes are defined before you access them. You can use isset(), array_key_exists(), or the null coalescing (??) operator.
- TypeError
PHP throws a TypeError exception whenever a type mismatch occurs. Common causes include passing an incorrect value to a function or returning an incorrect value from one:
declare(strict_types=1); function sum(int $a, int $b): int { return ($a + $b); } echo sum(10, "5"); // Fatal error: Uncaught TypeError: sum(): Argument #2 ($b) must be of type int, string given
Debug this error by checking the value types assigned to each of your variables. Types must be compatible with the typehints you've placed on each function, class, or interface.
- ArgumentCountError
An ArgumentCountError exception is thrown when you call a PHP function without specifying a value for one of its required arguments:
function sum(int $a, int $b): int { return ($a + $b); } echo sum(10); // Fatal error: Uncaught ArgumentCountError: Too few arguments to function sum(), 1 passed
In this example, sum() has two arguments, neither of which have default values, but only one value is passed in the function call.
- Class Not Found and Call to Undefined Function
Class ... not found is a fatal error that's triggered when you try to instantiate an instance of an unknown class:
$myUser = new User("demo"); // Fatal error: Uncaught Error: Class "User" not found
Similarly, call to undefined function means you've tried to call a function that doesn't exist in the current namespace:
createNewUser("demo"); // Fatal error: Uncaught Error: Call to undefined function createNewUser()
These errors are normally due to one of two causes:
- Cannot Redeclare Function
A cannot redeclare function fatal error means you've defined a function with the same name twice:
function sum(int $a, int $b): int { return ($a + $b); } function sum(int $a, int $b): int { return ($a - $b); } // Fatal error: Cannot redeclare sum()
- Failed to Open Stream
Failed to open stream warnings are emitted from PHP's stream handlers when a stream can't be created. This often happens when you're using the HTTP stream wrapper to load content from a webpage that doesn't exist, for example:
$content = file_get_contents("http://app.dev/example"); // Warning: file_get_contents(): php_network_getaddresses: getaddrinfo for app.dev failed // Warning: file_get_contents(http://app.dev/example): Failed to open stream
- Invalid Argument Supplied for Foreach
You'll see this warning when you try to iterate over an invalid value using foreach(). Only arrays and objects can be used for iteration; any other type of value will skip the loop and show the warning.
This error is commonly seen when you try to iterate a value that's sometimes a valid array or object, but could be undefined or null:
$items = null; foreach ($items as $i) { echo $i->name; } // Warning: foreach() argument must be of type array|object, null given
- Division By Zero
PHP doesn't support dividing numbers by zero - the operation is mathematically undefined. A DivisionByZeroError exception is thrown if your code uses zero as a denominator. This can happen if you don't properly check your inputs to ensure they're valid values:
$hoursPerDay = 8; $meetingLength = 0; echo ($hoursPerDay / $meetingLength); // Fatal error: Uncaught DivisionByZeroError: Division by zero
- Include and Require Errors
You may encounter errors when using include(), include_once(), require(), and require_once() to load other PHP files in your script. The errors are variations of the failed to open stream message detailed above, but will also display Failed opening <file> for inclusion afterwards.
include("demo.php"); // Warning: include(demo.php): Failed to open stream: No such file or directory // Warning: include(): Failed opening 'demo.php' for inclusion require("demo.php"); // Warning: require(demo.php): Failed to open stream: No such file or directory // Fatal error: Uncaught Error: Failed opening required 'demo.php'
As shown by this example, include() and include_once() failures only trigger a warning - your script will continue, but the file won't have been included. The require() and require_once() variants will trigger a fatal error if the file can't be loaded, causing your script to terminate. To fix these errors, it's important to check that the included file exists and is accessible to the PHP process.
- Maximum Execution Time Exceeded Errors
PHP caps the maximum time that your scripts can run for. By default, the value is set to 30 seconds, unless you've manually started PHP from your terminal. This helps ensure that web requests don't stay blocked for too long if an operation becomes stuck.
You'll see a maximum execution time exceeded error if your script runs for longer than the configured time:
set_time_limit(5); while (true) { // ... } // Triggers after 5 seconds // Fatal error: Maximum execution time of 5 seconds exceeded
- Undefined Constant
An undefined constant fatal error means you've tried to access the value of a constant that hasn't been set:
echo DEMO; // Fatal error: Uncaught Error: Undefined constant "DEMO"
Source: Orkhan Alishov's notes