What is an example of MVC in PHP? - php

I'm trying to understand the MVC pattern. Here's what I think MV is:
Model:
<?php
if($a == 2){
$variable = 'two';
}
else{
$variable = 'not two';
}
$this->output->addContent($variable);
$this->output->displayContent();
?>
View:
<?php
class output{
private $content;
public function addContent($var){
$this->content = 'The variable is '.$var;
}
public function displayContent(){
include 'header.php';
echo $content;
include 'footer.php';
}
}
?>
Is this right? If so, what is the controller?

The controller is your logic, the model is your data, and the view is your output.
So, this is the controller:
$model = new UserDB();
$user = $model->getUser("Chacha102");
$view = new UserPage($user->getName(), $user->getEmail());
echo $view->getHTML();
The model is the UserDB class which will give me my data. The view is the UserPage that I give the data from the model to, and it will then output that page.
As you can see, the controller doesn't do much in this example, because you are simply getting user data and displaying it. That is the beauty of MVC. The controller doesn't have to deal with the User SQL or HTML stuff, it just grabs the data and passes it to the view.
Also, the view doesn't know anything about the model, and the model doesn't know anything about the view. Therefore, you can chance the implementation of either, and it won't affect the other.
Relating more to your example, you have the view correct, but you have mixed your controller and model.
You could relieve this by:
Controller:
$model = new NumberToWord();
$word = $model->getWord($a);
$this->output->addContent($word);
$this->output->displayContent();
Model:
class NumberToWord{
public function getWord($number)
{
if($number == 2){
return 'two';
}
else{
return 'not two';
}
}
}
And keep your same output

Controllers receive user requests - usually there is some kind of router that takes a URL and routes the request to the appropriate controller method.
Models are used by a controller to query data to/from a database (or other data source).
Views are called from a controller to render the actual HTML output.

If all you want to do is create a simple template system, you might aswell go with:
$content = 'blaba';
$tpl = file_get_contents('tpl.html');
echo str_replace('{content}',$content,$tpl);
With a template file like:
<html>
<head><title>Whatever</title></head>
<body>{content}</body>
</html>

In your example, it's more like you've split a Controller into a Model and a View.
Model: Business logic / rules and typically some sort of database to object relational mapping
Controller: Responds to url requests by pulling together the appropriate Model(s) and View(s) to build an output.
View: The visual structure the output will take. Typically a "dumb" component.
It can be confusing when you first encounter MVC architecture for a web app, mainly because most web frameworks are not MVC at all, but bear a much closer resemblance to PAC. In other words, the Model and View don't talk, but are two elements pulled together by the context the Controller understands from the given request. Check out Larry Garfield's excellent commentary on the subject for more information:
http://www.garfieldtech.com/blog/mvc-vs-pac
Also, if you are interested in the MVC pattern of development, I suggest you download one of the many frameworks and run through a tutorial or two. Kohana, CodeIgnitor, CakePHP, and Zend should be enough to kick-start a Google-a-thon!

Zend Framework: Surviving The Deep End has some good sections explaining MVC. Check out the MCV Intro and especially this seciton on the model.
There are numerous interpretations of the Model but for many programmers the Model is equated with data access, a misconception most frameworks inadvertently promote by not obviously acknowledging that they do not provide full Models. In our buzzword inundated community, many frameworks leave the definition of the Model unclear and obscured in their documentation.
To answer "where's the controller":
Controllers must define application behaviour only in the sense that they map input from the UI onto calls in Models and handle client interaction, but beyond that role it should be clear all other application logic is contained within the Model. Controllers are lowly creatures with minimal code who just set the stage and let things work in an organised fashion for the environment the application operates in.
I think you'll fine it (and his references of other articles and books) a good read.

