Simple Html Dom Fatal error: Call to a member function on a non-object

Simple Html Dom is a PHP dom manipulator. This library is one of the easiest and most powerful dom manipulator for PHP. In fact, you can even use this to create your own web crawler like what i have done. However, Simple Html Dom library isn't perfect. Although you are able to do almost everything without a problem using simple htm dom, the most problematic thing that will happen in a complex program would be to have different combination of URL. The combination of a URL is endless and this can cause simple html dom to fail.

I faced this problem with simple html dom where fatal error keep stopping my php crawler using simple html dom. The fatal error always occurs around "call to a member function on a non-object at...." and when I look at the fatal error link being process, it was perfectly fine. In PHP, we cannot really stop a fatal error without using some black magic which not always work. Like many people would have say, prevention is better than cure. Hence, doing a checking to determine whether the variable is an object before proceeding will definitely fixed this problem. If you think like many other people out there, this is most likely what you would have done and bet that it will definitely fix your problem.

$html = file_get_html($url);
if(is_object($html)){
   foreach($html->find('img') as $img){
      //bla bla bla..
   }
}

Well, the above might work in some case but not all. when file_get_html failed, it will return false regardless of 404 or 500 occurs on the other side of the server. Hence, you may do this as well,

$html = file_get_html($url);
if($html){
   foreach($html->find('img') as $img){
      //bla bla bla..
   }
}

But if it still doesn't solve your problem which it really shouldn't be able to take care of all cases, you might turn to do the following,

$html = file_get_html($url);
if($html && is_object($html)){
   foreach($html->find('img') as $img){
      //bla bla bla..
   }
}

Well, if this still doesn't work and your brain is stuck, you might feel lucky this time that you come to this blog of mine.

Simple_Html_Dom Fatal Error Solution

The solution for your problem is actually quite simple but not direct. However, i have tested this with almost few hundred thousands of different URL so i can confirm you that this will definitely solve your fatal error and get rid of the "call to a member function on a non-object" especially when it reaches "find". The solution is simple, using the above example, we will just have to add in a condition where it doesn't fail and the object was created by simple html dom class but it doesn't contain any node! In this case, you should write something like the following,

$html = file_get_html($url);
if($html && is_object($html) && isset($html->nodes)){
   foreach($html->find('img') as $img){
      //bla bla bla..
   }
}

In the above example, i uses all the true condition but in my real program i was using all the false condition (is false). But it should still works. I tested this for a few days as the bot was required to run for a few lots of hours before i bang into a fatal error. This is really a wasteful of time. But the solution is rewarding. I hope this help some fellow out there 🙂

Closing new tab on Google Chrome Extension

This is something very new which i recently having problem with. I would like to open a new website and check for a certain criteria in my google chrome extension and close that particular new tab that i just open using chrome.tabs.create. However, the following code doesn't work when i inject the code into the new tab

windows.close();

The condition of closing a new tab has been fulfilled however i am not able to close that tab. Google for a few times doesn't give me any answer to my question until i try something new and it works. Looking at the below code,

chrome.tabs.create({'url': tab.url + 'feed/'}, 
function(tab) {
	$("#url").val(tab.url.replace("feed/",""));
	chrome.tabs.executeScript(tab.id, {code: "this.close();"});
});

take note that i uses chrome.tabs.create to open up a new tab on my google chrome extension. After i validate my url i injected a close command using "this" instead of "windows" with the id of the tab i just open. Apparently, it works!

Hope it helps someone 🙂

Installing WordPress using cpAddons – You do not have sufficient permissions to access this page.

I have a problem today using cpAddons to install my WordPress into one of my subdirectory. I receive "You do not have sufficient permissions to access this page." error upon logging into my WordPress panel. I believe this is not the first time i encounter this problem but this problem only appear if you are not using the default database "wp" as suggested by cpAddons. I google around for a while but didn't get the answer i want or any valuable solution. Hence, i debugged it myself.

Apparently,  everything generated by cpanel cpAddons was correct. The database data and wp-config.php was set correctly. Even the database user permission was also correctly given.  The file permission of wp-config.php was correct.

Now, i remove all the tables generated by cpAddons and run through WordPress configuration page and setup the WordPress installation again. This will install all the tables that i just deleted into the database. Guess what? It works. This means that the database tables installed by cpAddons is a buggy one. Therefore, we will have to erase the tables through phpmyadmin so that WordPress can be install correctly.

Step by step guide to write a Google Chrome Extension

I have absolutely no experience in writing a Google Chrome Extension myself. But if i can do it. I believe majority of the developer will want to know how i did it and what are the process that involve for me to accomplish this task. Hence, i write this out hopefully people get the idea of how Google Chrome Extension is build and how easy it is to make one once you understand the rule involve in building a google chrome extension. On Google Chrome Extension "Getting Started" page, it's pretty simple and straight forward for anyone to build an app in that scale. However, understanding it will be the task i'm gonna set out for. Hopefully this will be short and easy to understand. Let's start.

