📖 Pretty URLs

The front controller pattern provides the opportunity to enhance the URLs to simplify them into more intuitive and human-readable addresses. Leveraging the use of PHP we can simplify the URL for a page request.

mysite.com/index.php?controller=products&action=show becomes mysite.com/products/show

URL to file mapping

URL Rewriting

In order for pretty URLs to work, we need to separate the URL from the web server file system. This is done by modifying the server directives to rewrite teh URLs to match the MVC pattern we are creating.

Apache Settings

Edit the httpd.conf file to include the rewrite module

Open the httpd.conf file and look for the rewrite module to make sure it is not commented out. If the beginning of this line has a #, remove it.

LoadModule rewrite_module modules/mod_rewrite.so
Add Rewrite Rules to the httpd-vhosts.conf File

If you have access to the server configuration file, httpd-vhosts.conf in our case, be sure the AllowOverride All directive is in the VirtualHost rules. Also, be sure the DocumentRoot and Directory point to your project folder.

<VirtualHost *:80>
    DocumentRoot "C:\xampp\htdocs\path\to\project\folder"
    ServerName phpmvc.localhost
    ServerAlias phpmvc.localhost

    <Directory "C:\xampp\htdocs\path\to\project\folder">
        Require all granted
        AllowOverride All
    </Directory>
</VirtualHost>
Create the .htaccess File

Next create an .htaccess file and add the rules to the file and place the file in the web root directory of your project. The first rule we need is to redirect all requests to the index.php page for processing.

Create the .htaccess file in the root of your project folder. Add the following code to the file and save the file.

RewriteEngine On
RewriteRule ^ index.php

This should tell the server to load the index page regardless of the details in the URL request.

Add a line to the beginning of the index.php page to stop the script and provide a message to verify the index page loaded.

<?php

// test the .htaccess file directive
exit ("This is the index page");

// the remainder of the index.php page will not run
...

Restart your server and try to load various pages. You should see the exit message in the browser if the server is following the Rewrite rule. If this works, all URL requests are routed to the index.php file for processing. Now we can use the URL path to decide which controller and action to run.

Accessing URL Data

First, take a look at the data available in the URL using PHP to display the URL path. You can check the URL path information by adding code to the index.php page to print out the $_SERVER[] array. Open the view source and in the array, look for REQUEST_URI. If I visit my project using a /products/show path, the $_SERVER['REQUEST_URI'] displays the value /products/show from the URL.

<?php

print_r($_SERVER);
exit;

// the remainder of the index.php page will not run
...

URL: view-source:http://localhost/products/show

$_SERVER array: [REQUEST_URI] => /products/show

Extract the URI Path Info

We want to see the information extracted from the URI.

<?php

$path = $_SERVER['REQUEST_URI'];
exit($path);

// the remainder of the index.php page will not run
...

This should output the /products/show path to the page. Now we can get the value of the URL path in the front controller to help us route the request to the appropriate controller.

Using the Path Info to Route the Request

Some URLs can include a query string which we want to remove from our URI path. We can use the built-in PHP parse_url() function to separate the URL path from the query string. We can also add the PHP_URL_PATH flag to remove the query string form the path.

Now we need to separate the path into the individual segments for controller and action using the PHP explode() function on $path variable. We will include the forward slash (/) as the delimiter. This will provide the request information needed so our script can call the appropriate controller and action.

<?php

// parse the URL into the path without a query string
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// separate the path into segments using the / delimiter
$segments = explode('/', $path);

// assign path segments to the $controller and $action variables
$controller = $segments[1];
$action = $segments[2];

require "src/controllers/$controller.php";

$controller_object = new $controller;

$controller_object->$action();

Tutorial

NOTE: The information in this video was correct at the time of production. Some elements may have changed. Please refer to the course syllabus and assignments for current requirements.