Here is a very simple example of MVC using PHP. One thing missing is THE router. It selects one of the controller to do the job. We have only one controller, the customer.
If we compare it with 3 tiers
Model: The database
View: Client
Server:Controller
Router:It selects a controller
When you select something from an application on web browser, the request goes to router, from router it goes to controller. Controller asks from model and make a view. View is rendered to you.
Only model can talk to controller back and forth.
1- Model.php
<?php
class Model
{
private $con=null;
private $r=null;
function connect()
{
$host="localhost";
$db="mis";
$user="root";
$pass="";
$this->con=mysqli_connect($host,$user,$pass) or die(mysqli_error());
if(!$this->con){
echo die(mysqli_error());
}
else mysqli_select_db($this->con,$db);
}
function select_all()
{
$this->connect();
$sql="select * from customers";
$this->r=mysqli_query($this->con,$sql) or die(mysqli_error());
return $this->r;
}
function display_all()
{
$i=0;
echo "aaaaaaaaaa";
$this->r=$this->select_all();
while($q=mysqli_fetch_array($this->r))
{
$i++;
echo $i."-Id:".$q['id']."</br>";
echo $i."-Name:".$q['name']."</br>";
echo $i."-Phone:".$q['phone']."</br></br>";
}
}
}
?>
2. Controller: There may may be many controllers.
<?php
class Customers extends Model
{
function select_all1()
{
//echo "aaaaaaa";
$this->display_all();
}
}
?>
3. View: There may be many views
<?php
include("model.php");
include("customers.php");
?>
<html>
<head><title>Customers</title></head>
<body>
<?php
$c=new Customers();
echo $c->select_all1();
?>
</body>
</html>

Related

Which pattern to use and how to use it when I have Controller, Business Logic, and Repository?

Using MVC I have something like this:
class Controller
{
//returns View
function indexAction()
{
$data = $this->getData($this->id);
$view = new ViewModel();
$view->setVariable('data' => $data);
//used to render HTML template + data above later on
return $view;
}
//gets data from DB
//currently also does business-proprietary computation on data
function getData($id)
{
//repository/dao pattern
$data = $this->repository->getData($id);
//Business Logic "derivation"
foreach ($data as $datum)
{
//that does not go into "Controller
//that does not go into "Repository"
//but where does it go? - that's my question
$derivedData[] = (new Business())->doLogic($datum);
}
return $derivedData;
}
}
Recap
I used Controller to get my data out of DB using Repository pattern, then placed received data into view. But business-related computations are left stranded.
Question
Where do I place my business logic computations that act on the data gotten from repository? The derived data which is to return to Controller later, to be placed into View?
My personal choices of architecture are usually to:
Have small controllers as thin as I can, doing only session and general right checking
Services that are handling all business logic, one (one classe yes) per potential feature I need
Services are querying repositories, and eventually manipulate the data in and out, but usually no Controller, nor view will do a ->save() anywhere.
This means that those services are usually designed to be independent from the database and easier to be tested because they only take care of one and only one task.
In your example, the whole function getData will be a service that I would call GetCarDataById. This assuming that you manipulate Cars, I don't like to leave data wandering alone.
EDIT: to make it clear, this kind of approach is not MVC to some definition, most people interpret MVC as putting all code either in controller, either in repositories (model). To others view, MVC doesn't mean that you have other classes, what I call services, and actually most of my code lives here.
The MVC pattern is clear for me.
From wikipedia:
The model directly manages the data, logic and rules of the
application. A view can be any output representation of information,
such as a chart or a diagram. Multiple views of the same information
are possible, such as a bar chart for management and a tabular view
for accountants. The third part, the controller, accepts input and
converts it to commands for the model or view.
Answering your question. The modifications goes in the model domain.

MVC simple select count from db and display explained

