Die Funktion mkdir() gehört zu den grundlegenden Werkzeugen für die Arbeit mit dem Dateisystem in PHP. Sie erstellt ein einzelnes Verzeichnis oder mit dem Rekursiv-Flag eine ganze Ordnerstruktur auf einmal. Dabei lassen sich über oktale Werte gezielt Berechtigungen vergeben, sodass der Webserver und andere Benutzer genau die Rechte erhalten, die sie benötigen. Dieser Artikel erklärt die Syntax von mkdir(), zeigt den Umgang mit Berechtigungen und Umask und liefert praxisnahe Beispiele für den Einsatz in PHP-Projekten.

Los geht es mit der vollständigen Syntax der Funktion und einer Erklärung aller verfügbaren Parameter.
Syntax und Parameter von mkdir()
Die Funktion mkdir() akzeptiert bis zu vier Parameter. Jeder dieser Parameter steuert einen bestimmten Aspekt der Verzeichniserstellung.
<?php
mkdir(
string $directory,
int $permissions = 0777,
bool $recursive = false,
?resource $context = null
): bool
Pfadname (pathname)
Der erste Parameter gibt den Pfad des zu erstellenden Verzeichnisses an. Dieser kann als absoluter Pfad wie /var/www/html/uploads oder als relativer Pfad wie uploads/bilder angegeben werden. PHP interpretiert relative Pfade ausgehend vom aktuellen Arbeitsverzeichnis.
Berechtigungen (permissions)
Der zweite Parameter legt die Zugriffsrechte als oktalen Wert fest. Der Standardwert ist 0777, was Lese-, Schreib- und Ausführungsrechte für alle Benutzergruppen bedeutet. In der Praxis wird dieser Wert durch die Umask des Systems weiter eingeschränkt. Gängige Werte sind 0755 für öffentlich lesbare Verzeichnisse und 0700 für rein private Ordner.
Rekursiv-Flag
Der dritte Parameter bestimmt, ob mkdir() verschachtelte Verzeichnisse auf einmal erstellen soll. Ist er auf true gesetzt, legt PHP alle fehlenden übergeordneten Ordner automatisch an. Bei false schlägt der Aufruf fehl, wenn ein übergeordnetes Verzeichnis nicht existiert.
Stream-Kontext
Der vierte Parameter ermöglicht die Übergabe eines Stream-Kontexts. Dieser wird nur in speziellen Szenarien benötigt, etwa bei der Arbeit mit benutzerdefinierten Stream-Wrappern. Für die meisten Anwendungsfälle kann dieser Parameter weggelassen werden.
Ein einfaches Verzeichnis erstellen
Der einfachste Anwendungsfall von mkdir() ist das Erstellen eines einzelnen Ordners. Die Funktion gibt true bei Erfolg und false bei einem Fehler zurück.
<?php
$pfad = 'uploads';
$ergebnis = mkdir($pfad, 0755);
if ($ergebnis) {
echo 'Verzeichnis erfolgreich erstellt.';
} else {
echo 'Verzeichnis konnte nicht erstellt werden.';
}
In diesem Beispiel entsteht ein Ordner namens uploads im aktuellen Arbeitsverzeichnis. Die Berechtigung 0755 erlaubt dem Eigentümer vollen Zugriff, während andere Benutzer nur lesen und das Verzeichnis betreten dürfen.
Berechtigungen verstehen (Umask und oktale Werte)
Die tatsächlichen Rechte eines neu erstellten Verzeichnisses hängen nicht allein vom übergebenen Wert ab. Das Betriebssystem wendet zusätzlich die Umask an, die bestimmte Bits entfernt. Bei einer typischen Umask von 0022 wird aus 0777 der effektive Wert 0755.
graph LR
A["mkdir 0777"] --> B["Umask 0022"]
B --> C["Effektiv 0755"]
D["mkdir 0755"] --> E["Umask 0022"]
E --> F["Effektiv 0755"]
G["mkdir 0700"] --> H["Umask 0022"]
H --> I["Effektiv 0700"]
Um die gewünschten Rechte unabhängig von der Umask zu setzen, kann chmod() nach dem Erstellen aufgerufen werden.
<?php
$pfad = 'daten';
mkdir($pfad);
chmod($pfad, 0777);
echo 'Verzeichnis mit vollen Rechten erstellt.';
Durch den nachträglichen Aufruf von chmod() werden die Rechte exakt auf 0777 gesetzt, ohne dass die Umask den Wert verändert.
Verschachtelte Verzeichnisse rekursiv erstellen
Wenn mehrere Ebenen auf einmal entstehen sollen, muss das Rekursiv-Flag auf true gesetzt werden. Ohne dieses Flag scheitert mkdir(), sobald ein übergeordneter Ordner fehlt.
<?php
$pfad = 'projekt/module/templates';
$ergebnis = mkdir($pfad, 0755, true);
if ($ergebnis) {
echo 'Alle Verzeichnisse wurden erstellt.';
} else {
echo 'Fehler beim Erstellen der Verzeichnisse.';
}
PHP legt hier zunächst den Ordner projekt an, dann darin module und schließlich templates. Das erspart mehrere einzelne mkdir()-Aufrufe und macht den Code deutlich übersichtlicher.
Prüfen, ob ein Verzeichnis existiert
Vor dem Erstellen eines Verzeichnisses sollte geprüft werden, ob es bereits vorhanden ist. PHP bietet dafür die Funktionen is_dir() und file_exists() an.
<?php
$pfad = 'cache/images';
if (!is_dir($pfad)) {
mkdir($pfad, 0755, true);
echo 'Verzeichnis wurde angelegt.';
} else {
echo 'Verzeichnis existiert bereits.';
}
Die Funktion is_dir() eignet sich besser als file_exists(), weil sie gezielt prüft, ob der Pfad ein Verzeichnis ist. Eine gleichnamige Datei würde von file_exists() ebenfalls erkannt, was zu Verwirrung führen kann.
Fehlerbehandlung
Beim Erstellen von Verzeichnissen können verschiedene Fehler auftreten. Eine saubere Fehlerbehandlung verhindert unerwartetes Verhalten der Anwendung.
Permission Denied
Dieser Fehler tritt auf, wenn der Webserver-User (häufig www-data bei Apache) keine Schreibrechte im Zielverzeichnis besitzt. Der übergeordnete Ordner muss dem Webserver das Schreiben erlauben.
<?php
$pfad = '/var/www/html/uploads/neu';
if (!is_writable(dirname($pfad))) {
echo 'Keine Schreibrechte im Zielverzeichnis.';
} else {
if (mkdir($pfad, 0755)) {
echo 'Verzeichnis erstellt.';
} else {
echo 'Unbekannter Fehler beim Erstellen.';
}
}
Die Funktion is_writable() prüft vorab, ob der übergeordnete Ordner beschreibbar ist. So lässt sich eine hilfreiche Fehlermeldung ausgeben, bevor mkdir() überhaupt aufgerufen wird.
Verzeichnis existiert bereits
Wird mkdir() auf ein bereits vorhandenes Verzeichnis angewendet, gibt die Funktion false zurück und PHP erzeugt eine Warnung. Die vorherige Prüfung mit is_dir() verhindert dieses Problem zuverlässig.
mkdir() in der Praxis (Upload-Ordner und Datumsverzeichnisse)
Ein häufiger Anwendungsfall ist die automatische Erstellung von Upload-Ordnern, die nach Datum strukturiert sind. So lassen sich hochgeladene Dateien übersichtlich organisieren.
<?php
$basisPfad = 'uploads';
$jahr = date('Y');
$monat = date('m');
$tag = date('d');
$pfad = $basisPfad . '/' . $jahr . '/' . $monat . '/' . $tag;
if (!is_dir($pfad)) {
mkdir($pfad, 0755, true);
}
$dateiname = $pfad . '/' . uniqid() . '.jpg';
/* Beispiel: Hochgeladene Datei in den Tagesordner verschieben */
/* move_uploaded_file($_FILES['bild']['tmp_name'], $dateiname); */
echo 'Datei gespeichert unter: ' . $dateiname;
Dieses Muster erzeugt eine Struktur wie uploads/2026/03/06 und eignet sich hervorragend für Anwendungen mit vielen hochgeladenen Dateien. Die Kombination aus is_dir() und mkdir() mit dem Rekursiv-Flag stellt sicher, dass alle benötigten Unterordner automatisch entstehen, ohne dass Fehler auftreten, wenn Teile der Struktur bereits vorhanden sind.
Neben Upload-Ordnern ist dieses Vorgehen auch für Cache-Verzeichnisse, temporäre Dateien und Log-Ordner geeignet. Der Webserver-Benutzer muss in jedem Fall Schreibrechte auf den Basisordner besitzen.
Fazit
Die Funktion mkdir() ist ein unverzichtbares Werkzeug für die Arbeit mit dem Dateisystem in PHP. Mit dem Rekursiv-Flag lassen sich verschachtelte Verzeichnisstrukturen in einem einzigen Aufruf erstellen. Die Berechtigungen sollten stets bewusst gewählt werden, wobei 0755 für die meisten Webserver-Szenarien ein sinnvoller Standardwert ist. Die Prüfung mit is_dir() vor dem Erstellen und die Kontrolle der Schreibrechte mit is_writable() sorgen für robusten Code. In Kombination mit chmod() lassen sich auch Berechtigungen setzen, die von der Umask unabhängig sind.