link()
Die PHP-Funktion link() erstellt einen Hard Link — einen zweiten Dateisystemeintrag, der auf denselben Inode wie eine vorhandene Datei zeigt.
Die PHP-Funktion link() erstellt einen Hard Link — einen zweiten Dateisystemeintrag, der auf exakt dieselben Daten auf der Festplatte wie eine vorhandene Datei zeigt. Diese Seite erklärt, was ein Hard Link eigentlich ist, die Syntax und den Rückgabewert der Funktion, ein vollständiges ausführbares Beispiel, den Unterschied zu einem symbolischen Link und die Fallstricke, die zu Fehlern führen können.
Was ist die link()-Funktion?
link() erstellt einen Hard Link von einer vorhandenen Datei (dem Ziel) zu einem neuen Namen (dem Link). Ein Hard Link ist weder eine Kopie noch eine Verknüpfung: Es ist ein zweiter Verzeichniseintrag, der auf denselben Inode verweist — das zugrunde liegende Objekt auf der Festplatte, das die Daten und Metadaten einer Datei speichert. Da beide Namen auf denselben Inode zeigen, sind sie vollständig austauschbar: Bearbeitungen über einen Namen ändern auch, was man über den anderen sieht, und die Dateidaten werden erst gelöscht, wenn jeder Hard Link zu ihr entfernt wurde.
Daraus ergeben sich zwei direkte Konsequenzen:
- Hard Links müssen sich auf demselben Dateisystem (derselben Partition) wie das Ziel befinden. Inodes sind lokal für ein Dateisystem, daher können keine Hard Links über Laufwerke oder Einhängepunkte hinweg erstellt werden. Wenn Sie über Dateisysteme hinweg verlinken müssen, verwenden Sie stattdessen einen symbolischen Link — siehe
symlink(). - Verzeichnisse können in der Regel nicht per Hard Link verknüpft werden. Die meisten Betriebssysteme verbieten Hard Links auf Verzeichnisse, um Referenzzyklen im Dateisystembaum zu verhindern.
Syntax
link(string $target, string $link): bool| Parameter | Beschreibung |
|---|---|
$target | Pfad zur vorhandenen Datei, auf die verlinkt werden soll. |
$link | Pfad des neuen Hard Links, der erstellt werden soll (darf noch nicht existieren). |
Die Funktion gibt true bei Erfolg und false bei Fehler zurück und gibt dabei eine E_WARNING aus.
Ein vollständiges, ausführbares Beispiel
Dieses Beispiel erstellt eine Datei, verknüpft sie per Hard Link und beweist dann, dass beide Namen denselben Inode teilen:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
file_put_contents($target, "Hello hard links\n");
if (link($target, $link)) {
echo "Created hard link\n";
}
echo "Same inode? " . (fileinode($target) === fileinode($link) ? "yes" : "no") . "\n";
echo "Link count: " . stat($target)['nlink'] . "\n";
echo "Read via link: " . file_get_contents($link);
unlink($link); // remove only the new name
echo "After unlink, target still exists? " . (file_exists($target) ? "yes" : "no") . "\n";Ausgabe:
Created hard link
Same inode? yes
Link count: 2
Read via link: Hello hard links
After unlink, target still exists? yesBeachten Sie, dass nach link() die Link-Anzahl (nlink) 2 beträgt — der Inode hat jetzt zwei Namen. Das Entfernen eines Namens mit unlink() verringert lediglich diesen Zähler; die Daten bleiben erhalten, bis der Zähler null erreicht. Genau deshalb gibt das Löschen einer per Hard Link verknüpften Datei keinen Speicherplatz frei, wenn noch andere Hard Links vorhanden sind.
Fehler sauber behandeln
Da link() bei einem Fehler eine Warnung ausgibt, unterdrückt man in Produktionscode typischerweise die Warnung mit @ und reagiert auf den Rückgabewert, oder man prüft das Ziel vorher:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
if (file_exists($link)) {
echo "A file already exists at the link path.\n";
} elseif (@link($target, $link)) {
echo "Hard link created.\n";
} else {
echo "Could not create hard link.\n";
}Häufige Gründe, warum link() false zurückgibt:
- Die Zieldatei existiert nicht oder Sie haben keinen Lesezugriff darauf.
- Sie haben keine Schreibberechtigung für das Verzeichnis, in dem der Link erstellt werden soll.
- Der Link-Pfad existiert bereits.
- Ziel und Link befinden sich auf unterschiedlichen Dateisystemen.
- Das Ziel ist ein Verzeichnis (auf den meisten Systemen nicht erlaubt).
Hard Link vs. symbolischer Link
Hard Link (link()) | Symbolischer Link (symlink()) | |
|---|---|---|
| Zeigt auf | Denselben Inode (Daten) | Einen Pfad (einen anderen Dateinamen) |
| Überlebt das Löschen des Originals | Ja — Daten bleiben, bis alle Links entfernt sind | Nein — wird zu einem hängenden Link |
| Kann Dateisysteme überqueren | Nein | Ja |
| Kann ein Verzeichnis verknüpfen | Normalerweise nein | Ja |
| Erkennen mit | stat()['nlink'] > 1 | is_link() |
Wenn Sie wissen möchten, ob ein Pfad ein symbolischer Link ist oder wohin er zeigt, lesen Sie is_link() und readlink(). Um die Metadaten eines Links zu untersuchen, verwenden Sie linkinfo().
Wann sollte ich das verwenden?
Hard Links sind nützlich für Deduplizierung und atomare Dateitausche. Backup-Tools verwenden sie, damit unveränderte Dateien in verschiedenen Snapshots nur einmal auf der Festplatte gespeichert werden. Deployment-Skripte verknüpfen einen neuen Build per Hard Link und benennen ihn dann über den alten Namen, sodass Leser keine halb geschriebene Datei sehen. Für alltägliche „Verknüpfungs"-Anforderungen, die Laufwerke überqueren oder auf Verzeichnisse zeigen, sollte man stattdessen symlink() verwenden.
Fazit
link() erstellt einen Hard Link — einen zweiten Namen für denselben Inode auf demselben Dateisystem. Die Daten bleiben erhalten, bis der letzte Hard Link entfernt wird, Links können keine Dateisysteme überqueren, und Verzeichnisse können in der Regel nicht per Hard Link verknüpft werden. Verwenden Sie das obige ausführbare Beispiel, um das gemeinsame Inode-Verhalten selbst zu sehen, und kombinieren Sie link() mit unlink(), symlink() und is_link() für volle Kontrolle über Dateisystem-Links. Eine umfassendere Übersicht der Dateifunktionen finden Sie im Kapitel PHP Filesystem.