Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php oop MVC design - proper architecture for an application to edit data

Now that I have read an awfull lot of posts, articles, questions and answers on OOP, MVC and design patterns, I still have questions on what is the best way to build what i want to build.

My little framework is build in an MVC fashion. It uses smarty as the viewer and I have a class set up as the controller that is called from the url.

Now where I think I get lost is in the model part. I might be mixing models and classes/objects to much (or to little).

Anyway an example. When the aim is to get a list of users that reside in my database:

the application is called by e.g. "users/list" The controller then runs the function list, that opens an instance of a class "user" and requests that class to retrieve a list from the table. once returned to the controller, the controller pushes it to the viewer by assigning the result set (an array) to the template and setting the template. The user would then click on a line in the table that would tell the controler to start "user/edit" for example - which would in return create a form and fill that with the user data for me to edit.

so far so good.

right now i have all of that combined in one user class - so that class would have a function create, getMeAListOfUsers, update etc and properties like hairType and noseSize. But proper oop design would want me to seperate "user" (with properties like, login name, big nose, curly hair) from "getme a list of users" what would feel more like a "user manager class".

If I would implement a user manager class, how should that look like then? should it be an object (can't really compare it to a real world thing) or should it be an class with just public functions so that it more or less looks like a set of functions.

Should it return an array of found records (like: array([0]=>array("firstname"=>"dirk", "lastname"=>"diggler")) or should it return an array of objects.

All of that is still a bit confusing to me, and I wonder if anyone can give me a little insight on how to do approach this the best way.

like image 380
half-a-nerd Avatar asked Feb 22 '23 01:02

half-a-nerd


2 Answers

The level of abstraction you need for your processing and data (Business Logic) depends on your needs. For example for an application with Transaction Scripts (which probably is the case with your design), the class you describe that fetches and updates the data from the database sounds valid to me.

You can generalize things a bit more by using a Table Data Gateway, Row Data Gateway or Active Record even.

If you get the feeling that you then duplicate a lot of code in your transaction scripts, you might want to create your own Domain Model with a Data Mapper. However, I would not just blindly do this from the beginning because this needs much more code to get started. Also it's not wise to write a Data Mapper on your own but to use an existing component for that. Doctrine is such a component in PHP.

Another existing ORM (Object Relational Mapper) component is Propel which provides Active Records.

If you're just looking for a quick way to query your database, you might find NotORM inspiring.


You can find the Patterns listed in italics in

  • http://martinfowler.com/eaaCatalog/index.html

which lists all patterns in the book Patterns of Enterprise Application Architecture.

like image 192
hakre Avatar answered Feb 24 '23 14:02

hakre


I'm not an expert at this but have recently done pretty much exactly the same thing. The way I set it up is that I have one class for several rows (Users) and one class for one row (User). The "several rows class" is basically just a collection of (static) functions and they are used to retrieve row(s) from a table, like so:

$fiveLatestUsers = Users::getByDate(5);

And that returns an array of User objects. Each User object then has methods for retrieving the fields in the table (like $user->getUsername() or $user->getEmail() etc). I used to just return an associative array but then you run into occasions where you want to modify the data before it is returned and that's where having a class with methods for each field makes a lot of sense.

Edit: The User object also have methods for updating and deleting the current row;

$user->setUsername('Gandalf');
$user->save();
$user->delete();
like image 44
powerbuoy Avatar answered Feb 24 '23 14:02

powerbuoy