Using Memcache with MySQL and PHP

Memcache is a great caching tool available for nearly every scripting or programming environment. I use it with PHP to speed up some applications I have written by completely avoiding asking the database for information. I wanted a very clean way of implementing this in my various projects, with as little change to the existing code as possible. Since memcache is an OBJECT caching system, you can’t simply drop your mysql_query resource into memcache, ask for it at another time, and get your results back … Which is how I had originally thought it worked the first time I read about it. The good news is that it can also store Strings, Integers, Floats, Arrays etc … Below I have a few other things I’ve learned whilst using memcache as well as the caching script I use for database queries.

What I’ve learned:

  1. memcache is great for storing slow queries that return small data sets [1 – 50 results, depending on the average row weight]
  2. memcache is not so great for any query that returns large data sets [100 – ∞, depending on the average row weight]

… in fact, I’ve found that memcache can occasionally be slower than running high-yield queries again [that is, if you have your MySQL server caching queries as well]. It all really boils down to benchmarking the scripts yourself: test every situation with and without the cache! [the more realistic the DB load, the better]

Caching is faster? Yay! Cache it!
DB query is faster? Yay! DON’T cache it!

So, basically, this isn’t a plug-and-play solution for ALL slow page loads / queries, just some of them.

Here’s the code I use to cache MySQL queries:


<?php
    # Connect to memcache:
    global $memcache;
    $memcache = new Memcache;

    # Gets key / value pair into memcache ... called by mysql_query_cache()
    function getCache($key) {
        global $memcache;
        return ($memcache) ? $memcache->get($key) : false;
    }

    # Puts key / value pair into memcache ... called by mysql_query_cache()
    function setCache($key,$object,$timeout = 60) {
        global $memcache;
        return ($memcache) ? $memcache->set($key,$object,MEMCACHE_COMPRESSED,$timeout) : false;
    }

    # Caching version of mysql_query()
    function mysql_query_cache($sql,$linkIdentifier = false,$timeout = 60) {
        if (($cache = getCache(md5("mysql_query" . $sql))) !== false) {
            $cache = false;
            $r = ($linkIdentifier !== false) ? mysql_query($sql,$linkIdentifier) : mysql_query($sql);
            if (is_resource($r) && (($rows = mysql_num_rows($r)) !== 0)) {
                for ($i=0;$i<$rows;$i++) {
                    $fields = mysql_num_fields($r);
                    $row = mysql_fetch_array($r);
                    for ($j=0;$j<$fields;$j++) {
                        if ($i === 0) {
                            $columns[$j] = mysql_field_name($r,$j);
                        }
                        $cache[$i][$columns[$j]] = $row[$j];
                    }
                }
                if (!setCache(md5("mysql_query" . $sql),$cache,$timeout)) {
                    # If we get here, there isn't a memcache daemon running or responding
                }
            }
        }
        return $cache;
    }
?>

The function mysql_query_cache() will return an array filled with the results. Since I don’t use this for large result sets, I don’t free the MySQL resource … you may want to free the resource after it’s been used if you get larger data sets.

Like I had mentioned before, I wanted the code to be as easy-to-use as possible when using it. So, I’ve set up a before and after test scenario showing how to retrofit your code with the new caching code:


<?php
    $sql = "
        SELECT `dataID`, `dataTitle`
        FROM `tbldata`
        WHERE `dataTypeID` BETWEEN 2 AND 2093
        AND `dataStatusID` IN (1,2,3,4)
        AND `dataTitle` LIKE '%something%'
        ORDER BY `dataDate` DESC
        LIMIT 10
    ";

    # Before: [without memcache]
    $rSlowQuery = mysql_query($sql);
    # $rSlowQuery is a MySQL resource
    $rows = mysql_num_rows($rSlowQuery);
    for ($i=0;$i<$rows;$i++) {
        $dataID = intval(mysql_result($rSlowQuery,$i,"dataID"));
        $dataTitle = mysql_result($rSlowQuery,$i,"dataTitle");

        echo "<a href=\"/somewhere/$dataID\">$dataTitle</a><br />\n";
    }


    # After: [with memcache]
    $rSlowQuery = mysql_query_cache($sql);
    # $rSlowQuery is an array
    $rows = count($rSlowQuery);
    for ($i=0;$i<$rows;$i++) {
        $dataID = intval($rSlowQuery[$i]["dataID"]);
        $dataTitle = $rSlowQuery[$i]["dataTitle"];

        echo "<a href=\"/somewhere/$dataID\">$dataTitle</a><br />\n";
    }

?>

Easy, huh? Run print_r() on the returned array to get an idea of how the array is structured if need be.

As always, if you have a better, more efficient, objective, more adaptable solution than mine, please leave a comment! I am 100% open to constructive criticism 🙂

»»» https://pureform.wordpress.com/2008/05/21/using-memcache-with-mysql-and-php/

Advertisements
By Rz Rasel Posted in Php

PHP Dynamic Image Generation

Creating images on the fly can be a very useful skill. PHP has some built-in image generation functions, further more, to generate new images or edit existing images on the fly using PHP, we need to have the GD library installed. In this tutorial we will show you how to get quite interesting and useful effects using image handling functions. We will review two practical tasks: creating security images (captcha) on the fly and building a bar chart using numerical values retrieved from MySQL database.

Creating security images on the fly

At first, have a look at the following script that creates captcha image. Next, we will consider each step of image generation in details.

<?php
//Send a generated image to the browser
create_image();
exit();

function create_image()
{
//Let’s generate a totally random string using md5
$md5 = md5(rand(0,999));
//We don’t need a 32 character long string so we trim it down to 5 
$pass = substr($md5, 10, 5);

//Set the image width and height
$width = 100;
$height = 20;

//Create the image resource

$image = ImageCreate($width, $height);

//We are making three colors, white, black and gray
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);

//Make the background black 
ImageFill($image, 0, 0, $black);

//Add randomly generated string in white to the image
ImageString($image, 3, 30, 3, $pass, $white);

//Throw in some lines to make it a little bit harder for any bots to break
    ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/2, $width, $height/2, $grey);
imageline($image, $width/2, 0, $width/2, $height, $grey);

    //Tell the browser what kind of file is come in 
header(“Content-Type: image/jpeg”);

//Output the newly created image in jpeg format 
ImageJpeg($image);

//Free up resources
ImageDestroy($image);
}
?>

To create a new image or edit an existing one, we need to create image identifier. In the preceding example we created an empty canvas by calling ImageCreate() function, passing it width and height  of a new image as a parameters. Another way to do it is to read the existing image from the file.  Depending on the file format you can do it using one of the following functions: ImageCreateFromPNG(), ImageCreateFromGIF(), ImageCreateFromJPEG(). Parameter of each function is a file name.

Then, we need to choose colors to be used while painting. For this we can use ImageColorAllocate() function and image identifiers for red, green, and blue (RGB) components of necessary color will be passed as parameters.

On the next step, we will generate our image. First, using ImageFill() function we will create black background.  Parameters of this function are: image identifier, initial coordinates of the area to be filled and fill color.  Then, we will use ImageString() function to add text to the image. Its parameters are – image identifier, font, coordinates for the first text position and text color. Finally, we will draw two lines and a rectangular to protect our image a little bit.  Please note, that the final point of the rectangular has the following coordinates: $width-1 and $height-1. If they were equal to $width and $height, than the rectangular would have exceeded canvas frame.

When we had created the image, we can output it either to a browser, or to a file. Our example shows how to output it to the browser. We need to inform the browser, that we will output the image, not the text or html-code. To do it, call Header() function, setting image MIME-type. It’s worth mentioning that Header() function can not be executed if HTTP header has already been sent.   After sending the header we can output our image using ImageJpeg() function, passing it image identifier as a parameter.

When we have finished working with the image we need to free up resources using ImageDestroy() function.

Back to top

Building a bar chart

In the example below, using graphic functions we will build a bar chart based on the values stored in MySQL database. In our case, values represent poll results.

In this example we will use poll database. To create it run the following SQL script in your MySQL server:

CREATE DATABASE `poll`;
USE poll;

CREATE TABLE `results` (
book_type VARCHAR(50),
num_votes INT
);

INSERT INTO `results` values
(‘Classic’, 15),
(‘Fantasy’, 7),
(‘Humor’, 32),
(‘Mystery’, 12),
(‘Poetry’, 25);

Script building a bar chart is quite long, so let’s divide it into two parts and discuss them separately. The first part of the script connects to MySQL database and requests data that will be represented in the bar chart.

<?php
//Querying the database to get poll results

//connection to the database
$dbhandle = mysql_connect(“localhost”, “root”, “”)
or die(“Unable to connect to MySQL”);

//select a database to work with
$selected = mysql_select_db(“poll”,$dbhandle)
or die(“Could not select examples”);

//execute the SQL query and return records
$result = mysql_query(“SELECT * FROM results”);

$num_poller = mysql_num_rows($result);
$total_votes = 0;

//fetch the data from the database
while ($row = mysql_fetch_array($result)) {
$total_votes += $row{‘num_votes’};  //calculating total number of votes
}

//nulling the pointer $result
mysql_data_seek($result,0);

//close the connection
mysql_close($dbhandle);

In the second part of the script first of all we will calculate variables needed to build the chart. Then, we prepare primary image and actually output data. Results for each genre are picked from the database one by one, percentage of votes is calculated, and then bars and explanatory notes are outputted.

In this script we are using TrueType fonts to get anti-aliased text. Functions that work with the TrueType fonts have its own peculiarities. First, you need to point where the fonts are located. For this, system variable GDFONTPATH is set. Then, we need to set the font name. TrueType fonts are rendered using  ImageTTFText().

We have already discussed above all functions used for drawing, the code has been commented and is quite clear, so you shouldn’t have any trouble.

//Tell gd2, where your fonts reside 
putenv(‘GDFONTPATH=C:\WINDOWS\Fonts’);
$font = ‘arial’;

//Set starting point for drawing 
$y = 50;

//Specify constant values
$width = 700; //Image width in pixels
$bar_height = 20; //Bars height
$height = $num_poller * $bar_height * 1.5 + 70; //Calculating image height
$bar_unit = ($width – 400) / 100; //Distance on the bar chart standing for 1 unit

//Create the image resource
$image = ImageCreate($width, $height);

//We are making four colors, white, black, blue and red
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$red   = ImageColorAllocate($image, 255, 0, 0);
$blue  = imagecolorallocate($image,0,0,255);

//Create image background
ImageFill($image,$width,$height,$white);
//Draw background shape
ImageRectangle($image, 0, 0, $width-1, $height-1, $black);
//Output header
ImageTTFText($image, 16, 0, $width/3 + 50, $y – 20, $black, $font, ‘Poll Results’);

while ($row = mysql_fetch_object($result)) {
if ($total_votes > 0)
$percent = intval(round(($row->num_votes/$total_votes)*100));
else
$percent = 0;

//Output header for a particular value
ImageTTFText($image,12,0,10, $y+($bar_height/2), $black, $font, $row->book_type);
//Output percentage for a particular value
ImageTTFText($image, 12, 0, 170, $y + ($bar_height/2),$red,$font,$percent.’%’);

$bar_length = $percent * $bar_unit;

//Draw a shape that corresponds to 100%
ImageRectangle($image, $bar_length+221, $y-2, (220+(100*$bar_unit)), $y+$bar_height, $black);
//Output a bar for a particular value
ImageFilledRectangle($image,220,$y-2,220+$bar_length, $y+$bar_height, $blue);
//Output the number of votes
ImageTTFText($image, 12, 0, 250+100*$bar_unit, $y+($bar_height/2), $black, $font, $row->num_votes.’ votes cast.’);

//Going down to the next bar
$y = $y + ($bar_height * 1.5);

}

