What's the best way to transition to MVC coding? - php

It's been around 5 months since I picked up a PHP book and started coding in PHP. At first, I created all my sites without any organizational plan or MVC. I soon found out that was a pain..
Then I started to read on stackoverflow on how to separate php and html and that's what I have been doing ever since.
Ex:
profile.php <--this file is HTML,css. I just echo the functions here.
profile_functions.php <--this file is mostly PHP. has the functions.
This is how I have been separating all my coding so far and now I feel I should move on and start MVC. But the problem is, I never used classes before and suck with them. And since MVC (such as cakephp and codeigniter) is all classes, that can't be good.
My question: Is there any good books/sites/articles that teaches you how to code in MVC? I am looking for beginner beginner books :)
I just started reading the codeigniter manuel and I think I am going to use that.
EDIT: Is it possible to have a MVC organization structure to your coding without using cake, codeigniter, etc? Basically just separate say profile.php into 3 different files(the view, controller, model)

to answer your question
Is it possible to have a MVC
organization structure to your coding
without using cake, codeigniter, etc?
Basically just separate say
profile.php into 3 different files(the
view, controller, model)
absolutely...
first file profile.php ( the view, what gets hit by the browser )
<?php
include( 'controllers/UsersController.php' );
$controller = new UsersController();
$controller->profile();
$pageData = $controller->data;
?>
the controller
<?php
include 'models/UsersModel.php';
class UsersController{
public $data;
public $model;
public function __construct(){
$this->model = new UserModel();
}
public function profile(){
$this->data = $this->model->findUser();
}
}
the model
<?php
class UsersModel{
public function __constuct(){
// connect to your db or whatever you need to do
}
public function findUser(){
return mysql_query( "SELECT * FROM users WHERE users.id = 2 LIMIT 1" );
}
}

MVC is just a design pattern. It's not really something you can "code in".
If you like to code in PHP, here is an article regarding MVC in PHP. It has an overview explaining the design pattern, and then an example follows.

How I learned was by going through this tutorial:
http://www.symfony-project.org/jobeet/1_4/Doctrine/en/
The primary focus is to learn the Symfony Framework, but by default, you will be exposed to and learn good MVC principles.

It's not PHP, but see if you can get a copy of Tate's Bitter Java. It will discuss the organizational side of things (how and why the organizational code improves stuff).
I'm a bit hesitant to recommend one of the great Java books for PHP programming, but this book is one of the few that starts with code written without an organizational plan and improves it into a MVC like structure without the use of 3rd party libraries. This way it teaches you what the organization is about from a practical point of view. Hopefully once you understand the pattern, it won't be too difficult to translate the ideas into PHP.
Another alternative is to grab one of the dozens of PHP frameworks and recode to the framework. Doing so will get your results much faster, but the drawback is that you'll likely understand those results in greater detail, and there is a small chance your code will not behave the same after you rewrite it from scratch. We all like to think the new stuff will do everything the old stuff did, but often we forget something (or it behaves differently).

MVC is a "generic" design pattern that is not particular to any language. More of a coding philosophy. On the most basic level it's just separating data from business logic from presentation. Below is a simple example of a "templating" system using MVC. You would be able to swap out any of the parts without breaking anything, and the data is not tied to the formatting/display. This is sample code, not efficient.
Model, get the data:
function getName($id) {
$name = array('_first_'=>'Joe', '_last_'=>'Smith', '_mi_'=>'C');
return $name
}
Controller, processes it:
$name = getName(1);
$name['_fullname_'] = $name['_first_'].' '.$name['_mi_'].'. '.$name['_last_'];
outputView($name);
View, output the content:
// Example html file: <b>Hello _fullname_, how are you</b>
function outputView($view, $data) {
switch ($view) {
case 'xml':
$out = file_get_contents('view.xml');
case 'html':
$out = file_get_contents('view.html');
case 'json':
$out = file_get_contents('view.json');
}
$search_for = array_keys($data);
$replace_with = $data;
echo str_replace($search_for, $replace_with, $out);
}

Related

PHP folder structure for AJAX calls and form actions

