📖 PHP MVC Application

Now that we have an idea of how to break our code into the MVC components, we need to take a close look at how we are going to organize the app. We use a specific directory structure for development that will include elements that will not go into the final web app. Many of these files are for development purposes only and will not be needed to run the final app.

We will also rename the files to allow for more than one of each but still maintain a file name that refers to its function. Since the controller.php file is the controller for the products, we'll rename it products.php and place it in the controllers directory. It will now reside in src/controllers/. The model.php file will be renamed product.php and be placed in the src/models/ directory. Notice the model file is singular and the controller file is plural. This is a PSR recommended practice.

The base files of the MVC app are the Model files, Controller files and the View files. The Model and Controller files are part of the source files and will be placed in a src folder with sub-folders for each. The View files will be placed in their Views folder to keep them separate but available to the app.

MVC basic file structure

New Site File Structure

↧ MVC-BASIC-APP (SITE ROOT)
↳ src
| ↳ controllers
|  ↳ products.php
| ↳ models
|  ↳ product.php
↳ views
| ↳ product-list.php
↳ index.php

Notice the new src directory placed in the root of the file structure along with a controllers and models sub-directories. Also notice the new views directory also placed in the root directory of the site. Into each of these folders should be placed the corresponding files; controllers in the controllers directory, models in the models directory and views in the views directory. The index.php file which receives the HTTP request stays in the root directory.

Renaming Files

Remember that the files are reliant on relative referencing for each of their code to perform their expected functions and now that the file system has been reorganized, the file code must be edited to reflect the new structure.

The index.php File

The index.php file requires the products.php controller which has been moved to the src/controllers/ directory. The controller.php file was renamed to products.php and needs to be updated in the index.php file along with the class call to Products to create the new Products object.

<?php

require "src/controllers/products.php";

$controller = new Products;

$controller->index();
The products.php Controller

The products.php controller file needs to rename the class to Products to match its function. This file requires a model and the model was moved to the new src/models/ directory and renamed product.php so, the reference to the model file needs to be updated. The call to the Product class to instantiate the Product model needs to be updated. Lastly, the products.php controller requires a view that was renamed and moved into the new views directory which needs to be updated.

<?php

class Products
{
    public function index()
    {
        require "src/models/product.php";

        $model = new Product;

        $products = $model->getData();

        require "views/product-list.php";
    }
}
The product.php Model

The product.php model needs to have the class name renamed to Product to reflect the function of the model.

<?php

class Product
{
    public function getData(): array
    {
        $dsn = "mysql:
                host=localhost;
                dbname=adv_php;
                charset=utf8;
                port=3306";

        $pdo = new PDO($dsn, "adv_php_user", "secret", [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        ]);

        $stmt = $pdo->query("SELECT * FROM `products`");

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}
The product-list.php View

No changes needed in the file code as it only supports the app as a dependency. However, we do want to change the name to reflect its content. Since this file won't be public facing, we aren't as worried about making it user-friendly, but more developer -friendly. The index.php file will still be requested in the URL, but we might need a different view for individual products, so we name this to reflect the fact it will produce a view for the product list. While we could name the product-list file products and the individual product file product, that would may be difficult to differentiate from the products controller and product model in the code. Naming the views with more detail allows us to separate the file name from either the products controller and the product model.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Products</title>
</head>

<body>

    <h1>Products</h1>

    <?php foreach ($products as $product) : ?>
        <h2><?= htmlspecialchars($product["name"]) ?></h2>
        <p><?= htmlspecialchars($product["description"]) ?></p>
    <?php endforeach; ?>

</body>

</html>

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.