//Tell the browser what kind of file is come in
header(“Content-Type: image/jpeg”);

//Output the newly created image in jpeg format
ImageJpeg($image);

//Free up resources
ImageDestroy($image);
?>

Back to top

Using dynamically generated images on the other pages

Since the header can be sent only once and it is the only way to tell the browser that you are going to send image, it is not so easy to insert automatically generated images to the regular pages. There are three ways to do it:

  • The whole page can consist of the image.
  • You can save image in the file and then refer to it using <img> HTML descriptor.
  • You can  put a script producing image in HTML descriptor, e.g.:
<img height=”120″ alt=”Dynamically generated image” src=”generate_image.php” width=”200″>

Related Articles

 How to connect to MySQL database using PHP

By Rz Rasel Posted in Php

MVC in PHP tutorial part 1: Hello World

Introduction

A basic implementation demonstration of Model-View-Controller (MVC) in PHP.

Since writing my article Model-View-Confusion part 1: The View gets its own data from the Model I have received several e-mails asking me to provide a simple example of MVC in PHP. So I’ve decided to create one. However, my intent is to build up from a very simplistic example and include some of the reasoning behind certain design decisions and considerations involved in deploying MVC on the web.

As stated in my previous article, a lot of other tutorials/articles go off into irrelevant sub-topics. I want to cover pure MVC. As such, you’ll find no discussion of template engines, directory structures, DAO, ORMs or similar in this article. This is pure MVC. From the ground up I’ll explain the original implementation of MVC and why it has to be adapted to work on the web.

What is MVC?

This is a broad definition of the components as defined by the pattern. Later on I will describe variants of this but this is MVC as described by the original implementations in Smalltalk-80

The Model

In its simplest form the model stores data which is to be accessed by the view and written to by the controller.

The model is the most complex of all the parts of the system and will contain all the logic which is specific to the application and where domain entities which relate to real world concepts (such as “a user” or “an order”) are stored. It is the part of the application which takes data (from any source) and processes it. The model also handles all data access and storage. It has no knowledge of any controllers or views which may use it.

For example, in PHP the model may represent a “User” in the system. It will handle any operations regarding users. Saving/loading records, validating registrations.

The model is not (common mistakes made by those misinterpreting the pattern):

  • A simple data access point
  • A class called “model” which represents a single database table

The View

The view contains all the display logic. In PHP it will be the part of the application which generates the HTML. It has direct access to the Model and can query the model to get its data. It can create callbacks to its controller (for example a clicking a button in the view would trigger an action in the controller). A lot of MVC examples state that the view is decoupled from everything else and fed data by the controller. This is entirely inaccruate (see: Model-View-Confusion part 1: The View gets its own data from the Model for a detailed explanation). In MVC the vews queries the model to request its own data.

The View is not (common mistakes made by those misinterpreting the pattern):

  • Absent of logic
  • Given data by the controller

The Controller

The controller takes user input and updates the model where required. Where there is no user interaction (e.g. where a static data set is displayed and will be the same every time), no controller should be necessary. It is important to note that the controller is not a mediator or gateway between the view and the model. The view gets its own data from its model. The controller accesses the model but does not contain any display logic itself. All the controller does is respond to user input.

Each controller is linked to a single instance of a view and a single instance of a model.

The Controller is not (common mistakes made by those misinterpreting the pattern):

  • A gateway/mediator between the model and the view
  • The place where views get initialised based on the state of a model. The controller is linked to a single view class (although it could be assigned to multiple instances) and responds to actions on it. For example a list of products would be a single view. The controller would handle user actions such as sorting the list, filtering the records it’s displaying based on criteria specified by users. It would not also deal with displaying the info for a single product. This is a different view, which requires its own controller.

Program flow

The typical program flow in MVC is:

  • The model, view and controller are initialised
  • The view is displayed to the user, reading data from the model
  • The user interacts with the view (e.g. presses a button) which calls a specified controller action
  • The controller updates the model in some way
  • The view is refreshed (fetching the updated data from the model)

Hello World

In standard MVC, the view would be initiated, assigned a controller and model, then rendered (Burbeck, 1992; Krasner & Pope; 1988). The user would interact with the view and this would trigger actions on the controller.

A hello world application would look something like this:

PHP Code:

class Model {
public 
$text;

public function __construct() {
$this->text 'Hello world!';
}
}

class View {
private 
$model;
private 
$controller;

public function __construct(Controller $controllerModel $model) {
$this->controller $controller;
$this->model $model;
}

public function output() {
return 
'<h1>' $this->model->text .'</h1>';
}

}

class Controller {
private 
$model;

public function __construct(Model $model) {
$this->model $model;
}
}

//initiate the triad
$model = new Model();
//It is important that the controller and the view share the model
$controller = new Controller($model);
$view = new View($controller$model);
echo 
$view->output();
Notice how the controller isn’t doing anything? This is because there is no user interaction. Hello world is purely display.

N.b. the controller is passed to the view because in a desktop application, the view would need to create a callback on the correct controller, so it would need to know which controller was in use. This still happens on the web, but it a more subtle way. In Part 2 I’ll show how this is worked around on the web.

In a lot of (so called) MVC examples and frameworks, the controller acts as an entry point that creates its view and model. I’ll explain why this is later on, but it’s important to understand that this is not something defined by the pattern itself and using it as an entry point can imply the usage of “fat controllers” (Brady, 2009) whereby the controller is acting as a gateway between the view and model. See my article Model-View-Confusion part 1: Why the model is accessed by the view in MVC for more information on why this is not good practice.

In this case, the traditional approach works as intended on the web. However, when user actions need to be defined, a problem occurs that forces us as PHP developers to deviate from this standard approach.

User interaction

This wouldn’t be a complete example if one of the components (in this case the controller) wasn’t doing anything. So let’s add some user interaction so that the controller has something to do.

User interaction is the first problem with the MVC architecture on the web. There’s no way to create a callback to the controller directly. The whole page needs to be reloaded. Still, not a huge issue but there needs to be some code to route the action back to the (correct!) controller.

As a simple example I will extend the Hello World example and make it so that when “Hello world” is clicked, the text will be changed to “Text updated”.

Firstly, add a link to the view. This can be likened to adding a callback to the controller from the view. In GUI applications, the controller would just be another object in memory and the callback would be a simple function call. This is not an option on the web the only way to access the controller is another HTTP request.

PHP Code:

class View {
private 
$model;
private 
$controller;

public function __construct(Controller $controllerModel $model) {
$this->controller $controller;
$this->model $model;
}

public function output() {
return 
'<a href="mvc.php?action=textclicked">' $this->model->text '</a>';
}
}
On the callback (second request) all the components must be re-initialised. Some code must be added to route the action back to the controller:

PHP Code:

$model = new Model();
//It is important that the controller and the view share the model
$controller = new Controller($model);
$view = new View($controller$model);
if (isset(
$_GET['action'])) $controller->{$_GET['action']}();
echo 
$view->output();
All this does is call the relevant controller action (specified by $_GET[‘action’]) based on the user interaction.

Finally, a controller action to handle the event has to be added:

PHP Code:

class Controller {
private 
$model;

public function __construct(Model $model) {
$this->model $model;
}

public function textClicked() {
$this->model->text 'Text Updated';
}
}
Now, when the page is visited it will say “Hello World” when the link is clicked it will say “Text updated”. Not exactly rocket science but it’s a basic working example of pure MVC in php.

Click here to see it working or click here to see the full source code.

By Rz Rasel Posted in Php

PHP MVC Framework Tutorial

This post explains you about mvc framework.

MVC stands for Model View Controller.

The model view controller pattern is the most used pattern for web applications.

M (Model)-: Related With Database Query

V (View):- Related With Templates

C (Controller):- Used for communicating Model and View. A place where we write bushiness logic of our program.

MVC Flow:- Firstly user intersect  with controller. Now controller will call to the appropriate model and model return the data and now controller  pass this data   to appropriate view and flow goes again and again.

So here is a simple source code example for PHP MVC framework.

 

Download Link   Demo Link

 

Steps for using this framework:

  • Go to common.inc.php under library folder and define all the paths or for using the default path just paste mvc folder into you root directory.
  • Go to product.php under model folder and change you database setting.
  • And just copy sample database attached with zip file and load it into your database.
  • If you wana create a new controller and just create a new php file and put in undercontroller folder  and remember one thing controller file  name and your controller class will be same and additionally Controller  sufix add on it. Like in this example controller name is product and its class name is productController. Same thing apply in case of model.

Framework  Flow:- 

In the first time when user visit the site,  url is:  http://www.91weblessons.com/demo/mvc  and when user click to more link url will be http://www.91weblessons.com/demo/mvc?controller=product&function=detail&id=1

Working of index.php:- index.php is the  entry point of the application, and call everytime whenever user navigate within the website. So firstly we check  that there is any controller call or not, and we check this from query string, so if  $_GET[‘controller’] is set and $_GET[‘controller’] is not empty only than we take its value other wise we call the default controller that is product in our case.

Same thing work in case of function. Firstly we check that there is any function  call or not, and we check this from query string, so if  $_GET[‘function’] is set and $_GET[‘function’] is not empty only than we take its value other wise call our default function that is listing in our case.

And now if  corresponding controller and function not available  in respective folder and file. application will stop using die statement.

And if all is working fine you can create controller object  and call to its function. Now flow goes to controller.

<?php
include_once($_SERVER['DOCUMENT_ROOT'].'library/common.inc.php');
if(isset($_GET['controller']) && !empty($_GET['controller'])){
     $controller =$_GET['controller'];
}else{
     $controller ='product'; //default controller
}

if(isset($_GET['function']) && !empty($_GET['function'])){
    $function =$_GET['function'];
}else{
    $function ='listing'; //default function
}

$controller=strtolower($controller);
$fn = SITE_ROOT.'controller/'.$controller . '.php';
if(file_exists($fn)){
    require_once($fn);
    $controllerClass=$controller.'Controller';
    if(!method_exists($controllerClass,$function)){
       die($function .' function not found');
    }
    $obj=new $controllerClass;
    $obj-> $function();
}else{
    die($controller .' controller not found');
}
?>

 

Controller Working (product.php):-

loadView used for loading the view and loadModel is used for loading the model, both the function are define in common.inc.php file

<?php
 class productController{
   function __construct() {
 }

 function listing(){
    loadView('header.php');
    $arrValue=loadModel('product','showProductListing');
    loadView('product_listing.php',$arrValue);
    loadView('footer.php');
 }

 function detail(){
    loadView('header.php');
    $id=$_GET['id'];
    $arrArgument=array('id'=>$id);
    $arrValue=loadModel('product','productDetails',$arrArgument);
    loadView('product_detail.php',$arrValue);
    loadView('footer.php');
 }
}
?>

And now welcome to MVC family.

By Rz Rasel Posted in Php

