One thing to note is that whilst it may be reusable, it also contains no integrity and open to privacy violations between objects. Making use of PHP's magic property setting chained with PHP's datatype weakness means I cannot verify for 100% certainty that an object property is that of what I expect. It also makes debugging far more complex since I cannot tell at compile time what the properties are, only at runtime.
So in a full OO system you would presumably have a BlogPost object and you can have a BlogPosts collection of BlogPost objects. The problem with the magic properties is when I attempt to dereference the BlogPosts for a BlogPost, there is now no integrity to verify with 100% certainty that it will dereference to the proper datatype (since the properties are all public). Fortunately, with mysqli that is very easy to get around:
// add getters and setters
abstract class GenericArrayObject extends ArrayObject
public abstract function validate($data);
public function offsetSet($key, $val)
throw new InvalidArgumentException('Provided data does not fit into generic collection!');
// add some utility methods if you like. I'll use pop in my example
public function pop()
$ret = $this[count($this) - 1];
$this->offsetUnset(count($this) - 1);
class BlogPosts extends GenericArrayObject
public function validate($data)
$bResult = true;
if ($data != null && !($data instanceof BlogPost))
$bResult = false;
// and used by:
$query = "SELECT id, blog_name, content, new_blog_date, update_date, username FROM pages ORDER by id DESC";
$result = $database->query($query);
$blogposts = new BlogPosts();
while($blogposts = $result->fetch_object('BlogPost') or $blogposts->pop());
Simple as that. MySQLi is privileged and ignores the scope violation on the objects whilst setting a fetch_object to a class. There is a trick to this though, fetch_object will set the properties *before* calling the constructor. This means that the constructor must accept only optional arguments (if any), and an additional check would be done to massage the data as needed. Since they are set, you can check the value of them and cast to appropriate types, otherwise, set them as provided in the constructor. It's a shame that they didn't choose the __set functionality instead which could be chained directly to setters via reflection.
So in a full blown OO application, you would opt for writing the classes with integrity as needed since you need the objects anyway. You would then exploit the mysqli setting of the object and then calling the constructor to typecast anything you need. Now I get to keep my integrity rules, and have easy setting of my objects from a database (sorta, it will complicate the use of objects of objects of course, but I can get around that by writing an intermediate class to massage the data more).