Call to a member function getName() on null means a variable you expected to hold an object is holding null instead, and PHP tried to call a method on it anyway. The fastest fix is a null check or PHP 8’s nullsafe operator (?->) before the call. The actual fix is finding why it is null in the first place, which is almost always one of three things: a database query that found no matching row, a chained call where an earlier link in the chain silently returned null, or an object that was never constructed because a conditional branch or early return skipped the code that would have created it.
What PHP is telling you
Since PHP 8.0, calling a method on null throws a \Error with exactly this message rather than the older, less specific “call to a member function on a non-object” warning PHP 7 produced. The message names the method you called (getName(), getEmail(), whatever it was) and the file and line where the call happened. It does not tell you why the variable is null, only that it is, at the exact moment your code tried to use it as an object.
Cause 1: a query or lookup that found nothing
This is the single most common source of the error in any codebase that talks to a database or an API:
$user = $userRepository->find($id);
echo $user->getEmail(); // fatal if $id did not match any row
find() (whether it is a Doctrine, Eloquent, or hand-rolled repository method) commonly returns null when nothing matches, by design, rather than throwing an exception. The bug is not in find(). It is in code that assumes a match always exists. The fix is to check before using the result:
$user = $userRepository->find($id);
if ($user === null) {
// handle the missing-user case explicitly
return;
}
echo $user->getEmail();
Cause 2: a chained call where an earlier link returned null
echo $order->getCustomer()->getAddress()->getCity();
Any one of getCustomer(), getAddress(), or getCity() returning null breaks the whole chain, and the error message only names the last method actually called, getCity(), which is not necessarily where the real problem started. If a customer’s address is genuinely optional data, getAddress() returning null is correct behavior, and the bug is downstream code assuming it never happens. PHP 8’s nullsafe operator, from the PHP RFC on nullsafe operators, short-circuits the whole chain safely:
echo $order->getCustomer()?->getAddress()?->getCity() ?? 'Unknown city';
Each ?-> stops the chain and evaluates to null immediately if the value on its left is null, instead of throwing. The final ?? supplies a fallback so the variable being empty is handled deliberately rather than silently. This does not fix a genuine bug where getCustomer() should never be null and is; it correctly handles the cases where null is a legitimate, expected state.
Cause 3: the object was never constructed
class Report {
private ?Logger $logger = null;
public function __construct(bool $withLogging) {
if ($withLogging) {
$this->logger = new Logger();
}
}
public function generate(): void {
$this->logger->info('Generating report'); // fatal if $withLogging was false
}
}
Here $logger is null on purpose, when $withLogging is false, but generate() was written as though the property is always set. This pattern shows up constantly in classes with optional dependencies, feature flags, or constructors with early returns, where one code path initializes a property and another path silently does not. The fix is either a null check at the point of use, or requiring the dependency unconditionally in the constructor so the object genuinely cannot exist in a half-initialized state.
Reading the trace to find which variable it actually was
The error’s own stack trace names the file and line, but not the variable name. Reading a stack trace covers the general method; for this specific error, the fastest confirmation is a var_dump() or a debugger breakpoint on the line just before the failing call:
var_dump($order->getCustomer()); // is this actually null, or is it the next link in the chain?
Working backward one link at a time through a chained call is faster than staring at the final method name, since the error always names the last call attempted, which is frequently not where the actual missing data originated.
Where this connects to two other common fatal errors
An unchecked null is a specific case of a broader habit worth building: never trusting that a value is what you assumed without checking. The same discipline applies to PHP’s allowed memory size exhausted error, where the underlying assumption being wrong (that a loop terminates, or that a dataset is small) produces a different fatal error from the same root cause of unverified assumptions about what a piece of code actually returns.
FAQ
Does the nullsafe operator fix the underlying bug?
No, and this is worth being explicit about. ?-> prevents the fatal error, but if the value being null represents a genuine problem, a user that should exist and does not, for instance, silently continuing with a fallback can hide a bug rather than fix it. Use it where null is a legitimate, expected state, and use an explicit check with proper error handling where null means something actually went wrong.
Is this the same error as “Trying to get property of non-object”?
No, that is a related but different warning, thrown when you try to read a property ($user->email) rather than call a method ($user->getEmail()) on a null value. The diagnosis process, finding why the variable is null, is identical.
Can I use the nullsafe operator in PHP 7?
No. ?-> requires PHP 8.0 or later, per the RFC linked above. On PHP 7, an explicit if ($x !== null) check, or the older isset() pattern, is the equivalent.
Why did this only start happening after I upgraded PHP?
PHP 7 and earlier sometimes emitted a recoverable warning for the equivalent situation and let execution continue with unpredictable results. PHP 8 made this a hard \Error, per the language’s broader move toward converting silent failures into loud ones. The underlying null value was very likely already there; PHP 8 is simply the version that stopped tolerating it quietly.
What is the difference between this and a stack trace showing a deprecation notice instead?
A deprecation notice, like PHP 8.4’s implicitly nullable parameter warning, does not stop execution and often relates directly to this error’s root cause: a parameter that silently accepts null without the type declaration admitting it, which is exactly the kind of undeclared null that later causes a member-function-on-null crash somewhere downstream.
