As soon as a site has more than one page, the same header, footer and helper functions appear everywhere. Copying them into each file means fixing every bug several times. PHP solves this by loading code from other files.
include and require
Both load and run another PHP file at that point in the script, as if its code were pasted in:
<?php
require __DIR__ . '/helpers.php';
echo e('<b>Safe</b>');
The difference is what happens when the file is missing:
| Statement | File missing | Loaded twice? |
|---|---|---|
include | Warning, script continues | Yes |
require | Fatal error, script stops | Yes |
include_once | Warning, script continues | No, skipped the second time |
require_once | Fatal error, script stops | No, skipped the second time |
Rules of thumb:
- Use
require_oncefor files that define functions, classes or configuration. The page cannot work without them, and loading a function definition twice causes a "Cannot redeclare" fatal error. - Use
requirefor templates such as a header or footer that you deliberately output more than once. includeis rarely the right choice: carrying on without a file usually produces a broken page anyway.
Build paths with __DIR__
Relative paths like require 'helpers.php'; are resolved against the current working directory and PHP's include path, not necessarily the folder of the current file. The same code can work from one page and fail from another.
__DIR__ is the absolute folder of the file it appears in, so paths built from it always work:
<?php
require_once __DIR__ . '/../src/helpers.php';
Always start include paths with __DIR__. It removes a whole class of "failed to open stream" errors.
A small project layout
my-site/
├── config/
│ └── config.php Settings and secrets (not public)
├── src/
│ └── helpers.php Shared functions
├── templates/
│ ├── header.php
│ └── footer.php
└── public/ The only folder the web server exposes
├── index.php
└── contact.php
Point the web server, or php -S localhost:8000 -t public, at the public folder only. Then nobody can request config.php directly from a browser.
Never put database passwords or API keys in files inside the public folder, and never commit them to Git. Keep them in a config file outside public, or in environment variables.
Shared helpers
src/helpers.php:
<?php
declare(strict_types=1);
function e(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
Configuration that returns an array
A file can return a value, which makes a tidy config file. config/config.php:
<?php
return [
'site_name' => 'My Site',
'contact_email' => 'hello@example.com',
];
Templates
templates/header.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?= e($pageTitle) ?> | <?= e($config['site_name']) ?></title>
</head>
<body>
<header><a href="/"><?= e($config['site_name']) ?></a></header>
<main>
templates/footer.php:
</main>
<footer>© <?= date('Y') ?> <?= e($config['site_name']) ?></footer>
</body>
</html>
A page that uses everything
public/index.php:
<?php
declare(strict_types=1);
require_once __DIR__ . '/../src/helpers.php';
$config = require __DIR__ . '/../config/config.php';
$pageTitle = 'Home';
require __DIR__ . '/../templates/header.php';
?>
<h1>Welcome</h1>
<p>Contact us at <?= e($config['contact_email']) ?>.</p>
<?php require __DIR__ . '/../templates/footer.php'; ?>
Included files share the variables of the code that includes them, which is why header.php can use $pageTitle and $config.
Never include files based on user input
This pattern is dangerous:
<?php
// DO NOT DO THIS
require __DIR__ . '/pages/' . $_GET['page'] . '.php';
A request for ?page=../config/config loads files you never meant to expose, and other tricks can be worse. If the page comes from input, map it through an allowlist:
<?php
$pages = ['home', 'about', 'contact'];
$page = $_GET['page'] ?? 'home';
if (!in_array($page, $pages, true)) {
http_response_code(404);
$page = 'not-found';
}
require __DIR__ . "/../pages/{$page}.php";
Beyond include: autoloading
In larger projects with classes, you rarely write require yourself. Composer generates an autoloader that loads each class file the first time it is used. You will meet it in the object-oriented PHP course. The principles from this lesson still apply.
Summary
require_oncefor functions, classes and config;requirefor templates.- Build every path from
__DIR__. - Expose only a
publicfolder; keep config, secrets and source code outside it. - Included files share the including script's variables, and a file can
returna value. - Never build include paths from user input; use an allowlist.