How to Fix Fatal Error When Using Simple HTML DOM to Parse External HTML

I recently ran into a frustrating error while working on a small PHP project where I wanted to scrape parcel tracking information from TNT’s tracking website using Simple HTML DOM. Instead of getting the latest status, I was greeted with this nasty fatal error:

Fatal error: Call to a member function find() on a non-object

At first, I was scratching my head. But once I dug in, I realized the issue wasn’t actually in Simple HTML DOM itself — it was in the way I was calling it.

The Error Explain

Here’s the snippet I first wrote:

<?php 
include("simple_html_dom.php");

$html = file_get_html('http://www.tnt.com/webtracker/tracking.do?&cons=323626321');

$e = $html->find('table.appTable', 1)->find('tr[valign=top]', 0)->find('td', 3);

echo $e;
?>

The error occurs because one of the find() calls is returning null. When $html or any intermediate result is null, PHP throws a fatal error if I try to call ->find() on it.

This usually happens when:

  • The URL is not reachable (blocked, timeout, or allow_url_fopen disabled).
  • The HTML structure is different than I expect (for example, no table.appTable).

How I Fixed It

The solution was simple but powerful: always check if the object exists before calling find().

Here’s the updated version:

<?php 
include("simple_html_dom.php");

$html = file_get_html('http://www.tnt.com/webtracker/tracking.do?&cons=323626321');

if (!$html) {
    die("Error: Could not fetch HTML. Check your URL or network settings.");
}

$table = $html->find('table.appTable', 1);
if ($table) {
    $row = $table->find('tr[valign=top]', 0);
    if ($row) {
        $cell = $row->find('td', 3);
        if ($cell) {
            echo $cell->plaintext;
        } else {
            echo "Error: Could not find the required <td> element.";
        }
    } else {
        echo "Error: Could not find the required row.";
    }
} else {
    echo "Error: Could not find table.appTable.";
}
?>

Now, instead of crashing, the script gracefully tells me what went wrong.

Extra Practice Functionality

After fixing the fatal error, I decided to extend the project to practice more with Simple HTML DOM. Here are some enhancements I added:

Extract All Tracking Updates

Instead of just grabbing a single cell, I looped through the whole table:

<?php
foreach ($html->find('table.appTable tr[valign=top]') as $row) {
    $cells = $row->find('td');
    if (count($cells) > 3) {
        echo "Status: " . $cells[3]->plaintext . "<br>";
    }
}
?>

Save Results to a Log File

This way, I could keep a history of my parcel statuses.

<?php
$logfile = "tracking_log.txt";
file_put_contents($logfile, "Latest update: " . $cell->plaintext . "\n", FILE_APPEND);
echo "Status logged to $logfile";
?>

Parse Another Website

For fun, I tested the library with Google to pull all image sources:

<?php
$html = file_get_html('https://www.google.com/');
foreach ($html->find('img') as $element) {
    echo "Image: " . $element->src . "<br>";
}
?

Pro Tips I Learn

  • If file_get_contents is disabled on your server, switch to cURL:
<?php
function curl_get_html($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($ch);
    curl_close($ch);
    return str_get_html($data);
}

$html = curl_get_html('http://www.tnt.com/webtracker/tracking.do?&cons=323626321');
?>
  • Always check for null before chaining find().
  • Use ->plaintext if you only need clean text without HTML tags.

Final Thought

When I first hit the find() on a non-object error, I thought Simple HTML DOM was broken. In reality, the issue was my assumption that the structure would always be there. By adding defensive checks and experimenting with new features like logging and looping through all updates, I not only fixed the error but also turned it into a learning project.

Related blog posts