Organising code with include and require

Split a project into files, share headers and functions, and lay out a small project safely.

  • Beginner
  • 5 min read
  • Updated 17 Oct 2026

What you will learn

  • Choose between include, require and the _once variants
  • Build reliable file paths with __DIR__
  • Share layout and helper code across pages
  • Keep configuration and secrets outside the public folder

Before you start

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
<?php

require __DIR__ . '/helpers.php';

echo e('<b>Safe</b>');

The difference is what happens when the file is missing:

StatementFile missingLoaded twice?
includeWarning, script continuesYes
requireFatal error, script stopsYes
include_onceWarning, script continuesNo, skipped the second time
require_onceFatal error, script stopsNo, skipped the second time

Rules of thumb:

  • Use require_once for 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 require for templates such as a header or footer that you deliberately output more than once.
  • include is 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
<?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

Plain text
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
<?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
<?php

return [
    'site_name' => 'My Site',
    'contact_email' => 'hello@example.com',
];

Templates

templates/header.php:

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:

PHP
</main>
<footer>© <?= date('Y') ?> <?= e($config['site_name']) ?></footer>
</body>
</html>

A page that uses everything

public/index.php:

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
<?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
<?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_once for functions, classes and config; require for templates.
  • Build every path from __DIR__.
  • Expose only a public folder; keep config, secrets and source code outside it.
  • Included files share the including script's variables, and a file can return a value.
  • Never build include paths from user input; use an allowlist.

Further reading