The default routes ( as symlinks are ) are nothing more then simple header redirects to pages right? /page.php redirects to.. .. page.php, geez, Xaleph, we didn`t know that! Well, they do! Anyhow, what if you wanted to strip away the .php? Hmm ok, now it`s getting a little tougher right?
What if you wanted something like: game/city-view/workshop/buy .. Seems hard to get something like this set up. Well, fortunatly, it`s not
This tutorial will cover some basic .htaccess and some basic PHP understanding. And, since this is something i miss around here, some OO. OOoohh, what`s OO? OO stands for Object Orientation. Don`t get yourself confused right now, i will try and explain along the way.
Before i start, i want to make clear that , in order for this to work, you need to meet some requirements. These are:
Have PHP installed ( preferably PHP 5.3 > )
Have an apache server with the module mod_rewrite ( this is key!! )
Ok, enough talk, time to get some code`n done!
First of, lets start by creatin the .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Basicly, what this does is tell the apache server to listen what is being said here. The first statement: rewriteEngine On means you are turning on the mod_rewrite module, which we need to execute the other lines.
The next four lines are simple, each line is specifically checking if the current REQUEST is NOT a file, dir etc. If this is the case ( meaning, it`s not a file, dir, executable, what have you ) you can go to line 5.
Line 5 is a simple redirect to the root of your document. Which in most cases is the root where this file is being placed. If you have directory structure which consists of something like: C:/xampp/htdocs/ and you would have placed the .htacess file right in the htdocs, then all requests which did not meet the conditions, will be relocated to the root. Root is seen as the dot.
The last line is what`s doing the magic. Instead of routing only the root, we finally tell it route to the index.php, which is being stripped away, which is normal. But we explicitly tell it to.
So, now we have a simple handler for all requests to our index.php. You can still access all your directory`s and files, try it out.
If you verified this, we can move on
The next step: creating a class to handle our requests!
As you may have noticed, i used the word class. Which is probably uncommon for some people here, so i will elaborate. A class is a blueprint for a set of functions. You can group functions which all relate to one another, together. Which is called a class. There are different kinds of classes available, but for now, we`ll use the normal class. Now that you somewhat know what a class is, i`ll tell you a little secret: a class is the blueprint for an object! A default class will allways be an object, meaning you can access all functions inside an object by reference. Uhh, reference? That`s right!
Anyway, i will write a follow up tutorial on OO i suppose. Anyway, lets move on:
the Router.class.php:
Code: Select all
<?php
// The class followed by the name of the class, Router in our case.. :)
class Router
{
// This is the default constructor, which means, this function will ALWAYS execute if you create
// a new object from this class, there are some exceptions, but i will not go in to that now
public function Router ()
{
echo "Hello, this is a router object!";
}
}
For the constructor, which always executes, we want to do some stuff right? We need to decide on using a syntax for our router.
The best way is to simply use the / as seperator. It`s easy and everyone knows it.
So here we go:
Router.class.php
Code: Select all
<?php
class Router
{
private $index;
private $root;
private $prefix;
private $uri;
private $nodes;
/*
* The global constructor for our object. It currently accepts 1 parameter
* which is the prefix. If you work on a different level then the root of
* the document root, you can use the prefix to pass a string.
*
* @example $prefix = "Game/Document/"
*
*/
public function Router ($prefix = false)
{
// Our initial request is something like:
// www.domain.com/yourwebsite/home/user-profile/123/
$this->index = strrpos( $_SERVER['PHP_SELF'] , "index.php" );
$this->root = substr( $_SERVER['PHP_SELF'] , $this->index , -0 );
// if prefix was given
// in the test case you should specify /yourwebsite/
if( $prefix ) {
$this->prefix = $prefix;
}else{
$this->prefix = false;
}
// Let`s rebuild the actual request, we strip the $prefix
// and we are left with a working request like:
// $new = "/home/user-profile/123/";
$new = str_replace($this->prefix, "", $_SERVER['REQUEST_URI']);
// This time, we are going to replace the root with nothing.
// Based on our $new string. An example would be:
// $argument = "home/user-profile/123/";
$argument = str_replace( $this->root, "" , $new);
// Now to finalize our request, all we do is trim away the last /
// and call a function / METHOD < called in OO to set the complete URI.
// Btw, a URI is our request.
$this->setUri(trim($argument, "/"));
// Now we are going to split our argument up in seperate
// elements. We can use the explode function in PHP to explode a string
// on a given character, and it will return an array containing all elements.
// We also call in on the function / METHOD setNodes();
$this->setNodes(explode("/", $this->getUri()));
// As you can see, that`s about all it takes for the constructor. But we
// are not done yet, we still need to create at least 2 methods for this class in
// order for it work. These 2 are setUri(); and setNodes();
// However, we are still not there, what use does it have if we can`t get
// information from it? That`s why we`ll also use a method to get nodes.
}
/**
* Sets the proper URI for this page request
* @param <type> String the actual URI
*/
private function setUri ($uri)
{
// all this does is set this object field uri the good URI.
$this->uri = $uri;
}
/**
* This method will accept an array and will go through all elements within this
* array and add them to the object field called: nodes
* @param <type> $array
*/
private function setNodes ($array)
{
// Check wether the $array given is actually an array xD
if(is_array($array))
{
// loop through all elements using the foreach()
foreach($array as $node)
{
// add all elements to the field nodes.
array_push($this->nodes, $node);
}
}else{
return false;
}
}
public function getNodes ($number = false)
{
// if a number was given, return the node with the corresponding number
// Using this means you can get the get node by calling getNodes(1);
if( is_numeric( $number ) and $number <= count($this->nodes))
{
// Geef het huidige array nummer terug
return $this->nodes[$number-1];
}
else
{
// if no number was given, or number was out of scope, return the
// array with all nodes
return $this->nodes;
}
}
}
index.php
Code: Select all
<?php
// now if we want to use this object or class we have to call it and get it first.
// include the file
include("Router.class.php");
// Now that we have it, we can create a new object from this like:
// also note that Router is the classname, but indirectly points to the
// Router function, which accepts 1 parameter, the prefix. If you don`t need
// a prefix, you can use as down below:
$router = new Router();
// if however, you do need a prefix, you can use this:
$router2 = new Router("yourwebsite/document");
// Now, to get it some random node. you can type in your address bar:
// something like: www.website.com/home/article
// to call it, or in case it`s empty
if(is_string($router->getNodes(1))){
echo $router->getNodes(1);
}else{
echo 'No request was made';
}
// that`s basicly it, it can be fully customizable etc. but for the scope of the tutorial
// and due to the fact it`s getting too late ( 4:am ) i`m gonna quit.
// BTW DIDNT TEST THE CODE YET, so if you run into an error, post it, ill see it soon enough :)
?>