Url Routing with PHP - Part Two
This is the second part of a series, I assume you have read Url Routing with PHP - Part One as it covers the basics that I'll build on in Part Two.
Requirements
- Apache with mod_rewrite enabled
- PHP
Assign Responsibilities
The first problem I want to address is that there are two different things going on with the script in part one. 1. The parsing of the URL to obtain a command array and 2. The actual dispatch of the command by the switch statement. I want to create an architecture that easily allows changing the way incoming URLs are formatted, and also the substitution of alternative dispatch schemes.
Standardized Command Objects
To achieve this goal, I create a standard command object. This will allow changing the way the urls are interpreted or dispatched as long as the interpreter creates command objects and the dispatcher accepts them.
-
class Axial_Command
-
{
-
var $commandName = ";
-
-
function Axial_Command($commandName,$parameters)
-
{
-
$this->commandName = $commandName;
-
$this->parameters = $parameters;
-
}
-
function getCommandName()
-
{
-
return $this->commandName;
-
}
-
function getParameters()
-
{
-
return $this->parameters;
-
}
-
}
Interpreting URLs
Next we need a class that handles interpreting the incoming URL and creating a command object. The following class uses the same method as in part one and creates commands based on a simple format for the incoming URL, a command followed by its parameters separated by forward slashesÂ.
-
class Axial_UrlInterpreter
-
{
-
-
function Axial_UrlInterpreter()
-
{
-
{
-
if ($requestURI[$i] == $scriptName[$i])
-
{
-
}
-
}
-
$commandName = $commandArray[0];
-
$this->command = new Axial_Command($commandArray[0],$parameters);
-
}
-
-
function getCommand()
-
{
-
return $this->command;
-
}
-
}
Dispatching Commands
And finally we can pass the command object to the dispatcher. In order to keep the code simple I use a switch statement that includes different scripts based on the command. There are many other methods that could be used in fact thats the point the of architecture I'm presenting.
-
class Axial_CommandDispatcher
-
{
-
var $command;
-
function Axial_CommandDispatcher($command)
-
{
-
$this->command = $command;
-
}
-
-
function Dispatch()
-
{
-
switch ($this->command->getCommandName())
-
{
-
case 'commandOne' :
-
include('commandone.php');
-
break;
-
case 'commandTwo' :
-
include('commandtwo.php');
-
break;
-
case ":
-
include('root.php');
-
break;
-
default:
-
include('default.php');
-
break;
-
}
-
}
-
}
Put it all together
In the first part of this series I used an .htaccess file to redirect to index.php. The same .htaccess is all we need now. Our new index.php will look a bit different though. With the changes from part one made we can now substitute different classes to handle the interpretation of URLs or command dispatching easily.
-
include('axial.command.php');
-
include('axial.urlinterpreter.php');
-
include('axial.commanddispatcher.php');
-
$urlInterpreter = new Axial_UrlInterpreter();
-
$command = $urlInterpreter->getCommand();
-
$commandDispatcher = new Axial_CommandDispatcher($command);
-
$commandDispatcher->Dispatch();
Try it out
You can visit examples.phpaddiction.com/urlrouter/part_2/ to see it in action and download the sample code.
Next up
In the next part of this series I will explore some ways to get rid of the switch statement in the dispatcher and create a small framework to hang your code from.
Comments
5 Responses to “Url Routing with PHP - Part Two”
Leave a Reply
replace
$this->command = new Axial_Command($commandArray[0],$parameters);
to
$this->command = new Axial_Command($commandName ,$parameters);
Sure, either way works, It is quicker to leave out the array access and perhaps the clearer style, thanks for the pointer.
I use $_SERVER['PATH_INFO']. This way I only get what is past the script path.
Roman: I decided against using PATH_INFO since it wouldn't allow for separators other than forward slashes "/". I wanted the entire URL after the script not just the directories. Also I found that support for PATH_INFO wasn't the same across PHP versions.