Getting Started with Google Chrome Extension

Like many people out there, i started with "HELLO WORLD". Basically you need the following item for a simple Google Chrome extension.

  • a Folder to keep all your files
  • a manifest.json which is also a config file for Google Chrome Extension
  • png or ico image which act as a logo to represent your extension
  • html file which is the display of your chrome extension.

Once you have the above 4 things, your chrome extension is ready to build.  You can head down to the Google Chrome Extension "Getting Started" page to do the above and jump back here to what i wanted to do.

Description of my Google Chrome Extension

Before i get started, just wanted to explain a little bit on what i am going to do and what are the requirement of my extension. I am building a private extension for one of my website to ease my job a little bit. Here are the sequence of this Google Chrome Extension.

  1. I need a chrome extension (obviously)
  2. upon clicking on the extension, it should present me with a form
  3. within the form, the extension should determine the page "url" and "what is the title of the page" and place the correct url and title into the form.
  4. Once i click on the submit button, it will post the record to my website and submit this website feed.

A pretty straight forward chrome extension for any developer but for a starter, this is pretty interesting on how it can be done.

Setup the manifest.json file

Before anything, i believe the most important thing to start would be on the setup file. And here is what i have

{
"name": "PRIVATE SUBMIT",
"version": "1.0",
"description": "PRIVATE app to submit a website into for viewing",
"permissions": ["tabs", "http://*/*"],
"browser_action": {"default_icon": "icon.png","popup": "form.html"}
}

some explanation. Here we are giving permission to any tab with any URL other than https url. The name, description and version is self explained. The browser action is what our extension on the browser looks and will do for us. default icon is an image and popup. That's all we need on your manifest.json.

Our form

Here will list out the form i have when it pop up upon clicking on the extension. I have also added jQuery library from google code into my google chrome extensionfor my conveniences.

<div>
<label for="name">Name*</label>
<input id="name" class="input" type="text" name="name" value="" />
</div>

<div>
<label for="url">URL*</label>
<input id="url" class="input" type="text" name="url" value="" />
</div>

<div class="submit"><input id="button" class="button" type="button" value="Submit!" /></div>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

<script type="text/javascript">
  chrome.extension.onConnect.addListener(function(port) {
    var tab = port.sender.tab;

    // This will get called by the content script we execute in
    // the tab as a result of the user pressing the browser action.
    port.onMessage.addListener(function(info) {
      $("#url").val(tab.url);
      $("#name").val(info.title);
  	});
  });

      chrome.tabs.executeScript(null, {file: "content_script.js"});

$(document).ready(function() {

  $('#button').click(function(){
	var name	= $("#name").val(),
	    url		= $('#url').val();
	$.ajax({
            type: "POST", //or GET
            url: "http://private.com/submitasite/",
            data: {
  		name: name,
  		url: url},
            crossDomain:true,
            cache:false,
            async:false,
            success: function(msg){
              console.log(msg);
           },
           error: function(jxhr){
               console.log(jxhr.responseText);
                //do some thing
           }
         });
  	return false;
  });
});
</script>

Upon execution of the popup when a user clicked on the extension, the form will first load out and execute a programming executed content_script.js to fetch some data from the current website page. It will fetch the title of the page and pass it back to the listener where it will store it into our textfield. Now, all we have to do is click on the submit button where the ajax will be fired to wherever your service is located. Before that, you will also need the instruction of the content script.

var additionalInfo = {
  "title": document.title,
};
chrome.extension.connect().postMessage(additionalInfo);

The content script is pretty straight forward. We create a json object and post it to our extension where everything else is explained previously. For the backend part, you should know what to do right? 🙂

Sending data from background.html to popup display in Google Chrome Extension

You are trying to send data from your background.html back to your popup display in your google chrome extension. However, all you read was sending using message in google chrome to initial a one way message from your background.html to your content_script.js. But you do not understand why they are using a "tabs" api instead of extensions since you are still talking to your extension instead of the page itself.

Well, you are not wrong here to question the answer given from your result. The reason being is that you do not need to send data from background.html to your popup display. The reason is pretty simple, they are not separated. However, you do not know how to update the popup display when you get the data on your background.html. I believe the issue is similar to the one i previously written. You do not need that additional background.html if you are going to update your popup display and not working with other extension. All you have to do is write all your listener (assuming content_script is firing up to the extension) to your popup display. And you should get all you want in popup display without getting all headache about background.html not working etc. Hence,

  1. Copy all your background.html code into popup display
  2. Remove background.html entirely on manifest.json
  3. Now try to update like a normal page on your popup display
And it should do the trick. Hope it helps 🙂