The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Now, as I understand things, there should be a DAO for each table in the database, right? Wouldn't that be overkill? If so, and I use only a single "user_DAO", almost all of my stored queries are going to use long/complicated joins. However, if I do use a seperate DAO/model for every table, how would I set things up?

First of all, I'd like to say that DAO's are not necessarily a part of MVC. My guess is that you picked up that idea because so many threads here about MVC also presented code with a DAO in it.

You are right though, having a DAO for each table in your database is not necessary. Some tables are related to other tables, such as a user_ips table which is related to the users table. I am not exactly sure what the relation between those tables is, but I think that the UserDAO can be responsible for both of them. When there's a one-to-many relation between tables, the 'many' table can be part of the 'one' table DAO's responsibility.

Martin Fowler's Patterns of Enterprise Application Architecture book explains it better. Take a look at the Object-Relational Structural Patterns here, especially the Dependent Mapping, which I think applies to your situation.

From looking at your code, I think you understand the MVC pattern (if there is such a thing as 'the' MVC pattern, but that's another story..) a bit wrong. The fact that you're initiating a ipController and a groupController inside the UserController does not make any sense to me. A Controller's job should be to access and manipulate model data and pass it on to View objects for one specific action / task of an application. In your code this 'task' would be to view information about a User.

Thanks very much for your response. I believe you have pointed me in the right direction to get me past this "road block" I've been fighting. I'll look your code over in more depth later, and perhaps rework it to make sure I understand, especially that last little bit about redundancy.

I'll say it again, DAO (which is a form of object-relational mapping) has *nothing* to do with MVC, which is about separating the concerns of application data, presentation and interface control.

You're right though, you should leave the JOINing of tables to the database system, don't do it in PHP. That may be the easiest way to implement but it is certainly not the most efficient way. There are better ways to map objects to database tables, like the ones described in Martin Fowler's PoEAA.

Joins definitly belong on the DB side of the fence. This may be a problem with the "scope" of your model class. In general, you should be modeling somthing from the real world, like a customer or an order, not a database table. The model should be smart enough to run efficient queries within the domain of that model.

I use Oracle as a database at work, and many of my models simply end up as a mapping of database package functions to class methods, with some possible parameter binding. This keeps the bulk of the "business logic" in the database where it belongs. (I guess you could think of all of my PHP code as a giant "View" with the "Model" being the database )

My host only offers MySQL, and that without BDB or InnoDB type tables. So, I'm stuck doing my joins in PHP. It may not be the most efficient way, but that's the extent of my capabilities and knowlege. Thanks, though.

I understand that a DAO is not part of the MVC. I'm simply building off Harry's tutorials at phppatterns.com. Please keep in mind that I'm still trying to get my head around the MVC concept, and the part I'm having the most difficulty with is the model. After that, where to put specific methods, the controller, or the model. So, please bear with me.

Umm... Using PHP for JOINs ? Never used them myself personally, though for the general interest since the matter has now been brought up, here is the database SQL I use... You should get the general idea of the fields so I won't post the DB schema

At some point think I need to write version 2 of the articles on phppatterns (perhaps when PHP 5 hits the streets).

Where DAOs are concerned, think I need to emphasise the point that they're prime purpose is to limit the number of times you need to repeat the same SQL statement to as few as possible as well as "centralizing" queries in an easy to find / maintain layer.

Think it's not worth trying to use them too hard as a mechanism to be database independent (although it helps not to have queries repeated). Sun promote this as a reason for DAO's here but in practice, most databases have very varying SQL support and often the "temptation" to use the non standard stuff is overwhelming. Think that's really a Sun vs. Oracle issue.

The other thing about DAOs is, implemented as I suggested, they won't entirely limit the impact of, say, a change in a column name to the DAO classes. In my example I had column names turning up in the "view". Another layer is needed to represent a single row from a query which provides accessor methods which remain the same while the underlying fields they fetch may vary. The example of Articles -> Article in the Factory method might help you there. Articles could be a DAO itself or perhaps a class which uses a DAO.

Also it's worth looking at what "persistence layers" like DB_DataObject are doing.

My host only offers MySQL, and that without BDB or InnoDB type tables. So, I'm stuck doing my joins in PHP. It may not be the most efficient way, but that's the extent of my capabilities and knowlege. Thanks, though.
-texdc

This is a problem that many people have, so it frustrates me when I see some the devs say use Postgres or some other dbtype that natively handles foreign key mapping within the db schema. Lots of us dont have this option

But, although you cannot explicitly define the table relationships on MYISAM tables, You CAN still do JOINS on the using a join clauses in your select queries. But I guess you know this, since this is exactly the "problem" you are trying to solve. I fear that using PHP to do your "joins" is going to create a large performance hit on your application because you will be running multiple queries to get the related data from different tables, and even if you don't see a huge performance hit now, you will see later on down the road, after your application has grown, and you are still doing things this way.

shoebox: you're right on target on where I'm at, and where I'm going with this.

Here is what I've cooked up so far. I want to avoid passing the model itself to the view completely to keep them ignorant and separate. Currently, this solution does not allow that approach, but it's helping me understand the whole pattern better.

Note: The model will always instanciate the DAO and the DAO queries will always return a 'result' object.

I started down this path because I was looking at the Composite pattern in the GoF book. It sounded like it would work, but in putting it together, it may not be the best choice for a Model pattern, but I may be wrong. (I know I'm not implementing it in the code above; it was simply inspiration.) What about the Decorator pattern? Any comments or ideas?

I want to avoid passing the model itself to the view completely to keep them ignorant and separate.

Why do you want to do this? Is it a design requirement? The reason I ask is because it seems to make things much easier when you pass a model to view, or view to model.

// there are a lot of queries here, rather than one huge JOIN
// good or bad idea?

Yes I think one large join would be better. Can someone back me up on this?

If you keep doing things the way you mentioned you it seems you will end up writing a custom method for each "getBy()" you want to do.
Perhaps this could be a generic "getById()" method in your parent Model class.

I'm not familiar with Composite.

what about something like this instead??
I'm not familiar with Composite.

But you just described it in action in your prior statement Composite is aggregating objects, so if you pass a model to a view and use them together, you are using a form of the Composite design pattern

I use Oracle as a database at work, and many of my models simply end up as a mapping of database package functions to class methods, with some possible parameter binding. This keeps the bulk of the "business logic" in the database where it belongs. (I guess you could think of all of my PHP code as a giant "View" with the "Model" being the database )

Yay! Someone knows what they are doing! That's exactly how it should work.

Yay! Someone knows what they are doing! [img]images/smilies/smile.gif[/img] That's exactly how it should work.

I too use Oracle at work and also end up doing a lot of mapping like Jason indicates in his message further up this thread.

However, I would like to add that putting the business logic in the DB is not "exactly how it should work". It is simply one way of approaching a solution. And indeed, I think some people (many?) believe the business logic needs to be moved out of databases and into another tier - there are whole companies founded and doing strong business around the concept of "business rules" or "business intelligence" being its own component in an overall architecture....

However, I would like to add that putting the business logic in the DB is not "exactly how it should work". It is simply one way of approaching a solution.

But it's the right one.

Originally Posted by Taoism

And indeed, I think some people (many?) believe the business logic needs to be moved out of databases and into another tier - there are whole companies founded and doing strong business around the concept of "business rules" or "business intelligence" being its own component in an overall architecture....

It depends, really, on your definition of 'business rules', but these people are wrong.

As the old saying goes -- what once was old is now new again. Back-in-the-day people had to write their own data storage mechanisms. Lots of individual libraries which were buggy, hard to maintain, etc. Business rules were handled in the application (also buggy) and so data was, unfortunately, more often invalid than it should be.

Then, the world saw the light and Codd came up with the relational database management system. The whole (well, one of the main ones, I guess) concept of the RDBMS is, in laymans terms, that you encapsulate your business rules, in the form of constraints, into the management system so that you guarantee that the data in your database is logically sound.

In essence, the RDBMS is the intelligence behind business.

The best part is that you, typically, don’t have to code how to implement the business rules – you tell the RDBMS what to enforce and it does the rest. This is cross-platform, easy to read and understand, and virtually bug-free (provided you know what the business rules are ).

This figure from my article Industrial Strength MVC shows one way to architect a MVC application, including some of the recent discussion on this thread regarding moving business logic down to the database layer. I think picturing this "application stack" can help formalize some of the ideas of how to implement "Model-View-Controller" style frameworks in PHP. The yellow bars show the particular libraries I used in the article, but these could easily be changed out for your favorite RDBMS (except for MySQL), db abstraction layer, MVC controller framework and templating engine.