I am trying to develope good code organization habits and work exclusively with OOP in php but I can't seem to wrap my head around something.
Here is a simplified description of what I am working with:
I have all my class files in a folder '/resources/Classes'
I have all my html and javascript in '/public_html' & '/public_html/script respectively'
My question is concerning files that are the actions of forms or AJAX requests. For example 'formAction.php' and 'ajaxURL.php'. These files are not Classes and also do not contain any html or other such GUI.
I have been putting them in a folder 'resources/actions' but my gut tells me something about this is not fully OOP.
Is my usage of these files incorrect if I am trying for complete OOP? if so how can I approach this differently.
Here is an actual file from my project as a concrete example:
//file: getBalance.php
<?php
/**
* This script gets the balance of an account from the server
*/
if (!isset($Database)) {
$Database = require_once "../clear_finance_pkg.php";
}
/** #var User $User */
$User = $Database->getUserByID("1");//TODO: user should be set dynamically
$User->setAccounts($Database->getAccountsByUser($User));
if (isset($arg1)) {
$accountID = $arg1;
foreach ($User->getAccounts() as $Account) {
if ($Account->getId() == $accountID) {
$RbcChequing = RbcAccount::accountToRbcAccount($Account, "Chequing");
echo '$' . Money::toDollars($RbcChequing->getBalance());
break;
}
}
} else throw new Exception('Account ID is not set. Could not get balance');
It's difficult to say if your code is complete OOP, but i think it isn't. It looks like you are on the right track, because you are using classes, objects and methods. That's the basic of OOP. No longer large if/else statements and a lot of variables that doesn't make sense, but objects and methods without code-duplication.
I think your question in more related to the seperation of logic and view. First of all. In general it's ok to make a file for a function, but in a large application you will loose the overview. What you are doing know is combine view-related and logic-related things in one file, but actually that's not what you want. The ideal situation is full seperation of logic and view so you can create multiple seperate views based on the same logic.
My advice is to take a look at the MVC-pattern. Take a look at this link. It will help you to get a basic understanding of the MVC-pattern. Notice that you won't longer need to have a file for each function. And you have a seperation of your logic and view elements because you can use the same model in multiple views (although this is maybe not the best example).

PHP Software design pattern based on static classes

I've noticed a common pattern in some recently popular PHP libraries such as Laravel for example, where the API is heavily based on static classes and methods. A typical example of how this sort of API looks:
Logger::note('Handle routes for the welcome area of the site.');
Route::match('/welcome/:id', function ($id) {
$name = Model::from('users')->get('name')->where('id', $id);
$body = Template::body('templates/wecome.tpl', array('name' => $name));
HTTP::respond(200, $body);
}
The code seems nicely readable, and the 5 different static classes are autoloaded by Composer, so at first glance this seems like an attractive pattern to use. My question, for those more experienced in designing APIs, is does this seem like a good approach as things scale up?
For one example, I can immediately see some clunkiness on the horizon, if for example I should want multiple logs to be kept. In a non-static pattern I could do this:
$debugLog = new Logger('logs/debug.log');
$errorLog = new Logger('logs/errors.log');
Route::match('/welcome/:id', function ($id) {
$debugLog->note('Handle routes for the welcome area of the site.');
$name = Model::from('users')->get('name')->where('id', $id);
if (empty($name)) {
$errorLog->warn('Name is empty!');
}
}
But this gets difficult to share across many different methods and files.
#file1.php
Route::match('/welcome/:id', function ($id) {
$debugLog = new Logger('logs/debug.log');
$debugLog->note('Handle routes for the welcome area of the site.');
//etc
}
#file2.php
Route::match('/news', function ($id) {
$debugLog = new Logger('logs/debug.log');
$debugLog->note('Handle routes for the news area of the site.');
if ($error) {
$errorLog = new Logger('logs/errors.log');
$errorLog->warn('There is some problem: '.$error);
}
}
Now I am forced to repeat myself in order to instantiate the non-static class all over the place, which clutters up the code at least and arguably makes it harder to maintain.
But, on the other hand, it looks like the every-class-a-static approach doesn't scale easily either. Suppose I want to have multiple logs using the static API; I could try some singletons and factories...
Logger::get('debug')->note('Handle routes for the welcome area of the site.');
Logger::get('errors')->note('Danger!');
But this seems like it is just shifting the API from method names into string arguments (which could be misspelled, etc). And what if I want two different 'debug' loggers?
Either way I lean, static-based on the one side, or instance-based on the other, it seems like I run into limitations as the usage of the pattern grows.
Any advice on the best approach, given that I don't want to have to fill my application with repeated instantiation code, and yet I also want flexibility to grow with more kinds of classes, based on the existing ones?
These static classes in Laravel are actually glorified service locators.
"Syntactic sugar" they call "Facade" (not a good name but that is how Taylor calls them, do not confuse it with http://en.wikipedia.org/wiki/Facade_pattern)
Route::get('/', 'HomeController#showWelcome');
can be written as
$app['router']->get('/', 'HomeController#showWelcome');
read more: http://taylorotwell.com/response-dont-use-facades/

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

Standard form elements, where to place the code in MVC architecture

I'm in the creation of my own CMS. I'm doing this with the help of an MVC framework. I think a CMS should be build with a set of standard elements. Like, buttons, textfields and div containers where all the form elements reside in etc.
For instance, when i want to create a basic page then i want to do something like this in a view:
$cmsForm->beginTab('tab name');
$cmsForm->textfield('name', 'default value');
$cmsForm->textfield('email', '');
$cmsForm->textarea('info', '');
$cmsForm->submit('Save');
$cmsForm->endTab();
The problem is, is that i'm not sure where to put these methods. I obviously can't put these methods inside a controller. But perhaps a model is a good place? On the other hand, the model layer is used for storing/retrieving data from a persisten layer, not for returning HTML...
What would be a good place in an MVC architexture for this kind of thing?
This type of code belongs in your view layer. Remember, there's no rule that says your view layer can only be templates.
There's no rule that says what you have to do.
If I was you, I'd write my own class and implement it in framework, because it would be easier to re-factor later in case you need it. Also you won't change the logic of framework accidentally (everything may happen).
On the other hand, the model layer is used for storing/retrieving data from a persisten layer, not for returning HTML
Actually model layer is for business logic.
This clearly is code related to presentation logic, and thus should be in the View. Thought i think, that instead of such strange generator script, you would be better off by writing a template, which view then handles.
Also, your API is horrible. Haven't you even heard about SOLID principles.
If would be much better (but still misguided, IMHO )to have something like:
$foo = new HTML\Form();
$name = new HTML\Input('name');
$name->setValue('default value');
$name->setRules(array('required'));
$foo->addField( $name );
$email = new HTML\Input('email');
$email->setRules(array('required', 'email'));
$foo->addField( $email )
// other fields added
$template = new Template('/path/to/template.something');
$template->bind('form', $foo);
$output = $template->render();

is this an MVC?

this is a General Question about MVC ..
I wrote a PHP Class that send an Array with Core JsonData Strings to Jquery .. and on Jquery i´m accessing the data and add them to my views ( .append("htm stuff"+jsondata) )
now the Jquery is calling the data from a between.php page that has a catch block with many cases, and upon the called case/function , the between page is calling a function from the php class that sends the json data ..
so i have my oop php model that send the core jsondata , a controller ( catch block), and the view ( the jquery page) .. is this kind of MVC ? or i did miss understand it ?
an example of my code was posted on a previous Question here
Looking at the code you posted in your other post it is not a MVC implementation. Or at least it is a bad implementation.
The MVC is about seperating your presentation from your business logic. Looking at your POST class you don't seperate your business logic from your view:
public static function readPosts(){
$query = new Post_db("SELECT * FROM pmessage
ORDER BY p_id DESC
");
$posts = array();
while($row = $query->fetchRow()){
$posts [] = new Post($row);
}
foreach($posts as $item){
echo $item;
}
}
In this function you get information from your database (business logic) and print content (view). In other words, you combine your MV in one method. So I would say: No, this is not MVC.
In simple word MVC is a pattern, but it should follow some pattern in coding i.e. separation of concern
Model: the property class ,basically container for table data
View:Simple HTML Pages that show data using the models.
Controller:It send commands to the model to update the model's state
.It also work like a router that send model to view and vice-versa.
see the below link for reference...
Help Link
Anything that satisfies or follows Model-View-Controller pattern is called MVC. It's up to us to take it in this way or the other.
In my opinion, like I said if it satisfies MVC needs then call it MVC.

Categories