Search code examples
phpinheritanceormdoctrinesingle-table-inheritance

Doctrine 1.2 class table inheritance workaround?



ok, first of all, I know this is not possible with 1.2., that is why I'm looking for a workaround.
And no, unfortunately I can't use Doctrine 2, because my shared hosting server is stuck at PHP 5.2.16, and the admin refuses to install PHP 5.3 support.

So, here is my problem, basic parent-child issue:
Lets say I have a base class User and child classes Customer, Seller, Admin.

I have been looking at the inheritance methods: simple (pretty useless IMO), concrete and column aggregation, and even a workaround for "fake class table inheritance" found here.

What I really need is "class table inheritance", in other words User maps to separate table, which contains all shared values, and child tables define map to separate tables defining only their specific columns.

I have given up on perfection :) in PHP<5.3, I really don't care how will it be stored in the db, but my object model NEEDS to have all functionality.

So what is the best choice for a workaround?

This is what I need.

  • Base class definition with shared values (name, username, password, address...)
  • Child classes with all the values (shared and their specific)
  • Child classes should only see their variables, not from other child classes (for instance, Customer should not have workingHours defined, which is a Seller specific value)
  • I have to be able to form relationships on the base class, and on the separate child classes, and these relationships have to be bind to the specific class (for instance User class has to have a relationship to the Address class, Restourant class has to have a relationship to the Orders class, Restourant also has to have the Address relationship defined... but Admin can't have a Orders relationship, because he has nothing to do with orders)

Querying the base table would also be nice, but as I can see this is one of the biggest problems, it is not a must have.

I hope you understand my question. Any advice would be appreciated, because I really don't know what to do here.


Solution

  • I had the very same problem a few days ago, and I chose inherinance by column aggregation. The underlying concept is not the cleanest or most beautiful solution ever invented, but does the trick, and meets all your requirements, except one:

    • The base class (and table) has all the fields user by the child classes.
    • The child classes have all the fields they need.
    • The child classes can access fields belonging to other chields' field.
    • You can freely create relationships in your Doctrine schema using the parent or the child classes.

    The one thing that fails here is that I emphasized with a bold font, but you can easily work it around. You can override the setters and getters in your child classes, like that if anyone tries to access or modify a field on a Seller object that belongs to the Customer, then you do not allow it (throw an exception, return false, etc...).