views:

1316

answers:

4

Can someone please derive a concrete example from the following:

http://www.urdalen.com/blog/?p=210

..that shows how to deal with one-to-many and many-to-many relationships?

I've emailed the author some time ago but received no reply. I like his idea, but can't figure out how to implement it beyond simple single table relations.

Note: I don't want to use a full-blown ORM. I like doing my SQL by hand. I would like to improve the design of my app code though. Right now each domain object has its own class full of queries wrapped in static methods. They just return scalar, 1d-array (record) or 2d-array (recordset) depending on the query.

A: 

I think once you get into using relationships it will rapidly get much more complex than the simple example provided. I know you have specifically said you don't want to use an ORM, but I think you would genuinely be better off using something already written.

You would need to somehow store the tablenames/joins of the relationships (and I'm not sure how this would fit within the DataValue / DataMapper 'pattern' provided). Then you probably will need to somehow determine whether the relation-ed records should be fetched via a join from your first query (and then sorting the resultset back into the relevant objects), or by using separate queries.

Again, I know this isn't what you want, but I would recommend php Doctrine as this is standalone and does not force your whole project into MVC.

Tom Haigh
Thanks for your answer tom. This is an established app in production 24/7 for 3 years now. DB has about 42 tables. App has around 100 queries in format mentioned above. Do you still recommend trying to move to phpDoctrine in this case, or is it something best done from the beginning? (continued)
I'm obviously wanting to refactor one step at a time. Introducing an ORM seems like a big move.
In hindsight I think troelskn's answer is clearly better for your situation, so I gave him my vote.
Tom Haigh
+4  A: 

The problem of ORM's (The impedance mismatch, as it's called) is precisely with relations. In an object graph (In-memory objects), relationships are pointers to other objects. In a relational database, relationships are reversed; This makes it impossible to do a simple mapping between the two models, and that is why ORM's are so complex.

If you want to stay close to the database (avoiding an ORM), then you shouldn't try to abstract relationships away. The way I write datamappers is something like the following:

$car42 = $car_gateway->fetch(42);
$wheels = $wheel_gateway->selectByCar($car42);

In contrast to the ORM way:

$car42 = $car_gateway->fetch(42);
$wheels = $car42->selectWheels();

This does mean that the gateways end up in your client-code, but it also keeps things very transparent and close to the database.

troelskn
Thank you for the answer.
A: 

Given your response to Tom's answer, I would recommend that you look at something like Zend Framework. Its ORM has a take it or leave it architecture that can be implemented in stages.

When I came to my present employer, they had an application that had just been completed months previously but had been through one or two prior versions and the current version had been in development six months longer than it was supposed to have been. However, the code base was mess. For example there was no abstraction between the database access logic and the business logic. And, they wanted me to move the site forward building new functionality, extending existing features, and fixing existing bugs in the code. To further complicate things they weren't using any form of sanitation on data inputs or outputs.

As I started to wade into the problem, I realized that I would need a solution to abstract concerns that could be implemented in steps because they obviously weren't going to go for a complete rewrite. My initial approach was to write a custom ORM and DAL that would do the heavy lifting for me. It worked great because it didn't intrude on the existing code base, and so it allowed me to move entire portions of the application to the new architecture in an unobtrusive manner.

However, after having ported a large portion of the user's area of our site to this new structure and having built an entire application on my custom framework (which has come to also include a custom front-end controller and mvc implementation), I am switching to Zend Framework (this is my choice though I am certain that some of the other frameworks would also work in this situation).

In switching to the Zend Framework I have absolutely no concerns about the legacy code base because:

  • I can build new models and refactor old models (built on my custom framework) unobtrusively.
  • I can refactor the existing controllers (such as they are) to be wrapped within a class that behaves in a manner consistent with Zend's MVC framework so that it becomes a minor issue to actually begin using Zend's Front-End Controller.
  • Our views are already built in Smarty so I don't have to worry about separating controller and view logic, but I will be able to extend the Zend Framework so that I can render existing templates in Smarty while building new templates in straight PHP.

Basically, Zend Framework has a take it or leave architecture that makes its a joy to use within existing projects because new code and refactored code doesn't need to intrude on existing code.

Noah Goodrich
Thanks for your answer. I think I will leave things as they are based on troelskn's answer: "If you want to stay close to the database, then you shouldn't try to abstract relationships away." I do want to stay close to DB, because the existing queries work well. (continued)
As such, I only really want to refactor the PHP and not the SQL. I think I try an interface similar to troelskn suggested, which is almost exactly how it is except I don't encapsulate the results in an object.
Just a note on that; Encapsulating entities in objects may seem a bit superfluous in PHP, but I find that it helps to make things more clear.
troelskn
+1  A: 

If you're looking for a simple and portable DataMapper ORM, have a look at phpDataMapper. It's only dependencies are PHP5 and PDO, and it's very small and lightweight. It supports table relations and some other very nice features as well.

Vance Lucas