Jump to content

Recommended Posts

Below is an example of MVC - routing from PHPIT.com

 

The Router class

Our Router class will have to analyze the request, and then load the correct command. First step is to create a basic skeleton for the router class:
<?php

Class Router {
        private $registry;
private $path;
        private $args = array();

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

}

?>

And then add the following lines to the index.php file:
# Load router
$router = new Router($registry);
$registry->set ('router', $router);

We've now added the Router class to our MVC system, but it doesn't do anything yet, so let's add the necessary methods to the Router class.

The first thing we will want to add is a setPath() method, which is used to set the directory where we will hold all our controllers. The setPath() method looks like this, and needs to be added to the Router class:
function setPath($path) {
        $path = trim($path, '/\\');
        $path .= DIRSEP;

        if (is_dir($path) == false) {
                throw new Exception ('Invalid controller path: `' . $path . '`');
        }

        $this->path = $path;
}

Then add the following line to the index.php file:
$router->setPath (site_path . 'controllers');

Now that we've set the path to our controllers, we can write the actual method responsible for loading the correct controller. This method will be called delegate(), and will analyze the request. The first bit of this method looks like this:
function delegate() {
        // Analyze route
        $this->getController($file, $controller, $action, $args);

As you can see, it uses another method, getController() to get the controller name, and a few other variables. This method looks like this:
private function getController(&$file, &$controller, &$action, &$args) {
        $route = (empty($_GET['route'])) ? '' : $_GET['route'];

        if (empty($route)) { $route = 'index'; }

        // Get separate parts
        $route = trim($route, '/\\');
        $parts = explode('/', $route);

        // Find right controller
        $cmd_path = $this->path;
        foreach ($parts as $part) {
                $fullpath = $cmd_path . $part;
                       
                // Is there a dir with this path?
                if (is_dir($fullpath)) {
                        $cmd_path .= $part . DIRSEP;
                        array_shift($parts);
                        continue;
                }

                // Find the file
                if (is_file($fullpath . '.php')) {
                        $controller = $part;
                        array_shift($parts);
                        break;
                }
        }

        if (empty($controller)) { $controller = 'index'; };

        // Get action
        $action = array_shift($parts);
        if (empty($action)) { $action = 'index'; }

        $file = $cmd_path . $controller . '.php';
        $args = $parts;
}

Let's go through this method. It first gets the value of the $route querystring variable, and then proceeds to split it into separate parts, using the explode() function. If the request is 'members/view' it would split it into array('members', 'view').

We then use a foreach loop to walk through each part, and first check if the part is a directory. If it is, we add it to the filepath and move to the next part. This allows us to put controllers in sub-directories, and use hierarchies of controllers. If the part is not a directory, but a file, we save it to the $controller variable, and exit the loop since we've found the controller that we want.

After the loop we first make sure that a controller has been found, and if there is no controller we use the default one called 'index'. We then proceed to get the action that we need to execute. The controller is a class that consists of several different methods, and the action points to one of the methods. If no action is specified, we use the default action called 'index'.

Lastly, we get the full file path of the controller by concatenating the path, controller name and the extension.

Now that the request has been analyzed it's up to the delegate() method to load the controller and execute the action. The complete delegate() method looks like this:
function delegate() {
        // Analyze route
        $this->getController($file, $controller, $action, $args);

        // File available?
        if (is_readable($file) == false) {
                die ('404 Not Found');
        }

        // Include the file
        include ($file);

        // Initiate the class
        $class = 'Controller_' . $controller;
        $controller = new $class($this->registry);

        // Action available?
        if (is_callable(array($controller, $action)) == false) {
                die ('404 Not Found');
        }

        // Run action
        $controller->$action();
}

After having analyzed the request with the getController() method, we first make sure that the file actually exists, and if it doesn't we return an simple error message.

The next thing we do is include the controller file, and then initiate the class, which should always be called Controller_[name]. We'll learn more about the controller later on.

Then we check if the action exists and is executable by using the is_callable() function. Lastly, we run the action, which completes the role of the router.

Now that we have a fully working delegate() method, add the following line to the index.php file:
$router->delegate();

If you now try to run the system, you will either get the following error, if you haven't yet created the 'controllers' directory:
Fatal error: Uncaught exception 'Exception' with message 'Invalid controller path: `g:\Projects\PHPit\content\simple mvc php5\demo\controllers\`' in g:\Projects\PHPit\content\simple mvc php5\demo\classes\router.php:18 Stack trace: #0 g:\Projects\PHPit\content\simple mvc php5\demo\index.php(13): Router->setPath('g:\Projects\PHP...') #1 {main} thrown in g:\Projects\PHPit\content\simple mvc php5\demo\classes\router.php on line 18

Or you will get the '404 Not Found' error, because there are no controllers yet. But that's what we're going to create right now.

 

HERES the source code:

<?php

Class Router {
private $registry;
private $path;
private $args = array();

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

}

function setPath($path) {
	$path = trim($path, '/\\');
	$path .= DIRSEP;

	if (is_dir($path) == false) {
		throw new Exception ('Invalid controller path: `' . $path . '`');
	}

	$this->path = $path;
}

function getArg($key) {
	if (!isset($this->args[$key])) { return null; }
	return $this->args[$key];
}

function delegate() {
	// Analyze route
	$this->getController($file, $controller, $action, $args);

	// File available?
	if (is_readable($file) == false) {
		$this->notFound('no-file');
	}

	// Include the file
	include ($file);

	// Initiate the class
	$class = 'Controller_' . $controller;
	$controller = new $class($this->registry);

	// Action available?
	if (is_callable(array($controller, $action)) == false) {
		$this->notFound('no-action');
	}

	// Run action
	$controller->$action();
}

private function extractArgs($args) {
	if (count($args) == 0) { return false; }
	$this->args = $args;
}

private function getController(&$file, &$controller, &$action, &$args) {
	$route = (empty($_GET['route'])) ? '' : $_GET['route'];

	if (empty($route)) { $route = 'index'; }

	// Get separate parts
	$route = trim($route, '/\\');
	$parts = explode('/', $route);

	// Find right controller
	$cmd_path = $this->path;
	foreach ($parts as $part) {
		$fullpath = $cmd_path . $part;

		// Is there a dir with this path?
		if (is_dir($fullpath)) {
			$cmd_path .= $part . DIRSEP;
			array_shift($parts);
			continue;
		}

		// Find the file
		if (is_file($fullpath . '.php')) {
			$controller = $part;
			array_shift($parts);
			break;
		}
	}

	if (empty($controller)) { $controller = 'index'; };

	// Get action
	$action = array_shift($parts);
	if (empty($action)) { $action = 'index'; }

	$file = $cmd_path . $controller . '.php';
	$args = $parts;
}


private function notFound() {
	die("404 Not Found");
}

}

?>

 

 

Can some one help me disect this... am little new to OOPs.

if u can just add comments to the source code i wil make from it...

Link to comment
https://forums.phpfreaks.com/topic/128685-mvc-routing-explaination-needed/
Share on other sites

This is code from a tutorial from phpit.com. How the code works is explained here

 

In order to understand the code you should at least have a thorough understanding of the PHP syntax  (such as variables, data types, control structures, operators etc). Aswell as basic Object Oriented Programming knowledge.

i get what ur trying to say... the tutorial doesnt explain propely the code

 

i dont understand how the url is cpatured n routed....

 

when the url is demo/memebers/view

 

 

hows he using $_GET to capture it....pretty confusing... their forum is also closed down

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.