I've seen various MVC frameworks as well as standalone ORM frameworks for PHP, as well as other ORM questions here; however, most of the questions ask for existing frameworks to get started with, which is not what I'm looking for. (I have also read this SO question, but I'm not sure what to make of it as the answers are vague.)
Instead, I figured I'd learn best by getting my hands dirty and actually writing my own ORM, even a simple one. Except I don't really know how to get started, especially since the code I see in other ORMs is so complicated.
With my PHP 5.2.x (this is important) MVC framework I have a basic custom database abstraction layer, that has:
connect($host, $user, $pass, $base)
, query($sql, $binds)
, etcBut does not have:
EDIT: to clarify, I only have a database abstraction layer. I don't have models yet, but when I implement them I want them to be native ORM models (so to speak), hence this question.
I've read up a little about ORM, and from my understanding they provide a means to further abstract data models from the database itself by representing data as nothing more than PHP-based classes/objects; again, correct me if I am wrong or have missed out in any way.
Still, I'd like some simple tips from anyone else who's dabbled more or less with ORM frameworks. Is there anything else I need to take note of, simple, academic samples for me to refer to, or resources I can read?
Efficient Implement of ORM (Object/Relational Mapping) Use in J2EE Framework: Hibernate. Abstract: Object-relational mapping (ORM) in computer software is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming languages.
ORM Patterns - Active Record and Data Mapper. ORMs provide a high-level database abstraction. They expose a programmatic interface through objects to create, read, delete, and manipulate data while hiding some of the complexity of the database.
ORM stands for Object-Relational Mapping (ORM) is a programming technique for converting data between relational databases and object oriented programming languages such as Java, C#, etc. An ORM system has the following advantages over plain JDBC − Sr.No. Advantages. 1.
They usually look something like this: SELECT * FROM users WHERE email = '[email protected]'; Object-relational-mapping is the idea of being able to write queries like the one above, as well as much more complicated ones, using the object-oriented paradigm of your preferred programming language.
Object-relational mapping (ORM) is a mechanism that makes it possible to address, access and manipulate objects without having to consider how those objects relate to their data sources.
As this question is rather old, I guess you already have had your try at writing an ORM yourself. Nonetheless, as I wrote a custom ORM two years ago, I would still like to share my experience and ideas.
As said I implemented a custom ORM two years ago and even used it with some success in small to medium sized projects. I integrated it in a rather popular CMS which at that time (and even now) lacks such ORM functionality. Furthermore, back then, popular frameworks like Doctrine didn´t really convince me. Much has changed since then and Doctrine 2 evolved in a solid framework, so, if I now had the choice between implementing my own ORM or using one of the popular frameworks like Doctrine 2 for production use, this would be no question at all - use the existing, stable solutions. BUT: implementing such a framework (in a simple manner) was a very valuable learning exercise and it helped me a lot in working with larger open source ORMs, as you get a better understanding for the pitfalls and difficulties associated with object relational mapping.
It is not too difficult to implement basic ORM functionality, but as soon as mapping of relationships between objects come into play, it gets much, much more difficult/interesting.
How did I get started?
What got me hooked was Martin Fowlers book Patterns of Enterprise Application Architecture. If you want to program your own ORM or even if you are just working with some ORM framework, buy this book. It is one of the most valuable resources that cover many of the basic and advanced techniques regarding the field of object relational mapping. Read up on it, you get many great ideas on the patterns behind a ORM.
Basic Architecture
I decided if I would like to use rather an Active Record approach or some kind of Data Mapper. This decision influences on how the data from the database is mapped to the entity. I decided to implement a simple Data Mapper, the same approach as Doctrine 2 or Hibernate in Java uses. Active Record is the approach of the ORM functionality (if you can call it so) in Zend Framework. Active Record is much simpler then a Data Mapper, but also much more limited. Read up on these patterns and check the mentioned frameworks, you get the difference pretty fast. If you decide to go with a Data Mapper, you should also read up on PHPs reflection API.
Querying
I had the ambitious goal to create my own query language, much like DQL in Doctrine or HQL in Hibernate. I soon abondoned that, as writing a custom SQL parser/lexer seemed way to complicated (and it really is!). What I did was to implement a Query Object, in order to encapsulate the information which table is involved in the query (thats important as you need to map the data from the database to the relevant classes for each table).
Querying for an object in my ORM looked like this:
public function findCountryByUid($countryUid) {
$queryObject = new QueryObject();
$queryObject->addSelectFields(new SelectFields('countries', '*'))
->addTable(new Table('countries'))
->addWhere('countries.uid = "' . intval($countryUid) . '"');
$res = $this->findByQuery($queryObject);
return $res->getSingleResult();
}
Configuration
Normally, you also need to have some kind of configuration format, Hibernate uses XML (among others), Doctrine 2 uses PHP annotations, EZComponents uses PHP arrays in its Persistent Object component as config format. Thats what I used, too, it seemed like a natural choice and the CMS I worked with used the PHP configuration format, too.
With that configuration, you define
And thats the information you use in your Data Mapper to map the DB result to objects.
Implementation
I decided to go with a strong test driven approach, because of the complex nature of writing a custom ORM. TDD or not, writing many, many unit tests is a really good idea on such a project. Apart from that: get your hands dirty and keep Fowlers book close. ;-)
As I said it was really worth the effort, but I wouldn´t want to do it again, much because of the mature frameworks that exist nowadays.
I don´t use my ORM anymore, it worked, but lacked many features, among others: lazy loading, component mapping, transaction support, caching, custom types, prepared statements/parameters etc. And it´s performance wasn´t good enough for using it in large scale projects.
Nonetheless, I hope I could give you some starting points in the field of ORM, if you didn´t knew them already. ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With