PHP – create a new user into a db using MVC framework

I am a beginner and am creating a small web app. I’m working on the registration process for new users, and as this is largely a learning project I’m doing it from scratch.

Here is my user class: Class_user.php

<?php
    classUser{// The class variables are the same and have the same name as the db fields.private $userID;// Must be incremental + unique.  Also used as salt.private $userName;// Must be unique.private $hashedPassword;private $userEmail;function __construct($userID, $userName, $hashedPassword, $userEmail){
            $this->userID=$userID;
            $this->userName=$userName;
            $this->hashedPassword=$hashedPassword;
            $this->userEmail=$userEmail;}function getUserID(){return $this->userID;}function getUserName(){return $this->userName;}function getHashedPassword(){return $this->hashedPassword;}function getUserEmail(){return $this->userEmail;}}?>

Here is my model for the user – Model_User.php:

<?php
    require_once('Class_DB.php');
    require_once('Class_User.php');
    require_once('DAO_User.php');classModel_user{// Object that represents a connection to the user DBprivate $dbInstance;function __construct($dbInstance){// Using Dependency Injection passing a Class_DB object rather than global variable.
            $this->dbInstance=$dbInstance;}function insertNewUser($user, $userPassword){// INCOMPLETE
            $userDAO=new DAO_User($this->dbInstance);
            $insertedUser=$userDAO->createNewUser($user, $userPassword);
            $userPassword="";// We clear the user's password from memory.if($insertedUser){// User was correctly inserted in dbreturntrue;// Should return the $user object.}else{returnfalse;}}}?>

Here is the key snippet from my user registration controller, Controller_Register.php

<?php
    require_once("Controller.php");
    require_once("Model_User.php");
    require_once("General.php");classController_RegisterextendsController{protected $page='UI_Register.php';function execute($view){// Several lines to make sure the form is filled adequately.While(!$userInserted){// As long as the user isn't correctly inserted...
                $userName=$_POST["userName"];
                $userEmail=$_POST["userEmail"];
                $userPassword=$_POST["userPassword"];
                $_POST["userPassword"]="";// We don't keep the pw in memory.
                $user=new user("", $userName,"", $userEmail);// User ID will be generated by the db, and the hashed pw has not been generated at this point.
                $userInserted=$userDBConnection->insertNewUser($user,$userPassword);// We insert the user name not knowing what the autoincremented user ID is.
                $userPassword="";// We don't keep the pw in memory.}
            $_POST["password"]="";// We clear the user's password from memory.if($userInserted){// The value is true if the registration was succesful.
            $msg=newMessage("Congratulations ".$_POST['userName']."! You are now registered.");}}return $view;}?>

Finally, here is my user DAO code, with the key item I would like guidance on, the registration – DAO_User.php

<?php
    require_once('Class_User.php');
    require_once('Class_DB.php');
    require_once('General.php');class DAO_User {private $dbInstance;// This is an instance of Class_DB to be injected in the functions.function __construct($dbInstance){
            $this->dbInstance=$dbInstance;// Using Dependency Injection passing a Class_DB object rather than global variable.}function createNewUser($user, $userPassword){// The $user object only has a userName and a userEmail at this point.
            $dbConnection=$this->dbInstance->createConnexion();// This connection is local, so automatically closed after the function is completed.
            $inserted=false;while(!$inserted){// This insert a new user, without any value for pw, and generates an autoincrement user ID on the db side.
                $query=$dbConnection->prepare("INSERT INTO users (userName, userEmail) VALUES (?,?)");// userID is generated via autoincrement - therefore not known at time of insertion.
                $query->bindValue(1, $user->userName);
                $query->bindValue(2, $user->userEmail);
                $inserted=$query->execute();//True if succesful, False if not.}
            $query=$dbConnection->prepare("SELECT LAST_INSERT_ID()");// This allows us to retrieve the user ID as generated by the db.
            $userIDquery=$query->execute();
            $result=$userIDquery->fetch(PDO::FETCH_ASSOC);// returns an array indexed by column name as returned in result set - here column name is "userID" in the DB
            $userID=$result["userID"];
            $user->userID=$userID;// We modify the user ID of the $user object to be the autoincremented number generated by the db.
            $hashedPassword=stringHashing($userPassword,$user->userID);
            $userPassword="";
            $user->hashedPassword=hashedPassword;
            $hashedPWinserted=false;while(!$hashedPWinserted){// This modifies the user table in db to add hashed PW.
                $query=$dbConnection->prepare("UPDATE users SET hashedPassword=? WHERE userID=?");
                $query->bindValue(1, $user->hashedPassword);
                $query->bindValue(2, $user->userID);}return $user;}}?>

The General.php code contains the stringHashing function that receives a string and a salt as parameter and and returns the salted string. I’m not sure where it should live in an MVC framework.

My users table is a MySQL table with 4 fields:
– userID (INT(10), not null, autoincrement, PK) – also used as a salt for PW hashing
– userName (varchar(50), not null)
– hashedPassword (char(128), can be null)
– userEmail (varchar(255), can be null)

Some specific questions I have, mostly on the createNewUser function:
– Are the db transactions correctly and efficiently done?
– Should I split some functionalities outside of this function?
– Should I limit the use of intermediate variables?
– Does the function accomplish the goals I want it to do, i.e., insert in the db a new user with an autoincremented user ID generated by the db, and then a hashed password?

Also interested in any other piece of feedback people may have, especially with regards to readability (e.g., are my commentaries too verbose and obvious) and understandability of my code, as well as best practice object programming (e.g., I suppose I should modify my $user object with a setter rather than $user->userID=$userID;).

UPDATE When I run this code, I get no error, but I also don’t get any record in the db…

Thanks,

By Rz Rasel Posted in Php

SEO for Developers

Hey, you! Thanks for visiting. I don’t know if you found this website via a search engine or by social media link or whatever, but thank you for stopping by. As a matter of fact, this will be the topic of our little post: how to improve your SEO, from the technical side of things.

This will be the post about what you as developers can do about SEO. We’ll stay on the technical side of the equation, and leave the “snake oil salesmanship” to so-called “SEO experts, gurus and rockstars”. Therefore we’ll only mention the things that are proven to be SEO-friendly, and much more important than that, we’ll see how you can implement those things using some popular Web Development technologies.

So, let’s get started.

Table of Contents

  1. Clean URLs
    1. URL Rewriting
    2. ASP.NET Routing
  2. Duplicate content problemsPagination (link rel=”prev”, link rel=”next”)
    1. The HTTP 301 Redirect
    2. Specifying the canonical page
  3. Site speed
    1. Use CSS Sprites
    2. Use a CDN
    3. Minify site resources (JavaScript, CSS …)
  4. Other considerations Developers should pay attention toConclusion
    1. Issue with Separate mobile URLs
    2. Know the HTTP Status Codes
    3. Moving to a new domain – the right way
    4. Add social sharing buttons to a site
    5. Use Schema.org tags

1. Clean URLs

Everybody (and their grandma) already knows that so-called or user-friendly URLs (or clean URLs) are good for SEO. Not only that, but clean URLs are pretty, easy to remember and cool.

Take a look at these examples of URL rewriting:

http://localhost/index.php?view=content&id=1 -> http://localhost/content/1
http://localhost/NewsList.aspx?year=2013&month=08 -> http://localhost/news/2013/08

In previous two examples rewritten URLs are clearly better looking. They’re also more professional looking and people are just more likely to click on them. I mean, aren’t you?

Now take a look at this example:

http://localhost/NewsDetails.aspx?id=45 -> http://localhost/news/45/article-title

See what happened there? We not only made a cooler URL, but we managed to stick some words that help to describe the very nature of the article. And it certainly helps with Google and Bing. Haven’t you ever seen a search engine higlight a portion of the URL? Well, take a look:

Google Highlights parts of Clean URL

Of course, there’s another great advantage of URL Rewriting: original query strings used to retrieve blog posts can change and the rewritten URL can stay the same.

There’s also the security factor of rewritten URLs: they hide how site works, meaning users don’t really know what query strings are used and what is happening behind the scenes.

OK, so, how do we get clean URLs? Well, it’s simple, really. There are a lot of technologies for getting clean URLs. First, of course, is rewriting.

1.1. URL Rewriting

I did an entire article about rewriting on IIS, so you should look there for specifics. But the bottom line is you can use the IIS rewrite module for IIS which enables both simple and robust URL Rewriting based on request headers, IIS Server Variables and other rules.

You can download URL Rewrite from IIS.net website or install it using Web Platform Installer.

It’s cool and easy to use URL Rewrite Module from IIS manager:

Creating URL Rewrite rue via GUI from the IIS Manager

To learn more about URL Rewriting using IIS Rewrite module visit my previous blog post, or of course, more advanced Ruslan’s blog. He’s a Senior Software Design Engineer on Microsoft Windows Azure team, so you’re bound to learn a lot more by visiting his blog.

Of course, you can URL rewrite on Apache too, there are lots of great resources out there to help you to get started:

1.2. ASP.NET Routing

No, not that kind of routing. But, understanding that kind of routing can be helpful in understanding ASP.NET routing. 🙂

So, what is ASP.NET routing? Well, routing is a feature that enables us to map specific browser requests to primarily ASP.NET MVC controllers and actions, but routing can be used with Web Forms as well.

In previous versions of MVC routes were configured in Global.asax, but in newer versions of MVC, routes are congured by editing the “RouteConfig.cs” inside the “App_Start” folder.

When you create a new MVC 4 project, for example, you will have the following routing config already entered for you:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

The default route lists three parameters, with configured default values. For example default value for a controller is “Home”. If the “controller” parameter is missing, it will default to “Home”. If the action is missing, it will default to “Index”, and if id is missing, it will default to an empty string.

So, if you run your basis MVC start application, by default “Home” controller and “Index” action will be used. This means that if we wanted to have a URL like: http://localhost/posts/2008 we can enter a new route like this one:

1
2
3
4
5
routes.MapRoute(
    name: "Posts",
    url: "posts/{year}",
    defaults: new { controller = "Blog", action = "Archive" }
);

So this route will match a request that starts with “posts” and map it to the “Blog” controller and “Archive” method. That is, if you put that route above the “default” route

It’s important to notice as you play with routes that ordering is important, because as soon as a route is matched, the processing stops. For example if we put our route behind the default route, the default route will be matched and it will map our request to the “posts” controller which does not exist. So, if we do it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
    routes.MapRoute(
        name: "Posts",
        url: "posts/{year}",
        defaults: new { controller = "Blog", action = "Archive" }
    );
 
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

We get this:

Good routing configuration maps HTTP request to a specific controller and action

and if we do it like this:

Bad configured routing leads to a 404

So, it really doesn’t take a lot of imagination (or programming, really) to use routing to help us make our desired clean URLs. For deeper understanding of routes and various route tricks be sure to check out Phil Haack’s blog.

2. Duplicate content problems

There are some doubts whether is this actually a problem. For example, in this video Google’s Matt Cutts kinda says duplicate content shouldn’t be a problem, but I think it’s better to stay safe. If google is THAT smart, maybe other search engines aren’t.

Anyway, duplicate content can be a problem, because often search engines don’t know which version of the document to include on the resut pages.

So, what exactly IS “duplicate content”? Well, duplicate content can happen:

