Porting Rails’ ActiveRecord find_by_attributes method to PHP

Ruby on Rails’ ActiveRecord class has some really neat features, none more so perhaps than the incredibly useful find_by_attributes method. With object-oriented PHP programming we can bring that functionality to our PHP applications using PHP’s magic methods.

Create some classes

To get started, we’ll need our own ActiveRecord class. Let’s call it ActiveRecord, that seems like a sensible idea!

Now we want to call this method when we’re looking for pages, or other content, so we’ll also create a Page class that extends this ActiveRecord class:

Using method overloading

For this to work we’re going to use some method overloading – that essentially means we’re going to force PHP to look at a magic method we write before trying to find a function with the called method name in our classes. To do this we’ll be using the method __callStatic like so:

So let’s break look at how we might want to use this… in Ruby on Rails, if you want to find a page that has an enabled flag set to 1 and a unique identifier like a handle, you might use:

So in PHP, our equivalent will be:

Getting the key/value pairs for our query

Now we’ll need to add some logic into our ActiveRecord class to break up the method name and use it with the arguments to get the combination of key/value pairs:

Working out the database table name with late static binding

After doing the above, we now have an associative array of fields and their values which we can use in our SQL query. What we need to work out now is what the table name is. How you do this is up to you, personally I favour using singular table names that are underscore-separated equivalents to their CamelCase class name counterparts, so for the “Page” class it would simply be “page”, and for classes like “SalesOrder” the table name would be “sales_order”. If you want to save time you can always assign a table name variable to each class and use  self::$table_name to retrieve it. If however you’d like to do it the way I describe above, you’ll need a function in your ActiveRecord class to convert your CamelCase strings into underscore-separated table names:

We can now use this function in conjunction with PHP’s late static binding to get the table name for the class we’re using:

Getting some results

Now all we need to do is build a SQL query to fetch the result(s) for our conditions from the table in question – here’s a MySQL example – and to return the results:

Putting it all together

We now have all we need in order to use Ruby on Rails style ActiveRecord find_by_attributes methods with our PHP classes; the completed ActiveRecord class should look like this:

Taking it further

If you want to build on this you could introduce some error handling – the above would return an empty array if no results were found, but maybe you’d prefer to always assume they’re looking for one unique object, so you could throw an Exception if there was no unique object found using the given parameters.