Can someone present me an example which implements the three tier architecture in PHP. Let's say I have a class student with the fields ID and Name. I want to enter the student ID and Name through a web form and save it to the database. Could someone show me or provide me with a link to a PHP code example which shows the usage of the presentational, business and database layer in such a sitauation?

i dont want to use application frameworks.


thanks in advance.

Hi.

This is an example of a simple MVC application, just to give you an example of how it can be done.

I don't write out the base classes... no point really in this sample.

<?php
/**
 * File: index.php
 */

/* This assumes a file structure of:
 * ----
 * index.php
 * MVC/
 *   Controllers/
 *     BaseController.php
 *     RandomController.php
 *   Models/
 *     BaseModel.php
 *     RandomModel.php
 *   Views/
 *     BaseView.php
 *     RandomModel.php
 */

// Load the controller
$ctrlDir = "MVC/Controllers/";
($page = @$_GET['page']) or $page  = "";
($action = @$_GET['action']) or $action = "defaultAction";

$ctrlPath = $ctrlDir . ucfirst($page) ."Controller.php";

if(file_exists($ctrlPath)) {
    // Load and create a controller instance
    include($ctrlPath);
    
    $ctrlName = ucfirst($page) . "Controller";
    $controller = new $ctrlName();

    // Execute the selected action
    // Meaning, try to execute a method on the
    // controller that matches the $_GET['action']
    // value passed.
    $action = ucfirst($action);
    if(method_exists($controller, $action)) {
        $controller->$action();
    }
    else {
        // Execute the controllers default method
        $controller->DefaultAction();
    }
}else {
    // You probably want to handle errors more elegantly ;)
    user_error("Error 404. The page you requested does not exist", E_USER_ERROR);
}
?>
<?php
/**
 * File: RandomController.php
 */

/**
 * A ranom controller that does random things.
 * Extends the base controller, which should
 * define anything that would be shared amongst
 * all the Controllers.
 *
 * I am not going to define a base controller tho.
 * I'll leave that up to you ;)
 */
class RandomController extends BaseController
{
    protected $model;
    protected $view;

    public function __construct() {
        // Normally these would be in a configuration
        // file somewhere as constants, but I'll just put
        // them here for this example.
        $modelDir = "MVC/Models/";
        $viewDir = "MVC/Views";

        // Create the model
        $modelPath = $modelDir . "RandomModel.php";
        if(file_exists($modelPath)) {
            include($modelPath);
            $this->model = new RandomModel();
        }
        else {
            throw new Exception("Failed to load model");
        }

        // Create the view
        $viewPath = $viewDir . "RandomView.php";
        if(file_exists($modelPath)) {
            include($modelPath);
            $this->model = new RandomModel();
        }
        else {
            throw new Exception("Failed to load model");
        }
    }

    /**
     * The default action.
     * Used if the client doesn't specify a action,
     * or of the client specifies a invalid action.
     */
    public function DefaultAction() {
        // Get the name of the current user and show a message
        $username = $this->model->GetUsername();
        $this->_view->ShowDefaultMessage($username);
    }

    /**
     * A action.
     * This one doesnt' really do much, but you get the point :P
     */
    public function DoStuff() {
        // Get number of rows and show the message
        $dbNumRows = $this->model->GetTablebaseRowCount();
        $this->view->ShowDoStuffMessagE($dbNumRows);
    }
}
?>
<?php
/**
 * File: RandomView.php
 */

/**
 * A ranom view.
 * Handles the presentation of the Random page.
 */
class RandomView extends BaseView
{
    /**
     * Shows a default welcome message.
     * @param string $username The name to put into the welcome message.
     */
    public function ShowDefaultMessage($username=null) {
        // Show a welcome message
        $username = ($username ? $username : "visitor");
        echo "<h1>Welcome to the default page, $username.</h1>";

        // Show something else
        echo "Chose an action: <br />";
        echo " - <a href='?page=random&amp;action=doStuff>Do Stuff</a>";
    }

    /**
     * Display the output for the DoStuff action.
     * @param <type> $rowCount
     */
    public function ShowDoStuffMessage($rowCount=0) {
        echo "You have chosen to do stuff?!<br />";
        echo "Fine. I'll tell you how many rows we have in the database...<br />";
        echo " - Row count: {$rowCount}. <br />";
        echo "Happy now!";
    }
}
?>
<?php
/**
 * File: RandomModel.php
 */

/**
 * A random model.
 * Handles all the database interaction for the Random page.
 */
class RandomModel extends BaseModel
{
    protected $dbLink;

    public function __construct() {
        // This would be done in the BaseView, but I'm just gona
        // do it here instead.
        $this->dbLink = new mysqli("localhost", "usr", "pwd", "db_name");
        if(mysqli_connect_errno()) {
            throw new Exception("Failed to establish database link: ". mysqli_connect_error());
        }
    }

    /**
     * Gets the name of the current user... not that there
     * is anything written in here to keep track of users :P
     *
     * @return mixed The username on success, or FALSE on failiure.
     */
    public function GetUsername() {
        // Do some query to get the users name.
        // I didn't add any sort of user tracking system, so this is just random :P
        $sql = "SELECT username FROM usrTable WHERE something='somethingElse'";
        $result = $this->dbLink->query($sql);

        if($result || $result->num_rows > 0) {
            $row = $result->fetch_assoc();
            return $row['username'];
        }
        else {
            return false;
        }
    }

    /**
     * Returns the number of rows in the 'someTable' table.
     * @return int
     */
    public function GetTablebaseRowCount() {
        $sql = "SELECT COUNT(*) FROM someTable";
        $result = $this->dbLink->query($sql);

        if($result) {
            return $result->num_rows;
        }
        else {
            return 0;
        }
    }

}
?>