I am working with an MVC for the first time and developing a library app for personal dev. I am using the php login found here. I am new to php and sql so apologies for any amateur coding, I have taught myself php.
I have been reading for the past two weeks and trying to get my head around how to do the simplest of tasks. Maybe it's the MVC I am working with or it's just my inability to figure it out. I find myself copying chunks of code from one model/view/controller to the next in order to achieve my desired results, however this isn't ideal as I would like to know what the code does or I won't be learning.
I have been doing a lot of independent reading and following tutorials online however most of them are aimed towards CodeIgniter or CakePhp, therefore the syntax is different. I know that once I finally get my head around the syntax and logics then I won't have any issues.
I will use a simple example for reference below. Hopefully somebody will be able to shed some light on this for me and help me out.
I have been trying all day today to select the number of rows in my table and display this on a user profile page as "You have this number of favourites: x".
As I understand, I create the query in my model which is favouriteTotal(). I then reference this is the controller and render the view? Using PDO to connect to db.
login.php (model)
class LoginModel
{
public function favouriteTotal()
{
$query = $this->db->prepare("SELECT COUNT(*) FROM favourite");
$query->execute();
$count = $query->rowCount()
}
}
login.php (controller)
class Login extends Controller
{
function showProfile()
{
$login_model = $this->loadModel('Login');
$login_model->favouriteTotal();
$this->view->render('login/showprofile');
}
}
showprofile.php (view)
<div>
Your have this number of favourites: <? NUMBER OF FAVS HERE ?>
</div>
This is kind of a general answer about how it often works... Please tell us what framework you are using if you want a specific answer.
Many MVC applications use a ViewBag, a 'Container' of sorts, that gets passed along to the view that's being rendered.
(Updated the code below to reflect how the used framework passes data to the view)
login.php (controller)
class Login extends Controller
{
function showProfile()
{
$login_model = $this->loadModel('Login');
$this->view->count = $login_model->favouriteTotal();
$this->view->render('login/showprofile');
}
}
showprofile.php (view)
<div>
Your have this number of favourites: <?php echo $this->count; ?>
</div>
So, in the controller you assign the value of $login_model->favouriteTotal() to $this->view->count. Then you render the view. In that view, you call $this->count to access the previously sent data.

PHP MVC design - multiple actions to same url/controller

In a MVC pattern, what's the best way to handle when a single view could have multiple actions of the same type (e.g POST)?
Say for instance in a TODO list application. You might allow a user to create multiple lists. Each list could have multiple items. So a user navigates to site.com/list/1 which shows them all the items on the 1st list (1 is a GET parameter). There are then 2 forms (POST) on this page to allow a user to:
Create a new item
Delete an existing item
Should the bootstrap create a "listcontroller", inspect the POST variables and then call the appropriate method similar to :
$lc = new ListController();
if(strtolower($request->verb) === 'post'):
if(isset($_POST['title'])) :
$data = $lc->newItem($_POST);
$load->view('newitem.php', $data);
else if(isset($_POST['delete']) && isset($_POST['id'])):
$data = $lc->deleteItem($_POST);
$load-view('deleteitem.php', $data);
endif;// End if post title
else:
//GET request here so show view for single list
endif; //
Or is it better to just do something like
$lc = new ListController();
if(isset($_POST)):
//controller handles logic about what function to call
$data = $lc->PostAction($_POST);
// $data could also potentially hold correct view name based on post
$load->view();
else:
//again just show single list
endif;
I'm just struggling how best to have a controller potentially handle multiple different actions, as there's potentially quite a few nested if/else or case statements to handle different scenarios. I know these would have to sit somewhere, but where is cleanest?
I know that there are many frameworks out there, but I'm going through the whole "want to understand best practice" behind it phase. Or is this totally the wrong way to do it? Should the controllers actually be structured differently?
To begin with, I actually really like, how you are dealing with implementation of MVC. None of that rails-like parody, where view is managed inside the controller.
Here is what I think is the root of your problem: you are still using a "dumb view" approach.
View is not supposed to be a synonym for "template". Instead it should be a full object, which has knowledge-of and ability-to deal with multiple templates. Also, in most of MVC-inspired design patterns, the view instances are able to request information from model layer.
In your code the issue can be traced back to view's factory ( the $load->view() method ), which only gets what controller sends it. Instead controller should only change the name of the view, and maybe send something that would change the state of view.
The best solution for you would be to create full-blown view implementation. Such that view itself could request data from model layer and , based on data it received, decide which template(s) to use and whether to require additional information from model layer.
I think you're somewhat on the right track with the latter approach. However, you should not hard code the calling of actions in your bootstrap. The bootstrap should interpret the URL and call the action methods dynamically through the use of a function like call_user_func_array.
Also, I would suggest that you leave the rendering of views up to the action code so the action logic is self sufficient and flexible. That would allow the action to analyse the input for correctness and render errors or views appropriately. Also, you've got the method 'deleteItem' on your controller, but that should really be the work of a model. Perhaps you should read up some more on MVC and try to work with an existing framework to understand the concepts better before you try to implement your own framework (I would suggest the Yii framework for that).
Here's an example of how I think your logic should be implemented in a good MVC framework.
class ListController extends BaseController
{
public function CreateAction($title){
if(ctype_alnum($title))
{
$list = new List();
$list->Title = $title;
if($list->insert())
{
$this->render_view('list/create_successful');
}
else
{
$this->render_view('list/create_failed');
}
}
else
{
$this->render_view('list/invalid_title');
}
}
public function DeleteAction($id){
$list = List::model()->getById($id);
if($list == null)
{
$this->render_view('list/errors/list_not_found');
}
elseif($list->delete())
{
$this->render_view('list/delete_successful');
}
else
{
$this->render_view('list/delete_failed');
}
}
}
here is a great tutorial on how to write your own MVC framework