In all those examples the search engine can be in doubt which page to show.

So, what to do about it? Well, you basically have two options:

  1. Do a HTTP 301 Redirect
  2. Specify the canonical page using rel=”canonical”

2.1. The HTTP 301 Redirect

The HTTP 301 status code means that the page a user (or a bot) is trying to visit has moved to a new location. By using 301 redirect to a new location you’re letting the user agents know a new location of the page.

So, you basically need to decide which is the preferred URL of a page and when a user or a spider visits any other url version of that page redirect them to a preferred url.

The very act of redirecting is basically easy. You have several options to use, including .htaccess on Apache servers or through URL Rewrite module on IIS.

Here are some helpful links:

Of course, you can also implement HTTP 301 redirect directly from your preferred server-side technology:

PHP – Use the header function:

1
2
3
4
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.new-url.com");
exit();

ASP.NET Web Forms – Response:

1
2
3
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", http://www.new-url.com);
Response.End();

ASP.NET MVC:

There are actually a few good methods you can call from the controller:

1
2
3
return RedirectPermanent("http://www.new-url.com/");
return RedirectToActionPermanent("action", "controller", new { id = 1, title = "new-title"  });
return RedirectToRoutePermanent("route-name", new { id = 1, title = "new-title" });

TIP: If you’re using slugs in your URLs, but get the data from database, using a numeric value like for example, Stack Overflow does, you should do a redirect each time when you get a different slug from the one stored in your database.

So, the basic principle is kinda like this:

  1. Have a content slug (for example slug for this content is: “seo-for-developers”) stored in the database. A slug can be automatically generated or have users enter them via CMS. Whatever.
  2. Use a numeric ID to get the data from DB.
  3. When you have the data from DB, compare the stored slug with the one you got from query string.
  4. If they don’t match, do a 301.

I do this. This enables me to redirect whatever duplicate slugs someone may have to the correct one every time. For example, you can get to this article using this link: http://salopek.eu/content/32/bleh and you’ll be redirected to the correct one.

2.2. Specifying the canonical page

What is a canonical page? Well, to quote google:

A canonical page is the preferred version of a set of pages with highly similar content.

So, it’s kinda like a permanent redirect to a preferred version of the page. But, how do we “specify canonical page”? Well, we “Add a rel=”canonical” link to the <head> section of the non-canonical version of each page. “.

For example, if you could access my “Hello world” blog post using many slugs, the correct procedure would be to put a “canonical” with a preferred content url inside the head section of each duplicate content versions, like this:

<link rel=”canonical” href=”http://salopek.eu/content/31/hello-world&#8221; />

Using the canonical link tells the Bing, Yahoo and Google search engines where the preferred content is.

How to generate and display the canonical link? Simple, there are plugins for many popular blogging tools and CMS solutions. And if there are none, a simple google search will give you lots of plugins and useful options:

Still, if you don’t find a plugin for your CMS, it should be really easy to write one for yourself. After all this blog post is named “SEO for Developers” : )

Just remeber, link rel=”canonical” can contain both absolute and relative URLs, so don’t sweat about it too much, just pick a format and go with it.

3. Pagination

What’s the deal with pagination and paginated content? Well, the deal is, the content is spread out across multiple URLs, and unless you have an View-All page, the search engine may have trouble understanding that content is consolidated and view each page as a slightly different content, which means it can reduce the impact of your content as it’s spread out across multiple pages and no single page gets a big impact.

Link rel=”prev” and like rel=”next” basically help search engines understand each indvividual page as a part of the “series” of content, which in essence helps them to present the best, most relevant page to the user (usually page no. 1).

So, what’s the structure of link rel=”prev” and link rel=”next”? It’s really simple, so let’s see an example of paginated content that spans across three pages:

  1. First page in a series of paginated content:
    No rel=”prev”
    rel=”next” to next page:<link rel=”next” href=”http://example.com/page/2&#8243; />
  2. Second page in a series
    Both rel=”prev” and rel=”next”
    rel=”next” to next page <link rel=”next” href=”http://example.com/page/3&#8243; />
    rel=”prev” to previous page <link rel=”prev” href=”http://example.com/page/1&#8243; />
  3. Third and last page in a series:
    No rel=”next”
    rel=”prev” to previous page <link rel=”prev” href=”http://example.com/page/1&#8243; />

How to do that? Well, it’s simple, really. I’m betting that if you have pagination system in place you can easily access the variables needed to generate the mentioned tags. For example, this is how you would do it using ASP.NET MVC:

Layout:

1
2
3
<head>
    @RenderSection("seo", required: false)
</head>

View:

1
2
3
4
5
6
7
@section seo {
    @if (Model.HasPreviousPage)
    {
        <link rel="prev" href="@Url.Action("Index", "Home"
            , new { page = (Model.PageIndex - 1) }))" />
    }
}

Advanced tip: the added bonus of adding the rel=”next” is that Firefox prefetches “next” page so it loads faster:

Firefox pre-fetches the rel-next page

Also, it doesn’t hurt to set the page title to show to the visitor on what page they’re on: <title>salopek.eu | Web Development | Web Design | Networking (Page 1 of 8)</title>

4. Site speed

This is a quote from the Using site speed in web search ranking official Google webmaster central blog:

“…as part of that effort, today we’re including a new signal in our search ranking algorithms: site speed.”

So, the bottom line is: You should strive for small loading times for your website. How to do this? Well, there are lots of ways:

4.1. Use CSS Sprites

CSS Sprites enable us to store the graphics we need to display menus, icons or buttons in one big image while showing only a part of that image at a time. This helps to reduce the number of HTTP requests, which increases site speed.

This isn’t really a developer thing, it’s more a designer thing, but you can check out my earlier blog post for more information on CSS Sprites.

4.2. Use a CDN

You can load many great tools and libraries from the CDN:

4.3. Minify site resources (JavaScript, CSS …)

This means: “remove all unnecessary characters from resources to make them smaller and lighter.” There are tools to do this, like: JSMin or YUI Compressor, but since you are a developer, you can even write your own, if you want to learn something new and spend a little free time.

For example I use the new bundling and minification features in ASP.NET.

These few are only examples of what can you do. There are of course other things you can do to improve site speed. A great place to start would be checking out Yahoo’s Best Practices for Speeding Up Your Web Site.

Also, there are lots of great tools to help and assist you:

5. Other considerations Developers should pay attention to

5.1. Issue with separate mobile URLs

If you use redirects for mobile devices (which you shouldn’t do) you should:

“…Include <link rel=”alternate” /> in your desktop pages”.

5.2. Know the HTTP Status Codes

A lot of win comes from knowing the HTTP Status Codes and using them correctly. Here’s the list on Wikipedia. Study it. Know what status code to use and when.

For example, if a page doesn’t exist, returning a 200 OK status code and a “Page not found” message is

5.3. Moving to a new domain – the right way

301 Redirects should always be from a old URL of a content to a new URL of a same content, for example:
http://old-domain.com/example-page-123.html to
http://new-domain.com/example-page-123.html

You should never redirect all the traffic from the old domain to the new domain. Do NOT do this:
http://old-domain.com/example-page-123.html to
http://new-domain.com

You can also tell Google (using Webmaster tools) that your website has moved to a new domain.

Submit the change of address request via Google Webmaster tools

To do this, simply login to Webmaster Tools, click on a site and in the dropdown preferences menu select: Change of Address.

Webmaster tools: Change of address notice

5.4. Add social sharing buttons to a site

While social buttons aren’t having a direct impact on SEO, they make site’s content much easier to share with others using their favourite social networks. This means their friends, followers or what have you will visit your site and maybe share it further, maybe even link to it on their own site etc. So, how to share?

Well, every major social network has their share widget now, which you can easiy implement on your site:

Also, when implementing a share widget make sure to load JavaScript asynchronously.

5.5. Use Schema.org tags

Schema.org tags are another result of collaboration between Google, Bing and Yahoo. These tags help developers and webmaster to indicate to the search engines what their content is all about. If these tags are properly structured, search engines can read them and understand the meaning of a certain web page content. This is how you get those rich snippets you see when searching.

Getting started using schema.org tags is easy. For example this is how you would set up the tags to describe a book:

1
2
3
4
5
6
7
<div itemscope itemtype="http://schema.org/Book">
  <h1 itemprop="name">A Brief History of Time</h1>
  <span>Author: <a itemprop="author" href="http://en.wikipedia.org/wiki/Stephen_Hawking">Stephen Hawking</a></span>
  <span itemprop="genre">Popular science</span>
  <span itemprop="numberOfPages">256</span> pages
  <a href="http://en.wikipedia.org/wiki/A_brief_history_of_time" itemprop="detail">Details</a>
</div>

This does not have any effect on ranking at this time, but your site can look better in the search results, which can lead to more traffic.

Conclusion

This concludes or little list of stuff we as developers can do to help SEO both directly and indirectly (by giving the right tools to people that may know more about SEO than we). Note that I included only stuff that’s proven and that people who work at the search engines tell us themselves. If you feel I forgot something important, feel free to leave a comment and a link to your site. Please, no shady or black hat stuff, as this won’t help people and your comment will be deleted.

Also, do yourself a favor and stay away from guys that promise stuff they can’t deliver (or possibly can, but using techniques that will get penalized in the next search engine algorithm update). My advice is: try to write good and helpful content, stick to the common sense, use keywords in articles wisely (don’t blindly stuff your articles full of keywords) and the results will come.

Thank you for your time.

By Rz Rasel Posted in Php

Model View Controller(MVC) in PHP

The model view controller pattern is the most used pattern for today’s world web applications. It has been used for the first time in Smalltalk and then adopted and popularized by Java. At present there are more than a dozen PHP web frameworks based on MVC pattern.

Despite the fact that the MVC pattern is very popular in PHP, is hard to find a proper tutorial accompanied by a simple source code example. That is the purpose of this tutorial.

    The MVC pattern separates an application in 3 modules: Model, View and Controller:

  • The model is responsible to manage the data; it stores and retrieves entities used by an application, usually from a database, and contains the logic implemented by the application.
  • The view (presentation) is responsible to display the data provided by the model in a specific format. It has a similar usage with the template modules present in some popular web applications, like wordpress, joomla, …
  • The controller handles the model and view layers to work together. The controller receives a request from the client, invokes the model to perform the requested operations and sends the data to the View. The view formats the data to be presented to the user, in a web application as an html output.

The above figure contains the MVC Collaboration Diagram, where the links and dependencies between figures can be observed:
mvc-collaboration

Our short php example has a simple structure, putting each MVC module in one folder:
mvc-structure

Controller

The controller is the first thing which takes a request, parses it, initializes and invoke the model and takes the model response and sends it to the presentation layer. It’s practically the liant between the Model and the View, a small framework where Model and View are plugged in. In our naive php implementation the controller is implemented by only one class, named unexpectedly controller. The application entry point will be index.php. The index php file will delegate all the requests to the controller:

  1. // index.php file  
  2. include_once(“controller/Controller.php”);  
  3.   
  4. $controller = new Controller();  
  5. $controller->invoke();  

