PHP 8.3 Fatal Error Unsupported operand types – Common Causes and Fixes
After upgrading to PHP 8.3 you might suddenly start seeing this error: Fatal error: Unsupported operand types It usually appears when you are using operators like +, -, *, /, ., or += with values that PHP cannot combine anymore as loosely as before. PHP 8.x is stricter than older versions, so code that used to work silently can now break.
Let’s go through the most common situations and how to fix each one.
- 1. Adding numbers to non numeric values
- 2. Using + with arrays when you meant to merge
- 3. Concatenation vs addition: using + instead of .
- 4. Null values in arithmetic and concatenation
- 5. Objects used like numbers
- 6. Mixed data from JSON or database
- 7. Use strict types and type hints to catch issues early
- 8. Quick checklist when you see “Unsupported operand types” in PHP 8.3
1. Adding numbers to non numeric values
A very typical example is using + on values that are not numbers.
$a = "10";
$b = "ABC";
$result = $a + $b; // Fatal error in PHP 8.3
Here $b is a string that cannot be safely converted to a number, so PHP throws a fatal error.
Fix
Validate or cast your data before you perform arithmetic.
$a = "10";
$b = "ABC";
$a = (int) $a;
$b = is_numeric($b) ? (int) $b : 0;
$result = $a + $b;
Or, if you are getting values from a request or database, sanitize them early:
$qty = (int) ($_POST['qty'] ?? 0);
$price = (float) ($_POST['price'] ?? 0);
$total = $qty * $price;
2. Using + with arrays when you meant to merge
Another common source of this error is treating arrays like numbers.
$user = ['name' => 'John'];
$extra = ['role' => 'admin'];
$result = $user + 5; // unsupported operand types
$merged = $user + $extra; // works, but not what many expect
Array plus array uses the keys from the left array. It is not the same as merge, and using non arrays on either side will crash.
Fix
Use array_merge when you want to combine arrays and never mix arrays with non arrays.
$user = ['name' => 'John'];
$extra = ['role' => 'admin'];
$merged = array_merge($user, $extra); // ['name' => 'John', 'role' => 'admin']
If a value might be null, cast it to an array:
$filters = $requestFilters ?? [];
$defaults = ['status' => 'active'];
$mergedFilters = array_merge($defaults, (array) $filters);
3. Concatenation vs addition: using + instead of .
When building strings quickly, it is easy to mix up + and ..
$name = "John";
$msg = "Hello " + $name; // Fatal error
In PHP, + is numeric addition, . is string concatenation.
Fix
Use the dot operator for strings.
$name = "John";
$msg = "Hello " . $name;
If you really expect numbers, convert them:
$total = (int) $a + (int) $b;
4. Null values in arithmetic and concatenation
In many legacy apps a variable might be null and still get used in math. PHP 8.3 is less forgiving.
$discount = null;
$total = 100;
$final = $total - $discount; // unsupported operand types in some cases
Fix
Normalize nulls before using them.
$discount = $discount ?? 0;
$final = $total - $discount;
Or use null coalescing assignment:
$discount ??= 0;
$final = $total - $discount;
For strings:
$title = null;
$label = 'Product: ' . ($title ?? 'N/A');
5. Objects used like numbers
If a function returns an object and you treat it like an integer or float, PHP will complain.
$price = $cart->getTotal(); // returns Money object
$grandTotal = $price + 10; // Fatal error: unsupported operand types
Fix
Decide which value you want from the object. Many value objects have methods like getAmount().
$price = $cart->getTotal(); // Money object
$grandTotal = $price->getAmount() + 10;
If this is your own class, consider adding helper methods or converting it to a primitive explicitly.
6. Mixed data from JSON or database
When you decode JSON or fetch rows from the database, all values may come through as strings. Then this kind of code appears:
$row = [
'qty' => '3',
'price' => 'abc', // corrupted data
];
$total = $row['qty'] * $row['price']; // fatal
Fix
Validate and cast before using them.
$qty = (int) ($row['qty'] ?? 0);
$price = (float) ($row['price'] ?? 0);
$total = $qty * $price;
Consider centralizing this logic in DTOs or model accessors, so you do not repeat casting everywhere.
7. Use strict types and type hints to catch issues early
The best long term fix is to be explicit about types.
At the top of your PHP files you can enable strict mode:
<?php
declare(strict_types=1);
Then use type hints:
function calculateTotal(int $qty, float $price): float
{
return $qty * $price;
}
If you accidentally pass an array or string that is not numeric, PHP will throw a helpful TypeError before you get to the unsupported operand error.
In Laravel or other frameworks, add types to your methods, DTOs, and models wherever possible.
8. Quick checklist when you see “Unsupported operand types” in PHP 8.3
- Look at the exact line and see which operator is being used (
+,-,*,., etc.). - Dump or var_dump the variables to check their actual types.
- Do not mix arrays with numbers or strings when using
+. - Use
.for concatenation, not+. - Convert nulls to safe defaults with
??or explicit casting. - Extract primitive values from objects instead of adding objects directly.
- Add type hints and strict types to catch problems earlier.
Once you get into the habit of being explicit with your types, these fatal errors become rare and much easier to debug when they do happen.