mvc best practice view/controller/model in php and yii

This is a best practice question and not a specific issue.
I'm fairly new to the MVC approach and Yii, and have developed on an app for a while now. I keep seeing talks on best practice and what to put in which file (controller, model, view, helper etc.) however i have not yet found anything specific in terms of examples.
I currently have calls like: Model::function() in my view files as well as checks like $var = app()->request->getParam(value, false);
I have calls in my controller file like Model::function() and Model::model()->scope1()->scope2()->findAll() I also think my controller files are getting a bit thick, but not sure how and where to put some of the bloat, i have been reading about the DRY and i think i'm not exactly DRY'ing my code so to speak.
Could you give me a more clearer picture about what goes where, and suggestions or reasons why :)
Appreciate any advice, thanks in advance.
here's an example call in a viewfile
<?php
$this->pageTitle = 'Edit Action';
$this->subTitle = '<i>for</i> <b>' . Vendors::getName($_GET['vendor']) . '</b>';
?>
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model' => $model)); ?>
</div>
The getName is my function in the model, is this a good way to call a function in a view?
Another example view file:
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
echo $this->renderPartial('_form', array('model'=>$model));
} else {
$this->pageTitle = "New Vendor";
echo $this->renderPartial('_form', array('model'=>$model));
}
?>
</div>
$model is set in the controller with type...
Same question... could this be done.. cleaner..? better in terms of MVC and reusability/DRY?
EDIT
After reading some of the responses here, esp. #Simone I refactored my code, and wanted to share what it looks like now...
public function actionCreate() {
$model = new Vendors;
// Get and Set request params
$model->type = app()->request->getParam('type', Vendors::VENDOR_TYPE);
$vendorsForm = app()->request->getPost('Vendors', false);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if ($vendorsForm) {
$model->attributes = $vendorsForm;
if ($model->save())
$this->redirect(array('/crm/vendors', array('type' => $model->type)));
}
$model->categories = Categories::getAllParents($model->type);
$this->pageTitle = 'New ' . Lookup::item('VendorType', $model->type);
$this->render('create', array(
'model' => $model,
));
}
and the view create.php
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model));?>
Thanks for all respnses
I am not too familiar with the Yii framework but can offer a few suggestions on a few specific things you mentioned:
Don't get too caught up with 'best practices' as like all design patterns MVC can be implemented and in certain cases interpreted in many different ways by different developers. So what does this mean? it means read up on MVC as much as you can, then simply just have a go :o) You will soon find out what slots where and why when you come up with a problem (which is normally along the lines of 'where does this belong, the controller or model?...'.
In terms of what goes where, you can google / search stackoverflow or read in countless books many explinations of what should do what and go where, but from the code snippet you provided I would suggest:
View files: (Unless this is a Yii specific thing) in my opinion your view files are a bit dirty. You are talking to the model directly (which is in fact the classical approach of MVC rather than some PHP app's adopting the 'controller is the only one allowed to speak to the model' method) but it appears your view is trying to get request data directly and for me this should not be anywhere near the view. The controller should be dealing with the request, using a model for validation and then passing the output into the view.
Model: This seems OK from the small snippet, but in general one important thing to remember is that the model != database (despite some people's suggestion that it is).
Controller: Again seems fine from your snippet, but to address your bloat in your controller, without seeing one of your controllers it would be hard to offer a suggestion. One thing that is always worth considering is the use of Services. Basically a service can be used to greatly simplify your controller by encapsulating a lot of repetitive / complicated model stuff. So instead of calling separate validation and persistence models within your controller, you just instantiate a service class, and it could just be a case of calling one method (which often returns a bool to indicate to your controller the success or failure of the operation) and then your controller just has to deal with what it does best (and should only do) the app's flow (i.e. redirect to another page, show error, etc).
I'll show you an'example to refactor your code. This is you code
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
echo $this->renderPartial('_form', array('model'=>$model));
} else {
$this->pageTitle = "New Vendor";
echo $this->renderPartial('_form', array('model'=>$model));
}
?>
</div>
First question is: why write two time the same line with renderPartial? First refactoring:
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
} else {
$this->pageTitle = "New Vendor";
}
echo $this->renderPartial('_form', array('model'=>$model));
?>
</div>
And now second step:
<?php $this->pageTitle = $this->action->id != 'create' ? "New Media Contact" "New Vendor"; ?>
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>
FOR ME is more readable. I thing there are a lot of best practice. But can become a bad practice used in bad context. So... Is really useful rewrite code? For me yes! Because my goal is maintainability of code. Easy to read, easy to manage. But you need to find your standard or your team standard. Also, I prefer move any kind of logic in controller. For example I can set a default pageTitle in controller and redefine It in actionCreate method:
class SomeController extends CController
{
public $pageTitle = "New Vendor";
function actionCreate ()
{
$this->setPageTitle("New Media Contact")
$this->render('view');
}
}
And my viewfile will become just:
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>
I think we have to understand the responsibility of things: view is just a view.
Simply think of a view as a component that only display data. It shouldn't do database calls, interact with a model, create new variables (or very rarely), etc. If you want to do a check, or create an HTML block using some data, etc. use helpers for that purpose.
The data a view will display will come from a controller.
The controller is the maestro who'll do most of the work in your app: it will answer requests, ask the model for data if needed, pass the data to a view and render it, etc.
In your first example, simply save Vendors::getName($_GET['vendor']) in a variable, in your controller, and then pass it to the view.
Also, if you don't need all model's data, don't pass the whole object.
Regarding your second snippet, first of all you can move the echos out of the if statement because they are the same.
A good thing would be to do the check if ($this->action->id != 'create') in your controller, and give your view a simple boolean:
if ($this->action->id != 'create') { // not sure if $this->action->id would remain the same, I don't know Yii
$media = true;
// or
// $page = 'media';
} else {
$media = false;
// or
// $page = 'vendor';
}
And the render the partial depending on the values returned by the controller.
In my opinion there is no "best practice". As long as you do not work in a team or want to release your script as open source, where dozens of people have to work with it, use the framework however you like and need it. And even if you work with others on the code there are no "god given" rules for that.
There are much more important things that matter than the question if you are "really allowed" to use a static function inside your view.