Our Controller class has only one function and the constructor. The constructor instantiates a model class and when a request is done, the controller decides which data is required from the model. Then it calls the model class to retrieve the data. After that it calls the corresponding passing the data coming from the model. The code is extremely simple. Note that the controller does not know anything about the database or about how the page is generated.

  1. include_once(“model/Model.php”);  
  2.   
  3. class Controller {  
  4.      public $model;   
  5.   
  6.      public function __construct()    
  7.      {    
  8.           $this->model = new Model();  
  9.      }   
  10.       
  11.      public function invoke()  
  12.      {  
  13.           if (!isset($_GET[‘book’]))  
  14.           {  
  15.                // no special book is requested, we’ll show a list of all available books  
  16.                $books = $this->model->getBookList();  
  17.                include ‘view/booklist.php‘; 
  18.           } 
  19.           else 
  20.           { 
  21.                // show the requested book 
  22.                $book = $this->model->getBook($_GET[‘book‘]); 
  23.                include ‘view/viewbook.php’;  
  24.           }  
  25.      }  
  26. }  

In the following MVC Sequence Diagram you can observe the flow during a http request:
mvc-sequence1

Model and Entity Classes

    The Model represents the data and the logic of an application, what many calls business logic. Usually, it’s responsible for:

  • storing, deleting, updating the application data. Generally it includes the database operations, but implementing the same operations invoking external web services or APIs is not an unusual at all.
  • encapsulating the application logic. This is the layer that should implement all the logic of the application. The most common mistakes are to implement application logic operations inside the controller or the view(presentation) layer.

In our example the model is represented by 2 classes: the “Model” class and a “Book” class. The model doesn’t need any other presentation. The “Book” class is an entity class. This class should be exposed to the View layer and represents the format exported by the Model view. In a good implementation of the MVC pattern only entity classes should be exposed by the model and they should not encapsulate any business logic. Their solely purpose is to keep data. Depending on implementation Entity objects can be replaced by xml or json chunk of data. In the above snippet you can notice how Model is returning a specific book, or a list of all available books:

  1. include_once(“model/Book.php”);  
  2.   
  3. class Model {  
  4.     public function getBookList()  
  5.     {  
  6.         // here goes some hardcoded values to simulate the database  
  7.         return array(  
  8.             “Jungle Book” => new Book(“Jungle Book”“R. Kipling”“A classic book.”),  
  9.             “Moonwalker” => new Book(“Moonwalker”“J. Walker”“”),  
  10.             “PHP for Dummies” => new Book(“PHP for Dummies”“Some Smart Guy”“”)  
  11.         );  
  12.     }  
  13.       
  14.     public function getBook($title)  
  15.     {  
  16.         // we use the previous function to get all the books and then we return the requested one.  
  17.         // in a real life scenario this will be done through a db select command  
  18.         $allBooks = $this->getBookList();  
  19.         return $allBooks[$title];  
  20.     }  
  21.       
  22.       
  23. }  

In our example the model layer includes the Book class. In a real scenario, the model will include all the entities and the classes to persist data into the database, and the classes encapsulating the business logic.

  1. class Book {  
  2.     public $title;  
  3.     public $author;  
  4.     public $description;  
  5.       
  6.     public function __construct($title$author$description)    
  7.     {    
  8.         $this->title = $title;  
  9.         $this->author = $author;  
  10.         $this->description = $description;  
  11.     }   
  12. }  

View (Presentation)

The view(presentation layer)is responsible for formating the data received from the model in a form accessible to the user. The data can come in different formats from the model: simple objects( sometimes called Value Objects), xml structures, json, …

The view should not be confused to the template mechanism sometimes they work in the same manner and address similar issues. Both will reduce the dependency of the presentation layer of from rest of the system and separates the presentation elements(html) from the code. The controller delegates the data from the model to a specific view element, usually associated to the main entity in the model. For example the operation “display account” will be associated to a “display account” view. The view layer can use a template system to render the html pages. The template mechanism can reuse specific parts of the page: header, menus, footer, lists and tables, …. Speaking in the context of the MVC pattern

In our example the view contains only 2 files one for displaying one book and the other one for displaying a list of books.

viewbook.php

  1. <html>  
  2. <head></head>  
  3.   
  4. <body>  
  5.   
  6.     <?php   
  7.   
  8.         echo ‘Title:’ . $book->title . ‘<br/>‘;  
  9.         echo ‘Author:’ . $book->author . ‘<br/>‘;  
  10.         echo ‘Description:’ . $book->description . ‘<br/>‘;  
  11.   
  12.     ?>  
  13.   
  14. </body>  
  15. </html>  

booklist.php

  1. <html>  
  2. <head></head>  
  3.   
  4. <body>  
  5.   
  6.     <table>  
  7.         <tbody><tr><td>Title</td><td>Author</td><td>Description</td></tr></tbody>  
  8.         <?php   
  9.   
  10.             foreach ($books as $title => $book)  
  11.             {  
  12.                 echo ‘<tr><td><a href=“index.php?book=’.$book->title.'”>‘.$book->title.’</a></td><td>‘.$book->author.’</td><td>‘.$book->description.’</td></tr>‘;  
  13.             }  
  14.   
  15.         ?>  
  16.     </table>  
  17.   
  18. </body>  
  19. </html>  

The above example is a simplified implementation in PHP. Most of the PHP web frameworks based on MVC have similar implementations, in a much better shape. However, the possibility of MVC pattern are endless. For example different layers can be implemented in different languages or distributed on different machines. AJAX applications can implements the View layer directly in Javascript in the browser, invoking JSON services. The controller can be partially implemented on client, partially on server…

    This post should not be ended before enumerating the advantages of Model View Controller pattern:

  • the Model and View are separated, making the application more flexible.
  • the Model and view can be changed separately, or replaced. For example a web application can be transformed in a smart client application just by writing a new View module, or an application can use web services in the backend instead of a database, just replacing the model module.
  • each module can be tested and debugged separately.

The files are available for download as a zip from http://sourceforge.net/projects/mvc-php/files/mvc.zip/download

By Rz Rasel Posted in Php

Model View Controller MVC

Contents

  1. Abstract
  2. What is MVC
  3. The Site Structure
  4. The index file
  5. The Registry
  6. The Model
  7. The Router
  8. The Controller
  9. The View
  10. Templates
  11. Sod this, take me to the download
  12. Conclusion
  13. Credits

Abstract

Model View Controller.

This tutorial will take you from the beginning to the end of building a MVC framework. The object is not soley to produce the finished MVC framework, although that will happen, but to demonstrate how MVC works and some of the concepts that lay behind it..

What is MVC?

MVC is a design pattern. A Design pattern is a code structure that allows for common coding frameworks to be replicated quickly. You might think of a design pattern as a skeleton or framework on which your application will be built.

In the MVC framework that is created in this tutorial, several key points will be raised. The first is the frameworks needs a single point of entry, ie: index.php. This is where all access to the site must be controlled from. To ensure that a single point of entry is maintained, htaccess can be utilized to ensure no other file may be accessed, and that we hide the index.php file in the url. Thus creating SEO and user friendly URL’s.

It is beyond the scope of this tutorial to show how to set up htaccess and mod_rewrite and more information on these can be gained from the Apache manual. The .htaccess file itself looks like this.

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?rt=$1 [L,QSA]

The .htaccess file will permit access to the site via urls such as
http://www.example.com/news/show

If you do not have mod_rewrite available, the entry to the site will be the same, except that the URL will contain the values needed such as:
http://www.example.com/index.php?rt=news/show

The Site Structure

In this tutorial several directories are required to hold the various components that make up the MVC framework. The index.php and the .htaccess files will, of course, reside at the top level. We will need a directory to hold the application code, and directories for the model view and controllers. The site structure should look like this:

 html
application
controller
includes
model
views
.htaccess
index.php

The Index File

As previously mentioned, the index.php file is our single point of access. As such, it provides the ideal space for declaring variables and site wide configurations. It is in this file that we will also call a helper file to initialize a few values. This file will be called init.php and it will be placed in includes directory as shown in the direcory structure. The index file therefore, will begin like this:


<?php

/*** error reporting on ***/
error_reporting(E_ALL);

/*** define the site path constant ***/
$site_path realpath(dirname(__FILE__));
define ('__SITE_PATH'$site_path);

/*** include the init.php file ***/
include 'includes/init.php';

?>

The index.php file so far only sets the error reporting, includes the init file, and defines the site path constant. With this file in place, and the .htaccess file we can begin to build the registry. In this MVC framework, the registry object is passed to other objects and contains site wide variables without the the use globals. To create a new registry object, we use the init.php file in the includes directory.

Of course, to create new object we need to include the registry class definition file. During the building of the MVC framework we will be including the application class files directly. Any PHP class definition files which are used by the model will be autoloaded as they can become quite cumbersome with larger applications. To alleviate some of this PHP has the __autoload function to help us out. After the application includes, the __autoload function will immediately follow to load class definition files automatically when they are required by the system. That is, when the new keyword is used. The class definitions will be stored in a directory called model. The includes/init.php file should now look like this.


<?php

/*** include the controller class ***/
include __SITE_PATH '/application/' 'controller_base.class.php';

/*** include the registry class ***/
include __SITE_PATH '/application/' 'registry.class.php';

/*** include the router class ***/
include __SITE_PATH '/application/' 'router.class.php';

/*** include the template class ***/
include __SITE_PATH '/application/' 'template.class.php';

/*** auto load model classes ***/
function __autoload($class_name) {
$filename strtolower($class_name) . '.class.php';
$file __SITE_PATH '/model/' $filename;

if (file_exists($file) == false)
{
return 
false;
}
include (
$file);
}

/*** a new registry object ***/
$registry = new registry;

?>

Here is should be noted that the autoload function uses a naming convention for the class definition files to be included. They must all follow the convention of ending in .class.php and the class name must be that of the .class.php file name. So that to create a new “news” object the class definition file name must be news.class.php and the class must be named “news”. With these files in place we are well on the way, however our MVC does not do anything yet. In fact, if you tried to access the index.php file now, you would get many errors about missing files. Mostly from the files in the application directory. So, lets begin by creating those files each can be blank or simply contain

<?php

?>

The files to create in the application directory are:

  • controller_base.class.php
  • registry.class.php
  • router.class.php
  • template.class.php

Note that although these files are not autoloaded, we have still maintained the same naming convention by calling the files .class.php

The Registry

The registry is an object where site wide variables can be stored without the use of globals. By passing the registry object to the controllers that need them, we avoid pollution of the global namespace and render our variables safe. We need to be able to set registry variables and to get them. The php magic functions __set() and __get() are ideal for this purpose. So, open up the registry.class.php in the applications directory and put the following code in it:


<?php

Class Registry {

/*
* @the vars array
* @access private
*/
private $vars = array();

/**
*
* @set undefined vars
*
* @param string $index
*
* @param mixed $value
*
* @return void
*
*/
public function __set($index$value)
{
$this->vars[$index] = $value;
}

/**
*
* @get variables
*
* @param mixed $index
*
* @return mixed
*
*/
public function __get($index)
{
return 
$this->vars[$index];
}

}

?>

With the registry in place, our system is working. It does not do anything or display anything, but we have a functional system. The __set() and __get() magic function now allow us to set variables within the registry and store them there. Now to add the Model and router classes.

The Model

