Question
Understanding Common PHP Errors, Warnings, and Notices
Question
In PHP, I keep encountering error messages such as warnings, notices, parse errors, and fatal errors, but I do not understand what they mean or how to fix them.
Examples include messages like:
Warning: Cannot modify header information - headers already sentFatal error: Call to a member function ... on nullNotice: Undefined variableWarning: Undefined array keyParse error: syntax error, unexpected T_VARIABLEWarning: foreach() argument must be of type array|object, string given
I want a general reference for understanding these kinds of PHP errors:
- what each category means
- why it happens
- how to debug it
- how to apply the fix to my own code
The goal is not just to fix one specific line, but to understand the root cause of common PHP error messages so I can solve similar problems in any PHP project.
Short Answer
By the end of this page, you will understand the main categories of PHP errors, what common messages are trying to tell you, and how to debug them systematically. You will also learn practical patterns for preventing common mistakes such as undefined variables, invalid array access, header issues, null method calls, and syntax errors.
Concept
PHP error messages are not random: they are clues about what the engine expected, what it actually received, and where the problem happened.
In beginner-friendly terms, most PHP problems fall into a few broad groups:
1. Parse errors
These happen before your program runs. PHP cannot understand the code because of invalid syntax.
Examples:
if ($x > 10 {
echo "Hi";
}
The missing ) causes a parse error.
2. Warnings
Warnings mean PHP was able to continue running, but something is wrong or risky.
Examples:
- including a missing file
- using the wrong type in a function
- sending headers after output
Warnings should not be ignored. They often lead to broken behavior later.
3. Notices
Notices usually point to small but important mistakes, such as using a variable that was never defined.
Example:
echo $name;
If $name was never assigned, PHP raises an undefined variable notice.
Even though older PHP code sometimes treated notices casually, they often reveal real bugs.
4. Fatal errors
Fatal errors stop execution. PHP cannot continue.
Examples:
- calling a function that does not exist
- calling a method on
null - type mismatches in strict contexts
Why this matters
In real programming, reading errors well saves time. Most debugging is not guessing; it is translating the message.
A typical PHP error tells you:
- severity: notice, warning, fatal error, parse error
- problem: what went wrong
- location: file and line number
For example:
Warning: Undefined array key "email" in /var/www/app.php on line 12
This tells you:
- the issue is a warning
- the missing key is
email - it happened in
app.php - the problematic access is around line 12
Once you understand this structure, debugging becomes much easier.
Mental Model
Think of PHP as a strict assistant following instructions.
- A parse error means your instructions are written in broken grammar, so the assistant cannot even start.
- A notice means: "I can continue, but I think you forgot something."
- A warning means: "I tried, but this looks unsafe or incorrect."
- A fatal error means: "I cannot continue from here."
Another useful analogy:
- Variables are labeled boxes.
- Arrays are shelves with named or numbered slots.
- Functions are tools.
- Objects are machines with built-in tools called methods.
Many PHP errors happen because:
- you used a box that was never created
- you tried to read a shelf slot that does not exist
- you used the wrong tool for the job
- you tried to call a tool on a machine that is actually
null - you wrote the instructions with invalid syntax
Syntax and Examples
Reading a PHP error message
A PHP error often looks like this:
Warning: Undefined array key "email" in /path/file.php on line 8
Break it into parts:
Warning→ severityUndefined array key "email"→ actual issue/path/file.php→ fileline 8→ location
Example 1: Undefined variable
<?php
$name = "Ava";
echo $name;
echo $age;
Problem:
$agewas never defined.
Fix:
<?php
$name = "Ava";
$age = 25;
echo $name;
echo $age;
Or, if the variable is optional:
<?php
echo $age ?? "Unknown";
Example 2: Undefined array key
<?php
$user = ["name" => "Ava"];
echo $user["email"];
Problem:
- The
emailkey does not exist.
Fix:
<?php
$user = ["name" => "Ava"];
echo $user["email"] ?? "No email provided";
Example 3: Call to a member function on null
<?php
$user = null;
echo $user->getName();
Problem:
$useris not an object.
Fix:
<?php
if ($user !== null) {
echo $user->getName();
} else {
echo "User not found";
}
With the nullsafe operator in modern PHP:
<?php
echo $user?->getName() ?? "User not found";
Example 4: Headers already sent
Broken code:
<?php
echo "Loading...";
header("Location: /dashboard.php");
Problem:
- Output was sent before
header().
Fix:
<?php
header("Location: /dashboard.php");
exit;
Example 5: Parse error
Broken code:
<?php
if ($loggedIn) {
echo "Welcome";
Problem:
- Missing closing
}.
Fix:
<?php
if ($loggedIn) {
echo "Welcome";
}
Step by Step Execution
Consider this example:
<?php
$data = ["count" => 3];
echo $data["count"];
echo $data["total"];
Here is what happens step by step:
- PHP creates an array called
$data. - The array contains one key:
countwith value3. echo $data["count"];works because that key exists.echo $data["total"];fails becausetotalwas never defined in the array.- PHP raises an error such as:
Warning: Undefined array key "total"
A safer version is:
<?php
$data = ["count" => 3];
echo $data["count"];
echo $data["total"] ?? 0;
Now the execution changes:
- PHP checks
$data["total"]. - That key does not exist.
- The null coalescing operator
??uses the fallback value0. - The program continues without the warning.
Another traceable example with a null object:
<?php
$user = null;
$name = $user?->getName() ?? "Guest";
echo $name;
Step by step:
$useris assignednull.$user?->getName()checks whether$useris an object.- Because it is
null, PHP does not call the method. - The result becomes
null. ?? "Guest"provides the fallback.Guestis printed.
Real World Use Cases
PHP errors appear in almost every kind of application.
Form handling
When processing form input, you often access $_POST or $_GET.
$email = $_POST['email'] ?? '';
This avoids undefined key warnings when the field is missing.
Database queries
A query may fail and return false, null, or an empty result. If you assume success and use the result directly, you may get fatal errors or warnings.
$result = $pdo->query($sql);
if ($result === false) {
// handle query failure
}
API responses
External APIs may omit fields or return unexpected structures.
$city = $response['address']['city'] ?? 'Unknown';
Authentication and redirects
Header errors commonly appear in login systems when developers echo content before redirecting.
if (!$loggedIn) {
header('Location: /login.php');
exit;
}
Template rendering
Views often produce notices if variables are not passed consistently.
<h1><?= $title ?? 'Default Title' ?></h1>
File handling
Warnings such as failed to open stream happen when paths are wrong, permissions are missing, or files do not exist.
if (file_exists($path)) {
$content = file_get_contents($path);
}
Real Codebase Usage
In real projects, developers rarely fix errors by patching random lines. They use patterns that make code safer by design.
Guard clauses
Check invalid conditions early and stop before bad data spreads.
<?php
function getUserName(?array $user): string
{
if ($user === null) {
return 'Guest';
}
return $user['name'] ?? 'Guest';
}
Input validation
Never trust request data.
<?php
$email = $_POST['email'] ?? null;
if ($email === null || $email === '') {
$errors[] = 'Email is required.';
}
Early returns
Avoid deeply nested conditions.
<?php
function redirectIfNotLoggedIn(bool $loggedIn): void
{
if ($loggedIn) {
return;
}
header('Location: /login.php');
exit;
}
Defensive array access
Use ??, isset(), or validation before reading array keys.
<?php
$role = $config['role'] ?? 'user';
Error reporting during development
Developers enable full error visibility locally.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
Exceptions and explicit failure handling
Modern code often converts hidden problems into explicit ones.
<?php
$file = 'data.json';
if (!file_exists($file)) {
throw new RuntimeException('Required file not found.');
}
Null handling
Developers avoid assuming a value exists.
<?php
$username = $user?->name ?? 'Guest';
Common Mistakes
1. Ignoring notices and warnings
Beginners sometimes assume only fatal errors matter. That is risky.
A notice like this:
Notice: Undefined variable $total
often means your logic is incomplete.
2. Accessing array keys without checking
Broken code:
<?php
echo $_POST['email'];
Safer version:
<?php
echo $_POST['email'] ?? '';
3. Calling methods on null
Broken code:
<?php
echo $order->customer->getName();
If $order or $order->customer is null, this fails.
Safer version:
<?php
echo $order?->customer?->getName() ?? 'Unknown customer';
4. Sending output before headers
Broken code:
<?php
echo 'Saved';
header('Location: /done.php');
Fix:
- call
header()before output - remove accidental spaces or BOM before
<?php - use
exit;after redirect
5. Misreading the line number
The reported line is where PHP noticed the issue, not always where the mistake started.
For example, a missing quote on one line may cause a parse error on the next line.
6. Using old or removed APIs
Code using mysql_* functions is outdated.
Broken old style:
<?php
$result = mysql_query($sql);
Use mysqli or PDO instead.
7. Mixing types carelessly
Broken code:
<?php
$count = 'ten' + 5;
PHP may raise warnings or type errors depending on the version and context.
Prefer explicit, validated values.
8. Debugging by guessing
A better process is:
- read the full message
- inspect the file and line
- dump the value with
var_dump() - confirm expected type and structure
- add checks before use
Comparisons
| Category | Does execution continue? | Typical cause | Example |
|---|---|---|---|
| Parse error | No | Invalid syntax | Missing ;, }, ) |
| Notice | Usually yes | Missing variable/key, minor issue | Undefined variable |
| Warning | Usually yes | Incorrect usage, missing file, bad type in some cases | Headers already sent |
| Fatal error | No | Unrecoverable problem | Call to a member function on null |
Common related comparisons
| Situation | Risky approach | Safer approach |
|---|---|---|
| Reading request input | $_POST['email'] | $_POST['email'] ?? '' |
| Reading nested object data | $user->profile->name | $user?->profile?->name ?? 'Guest' |
| Redirecting | echo 'Hi'; header(...) | header(...); exit; |
| File loading | file_get_contents($path) | file_exists($path) check first |
| Handling optional values | Assume it exists | Use guards, defaults, or validation |
isset() vs array_key_exists()
| Function | Returns false for missing key | Returns false for key with null value |
|---|---|---|
isset($array['x']) | Yes | Yes |
array_key_exists('x', $array) | Yes | No |
Use isset() when you want to know whether a value is present and not null. Use array_key_exists() when null is still a valid stored value.
Cheat Sheet
Quick debugging checklist
- Read the full error message.
- Identify the severity: parse error, warning, notice, fatal error.
- Go to the file and line number.
- Check the values involved with
var_dump(). - Confirm the expected type: string, array, object,
null, boolean. - Add validation, defaults, or guard clauses.
Common fixes
Undefined variable
$value = $value ?? 'default';
Undefined array key
$email = $_POST['email'] ?? '';
Call to member function on null
$name = $user?->getName() ?? 'Guest';
Headers already sent
header('Location: /home.php');
exit;
Missing file
if (file_exists($path)) {
$content = file_get_contents($path);
}
Show all errors in development
error_reporting(E_ALL);
ini_set('display_errors', '1');
Rules to remember
- Notices and warnings often point to real bugs.
- Fatal errors stop the script.
- Parse errors mean PHP could not understand the code.
- Validate external input.
- Do not assume array keys or object properties exist.
- Redirect before any output.
- Prefer modern APIs like
PDOormysqliover removedmysql_*functions.
FAQ
What is the difference between a PHP warning and a fatal error?
A warning means PHP can usually continue running, but something is wrong. A fatal error stops the script completely.
Are PHP notices important?
Yes. Notices often reveal bugs such as missing variables, missing array keys, or incomplete logic.
Why does PHP say "undefined array key"?
Because you tried to access an array key that does not exist, such as $_POST['email'] when the form field was not submitted.
What does "headers already sent" mean in PHP?
It means output was sent to the browser before calling header() or setcookie(). Headers must be sent first.
Why am I getting "call to a member function on null"?
You are trying to call a method on a variable that is null instead of an object.
How do I debug a PHP error faster?
Read the full message, inspect the file and line, dump the relevant values with var_dump(), and verify the variable type before using it.
Why does a parse error point to the wrong line?
It often points to where PHP noticed the syntax problem, not where it started. Check lines just before the reported line too.
Should I hide PHP errors in production?
Yes. Show detailed errors during development, but log them instead of displaying them in production.
Mini Project
Description
Build a small PHP diagnostic page that safely reads user input, validates optional data, handles missing values, and demonstrates common defensive coding patterns that prevent notices, warnings, and fatal errors.
Goal
Create a PHP page that reads query parameters, displays safe fallback values, and avoids common runtime errors.
Requirements
- Read
name,email, andagefrom the query string using safe defaults. - Display a friendly message even when one or more parameters are missing.
- Validate that
age, if provided, is numeric. - Redirect to another page if a
redirect=1parameter is present, without sending output first. - Avoid undefined variable and undefined array key errors.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.