05.25
I’ve just finished a few weeks’ work writing an ORM library for PHP5. Initially I was going to use one of the existing ORM libraries which are already available, but after researching I discovered that most were either too large and clunky for everyday use, didn’t have enough features, or didn’t conform to my own personal coding preferences. So I decided to code my own from scratch. The result: an ORM library that fits all my current requirements and doesn’t take forever to set up.
To start with I wanted an ORM library which didn’t require much in the way of configuration. I’ve therefore made sure that mine follows the ‘convention over configuration‘ principle, meaning I can get the library set up quickly and effectively, without having to specify every database table, relationship and column that my database models consist of. My conventions currently consist of the following:
- Ensuring all database table names relate to the ORM class we’re using for the model, for example, a Customer model would require a corresponding ‘customers’ database table, where as an Account model would require an ‘accounts’ database table for storing its’ data. The library automatically knows which database table it needs to use through an inflection library, but of course this can also be over-ridden on a per-class basis by setting a static $table property;
- Ensuring that all tables related to ORM classes have an auto-incrementing ‘id’ column for their primary key. I may allow this to be overridable in the future, but for now this should suffice;
- Ensuring that all foreign keys follow their related table’s name prepended with ‘_id’, so an ‘accounts’ database table may have a ‘customer_id’ column, which would link it (many-to-one relationship) to the ‘customers’ table. Once again the inflection class has been used here to work this out automatically.
The whole reason I favour using ORM over writing multiple SQL statements is that for the most common operations (inserting, updating, deleting, selecting, etc) I can put OOP practices to good use to do the hard work for me. I’ve provided some examples below of just how simple it is to use the library currently:
$customer = orm(Customer)->fetch(100); // Fetch customer 100 from the database
$customer->first_name(“John”); // Change the customer’s first name
echo $customer->surname(); // Print out the customer’s surname to screen
orm()->save($customer); // Save the changes back to the database
$account = orm(Account)->fetch_by_domain(“example.com”); // Fetch an account based on a different column
orm(User)->fetch_by_email_address(“joe@bloggs.com”)->delete(); // Delete a user’s record from the database, based on their email address
Of course, for anything more complex (multiple joins across more than one or two tables, unions, sub-selects, etc) I will still need to write the SQL and execute this manually, but this still suits my needs as it is beneficial to be able to see the exact SQL in these cases, rather than it being abstracted by a library.
My ORM library will now be put to good use on the new Hartserver backend, and I may even consider releasing it publically in the future as and when I add even more features to it.