16 December 2008

__get, __set, __construct and MySQL_Result::fetch_object()

I realise this is my first blog post in a long while. Despite the fact that I want to make it interesting, I am terribly busy. However I needed to get this off my chest as it has been bugging me for ages (hopefully it will help some of you!).

While researching faster methods for data retrieval and manipulation for my *TOP SECRET PROJECT* I found that, as of a very recent version of PHP, the MySQL_Result class' method 'fetch_object' allows you to specify a class to dump the object into.

My first thoughts were: fantastic! What a better method than what I was doing previously. I can instantiate an object and set all the properties all of the back of the query - dynamic properties while still inheriting all methods and hard-coded properties... excellent!

As I continued down this route I found some unusual behaviour though. First of all, it appears that a call to $result->fetch_object('Class') makes use of the magic method __set() *EVEN WITHOUT __set() BEING DEFINED IN THE CLASS*. Now there's no note of that in the docs!

So what happens when I do define a __set() method? Interestingly $result->fetch_object('Class') then uses the __set() method I define. Good, it behaves. But then I found something else. A little irritating "bug" is that, upon calling $result->fetch_object('Class'), it constructs the object in an unusual order.

Perhaps it's just me and my thought process, but I would've gone for:

  • Check if __construct() is defined
  • Instantiate object
  • Check if __set() is defined
  • Set properties
However the actual process order is:
  • Check if __set() is defined
  • Set properties
  • Check if __construct() is defined
  • Instantiate object
This threw me a little, especially as there's little documentation detailing the behaviour of MySQL_Result::fetch_object() when overloading with a class name. It does make some sense, but it's not the human way of doing it (if my way is human :P ). I tend to think like 'build box, put toys in', rather than 'pile toys up, build box around toys,' but that's me.

But now I've sorted it and it's out there! Let me know if that helps you.

No comments: