Prezi

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in the manual

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

MVC for PHP

Take a look at how a legacy PHP application is structured. A collection of PHP files in the webroot, the expected ‘inc’ directory, a config.php, and a gang of header.php, footer.php, and other assorted ‘template’ files. What’s wrong with all that?
by Tim Lytle on 2 April 2014

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of MVC for PHP

<div class='product'>
<h1><?php echo $product->title?></h1>
<div>
<?php echo $product->description?>
</div>
</div>
MVC
Model
View
Controller
<?php
include 'common/header.php';

require_once 'inc/config.php';
require_once 'inc/functions.php';

//sanitize the product id
$id = (int) $_GET['id'];

//make sure we have a db connection
db_connect();

//get the requested product
$res = mysql_query("SELECT * FROM products WHERE id = " . $id);
$product = mysql_fetch_assoc($res);

//show the product
echo "<h1>" . $product['name'] . "</h1>";
echo "<div>" . $product['description'] . "</div>";

?>
<div class='sidebar'>
<div class='cart'>
<?php
//add to card
if($_POST['quantity']){
$_SESSION['cart']['products'][$id]['quantity']
= (int) $_POST['quantity'];

//show undo button
echo "<a href='product.php?undo'>Undo</a>";
} else {
//show add form
form_helper('add',
'product.php',
$id,
array('quantity' => 'Quantity'));
}

//common cart html
include_once 'common/cart.php';
?>
</div>
</div>

<?php
include_once 'common/footer.php';
?>
product.php
cart.php
order.php
Legacy Application
/
/common
/inc
header.php
footer.php
config.php
func.php
General Configuration
Common Functions
cart.php
HTML Partials
These are included in all of these.
Most of this
ends up over here.
Include common HTML
And config and common functions.
And query the DB.
We do this anywhere we need a product.
Output some dynamic data.
Check for an action.
Conditionally output HTML.
Avoid copy and paste.
The include is nice, but now it's on every page.
function getProduct($id){
//do some stuff
return $product;
}
class Product
{
public $id;
public $title;
public $description;

public function getOptions()
{
//do stuff
return $options;
}
}
Now we can get a product anywhere.
We could return a simple array.
But why not use an object?
class ProductMapper
{
public function getProductById($id)
{
//do some stuff
return $product;
}

public function getProductBySKU($sku)
{
//do other stuff
return $product;
}
}
And then why not do this?
Model
<div class='sidebar'>
<div class='cart'>
<?php
if($inCart){
render('edit');
} else {
render('add');
}
?>
<!-- more cart HTML -->
</div>
</div>
Templates only contain code that outputs data.
Any logic is only related to the presentation.
View
//get the product
$product = $productMapper->getById($_GET['id']);

//pass it to the view
$view->set('product', $product);

//some cart functions
$cart = $cartMapper->getCartBySession();
if($_POST['quantity']){
$cart->add($product, $_POST['quantity']);
}

if($cart->has($product)){
$view->set('inCart', true);
}

//the view will include the site wide template
$view->render('product');
The code only relates to handling the specific request.
Controller
But there's still multiple files, and common code needed to setup the views and the models.
Single Gateway Script
//include the framework
$application = new Application();

//setup MVC
$application->bootstrap();

//handle the request
$application->run();
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Router
//parse request
$parts = explode('/', $_SERVER['REQUEST_URI');

//load matching controller
$controller = $application->load($part[0]);

//call matching method
$action = $parts[1] . 'Action';
$controller->$action($parts[2]);
http://example.com/product/show/23
class ProductController
{
public function showAction($id)
{
//pass the product to view
}
}
For
Zend Framework
Solid MVC Framework for PHP
Pick and Choose Component Library
No reason to use the MVC core if you don't need it.
Sponsored by Zend, but community driven.
Well tested,
'enterprise' ready.
Regular update cycle.
Easily use and extend the base classes.
Basic Request
http://example.com/[controller]/[action]
application/controllers/IndexController.php
public function indexAction(){}
http://example.com/order/search
application/controllers/OrderController.php
public function searchAction(){}
Just the default route.
Regex, module, REST routes can be used, or any custom route object.
application/views/scripts/order/search.phtml
Will render this as the view by default.
Controller.
Action.
No template 'language', just PHP.
MVC Structure
/application
/configs
/controllers
/models
/views
/Bootstrap.php
/public
/index.php
/library
/forms
/plugins
/services
Not created by default,
but can be added:
Anything here is on the include path.
application.ini contains the general configuration.
Custom bootstrap code is here.
$zf create project ./
Tim Lytle
Contract Developer
Zend CE
@tjlytle
In case you only recognize people by their profile pics.
Organizer of the
Lehigh Valley PHP Meetup
See the full transcript