Share via:

Debugging: Call to a member function query() on null

Why you should not query the database from within the constructor method in your database class.


Edited: 2018-07-27 08:55

One thing that frustrates me about my own code is the level of complexity it has reached. To make matters worse, I seem to have also made some bad decisions early on that are now affecting the entire project I am working on. And, I think, this recently caused a really obvious problem, but one I somehow still struggled to solve.

The code I had was not working as I expected. It turned out I was trying to query the database from within the constructor method of my database class. This will not work, because the database object has not finished instantiating yet.

The exact error I kept getting was this:

PHP Fatal error: Uncaught Error: Call to a member function query() on null in ...

I know this happens if you do not inject objects in classes where they are used (dependency injection), however, I had already done all this. I resorted to Google to find a solution, and people was basically talking about the same thing. So, this did not help me. I had to solve this the hard way. On my own.

Debugging PHP errors

The error log is the first place I look for clues, as to what might be happening. The problem is that, sometimes, this log does not tell you what is wrong, and then you have to figure it out on your own.

Once you reach a certain level of "skill" with coding, you will start to solve problems logically. You do not need to "know" the language you are coding in, since you can just read the code, and make sense of it. I have reached this point (to some degree), which is very valuable in situations like this.

The way I debugged the Call to a member function... issue, was to mentally picture how my code was working. It turned out I was trying to send database queries inside a constructor function of the database class itself. What this basically means is that I was trying to use my database object, before it was instantiated. I logically narrowed down the possible causes to the problem, and found that it must be because the database object was not available in the constructor, since it had not finished instantiating yet.

So, if you have this problem, and you are trying to query the database from within an constructor, either make sure your database object has been properly instantiated before hand, (and injected where needed). Or, you move the queries to a method instead of using the constructor.

It was a really stupid problem, and it caused a delay in my GDPR implementation. Hopefully I will now be able to move on to more interesting things.