The Model is the “M” in MVC. The model is where business logic is stored. Business logic is loosely defined as database connections or connections to data sources, and provides the data to the controller. As I am a fan of CAV (Controller Action View) we will blur the line between the Model and Controller. This is not strictly how MVC should work, but this is PHP baby. Our database connection is a simple singleton design pattern and resides in the classes directory and can be called statically from the controller and set in the registry. Add this code to the init.php file we created earlier.


<?php

/*** create the database registry object ***/
$registry->db db::getInstance();

?>

Like all registry members, the database is now globally availabe to our scripts. As the class is a singleton we always get the same instance back. Now that registry objects can be created a method of controlling what is loaded is needed.

The Router

The router class is responsible for loading up the correct controller. It does nothing else. The value of the controller comes from the URL. The url will look a like this:
http://www.example.com/index.php?rt=news
or if you have htaccess amd mod_rewrite working like this:
http://www.example.com/news

As you can see, the route is the rt variable with the value of news. To begin the router class a few things need to be set. Now add this code to the router.class.php file in the application directory.

 


<?php

class router {
/*
* @the registry
*/
private $registry;

/*
* @the controller path
*/
private $path;

private $args = array();

public $file;

public $controller;

public $action;

function __construct($registry) {
$this->registry $registry;
}

So it does not look like much yet but is enough to get us started. We can load the router into the registry also. Add this code to the index.php file.


/*** load the router ***/
$registry->router = new router($registry);

Now that the router class can be loaded, we can continue with the router class by adding a method to set the controller directory path. Add this block of code to the router.class.php file.


<?php
/**
*
* @set controller directory path
*
* @param string $path
*
* @return void
*
*/
function setPath($path) {

/*** check if path i sa directory ***/
if (is_dir($path) == false)
{
throw new 
Exception ('Invalid controller path: `' $path '`');
}
/*** set the path ***/
$this->path $path;
}

And to set the controller path in the registry is a simple matter of adding this line to the index.php file


/*** set the path to the controllers directory ***/
$router->setPath (__SITE_PATH . 'controller');

With the controller path set we can load the controller. We will create a method to called loader() to get the controller and load it. This method will call a getController() method that will decide which controller to load. If a controller is not found then it will default back to the index. The loader method looks like this.


<?php

/**
*
* @load the controller
*
* @access public
*
* @return void
*
*/
public function loader()
{
/*** check the route ***/
$this->getController();

/*** if the file is not there diaf ***/
if (is_readable($this->file) == false)
{
echo 
$this->file;
die (
'404 Not Found');
}

/*** include the controller ***/
include $this->file;

/*** a new controller class instance ***/
$class $this->controller 'Controller_';
$controller = new $class($this->registry);

/*** check if the action is callable ***/
if (is_callable(array($controller$this->action)) == false)
{
$action 'index';
}
else
{
$action $this->action;
}
/*** run the action ***/
$controller->$action();
}

The getController method that the loader() method calls does the work. By taking the route variables from the url via $_GET[‘rt’] it is able to check if a contoller was loaded, and if not default to index. It also checks if an action was loaded. An action is a method within the specified controller. If no action has been declared, it defaults to index. Add the getController method to the router.class.php file.


<?php
/**
*
* @get the controller
*
* @access private
*
* @return void
*
*/
private function getController() {

/*** get the route from the url ***/
$route = (empty($_GET['rt'])) ? '' $_GET['rt'];

if (empty($route))
{
$route 'index';
}
else
{
/*** get the parts of the route ***/
$parts explode('/'$route);
$this->controller $parts[0];
if(isset( 
$parts[1]))
{
$this->action $parts[1];
}
}

if (empty($this->controller))
{
$this->controller 'index';
}

/*** Get action ***/
if (empty($this->action))
{
$this->action 'index';
}

/*** set the file path ***/
$this->file $this->path .'/'$this->controller '.php';
}
?>

The Controller

The Contoller is the C in MVC. The base controller is a simple abstract class that defines the structure of all controllers. By including the registry here, the registry is available to all class that extend from the base controller. An index() method has also been included in the base controller which means all controller classes that extend from it must have an index() method themselves. Add this code to the controller.class.php file in the application directory.


<?php

Abstract Class baseController {

/*
* @registry object
*/
protected $registry;

function __construct($registry) {
$this->registry $registry;
}

/**
* @all controllers must contain an index method
*/
abstract function index();
}

?>

Whilst we are in the controller creating mood, we can create an index controller and a blog controller. The index controller is the sytem default and it is from here that the first page is loaded. The blog controller is for an imaginary blog module. When the blog module is specified in the URL
http://www.example.com/blog
then the index method in the blog controller is called. A view method will also be created in the blog controller and when specified in the URL
http://www.example.com/blog/view
then the view method in the blog controller will be loaded. First lets see the index controller. This will reside in the controller directory.


<?php

class indexController extends baseController {

public function index() {
/*** set a template variable ***/
$this->registry->template->welcome 'Welcome to PHPRO MVC';

/*** load the index template ***/
$this->registry->template->show('index');
}

}

?>

The indexController class above shows that the indexController extends the baseController class, thereby making the registry available to it without the need for global variables. The indexController class also contains the mandatory index() method that ll controllers must have. Within itn index() method a variable named “welcome” is set in the registry. This variable is available to the template when it is loaded via the template->show() method.

The blogController class follows the same format but has has one small addition, a view() method. The view() method is an example of how a method other than the index() method may be called. The view method is loaded via the URL
http://www.example.com/blog/view


<?php

Class blogController Extends baseController {

public function index() {
$this->registry->template->blog_heading 'This is the blog Index';
$this->registry->template->show('blog_index');
}

public function view(){

/*** should not have to call this here.... FIX ME ***/

$this->registry->template->blog_heading 'This is the blog heading';
$this->registry->template->blog_content 'This is the blog content';
$this->registry->template->show('blog_view');
}

}
?>

The View

The View, as you might have guessed, is the V in MVC. The View contains code that relates to presentation and presentation logic such as templating and caching. In the controller above we saw the show() method. This is the method that calls the view. The major component in the PHPRO MVC is the template class. The template.class.php file contains the class definition. Like the other classes, it has the registry available to it and also contains a __set() method in which template variables may be set and stored.

The show method is the engine room of the view. This is the method that loads up the template itself, and makes the template variables available. Some larger MVC’s will implement a template language that adds a further layer of abstraction from PHP. Added layers mean added overhead. Here we stick with the speed of PHP within the template, yet all the logic stays outside. This makes it easy for HTML monkies to create websites without any need to learn PHP or a template language. The template.class.php file looks like this:


<?php

Class Template {

/*
* @the registry
* @access private
*/
private $registry;

/*
* @Variables array
* @access private
*/
private $vars = array();

/**
*
* @constructor
*
* @access public
*
* @return void
*
*/
function __construct($registry) {
$this->registry $registry;

}

/**
*
* @set undefined vars
*
* @param string $index
*
* @param mixed $value
*
* @return void
*
*/
public function __set($index$value)
{
$this->vars[$index] = $value;
}

function show($name) {
$path __SITE_PATH '/views' '/' $name '.php';

if (file_exists($path) == false)
{
throw new 
Exception('Template not found in '$path);
return 
false;
}

// Load variables
foreach ($this->vars as $key => $value)
{
$
$key $value;
}

include ($path);
}

}

?>

Templates

The templates themselves are basically HTML files with a little PHP embedded. Do not let the separation Nazi’s try to tell you that you need to have full seperation of HTML and PHP. Remember, PHP is an embeddable scripting language. This is the sort of task it is designed for and makes an efficient templating language. The template files belong in the views directory. Here is the index.php file.


<h1><?php echo $welcome?></h1>

Well, that was pretty amazing.. Now for the blog_index.php file.


<h1><?php echo $blog_heading?></h1>

And finally the blog_view.php file..


<h1><?php echo $blog_heading?></h1>

<p><?php echo $blog_content?></p>

In the above template files note that the variable names in the templates, match the template variables created in the controller.

By Rz Rasel Posted in Php

Create a simple PHP MVC Framework

In this blog post we’ll create a simple PHP MVC Framework from scratch. This simple framework can be used as a tool for learning the basic plot behing MVC or you can modify it and make it grow into something bigger and much more useful.

MVC?

MVC stands for “Model View Controller”. MVC is a concept that enables us to separate our business logic from the presentation. One of the biggest advantages is the code reusability. There are other benefits, such as: We can let the designers edit the Views, without worrying that they will screw up database access logic.

I’m convinced. What do I need to begin?

For this tutorial you will need PHP/MySQL. You can get them in a variety of ways, but it’s much simpler to get a distribution that installs everything you need for you, such as XAMPP. Or get PHP/MySQL using Microsoft’s Web Platform Installer and run PHP on IIS.

Let’s get to it. We’ll create a PHP MVC framework and use it to create a simple news portal.

Setting up the Database

We’ll have a simple database with just two tables which will contain our news. You can create the MySQL database using phpMyAdmin or an SQL client, such as HeidiSQL, for example.

The basic plot is: One category can have many articles and article can’t be without a category, so we need to add a foreign key to reference categories in the articles table.

Foreign key also controls the changes in the primary key table. For example, we can’t delete a category from categories table if there is a article in the articles table that references the category, because that would compromise the integrity of our data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `categories` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_name` varchar(150) NOT NULL,
  PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `intro` text NOT NULL,
  `article` text NOT NULL,
  `date` datetime NOT NULL,
  `status` enum('Y','N') NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_articles_categories` (`category`),
  CONSTRAINT `FK_articles_categories` FOREIGN KEY (`category`) REFERENCES `categories` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Now use you SQL client to enter some sample data.

For example, look at the following screenshot. Because HeidiSQL understands that there is a foreign key constraint, it allows us to select the category from the categories table when entering data into articles table:

HeidiSQL understands forign key constraints

Once you create the tables, we need some data to play around with. You can just enter some data yourself, or Download Samples for this blog post which include some data.

Basic philosophy

We’ll set up a system where we can include the appropriate file based on url. As user goes through our site, we’ll use the appropriate controller, which is basically just a PHP file which uses our classes (models).

Controllers are the entry points. They say which model to use and which view to display. Models are the business logic. They get the data. We use views to display the data. It may sound complicated, but it’s really not. You’ll see.

Our URLs will look like this: http://simplemvc.local/?load=news/details/1. As you can see, we’ll use load parameter to tell what controller and view to use. In this example, we’ll use news controller and list and details views.

NOTE: We’ll make URLs look better later.

First Steps

First thing we need is to create a View class which will enable us to create PHP templates.

So, let’s demonstrate how to do that.

view.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
 
class View
{
    protected $_file;
    protected $_data = array();
     
    public function __construct($file)
    {
        $this->_file = $file;
    }
     
    public function set($key, $value)
    {
        $this->_data[$key] = $value;
    }
     
    public function get($key)
    {
        return $this->_data[$key];
    }
     
    public function output()
    {
        if (!file_exists($this->_file))
        {
            throw new Exception("Template " . $this->_file . " doesn't exist.");
        }
         
        extract($this->_data);
        ob_start();
        include($this->_file);
        $output = ob_get_contents();
        ob_end_clean();
        echo $output;
    }
}

This class is simple. When creating objects from this class we simply need to provide path to the Template file. Then we need to set the data we want to display in our template. When we set all the data we simply use the output() method which extracts the data from the array and uses output buffering to “fill” the placeholders in the template with values from the array.

How do I use the View class?

Simple. First, create a Template file and save it as simpletemplate.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title><?php echo $title; ?></title>
    </head>
    <body>
     
