PHP Fatal Error in cache.php on line 123 $wp_object_cache is non-object

Indeed, you have to be careful when using __destruct.

This is a special function that fires when the object is about to be destroyed. When PHP calls exit (as wp_send_json() does), we do not control in what order PHP will destroy the objects.

So __destruct is very dangerous when it relies on other classes. I’ve seen this causing fatals especially on PHP 5.6, which leads to errors like this:

/**
 * Job destructor
 */
public function __destruct()
{
    $this->logger->commit();
}

Fatal error: Uncaught Error: Call to a member function commit() on null

The Solution

Instead of:

$job = new Job;
wp_send_json($job->start());

Do:

wp_send_json((new Job)->start());

Which is the same as:

$job = new Job;

$results = $job->start();

// Trigger __destruct while we are on a known state
unset($job);

wp_send_json($results);

You have to do this when the PHP process is going to be interrupted by an exit or a die.

wp_send_json() is the most notable example, as we use it a lot and it calls exit right after echoing the JSON string. But this could apply to other functions, like wp_die(), exit, die, etc.

Bottom line, just make sure that a function that uses __destruct is destroyed if the PHP process is going to be interrupted, otherwise, this could cause issues.

Proof of concept: https://3v4l.org/GBBIV

__destruct running on multiple PHP versions

error code: 523