PHP, understanding MVC and Codeigniter

I'm trying to understand MVC, and learning CI framework. I've some questions about MVC and some basic questions about CI.
1)Views are visual part of application as i read from tutorials, my question is: e.g There is a button "Login" but if user already logged in button will be "Logout". Where will that login check be? On controller or on view? i mean
//this is view//
<?php if($_SESSION('logged') == true):?>
Logout
<?php else: ?>
login
<?php endif; ?>
or
//this is controller//
if($_SESSION('logged') == true)
$buttonVal = 'logout';
else
$buttonVal = 'login';
//and we pass these value to view like
$this->view->load('header',$someData);
//this time view is like
<?=$somedata['buttonVal']?>
i just write theese codes as an example i know they wont work, they are imaginary codes, but i guess you got what i mean. Login check should be on controller or on view?
2)Should models contain only codes about data and return them to controller? For example there is a math, we get 2 value from database and multiply them and display them. Model will multiply or controller will do it?
here we load data with model and do math on controller:
//model
$db->query(....);
$vars=$db->fetchAll();
return $vars;
//controller
$multi = $vars[0] * $vars[1];
$this-load->view('bla.php',$mutli);
here we load data with model and do math on model too, controller just passes data from model to view:
//model
$db->query(....);
$vars=$db->fetchAll();
$multi = $vars[0] * $vars[1];
return $multi;
//controller
$multi = $this->model->multiply();
$this-load->view('bla.php',$mutli);
i mean with that, models should do only database works and pass data to controllers, controller do rest of work and send view to render? Or models do work, controllers get them and send them to view?
3)This is about codeigniter, i have a header which has to be in every page, but it has javascripts,css depending to page i'm using
<?php foreach ($styles as $style): ?>
<link id="stil" href="<?= base_url() ?>/css/<?= $style ?>.css" rel="stylesheet" type="text/css" />
<?php endforeach; ?>
this will be on every page, so in every controller i have
$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);
i'm thinking to make a main controller, write this in it, and all my others controllers will extend this, i see something MY_Controller on CI wiki, is this MY_Controller same with what i'm doing? Are there any other ways to do this?
Sorry for bad English and dummy questions. Thanks for answers.
This is absolutely view logic, the correct way to do it in my opinion:
<?php if($logged_in):?>
Logout
<?php else: ?>
login
<?php endif; ?>
The value of $logged_in would probably be retrieved from a call to a library method:
<?php if ($this->auth->logged_in()): ?>
Authentication is one of those things you'll want access to globally, so you may be calling $this->auth->logged_in() in controller or views for different reasons (but probably not in models).
In every controller i have
$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);
Yes you could extend the controller class with MY_Controller, but you're better off keeping this in the view/presentation layer. I usually create a master template:
<html>
<head><!-- load assets --></head>
<body id="my_page">
<header />
<?php $this->load->view($view); ?>
<footer />
</body>
</html>
And write a little wrapper class for loading templates:
class Template {
function load($view_file, $data) {
$CI = &get_instance();
$view = $CI->load->view($view_file, $data, TRUE);
$CI->load->view('master', array('view' => $view));
}
}
Usage in a controller:
$this->template->load('my_view', $some_data);
This saves you from loading header/footer repeatedly. In my opinion, presentation logic like which CSS file to load or what the page title should be belongs in the view whenever possible.
As far as models go, you want them to be reusable - so make them do what you need and keep it strictly related to data manipulation (usually just your database). Let your controller decide what to do with the data.
Not related to MVC, but in general you want to write as little code as possible. Redundancy is a sign that you could probably find a better solution. These are broad tips (as is your question) but hopefully it helps.
1) View logic should be simple and mostly if-then statements, if needed. In your example, either case would work but use the logic in the view. However, if you were checking for login and redirecting if not logged in, then that would occur in a controller (or a library).
2) Think of Codeigniter models as ways to access database functions - Create, Retrieve, Update, Delete. My (loose) rule of thumb is for Codeigniter models is to return results from update, delete or insert queries or a result set from a fetch query. Any applicable math can then occur in the controller. If this is a math operation that occurs EVERY time, consider adding it to a library function. See below...
3) Extending the controller is the proper and best way to accomplish this.
*) Not to add more to your plate, but also be sure to learn about Codeigniter Libraries. For example, in your controller you could load your library. You then call your library function from your controller. The library function calls a model which retrieves your database result. The library function then performs math on that function and returns the result to the controller. The controller is left with little code but a lot is accomplished due to the library and model.
The user lo-gin check should be in the controller.
This should be the first function that need to be invoked in the constructor.
Below i have given the sample code which redirects the user to the login page if he is not logged in, hope this would give you some idea,
<?php
class Summary extends Controller {
function Summary() {
parent::Controller();
$this->is_logged_in();
}
function is_logged_in() {
$logged_in = $this->session->userdata('logged_in');
if (!isset($logged_in) || $logged_in != true) {
$url = base_url() . 'index.php';
redirect($url);
exit();
}
}
?>
The button change can be implemented in the view by checking the session variable in view and making decisions accordingly.
Please take look at this link

Categories