Symfony2: Transformation of database records for displaying - php

I have rather theoretical question about proper approach of using Symfony though I believe the approach is to be same for any other PHP framework.
I have tariff objects stored in database. I want to provide a cost model for each tariff basing on user input.
My initial approach was to create an array, one's each element would contain data from corresponding tariff object and calculated data. All of that was done in controller's action method.
Later I have created another class CostModel and then created an array CostModel[], which than was passed to $this->render() method. Again it's done in controller.
This approach works well enough. However, since I have not much experience with Symfony, I have doubts that this approach - performing calculations in controller - is good one.
Is there any better way for this?

Well, your question could have more than one answer as it is very opinion-based.
What I can say without any doubt about controller's code is that the less it is the more is good. Why I said that? Because controller code isn't reusable, because controllers are made to "connected" views and business logic (keep attention: connect, not encapsulate) and a general rule that I follow when I develop with Symfony2, is to write, into controller, lines of code for "objects" that are directly accessible from controller (form, request, views, and so on); all code that isn't related to these concepts should be migrated elsewhere.
Your solution is a good starting point but we cannot judge as we haven't more details and we don't know the architecture of your software. What can I say - and I hope you already know - is that you can pass to render (so to view templating system; I suppose you are using twig) directly the ArrayCollection you've obtained querying the database (so basically you don't neeed CostModel[] array). So, maybe, your approach is good but not the best: maybe you can take advantage of Repository facility, write a good query that can extract and calculate data for you (in a more optimized way) and use repository directly into controller. That way you could at the same time, migrate code where it should stay, write less number of code lines, do some optimitazion (or better, let Doctrine do for you) and you don't need to create a brand new class (model).

Related

Laravel - difference between Controller & Model

I'm learning Laravel and I'm watching many tutorials, but I dont really get it, what's the difference between the controller and model, because you can put in both a function.
Controllers in Laravel are used to determine how to handle http requests.
When you have anything to do with the DB, its better to place those function in the model, and call them from the controller.
In clear terms:
Model performs all operations on data from DB.
Controller call necessary model methods and ready the data.
View take care of displaying the data.
I hope this is clear enough.
You will be familiar with all of this soon.
model methods is for relationships mainly , or to make some thing for every object of this model (database table) every column in db is an object and every table is a model.
but in controller you set your app functionality that you want , and its an intermediator between model and view .
i hop this makes you good in this point.
good luck
You can write functions anywhere, you are perfectly right.
But is not an efficient way to do things.
The answers for those questions can be easily find out. Search about MVC pattern. In few words, remember brief:
MODEL => working with relational databases / storing the data
CONTROLLER => working with the logic(taking inputs, calculus etc) / general functionalities
Combining them is more efficient than working with those together, that is the reason why using a pattern is more great than writing code in a old style mode reinventing the wheel again.

Mapping between Model, View and Controller in PHP MVC implementation

Overview: I am building a CMS using PHP, and I am trying to implement this using MVC. I am trying to extend my code using this structure, as it represents an accurate representation of MVC and it is quite straightforward. To communicate with my database I use Domain Objects and Data Mappers.
Questions:
Is it really necessary to have a 1:1:1 mapping between a model, a view, and a controller?
Example: For a blog system, when displaying a blog entry page I would create a controller called DisplayEntryController, and a View called DisplayEntryView. The view would get its information from the BlogMapper class (which communicates with the DB to retrieve the current blog entry) and a CommentMapper class (which communicates with the DB to retrieve the comments for the current blog entry). Is this good practice, considering that view works with 2 model objects? If not what is the alternative? If yes, how can this be implemented in a generic way?
Can multiple controllers handle one page? For the example above, would it be possible to have a DisplayEntryController and a CommentController handling the relevant parts of a page displaying the blog entry? If yes, how would the 2 controllers coordinate?
Thank you in advance. Examples will be greatly appreciated.
Most PHP MVC implementations I've seen on the web use the page approach to organise their MVC. E.g. for the Home page, you have one view, one controller and one model. Routing for 1:1:1 mapping in MVC is straightforward, as you can enforce the location and naming of your MVC components, and when a request for the Home page comes it automatically looks for the following classes: HomeView HomeController and HomeModel.
This obviously doesn't work well in larger projects. How should routing be handled to support routing to multiple models (DataMappers), multiple views, without creating an overcomplicated router or adding a complex dependency injection layer?
Example: As discussed above, when displaying a blog entry you display
the blog entry code and the comment section. To achieve this, it
communicates with two DataMappers, the one which gets the blog entry,
and the one which returns the comments for the blog. How can the view
be assigned to work with these two datamappers to get the data from
the DB?
There is no requirement to have a 1:1 mapping of the model, controller and view.
MVC works of a concept of a tiered approach to handling your application, with each tier being handled by 'agents' to implement the way they see fit. To explain this further, consider the following scenario.
Assume you process data, then hand them over to someone to store. You don't care where they store it and how they store the data, as long as the information is available again when you need it. You can happily go about processing your data, and then say to them for example 'This is project data for Client X, store it,' and later say 'Can you give me the project data for Client X.'
SO MVC works on this approach, whether the data storage guys dump all data together or pack them away is not important to you. However, what is important is the interface between the two parties when sending and retrieving. For example, you could decide to store the information as either Client data, or Project Data, or both.
Likewise, you could have agents collecting data and handling it to you to process. You don't care how many interfaces they use (for example, phone, web, email, mobile devices), but you care about what data they hand you. (Of course a rule might dictate that only web information must be handled). So the interfaces for collecting data might be different.
Therefore, each agent can use the most efficient method (and even combine or split them) to get the system working in their side, and therefore there is no mapping of the data.

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.
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.
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();
Another alternative to Doctrine and Propel is PHP Activerecords.
Doctrine and Propel are really mighty beasts. If you are doing a smaller project, I think you are better off with something lighter.
Also, when talking about third-party solutions there are a lot of MVC frameworks for PHP like: Kohana, Codeigniter, CakePHP, Zend (of course)...
All of them have their own ORM implementations, usually lighter alternatives.
For Kohana framework there is also Auto modeler which is supposedly very lightweight.
Personally I'm using Doctrine, but its a huge project. If I was doing something smaller I'd sooner go with a lighter alternative.

