No history yet

Modular Application Architecture

From Page to Application

When you first start building websites with PHP, it's common to put everything for a single page into one file. You have your HTML structure, your content, and your PHP logic all mixed together. This works for a single page, but what happens when you build a second one? Or a third?

You quickly find yourself copying and pasting the same header, navigation bar, and footer into every new file. If you need to change a link in the navigation, you have to hunt down every single file and update it. This is tedious and a recipe for mistakes.

The solution is to think of your site not as a collection of separate pages, but as a modular application. We can break our user interface into reusable chunks—like a header, a footer, and a navigation menu—and then assemble them as needed for each page. PHP gives us two primary tools for this: include and require.

Include vs. Require

At a basic level, include and require do the same thing: they take all the code from a specified file and insert it into the file that calls them. It's as if you had copied and pasted the content yourself.

Let's imagine a simple site structure. We'll create a folder called partials to hold our reusable UI components.

project/
├── index.php
├── about.php
└── partials/
    ├── header.php
    └── footer.php

Our header.php file might contain the start of our HTML document and the main navigation.

<!-- partials/header.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Awesome Site</title>
</head>
<body>
    <nav>
        <a href="index.php">Home</a>
        <a href="about.php">About</a>
    </nav>
    <main>

And footer.php closes out the page.

<!-- partials/footer.php -->
    </main>
    <footer>
        <p>&copy; 2024 My Awesome Site</p>
    </footer>
</body>
</html>

Now, our index.php file becomes much cleaner. We can use require to pull in these components.

<?php require 'partials/header.php'; ?>

<h1>Welcome to the Home Page</h1>
<p>This is the main content of our home page.</p>

<?php require 'partials/footer.php'; ?>

The key difference between include and require lies in how they handle errors. If the file specified in an include statement can't be found, PHP will issue a warning, but the script will attempt to continue running. If require can't find the file, it will trigger a fatal error and stop the script immediately.

For critical components like a header, footer, or a database connection file, require is almost always the correct choice. If your header is missing, the page is fundamentally broken, and it's better for the script to stop than to render an incomplete, garbled page.

Rule of thumb: If your application can't function without the file, use require. If the file is optional, like a widget that isn't essential to the page's core content, include might be appropriate.

Preventing Duplicates

What happens if you accidentally include the same file twice? If the file just contains HTML, you'll just see duplicated content. But if it contains a PHP function or class definition, you'll get a fatal error because PHP doesn't allow you to declare the same function twice.

This can happen in complex applications where one included file might itself include another. To prevent this, PHP provides two alternative statements: include_once and require_once.

These work exactly like their counterparts, but with an important addition: PHP keeps track of which files have been included. If you try to include or require a file a second time using the _once version, PHP will see it has already been loaded and simply ignore the second call.

<?php
// This is safe, even if some_other_file.php also includes functions.php
require_once 'functions.php'; 
require_once 'some_other_file.php'; 

sayHello(); // Function from functions.php

Using require_once is a best practice for including files that contain function or class declarations. It makes your application more robust and prevents hard-to-debug redeclaration errors.

Navigating Your Project

As your application grows, so will its directory structure. You might have a top-level directory, an includes folder inside that, and maybe an admin folder for back-end pages. How do you reliably reference files across this structure?

The answer lies in understanding file paths. The examples above used , which are interpreted from the location of the currently running script. If index.php is in the root directory, 'partials/header.php' works perfectly.

But what if you have a file at admin/dashboard.php? From its perspective, the path 'partials/header.php' is incorrect. The partials folder isn't inside the admin folder. It would need to go up one level first, using '../partials/header.php'.

This can get confusing. A more robust solution is to use paths built from a known starting point. One common technique is to use PHP's to construct a path from the project's root directory.

// In admin/dashboard.php

// __DIR__ will resolve to the full path of the 'admin' directory
// For example: '/var/www/html/project/admin'

// We can go up one level from there and then into 'partials'
require_once __DIR__ . '/../partials/header.php';

// Page content here

require_once __DIR__ . '/../partials/footer.php';

This approach is much more reliable. It doesn't matter where the script is executed from; the path to the partials will always be correct relative to the file itself.

By breaking your application into reusable components and managing file paths carefully, you create a foundation that is easy to maintain and scale.

Quiz Questions 1/5

What is the primary difference between include and require in PHP?

Quiz Questions 2/5

For which of the following files would require be the most appropriate choice over include?