PHP: Was ist der Unterschied zwischen require und include?

Zum Einbinden einer Datei gibt es in PHP gleich vier Konstrukte. Dahinter stecken aber nur zwei voneinander unabhängige Entscheidungen.

Die zwei Entscheidungen

  1. require oder include — was passiert, wenn die Datei fehlt?
  2. mit oder ohne _once — darf dieselbe Datei mehrfach eingebunden werden?

Alles andere ist identisch. Die vier Kombinationen ergeben die vier Konstrukte.

require oder include

Der Unterschied zeigt sich nur im Fehlerfall. Binden wir eine Datei ein, die es nicht gibt.

Mit include:

Warning: include(gibt-es-nicht.php): Failed to open stream:
No such file or directory in /app/mit-include.php on line 2

Nach include: das Skript laeuft weiter
(exit code: 0)

Mit require:

Warning: require(gibt-es-nicht.php): Failed to open stream:
No such file or directory in /app/mit-require.php on line 2

Fatal error: Uncaught Error: Failed opening required 'gibt-es-nicht.php'
in /app/mit-require.php:2
(exit code: 255)

include gibt eine Warnung aus und macht weiter. require bricht ab. Der Exit-Code zeigt den Unterschied deutlich: einmal 0, einmal 255.

Daraus ergibt sich die Faustregel: require für alles, ohne das es nicht weitergeht — Klassen, Konfiguration, der Autoloader. include nur für Optionales, etwa ein Werbebanner oder ein Template-Fragment, dessen Fehlen die Seite nicht kaputt macht.

Im Zweifel require. Eine halb geladene Anwendung, die munter weiterläuft, ist schwerer zu debuggen als ein sauberer Abbruch.

Mit oder ohne _once

Die _once-Varianten binden eine Datei nur dann ein, wenn das nicht bereits geschehen ist:

1. include:            [zaehler.php wurde eingebunden]
2. include (nochmal):  [zaehler.php wurde eingebunden]
3. include_once:       (nichts)
4. include_once:       (nichts)

Interessant ist Zeile 3. Das ist das erste include_once, trotzdem passiert nichts. Der Grund: Die Prüfung bezieht sich auf die Datei, nicht auf das Konstrukt. Sie wurde vorher schon zweimal per include geladen, also gilt sie als eingebunden.

Warum das wichtig ist

Solange eine Datei nur etwas ausgibt, ist mehrfaches Einbinden harmlos. Sobald sie aber eine Funktion oder eine Klasse definiert, ist es ein fataler Fehler:

<?php
  include 'lib.php';
  include 'lib.php';   // definiert begruessung() ein zweites Mal
?>
Fatal error: Cannot redeclare function begruessung()
(previously declared in /app/lib.php:3)

Genau dafür gibt es die _once-Varianten. Bei Dateien, die Funktionen oder Klassen enthalten, nimmst du also require_once.

Eingebundene Dateien können etwas zurückgeben

Das ist ein Detail, das viele nicht kennen, und die Grundlage für ein sehr verbreitetes Muster. Eine eingebundene Datei kann mit return einen Wert liefern:

<?php
  // config.php
  return [
    'host' => 'localhost',
    'port' => 3306,
  ];
?>

Und an der Aufrufstelle:

<?php
  $config = include 'config.php';
  echo $config['host'];   // localhost
?>
Aus nur-array.php: array (
  'host' => 'localhost',
  'port' => 3306,
)

Das ist deutlich sauberer, als in der eingebundenen Datei eine globale Variable zu setzen und zu hoffen, dass sie niemand überschreibt. Praktisch alle modernen Frameworks lesen ihre Konfiguration so ein.

Brauche ich das heute überhaupt noch?

Ehrlich gesagt: kaum noch. Seit es Autoloading gibt, bindet man Klassen nicht mehr von Hand ein. In einem Projekt mit Composer steht in aller Regel genau ein require im ganzen Anwendungscode:

<?php
  require_once __DIR__ . '/vendor/autoload.php';
?>

Alles Weitere lädt der Autoloader bei Bedarf nach. __DIR__ ist dabei wichtig, damit der Pfad unabhängig vom Arbeitsverzeichnis stimmt.

Übrig bleiben die Konfigurationsdateien von oben und gelegentlich ein Template-Fragment.

Zusammenfassung

  • require bricht ab, include macht weiter — Exit-Code 255 gegen 0.
  • Im Zweifel require.
  • _once immer dann, wenn die Datei Funktionen oder Klassen definiert.
  • include_once prüft die Datei, nicht das verwendete Konstrukt.
  • Eine eingebundene Datei kann per return einen Wert liefern — das übliche Muster für Konfiguration.
  • Mit Composer brauchst du im Normalfall nur ein einziges require_once.

Hinweis zu Netcup (Werbung)

Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).