The Goal: Separating Logic from Presentation

In the last lesson, our controller directly printed a string using echo. This is bad practice because it mixes application logic with presentation (HTML). The goal of MVC is to separate these concerns. The Controller's job is to get data and decide which view to show, but it shouldn't be responsible for the HTML itself. The View's only job is to display the data it is given.

To achieve this, we will create a "View" helper function that our controllers can use to render a view file and pass data to it.


Step 1: Creating a View Helper Function

We'll create a simple helper function called view(). This function will handle the logic of including the view file and making our data available to it.

Create a new file: app/Core/helpers.php


<?php

// File: app/Core/helpers.php

/**
 * Render a view file.
 *
 * @param string $path The path to the view file (without .view.php)
 * @param array $data The data to pass to the view
 * @return void
 */
function view($path, $data = [])
{
    // The extract() function is a clever way to turn array keys into variables.
    // For example, an array ['name' => 'Bob'] becomes a $name variable with the value 'Bob'.
    extract($data);

    // Construct the full path to the view file.
    // We use a .view.php extension to make it clear these are view files.
    $fullPath = __DIR__ . '/../../views/' . str_replace('.', '/', $path) . '.view.php';

    if (file_exists($fullPath)) {
        require $fullPath;
    } else {
        echo "View not found at path: {$fullPath}";
    }
}


Step 2: Loading the Helper File with Composer

For our application to find the view() function, we need to tell Composer to load this new helper file automatically. We can do this by adding a "files" array to our composer.json.

Update your file: composer.json


{
    "name": "your-name/mvc-project",
    "description": "A simple PHP MVC framework.",
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "files": [
            "app/Core/helpers.php"
        ]
    }
}

After updating the file, run composer dump-autoload in your terminal. This command regenerates the autoloader to include our new file.


Step 3: Creating Our First View File

Now, let's create the actual HTML file that we want to display. This file will be able to use the variables we pass from the controller.

Create a new file: views/home.view.php


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Welcome to Our Framework</title>
    <style>
        body { font-family: sans-serif; display: grid; place-content: center; height: 100vh; margin: 0; background-color: #f0f2f5; }
        .container { text-align: center; background: white; padding: 40px; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); }
        h1 { color: #333; }
        p { color: #666; font-size: 1.2rem; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Welcome, <?php echo htmlspecialchars($name); ?>!</h1>
        <p>This page is being rendered by our custom MVC framework.</p>
    </div>
</body>
</html>

Step 4: Updating the HomeController

Finally, let's change our HomeController to use our new view() helper function instead of just echoing a string. We will pass it the name of our view ('home') and an array of data containing a 'name' key.

Update your file: app/Controllers/HomeController.php


<?php

namespace App\Controllers;

class HomeController
{
    public function index()
    {
        // Instead of echoing, we now call our view helper.
        // We pass the name of the view file 'home' 
        // and an array of data we want to make available to the view.
        view('home', [
            'name' => 'StartWithSite Learner'
        ]);
    }
}

Your Mission

  1. Create the new file app/Core/helpers.php.
  2. Update your composer.json file and run composer dump-autoload.
  3. Create the new view file views/home.view.php.
  4. Update the app/Controllers/HomeController.php file.
  5. Visit your project's homepage. You should now see a styled welcome page with the message "Welcome, StartWithSite Learner!".

You have now successfully separated your application's logic from its presentation. This is a massive step towards building a clean, maintainable application!