Let me know if something is unclear or if I left something out.

MVC is different from 3-tier from what I have read. MVC uses a triangle type layout where 3-tier is linear (I put this in his other thread, don't see why this one was created).

MVC is different from 3-tier from what I have read. MVC uses a triangle type layout where 3-tier is linear (I put this in his other thread, don't see why this one was created).

True, but notice how I've made the View unaware of the Model.
I've effectively mutated my MVC from the typical triangle into a more linear mode, making the controller responsible for controlling all interaction between the view and the model, rather than only being responsible for relaying changes in the view to the model.

It never made sense to me to have the view connect to the model anyways... makes it that much harder to control the flow of it all.

In any case, one could argue that MVC is a type of tier-3 architecture (that's how I see it, anyways).
The definitions for both are purposefully vague.

Actually, after digging a little deeper into the differences between n-tier architectures and MVC design patters, what I posted earlier is most likely mislabeled.

A tier-3 design pattern separates the buisness logic, the presentation layer, and the data layer and stacks them in a linear order, where each layer would only be able to communicate with the layers directly above or below it in the line.

This would put the buissnes logic in the middle, able to communicate with both the data layer and the presentation layer, but the latter two would only be able to communicate with the buisnes layer.

Which is pretty much exactly what the code I posted does.

A MVC pattern, on the other hand, defines three separate "modules" of sorts, each responsible for a specific part of the process, but each communicating with the others. (The communication triangle)

  • The Model; representing the application data. Receiving updates from the Controller, and providing data to the View.
  • The View; presents the application data to the "user". In the case of websites, the HTML output. It would receive data from the Model and present it to the "user". In the case of interactive UIs, the View would also pass on any user interaction to the Controller. (Button clicks and such)
  • The Controller; representing the buisness logic. Receives events from the View, interprets them and triggers updates in the Model, which are then reflected by the View.

So, according to my current interpritation of the two design patters, my MVC design example would in fact really be a tier-3 design patten.
(Which should not be confused with a tier-3 architectural pattern, which is apparently something completely different)

thanks for the reply Atli.
actually i didnot understand your code at all.
it seems very complex to me.

can you provide me simple example?

lets take a simple example:
classperson.php

Class Person{

    Protected $Name, $Age;

    Public Function __Construct($Name, $Age){

        $this->SetName($Name);

        $this->SetAge($Age);

    }

    Public Function SetName($Name){

        $this->Name = $Name;

    }

    Public Function SetAge($Age){

        $this->Age = $Age;

    }

    Public Function SetName($Name){

        Return $this->Name;

    }

    Public Function GetAge($Age){

        Return $this->Age;

    }

    Public Function __toString(){

        return <<<DETAILS

            Name:  {$this->Name}

            Age:    {$this->Age}

DETAILS;
    }

}

queryperson.php

Public Function Save() {
$Query=mysql_Query('insert into Person(name,age)
values ($Name,$Age)';
Return $query;
}

personresult.php

$Dave = new Person('Dave', 32);
$Dave.Save()

above are three files..
am i right in above example?

if any changes required in the code you can do?

Why is your Save() method in a separate file?
If it is supposed to be a part of the Person class, it should be defined inside it.

Also, in PHP, you call class functions and variables using an arrow -> , not a dot.
Like:

$person = new Person('John Doe', 15);
$person->SetAge(35);
$person->Save();

I'm getting the feeling that your trying to use C/C++ style OOP design.

You should go over the PHP5 OOP pages in the manual, to get familiar with how OOP works in PHP.

that was just a simple example. i want to show u.

ok..
i want to apply above example using 3 tier architecture.
pls modify above code with 3 tier implementation.
nd pls tell me about each layer?

I think you are misunderstanding what tier-3 architecture is.
It's a design patter used to organize large scale projects, and when used in software development, it is usually implemented using OOP.

But you can't take a single example class, like that, and "apply" tier-3 architecture to it.
Classes are used to implement tier-3 architecture. Tier-3 architecture is not used to improve single class designs.

The example I originally posted included 3 classes, each of them requiring at least one more base class, and an index script.
That is as simple an example of tier-3 architecture as I can give.
(I could probably boil it down to less code, and throw out the base classes, but it would be pretty much the same code)

If you want to know how to implement tier-3 architecture, I suggest you go closely over that example (the manual is your friend here), because anything less than that won't be enough to properly demonstrate it.

It's not really that complex once you get a hang of how OOP works in PHP.
So I suggest you start there.

I'll be happy to help if you have any questions about that.

Basically i m using smarty in my projects which keeps presentation logic different from application logic. that is a 2 tier architecture.
Now in 3 tier architecture i need three layers. business, presentation and model layer.

1)Presentation layer(suppose web form displyed at the front end)
2)application layer(logic at back end)
3)model layer(sql queries).

now tell me one thing we need different files to handle each layer.?
for every layer different file.?
am i right?

Not really. There is no specific way to implement n-tier architecture.

But typically (when implemented in OOP), each layer is put into it's own class. Whether or not those classes are defined in separate files is irrelevant (although people tend to put one class per file... easier to maintain that way).

thanks for the reply atli.
pls tell me which is better 3 tier archtecture and mvc? and how?
which structure you are using in your projects?

That's a huge question.
I bet there could be entire books written about the answer to that :)

Ultimately, I doubt there really is a definite answer to that.
The example I posted in the beginning is roughly what I like to do with my applications. It looks like a MCV design, but, as I've found out, it is more like a Tier-3 design.

You should really just pick on and try it out... see how you like it. Then try the other one and compare.

I'd recommend trying MVC first. It's less constricted.
You could always download one of the popular MVC frameworks and study how they work.

This article has been dead for over six months. Start a new discussion instead.