Disk I/O in PHP verbessern

Heute möchte ich eine Möglichkeit vorstellen, wie in PHP-Anwendungen die Zugriffe auf das Dateisystem optimiert werden können und dabei eine mögliche Race-Conditions eleminiert wird ….

Oft steht man in seiner PHP-Anwendung vor der Problematik, dass man auf Dateien im Dateisystem zugreifen muss. Sehr oft wird hierbei neben der Prüfung, ob die Datei existiert, auch der Zeitpunkt der letzten Änderung erfragt:

$filePath = "/tmp/example.txt";
$fileExists = file_exists($filePath);
$fileMtime = null;
if ($fileExists) {
   $fileMtime = filemtime($filePath);
}

Neben dem doppelten Zugriff auf das Dateisystem birgt dieses Vorgehen noch die Gefahr einer möglichen Race-Condition. Sollte ein zweiter Prozess in der Zwischenzeit die Datei gelöscht haben, so würde filemtime() trotzdem mit einem E_WARNING fehlschlagen.

Für die Race-Condition bietet PHP zwar den silence-Operator @, der zwar verhindert, dass der Aufruf von filemtime() nun einen Fehler wirft, das Problem mit den doppelten Zugriffen auf das Dateisystem besteht aber weiterhin:

$filePath = "/tmp/example.txt";
$fileExists = file_exists($filePath);
$fileMtime = null;
if ($fileExists) {
   $fileMtime = @filemtime($filePath);
}

Um jetzt noch die Anzahl der Dateisystem-Zugriffe zu optimieren, können wir uns den silence-Operator zu Nutze machen, da filemtime() normalerweise false zurückliefert, wenn die zu überprüfende Datei nicht existiert, kann der Aufruf von file_exists() weggelassen werden:

$filePath = "/tmp/example.txt";
$fileMtime = @filemtime($filePath);
$fileExists = !!$fileMtime;