In PHP ermöglicht die Funktion Symlink () Entwicklern, einen symbolischen Link zu erstellen, der in vielen Szenarien, wie z. B. das Organisieren von Dateien, das Erstellen von Verknüpfungen oder das Erstellen von virtuellen Dateisystemstrukturen, ähnlich wie Container, sehr nützlich ist. Aufgrund seiner betrieblichen Art des zugrunde liegenden Dateisystems ist es jedoch einfach, Berechtigungsprobleme und sogar Sicherheitsrisiken zu verursachen.
Dieser Artikel führt aus der Perspektive praktischer Anwendungen eingehende Diskussionen über allgemeine Berechtigungsprobleme und -lösungen durch, um Entwicklern dabei zu helfen, diese Funktion sicher und effizient zu nutzen.
$target = '/var/www/html/data/original.txt';
$link = '/var/www/html/data/link.txt';
if (symlink($target, $link)) {
echo 'Symbolverbindungsschöpfung erfolgreich。';
} else {
echo 'Versäumte es, einen symbolischen Link zu erstellen。';
}
Obwohl die Verwendung einfach und klar ist, treten Entwickler häufig auf die folgenden Probleme im tatsächlichen Einsatz auf.
Das häufigste Problem ist, dass Symlink () ohne Fehler auf Eingabeaufforderungen falsch zurückgibt. Die Grundursache ist normalerweise:
Der Benutzer der PHP-Skript-Ausführung (z. B. www-data ) verfügt nicht über geeignete Berechtigungen für die Zieldatei oder sein überlegenes Verzeichnis.
Einige Systeme (insbesondere selinux-fähige Linux-Systeme) begrenzen das Verhalten von Symlink () .
Nicht-Administratorkonten in Windows-Plattformen verfügen nicht über die standardmäßige Erstellung symbolischer Links.
Stellen Sie sicher, dass PHP -Benutzer Berechtigungen auf "Ausführung" und "Schreiben" auf den Zielpfad haben.
Unter Linux können Sie den folgenden Befehl verwenden, um die Berechtigungen zu ändern:
sudo chown -R www-data:www-data /var/www/html/data
sudo chmod -R 755 /var/www/html/data
Überprüfen Sie den Selinux -Status und konfigurieren Sie die entsprechende Richtlinie (z. B. die Verwendung von SetSbool -p httpd_enable_homedirs an ).
Aktivieren Sie den Entwicklermodus in Windows oder führen Sie PHP als Administrator aus.
Überprüfen Sie die Berechtigungen, bevor Sie Symlink () anrufen, um eine blinde Ausführung zu vermeiden:
if (is_writable(dirname($link)) && is_readable($target)) {
symlink($target, $link);
} else {
error_log('Erstellen Sie symbolische Verbindungen ohne ausreichende Berechtigungen');
}
Einige Systeme weigern sich möglicherweise, aufgrund unregelmäßiger Pfade (z. B. der Verwendung relativer Pfade) Links zu erstellen. Sie können RealPath () verwenden, um sicherzustellen, dass der Pfad korrekt ist:
$target = realpath('/var/www/html/data/original.txt');
$link = '/var/www/html/data/link.txt';
Lassen Sie nicht zulassen, dass benutzergesteuerte Pfade direkt an Symlink () teilnehmen, da dies sonst zu beliebigen Dateireferenzangriffen führen kann. Sie können die Whitelist -Überprüfung verwenden, um den Pfad einzuschränken:
$allowedDir = '/var/www/html/data/';
$target = realpath($_POST['path']);
if (strpos($target, $allowedDir) === 0) {
symlink($target, $link);
} else {
die('Illegaler Weg');
}
Verwenden Sie Readlink () oder RealPath (), um das Link -Ziel zu überprüfen und auf sensible Systemdateien wie /etc /passwd zu vermeiden:
$realTarget = realpath($target);
if (strpos($realTarget, '/var/www/html/data/') !== 0) {
die('Illegales Linkziel');
}
Das Erstellen eines Links umfasst Änderungen des Dateisystems. Es wird empfohlen, Protokolle aufzuzeichnen, um die Verfolgung von Ausnahmen zu erleichtern:
file_put_contents('/var/log/link_log.txt', date('c') . " Erstellen Sie einen Link: $link -> $target\n", FILE_APPEND);
Um die Berechtigungsprobleme zu vermeiden, die durch hohe Parallelitäts- oder Rassenbedingungen verursacht werden, können Sie Flock () verwenden, um den Betriebsprozess zu sperren:
$fp = fopen('/tmp/link.lock', 'w+');
if (flock($fp, LOCK_EX)) {
symlink($target, $link);
flock($fp, LOCK_UN);
}
fclose($fp);
Wenn die Umgebung symlink () überhaupt nicht zulässt (z. B. Shared Hosting), können Sie PHP verwenden, um "logische Verknüpfung" zu implementieren und sie durch Sprung oder Proxy zu simulieren:
header('Location: https://gitbox.net/files/original.txt');
exit;
Obwohl diese Methode kein Link auf Systemebene ist, kann sie einige Anforderungen erfüllen und hat keine strengen Anforderungen an Berechtigungen.