        <h1><?php echo $greeting; ?></h1>
         
    </body>
</html>

Then in a new php file do:

1
2
3
4
5
6
7
8
<?php
 
require 'view.php';
 
$view = new View('simpletemplate.tpl');
$view->set('title', 'This is a simple template file!');
$view->set('greeting', 'Hello, World');
echo $view->output();

Our template loaded.

I’m pretty sure you understand how cool is this! 🙂 So, let’s continue with our project!

Other stuff needed

Now we can continue with creating our little MVC project. First, we’ll need a good directory structure. Here is the final:

  • controllers
  • includes
  • utilities
  • models
  • views
    • news

Move the view.php file to utilities folder, we’ll need it to display an appropriate view.

Utilities

We also need is a simple class for connecting to the database. Indide utilities folder create a new file named db.php.

db.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
class Db
{
    private static $db;
     
    public static function init()
    {
        if (!self::$db)
        {
            try {
                $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=UTF-8';
                self::$db = new PDO($dsn, DB_USER, DB_PASS);
                self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                self::$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            } catch (PDOException $e) {
                die('Connection error: ' . $e->getMessage());
            }
        }
        return self::$db;
    }
}

You might say this step isn’t really needed, but I find it’s cool to have a database class which we can later use. Also what we got is a singleton class that limits class instantiation to one object.

Adding the basics

OK, now we have all the utilities we need for successfully connecting to the database and working with Templates. Let’s continue with adding the basics of our simple MVC project.

Create a new PHP file, named index.php. In here we’ll setup autoloading, and include basic files. I got defining DS and HOME constants from this article. It also helped to make my original autoloader a little better.

Our index.php looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
define ('DS', DIRECTORY_SEPARATOR);
define ('HOME', dirname(__FILE__));
 
ini_set ('display_errors', 1);
 
require_once HOME . DS . 'config.php';
require_once HOME . DS . 'utilities' . DS . 'bootstrap.php';
 
function __autoload($class)
{
    if (file_exists(HOME . DS . 'utilities' . DS . strtolower($class) . '.php'))
    {
        require_once HOME . DS . 'utilities' . DS . strtolower($class) . '.php';
    }
    else if (file_exists(HOME . DS . 'models' . DS . strtolower($class) . '.php'))
    {
        require_once HOME . DS . 'models' . DS . strtolower($class) . '.php';
    }
    else if (file_exists(HOME . DS . 'controllers' . DS . strtolower($class) . '.php'))
    {
        require_once HOME . DS . 'controllers'  . DS . strtolower($class) . '.php';
    }
}

We setup autoloading so correct file is included when we create a new object from a specified class.

config.php

As in some previous blog posts, the config.php file will contain the data needed to connect to the database, so this file is pretty simple.

1
2
3
4
5
<?php
define ('DB_HOST''localhost');
define ('DB_NAME''simplemvc');
define ('DB_USER''root');
define ('DB_PASS''');

bootstrap.php

After that comes our bootstrap.php file. Create it inside utilities folder, per index.php file. This one’s a bit more complicated, but I’m sure you’ll understand everything:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
$controller = "news";
$action = "index";
$query = null;
 
if (isset($_GET['load']))
{
    $params = array();
    $params = explode("/", $_GET['load']);
 
    $controller = ucwords($params[0]);
     
    if (isset($params[1]) && !empty($params[1]))
    {
        $action = $params[1];
    }
     
    if (isset($params[2]) && !empty($params[2]))
    {
        $query = $params[2];
    }
}
 
$modelName = $controller;
$controller .= 'Controller';
$load = new $controller($modelName, $action);
 
if (method_exists($load, $action))
{
    $load->$action($query);
}
else
{
    die('Invalid method. Please check the URL.');
}

If you don’t get it, here’s a simple explanation: First we setup default values for our controller, view and optional query string. So if there’s no load parameter, default controller is news, and default action (view) index.

Next, we create a new Controller object based on the supplied parameters.

1
2
3
$modelName = $controller;
$controller .= 'Controller';
$load = new $controller($modelName, $action);

So, by default it will be like we said:
$load = new NewsController(‘news’, ‘index’);

After that, we simply invoke a method which must be named like our $action parameter. By default that method will be “index()“. This is called Variable functions.

1
2
3
4
5
6
7
8
if (method_exists($load, $action))
{
    $load->{$action}($query);
}
else
{
    die('Invalid method. Please check the URL.');
}

Of course, if there’s no such method, we can’t continue.

Adding main stuff

First, we’ll add a new base Controller class from which all of our Controllers will inherit. This base class will set a default view and have a method to set a model, because we want to be able to set the model manually.

Controller base class

Inside controllers folder create a new controller.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
class Controller
{
    protected $_model;
    protected $_controller;
    protected $_action;
    protected $_view;
    protected $_modelBaseName;
     
    public function __construct($model, $action)
    {
        $this->_controller = ucwords(__CLASS__);
        $this->_action = $action;
        $this->_modelBaseName = $model;
         
        $this->_view = new View(HOME . DS . 'views' . DS . strtolower($this->_modelBaseName) . DS . $action . '.tpl');
    }
     
    protected function _setModel($modelName)
    {
        $modelName .= 'Model';
        $this->_model = new $modelName();
    }
     
    protected function _setView($viewName)
    {
        $this->_view = new View(HOME . DS . 'views' . DS . strtolower($this->_modelBaseName) . DS . $viewName . '.tpl');
    }
}

Not exactly nuclear science, huh? 🙂 This is simply a base class which enables us to create a new Model, and set a View using already known syntax.

The constructor sets a default view to /views/MODEL_BASE_NAME/ACTION_NAME, so, for example default view for a NewsController controller and a index action would be: /views/news/index.tpl. The Controller class also enables us to setup our own View via the _setView() method.

You also might notice that we don’t create an appropriate Model object. That’s deliberate. For instance, there might be a Controller which doesn’t use Models at all. And for those that do, we have a method to set the Model.

Model base class

Now, let’s create a same base class for our Models. Create a new file named model.php inside the models folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
 
class Model
{
    protected $_db;
    protected $_sql;
     
    public function __construct()
    {
        $this->_db = Db::init();
    }
     
    protected function _setSql($sql)
    {
        $this->_sql = $sql;
    }
     
    public function getAll($data = null)
    {
        if (!$this->_sql)
        {
            throw new Exception("No SQL query!");
        }
         
        $sth = $this->_db->prepare($this->_sql);
        $sth->execute($data);
        return $sth->fetchAll();
    }
     
    public function getRow($data = null)
    {
        if (!$this->_sql)
        {
            throw new Exception("No SQL query!");
        }
         
        $sth = $this->_db->prepare($this->_sql);
        $sth->execute($data);
        return $sth->fetch();
    }
}

We simply created a wrapper around PHP PDO, so all our models that extend the Model class can use those methods easily.

Reading the articles

We’ll add a new class which inherits from the Model Class. This class will use methods from the base class to return an array with articles and the details of a single article.

Adding NewsModel

Inside the models folder create a new file: newsmodel.php. Remember, we setup autoloading to use lowercase.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
 
class NewsModel extends Model
{
    public function getNews()
    {
        $sql = "SELECT
                    a.id,
                    a.title,
                    a.intro,
                    DATE_FORMAT(a.date, '%d.%m.%Y.') as date,
                    c.category_name
                FROM
                    articles a
                INNER JOIN
                    categories AS c ON a.category = c.category_id
                ORDER BY a.date DESC";
         
        $this->_setSql($sql);
        $articles = $this->getAll();
         
        if (empty($articles))
        {
            return false;
        }
         
        return $articles;
    }
     
    public function getArticleById($id)
    {
        $sql = "SELECT
                    a.title,
                    a.article,
                    DATE_FORMAT(a.date, '%d.%m.%Y.') as date,
                    c.category_name
                FROM
                    articles a
                INNER JOIN categories AS c ON a.category = c.category_id
                WHERE
                    a.id = ?";
         
        $this->_setSql($sql);
        $articleDetails = $this->getRow(array($id));
         
        if (empty($articleDetails))
        {
            return false;
        }
         
        return $articleDetails;
    }
}

As you can see, this is a very simple class which has two methods. getVisibleNews() method simply returns all the Articles that are active. getArticleById($id) method accepts an $id parameter which specifies the ID of the article to be returned.

Adding the controller

OK, that’s cool. Now we need to create a new Controller which will use the model to get the data and then load the appropriate view. Remember the index.php file? We said there that our default controller will be NewsController. Create a new file named newscontoller.php inside a controllers folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
 
class NewsController extends Controller
{
    public function __construct($model, $action)
    {
        parent::__construct($model, $action);
        $this->_setModel($model);
    }
     
    public function index()
    {
        try {
             
            $articles = $this->_model->getNews();
            $this->_view->set('articles', $articles);
            $this->_view->set('title', 'News articles from the database');
             
            return $this->_view->output();
             
        } catch (Exception $e) {
            echo "Application error:" . $e->getMessage();
        }
    }
}

So, we have a basic controller with one default action -> index. Just like we said in our bootstrap.php file. If we try to run our little application now we’ll get an Exception, because one thing’s missing. Yes, you got that right – our template file (View). So, let’s create it.

Default view

If you followed this blog post from the beginning you have a news folder inside your views folder. That’s because our controller can have lots of actions and almost every action can have it’s view.

Now inside includes folder create a file named menu.inc.php.

1
2
3
4
5
6
<nav>
    <ul id="menu">
        <li><a href="/">Home</a></li>
        <li><a href="/contact/index">Contact</a></li>
    </ul>
</nav>

We’ll include this menu in our template files.

Because we’re using a default view for this situation, we’ll create a new file named index.tpl inside the /views/news folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title><?php echo $title; ?></title>
    </head>
    <body>
     
        <?php include HOME . DS . 'includes' . DS . 'menu.inc.php'; ?>
         
        <h1>News articles</h1>
 
        <?php
            if ($articles):
            foreach ($articles as $a): ?>
 
            <article>
                <header>
                    <h1><a href="/news/details/<?php echo $a['id']; ?>"><?php echo $a['title']; ?></a></h1>
                    <p><?php echo $a['category_name']; ?></p>
                    <p>Published on: <time pubdate="pubdate"><?php echo $a['date']; ?></time></p>
                </header>
                <p><?php echo $a['intro']; ?></p>
                <p><a href="/news/details/<?php echo $a['id']; ?>">Continue reading</a></p>
                <hr/>
            </article>
        <?php
            endforeach;
            else: ?>
 
        <h1>Welcome!</h1>
        <p>We currently do not have any articles.</p>
 
        <?php endif; ?>
         
