📖 PHP MVC Front Controller Pattern
Adding pages to a MVC app is different from a traditional website. In a traditional website you simply add more scripts that are called from the browser URL to load the requested page. In an MVC app, we want to load the page from a call to the index.php page with additional details in the URL. For example, in a traditional ecommerce site, we might show a list of products on the index.php page then create a link to a product-show.php page to load a single product. In the MVC app, we will replace the call to the index.php with the name of the resource we want. An example might look like this: mysite.com/products
URL Mapping to File System
This file pattern will align each URL to a related file in the file system with the path of the file system reflected in the URL. To build a site using this traditional URL = file approach, we lock ourselves into the one-file-equals-one-page approach.
Front Controller Pattern
In the MVC pattern we want to direct all requests to the index.php page and then route the individual requests through the front controller. The front controller will evaluate the URL request to determine which controller to enable to process the request and return the response to the client.

In the front controller pattern, visitor traffic (HTTP requests) are received by the index page which acts as a router to route the request to the appropriate controller class for processing. This allows for the usage of pretty URL like mysite.com/show-product. In order for this to work, we must provide code in the index.php page to process the expected URLs.
In traditional PHP, we use a query string to provide detailed information about the page we want returned. In the case of viewing a specific product, we might have a URL that looks like this: mysite.com/products.php?productId=1
. This actually gives us 2 pieces of information. The first is the page we want to load (products) and the second is the action we want to take (load productId 1) to provide the specific page content.
In the MVC front controller pattern, we would use the index file as the default file and place the page in the query string that matches the controller that loads the page and the action that responds to the action we want to take.
mysite.com/products.php?productId=1
becomes mysite.com/index.php?controller=products&action=show
Setting Up the Code
First, we want to create a new page to show the product view. For now, this can be just a simple HTML page. We"ll name this file product-show.php.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Show Product</title>
</head>
<body>
<h1>This is the Show Product page.</h1>
</body>
</html>
Next, we add a method to the products.php controller file to show the new show product view.
<?php
class Products
{
public function index()
{
require "src/models/product.php";
$model = new Product;
$products = $model->getData();
require "views/product-list.php";
}
public function show()
{
require "views/product-show.php";
}
}
Now the index.php page can be coded to pull the necessary information from the query string using the $_GET()
method.
<?php
// get the controller and action from the query string
$controller = $_GET["controller"];
$action = $_GET["action"];
// require the necessary controller using the variable value
require "src/controllers/$controller.php";
// assign the name of the desired controller to a $controller_object variable
$controller_object = new $controller;
// call the method from the controller using the $action value
$controller_object->$action();
Note: The domain for this URL must match the domain you are using in your local development environment. For example, I have my virtual host set to map to my development folder so I use localhost/index.php?controller=products&action=show
to load the show products page.
Adding More Pages
We will certainly want to add more pages beyond the products page to our site. In order to do so, we need to add new controllers to manage the requests. Since our app is already parsing the URL query string controller and action properties, we can use these to create our new controller class.
Let's add a Home page to the site by first creating a new home controller.
<?php
class Home
{
public function index()
{
require "views/home-index.php";
}
}
Now we can add a new Home page view in the views directory. For now, let's keep it simple with just a recognizable "This is the home page view" message. We can add page content later later.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page</title>
</head>
<body>
<h1>This is the home page view</h1>
</body>
</html>
Now when we visit our site using localhost/index.php?controller=home&action=index
it should load the "This is the home page" message. this is because we are parsing the URL query string into controller/action segments to define the controller class and action method to execute.
We have now added a new page to our app.