PHP MVC (no framework), should I be calling a lot of methods in my controller or model?

I've been working on creating my own MVC app in PHP and I've seen a lot of differing opinions online about how exactly this should be set up. Sure, I understand there seems to be a general "It's MVC, it is what you make of it" approach, but I'm running into 2 seemingly conflicting viewpoints.
A little background on my app: I'm using smarty as my presenter and an object-oriented approach. Seems simple enough, but I'm trying to figure out the ubiquitous "what is a model" question.
If I take a look at some tutorials and frameworks, they seem to view the model as strictly a class that inherits DAL methods from an abstract class, with a little bit extra defined in the class itself as your data needs differ from object to object. For example, I might see something like $productModel->get(5) that returns an array of 5 products from the database. So what if I need to query multiple models? Do I store all of the data in the controller or an array and pass that to the view? Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view? This seems bad, especially because I then have to pass in things like "controllerName", "controllerData", and my View::render() method gets hugely bloated with parameters, unless I pass in the controller itself. Maybe I'm missing something here.
Let's say I want to make a login that queries a users table. Login is a model or a controller, depending on certain implementations I've seen online. Some implementations (I'll call this method 1) make a LoginController with method login() that might do a comparison of $_POST and what's returned from the user model instance $user->get(1) to see if a user is validated. Or maybe login() might be a method in a default controller. On the flipside, an implementation (implementation method 2) that resembles more of a Joomla approach would make a Login model and declare all of the actions inside of that. Then any data that needs to get assigned to the view would get returned from those methods. So login->login() would actually check post, see if there's a match, etc. Also the User model would probably be instantiated inside that model method.
My feelings about 1: The controller is fat. Additionally the controller is storing data pulled from models or passing in ten thousand variables. It doesn't seem to jibe with the idea that the model should be passing data to the view that the controller should be blind to. Also, let's say I want to wrap everything that is in a specific model handled by a specific controller in an outer template. I'd have to copy this template-setting code all across my controller functions that interface with this model. It seems grossly inefficient.
My feelings about 2: It doesn't make for having actions that aren't model methods. If I want to go to my site root, I have to make an index model or something that seems like overkill in order to have a model that passes data to the view. Also, this doesn't seem to be a very popular approach. However, I do like it more because I can just do View::render(mymodel->func()) and ensure that the data is going to be passed back just the way I like it without having to crap up my controller with code merging a thousand query results together.
I've waded through far too many religious arguments about this and want to know what you guys think.
I've built my own framework in the past too so I know what you're going through. I've heard the saying "build fat models" and I agree with that -- as long as the main goal is to return data. I considered the controller to be "The Overlord" as it manipulated data and directed where it should go.
For a login controller i might create something it like...
Post URI: http://example.com/login/authenticate
LoginController extends ParentController {
public function authenticate() {
$credential_model = $this->getModel('credentials');
// Obviously you should sanitize the $_POST values.
$is_valid = $credential_model->isValid($_POST['user'], $_POST['email']);
$view = $is_valid ? 'login_fail.php' : 'login_success.php';
$data = array();
$data['a'] = $a;
// .. more vars
$this->view->render($view, $data);
}
}
In my opinion data should always flow from the model -> controller -> view as it makes the most sense (data, manipulation, output). The View should only have access to what it has been given by the controller.
As for this...
Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view?
Well I would imagine you're building a 'base' or 'parent' controller that gets extended off of by your dynamically called controllers. Those child controllers can have properties that are needed for for the view to render -- honestly I'd need an example to go further.
Hopefully this helps a bit. If you ask more specific questions I might be able to give a better thought out opinion.
If you're writing your own app, I think the best solution is to do it yourself and find out.
Ultimately, whatever makes the most sense to you, and whatever makes it easier for you to conceptualize your app and quickly add to or change it, is going to be your best option.
If one way is "wrong", then you'll find out through experience, rather than someone else telling you. And you'll know the entire situation that much better, and know EXACTLY why one way is better.
What helped me when I was writing my own framework in PHP was, strangely enough, CherryPy. It made the concept of an object-oriented web app so simple and obvious, and I enjoyed using it so much, that I modeled the basic structure of my PHP framework to imitate CherryPy.
I don't mean to imply you should learn CherryPy. I mean that simplicity, clarity, and enjoying developing with your own web app go a LONG way.
If I were to give one piece of specific advice, I'd say try to avoid retyping code; write your code to be reusable in as many situations as possible. This will not only be good for your app, but for future apps you may write or work on.
You might check out Eric S. Raymond's Rules for Unix Programming. I think they're definitely applicable here.

PHP MVC & SQL minus Model

I've been reading several articles on MVC and had a few questions I was hoping someone could possibly assist me in answering.
Firstly if MODEL is a representation of the data and a means in which to manipulate that data, then a Data Access Object (DAO) with a certain level of abstraction using a common interface should be sufficient for most task should it not?
To further elaborate on this point, say most of my development is done with MySQL as the underlying storage mechanism for my data, if I avoided vendor specific functions -- (i.e. UNIX_TIMESTAMP) -- in the construction of my SQL statements and used a abstract DB object that has a common interface moving between MySQL and maybe PostgreSQL, or MySQL and SQLite should be a simple process.
Here's what I'm getting at some task, are handled by a single CONTROLLER -- (i.e. UserRegistration) and rather that creating a MODEL for that task, I can get an instance of the db object -- (i.e. DB::getInstance()) -- then make the necessary db calls to INSERT a new user. Why with such a simple task would I create a new MODEL?
In some of the examples I've seen a MODEL is created, and within that MODEL there's a SELECT statement that fetches x number of orders from the order table and returns an array. Why do this, if in your CONTROLLER your creating another loop to iterate over that array and assign it to the VIEW; ex. 1?
ex. 1: foreach ($list as $order) { $this->view->set('order', $order); }
I guess one could modify the return so something like this is possibly; ex. 2.
ex. 2: while ($order = $this->model->getOrders(10)) { $this->view->set('order', $order); }
I guess my argument is that why create a model when you can simply make the necessary db calls from within your CONTROLLER, assuming your using a DB object with common interface to access your data, as I suspect most of websites are using. Yes I don't expect this is practical for all task, but again when most of what's being done is simple enough to not necessarily warrant a separate MODEL.
As it stands right now a user makes a request 'www.mysite.com/Controller/action/args1/args2', the front controller (I call it router) passes off to Controller (class) and within that controller a certain action (method) is called and from there the appropriate VIEW is created and then output.
So I guess you're wondering whether the added complexity of a model layer -on top- of a Database Access Object is the way you want to go. In my experience, simplicity trumps any other concern, so I would suggest that if you see a clear situation where it's simpler to completely go without a Model and have the data access occur in the equivalent of a controller, then you should go with that.
However, there are still other potential benefits to having an MVC separation:
No SQL at all in the controller: Maybe you decide to gather your data from a source other than a database (an array in the session? A mock object for testing? a file? just something else), or your database schema changes and you have to look for all the places that your code has to change, you could look through just the models.
Seperation of skillsets: Maybe someone on your team is great at complex SQL queries, but not great at dealing with the php side. Then the more separated the code is, the more people can play to their strengths (even more so when it comes to the html/css/javascript side of things).
Conceptual object that represents a block of data: As Steven said, there's a difference in the benefits you get from being database agnostic (so you can switch between mysql and postgresql if need be) and being schema agnostic (so you have an object full of data that fits together well, even if it came from different relational tables). When you have a model that represents a good block of data, you should be able to reuse that model in more than one place (e.g. a person model could be used in logins and when displaying a personnel list).
I certainly think that the ideals of separation of the tasks of MVC are very useful. But over time I've come to think that alternate styles, like keeping that MVC-like separation with a functional programming style, may be easier to deal with in php than a full blown OOP MVC system.
I found this great article that addressed most of my questions. In case anyone else had similar questions or is interested in reading this article. You can find it here http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html.
The idea behind MVC is to have a clean separation between your logic. So your view is just your output, and your controller is a way of interacting with your models and using your models to get the necessary data to give to the necessary views. But all the work of actually getting data will go on your model.
If you think of your User model as an actual person and not a piece of data. If you want to know that persons name is it easier to call up a central office on the phone (the database) and request the name or to just ask the person, "what is your name?" That's one of the ideas behind the model. In a most simplistic way you can view your models as real living things and the methods you attach to them allow your controllers to ask those living things a series of questions (IE - can you view this page? are you logged in? what type of image are you? are you published? when were you last modified?). Your controller should be dumb and your model should be smart.
The other idea is to keep your SQL work in one central location, in this case your models. So that you don't have errant SQL floating around your controllers and (worst case scenario) your views.

Categories