    </body>
</html>

Now save the file and reload the site. You should get something similar to this:

List of articles from database

If you try to click on a link you’ll notice the links don’t work. Well, that’s because we need a URL Rewrite to map those pretty URLs to our load parameter from bootstrap.php file. Remember? 🙂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (isset($_GET['load']))
{
    $params = array();
    $params = explode("/", $_GET['load']);
 
    $controller = ucwords($params[0]);
     
    if (isset($params[1]) && !empty($params[1]))
    {
        $action = $params[1];
    }
     
    if (isset($params[2]) && !empty($params[2]))
    {
        $query = $params[2];
    }
}

URL Rewriting

So for those pretty URLs to work we need to create a .htaccess (if you’re running XAMPP, LAMPP or something similar) or web.config (if you’re on IIS) file. So, go right ahead and grab the code you need:

.htaccess

1
2
3
4
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?load=$1 [PT,L]

web.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="MVCRewrite" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php?load={R:1}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Wohoo! Now the URLs work, but we still need a way to display the Article Details. That’s right. We don’t have a details action in our News controller.

Article Details

Open our newscontroller.php and add a details() method so our controller now looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
 
class NewsController extends Controller
{
    public function __construct($model, $action)
    {
        parent::__construct($model, $action);
        $this->_setModel($model);
    }
     
    public function index()
    {
        try {
             
            $articles = $this->_model->getVisibleNews();
            $this->_view->set('articles', $articles);
            $this->_view->set('title', 'News articles from the database');
             
            return $this->_view->output();
             
        } catch (Exception $e) {
            echo "Application error:" . $e->getMessage();
        }
    }
     
    // Add THIS
    public function details($articleId)
    {
        try {
             
            $article = $this->_model->getArticleById((int)$articleId);
             
            if ($article)
            {
                $this->_view->set('title', $article['title']);
                $this->_view->set('articleBody', $article['article']);
                $this->_view->set('datePublished', $article['date']);
            }
            else
            {
                $this->_view->set('title', 'Invalid article ID');
                $this->_view->set('noArticle', true);
            }
             
            return $this->_view->output();
              
        } catch (Exception $e) {
            echo "Application error:" . $e->getMessage();
        }
    }
    // End
}

So, there’s just one thing missing: The View. So, let’s add that.

Inside a /views/news folder create a new file: details.tpl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title><?php echo $title; ?> | Article Details</title>
    </head>
    <body>
     
        <?php include HOME . DS . 'includes' . DS . 'menu.inc.php'; ?>
         
        <article>
            <header>
                <h1><?php echo $title; ?></h1>
                <p>Published on: <time pubdate="pubdate"><?php echo $datePublished; ?></time></p>
            </header>
            <p>
                <?php echo $articleBody; ?>
            </p>
        </article>
         
        <a href="/">Back to article list</a>
         
    </body>
</html>

If you check the details page now, you’ll see that it works and we see the article details.

Article details

Simple contact form

Now let’s create a simple Contact form that saves info into the database.

First thing we need is, of course, the contact table in the database. Let’s add that:

1
2
3
4
5
6
7
8
9
CREATE TABLE `contact` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `first_name` VARCHAR(50) NULL,
    `last_name` VARCHAR(50) NULL,
    `email` VARCHAR(50) NOT NULL,
    `message` TEXT NOT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'

Next, we’ll need a controller. Create a new file named contactcontroller.php inside the controllers folder.

1
2
3
4
5
6
7
8
9
10
<?php
 
class ContactController extends Controller
{
    public function index()
    {
        $this->_view->set('title', 'Simple site Contact Form');
        return $this->_view->output();
    }
}

This method will simply return the form once user visits /contact url. Now we need a model to handle saving the data to database.

Contact model

Inside the models folder create a new file named contactmodel.php. This class will handle saving the data to the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
 
class ContactModel extends Model
{
    private $_firstName;
    private $_lastName;
    private $_email;
    private $_message;
     
    public function setFirstName($firstName)
    {
        $this->_firstName = $firstName;
    }
     
    public function setLastName($lastName)
    {
        $this->_lastName = $lastName;
    }
     
    public function setEmail($email)
    {
        $this->_email = $email;
    }
     
    public function setMessage($message)
    {
        $this->_message = $message;
    }
     
    public function store()
    {
        $sql = "INSERT INTO contact
                    (first_name, last_name, email, message)
                VALUES
                    (?, ?, ?, ?)";
         
        $data = array(
            $this->_firstName,
            $this->_lastName,
            $this->_email,
            $this->_message
        );
         
        $sth = $this->_db->prepare($sql);
        return $sth->execute($data);
    }
}

This is a simple class. We have set methods for our form data, and a store() method to save the data.

Save method in the controller

Let’s save form input. Add this method to the ContactController class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public function save()
{
    if (!isset($_POST['contactFormSubmit']))
    {
        header('Location: /contact/index');
    }
     
    $errors = array();
    $check = true;
         
    $firstName = isset($_POST['first_name']) ? trim($_POST['first_name']) : NULL;
    $lastName = isset($_POST['last_name']) ? trim($_POST['last_name']) : NULL;
    $email = isset($_POST['email']) ? trim($_POST['email']) : "";
    $message = isset($_POST['message']) ? trim($_POST['message']) : "";
         
    if (empty($email))
    {
        $check = false;
        array_push($errors, "E-mail is required!");
    }
    else if (!filter_var( $email, FILTER_VALIDATE_EMAIL ))
    {
        $check = false;
        array_push($errors, "Invalid E-mail!");
    }
         
    if (empty($message))
    {
        $check = false;
        array_push($errors, "Message is required!");
    }
 
    if (!$check)
    {
        $this->_setView('index');
        $this->_view->set('title', 'Invalid form data!');
        $this->_view->set('errors', $errors);
        $this->_view->set('formData', $_POST);
        return $this->_view->output();
    }
         
    try {
                 
        $contact = new ContactModel();
        $contact->setFirstName($firstName);
        $contact->setLastName($lastName);
        $contact->setEmail($email);
        $contact->setMessage($message);
        $contact->store();
                 
        $this->_setView('success');
        $this->_view->set('title', 'Store success!');
                 
        $data = array(
            'firstName' => $firstName,
            'lastName' => $lastName,
            'email' => $email,
            'message' => $message
        );
                 
        $this->_view->set('userData', $data);
                 
    } catch (Exception $e) {
        $this->_setView('index');
        $this->_view->set('title', 'There was an error saving the data!');
        $this->_view->set('formData', $_POST);
        $this->_view->set('saveError', $e->getMessage());
    }
 
    return $this->_view->output();
}

Now, we’ll need a View to display our form. Inside views folder create a new folder named contact. Then inside it create a file named index.tpl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title><?php echo $title; ?></title>
    </head>
    <body>
     
        <?php include HOME . DS . 'includes' . DS . 'menu.inc.php'; ?>
         
        <h1><?php echo $title; ?></h1>
         
        <?php
        if (isset($errors))
        {
            echo '<ul>';
            foreach ($errors as $e)
            {
                echo '<li>' . $e . '</li>';
            }
            echo '</ul>';
        }
         
        if (isset($saveError))
        {
            echo "<h2>Error saving data. Please try again.</h2>" . $saveError;
        }
        ?>
         
        <form action="/contact/save" method="post">
             
            <p>
                <label for="first_name">First Name:</label>
                <input value="<?php if(isset($formData)) echo $formData['first_name']; ?>" type="text" id="first_name" name="first_name" />
            </p>
             
            <p>
                <label for="last_name">Last Name:</label>
                <input value="<?php if(isset($formData)) echo $formData['last_name']; ?>" type="text" id="last_name" name="last_name" />
            </p>
             
            <p>
                <label for="email">* E-mail:</label>
                <input value="<?php if(isset($formData)) echo $formData['email']; ?>" type="text" id="email" name="email" />
            </p>
             
            <p>
                <label for="message">* Message:</label>
                <textarea name="message" id="message" rows="5" cols="50"><?php if(isset($formData)) echo $formData['message']; ?></textarea>
            </p>
             
            <input type="submit" name="contactFormSubmit" value="Send" />
        </form>
         
    </body>
</html>

Form looks like this:

Contact form

As you can see in the save method, we’ll also need a success view. This one’s pretty simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
 
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title><?php echo $title; ?></title>
    </head>
    <body>
     
        <?php include HOME . DS .  'includes' . DS . 'menu.inc.php'; ?>
         
        <h1><?php echo $title; ?></h1>
        <h2>Data stored:</h2>
         
        <?php if (!empty($userData['firstName'])): ?>
            <h3>First Name:</h3>
            <p><?php echo $userData['firstName']; ?></p>
        <?php endif;?>
         
        <?php if (!empty($userData['lastName'])): ?>
            <h3>Last Name:</h3>
            <p><?php echo $userData['lastName']; ?></p>
        <?php endif;?>
         
        <h3>E-mail:</h3>
        <p><?php echo $userData['email']; ?></p>
         
        <h3>Message:</h3>
        <?php echo $userData['message']; ?>
         
    </body>
</html>

If you submit the form and got a success view, everything worked!

Contact form data is stored into the database

Conclusion

That’s it. We created a simple MVC framework which you can easily extend to meet your needs.

Article you might want to visit is: Write your own PHP MVC Framework. This article is awesome and it’s the one you should visit next. From there I got defining DS and HOME.

By Rz Rasel Posted in Php

Paypal payment process integration with automated function

Firs of all excuse me for my English, is not my native language.

Disclaimer: I don’t recommend anyone to use the files i give in this tutorial in a production server, I’m no responsible of any lost, hack, liability or any other thing that happen for the use of this files.

The purpose of this tutorial is to guide people in the payment process integration with Paypal, but you need to study a little to make great things happen.

Requirements:
– Paypal account (you at least must know how to use it)
– Web Server with PHP (no free host, unless you find a great free PHP host with cURL built in, try to find at least a shared host. Note that is for testing purposes, i recommend you for real environment your own VPS, AWS and so on)

Where going to use the Instant Payment Notification (IPN) service from paypal.

Short description: Instant Payment Notification (IPN) is a message service that notifies you of events related to PayPal transactions. You can use it to automate back-office and administrative functions, such as fulfilling orders, tracking customers, and providing status and other information related to a transaction.

For use this service we’re going to need 4 files:
– The listener (ipn.php)
– A certify (cacert.pem)
– A pay form (payform.php)
– The check items file (itemcheck.php)

The listener will receive the Paypal transactions and if the transaction is ok it will create a file in your server inside a folder called “pays” with the id of the player.

The certify as always, you need a key for transactions.

The pay form is where you copy your html from your paypay account.

The check items file is the one that finds if the user already pay for the weapon and if so, show to the player. You can find a capx file with an ajax query to this file.

You can download all those files here:

Put all the files in your server for example:

http://www.example.com/paypal/ipn.php
http://www.example.com/paypal/cacert.php
http://www.example.com/paypal/payform.php
http://www.example.com/paypal/itemcheck.php

You can put where you want but remember that path because we need for the next step.

Now we need to enable the service in our account so you need to log in to your Paypal account, then you land in My Account tab, under the same tab we need to go on the Profile link:

Then go on the link Instant Payment Notification Preferences:

Set the settings for our IPN:

Now we must fill the Notification URL field with the URL where we place the listener (ipn.php), then select the Receive IPN messages (Enabled) option to get the notifications when someone makes a payment and Save.

Now you should see you current settings, in my case I use one of my testing domains  so this is how my settings looks like:

Now that all is up, every payment we receive will be listened by our listener (ipn.php), currently supported payments are eCheck, Express Checkout, Cart Checkout, Web Accept, Refunds, eBay Checkout and Reversal.

So lets create a payment button under the merchant services tab:

When you finish your button copy the code that paypal generates: