Signatur
Beschreibung
ftok() ist die PHP-Entsprechung der gleichnamigen POSIX-C-Funktion und erzeugt einen eindeutigen ganzzahligen Schlüssel, der für die System-V-IPC-Mechanismen benötigt wird. Dieser Schlüssel dient als gemeinsamer Bezeichner, über den verschiedene Prozesse auf dieselbe Shared-Memory-Ressource, dieselbe Semaphore oder dieselbe Message Queue zugreifen können.
Die Funktion kombiniert Inode-Nummer und Gerätekennzahl der angegebenen Datei mit dem einstelligen Projektbezeichner zu einem int-Schlüssel. Zwei Aufrufe mit demselben existierenden Pfad und demselben Projektbezeichner liefern daher stets denselben Schlüssel – solange die Datei nicht gelöscht und neu erstellt wird (wodurch sich die Inode ändern würde).
Typischer Anwendungsfall ist die Koordination mehrerer PHP-Prozesse oder -Worker über Shared Memory (shmop_open, shm_attach) oder Semaphoren (sem_get). Die Funktion ist ausschließlich auf Unix-/Linux-Systemen verfügbar; unter Windows ist sie nicht implementiert.
- Die Datei muss existieren und für den aufrufenden Prozess lesbar sein.
- Der Projektbezeichner muss genau ein ASCII-Zeichen sein (intern wird nur das erste Byte verwendet).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $filename Pflicht | string | Absoluter oder relativer Pfad zu einer existierenden Datei. Die Datei muss zugänglich sein, da ihre Inode-Nummer und Gerätekennzahl in den Schlüssel einfließen. | |
| $proj Pflicht | string | Einstelliger Projektbezeichner (ein ASCII-Zeichen, z. B. 'a'). Nur das erste Byte des Strings wird verwendet. |
Rückgabewert
int zurück. Im Fehlerfall (Datei nicht vorhanden, nicht zugänglich) wird -1 zurückgegeben.Beispiele
Shared-Memory-Segment über ftok-Schlüssel öffnen
<?php
// Gemeinsame Lock-Datei, die alle beteiligten Prozesse kennen
$lockFile = '/tmp/myapp.lock';
// Datei anlegen, falls sie noch nicht existiert
if (!file_exists($lockFile)) {
touch($lockFile);
}
// IPC-Schlüssel erzeugen
$key = ftok($lockFile, 'A');
if ($key === -1) {
die('ftok fehlgeschlagen – Datei nicht erreichbar.');
}
echo 'IPC-Schlüssel: ' . $key . PHP_EOL;
// Shared-Memory-Segment anlegen oder öffnen (4 KB)
$shm = shmop_open($key, 'c', 0644, 4096);
if ($shm === false) {
die('Shared Memory konnte nicht geöffnet werden.');
}
// Wert schreiben
shmop_write($shm, 'Hallo IPC', 0);
// Wert lesen
$data = shmop_read($shm, 0, 9);
echo 'Gelesener Wert: ' . $data . PHP_EOL;
shmop_close($shm);
Semaphore mit ftok-Schlüssel für Prozess-Synchronisation
<?php
$lockFile = '/tmp/myapp.lock';
touch($lockFile);
$key = ftok($lockFile, 'S');
if ($key === -1) {
die('ftok fehlgeschlagen.');
}
// Semaphore anlegen: 1 Token, automatisch freigeben beim Prozessende
$semId = sem_get($key, 1, 0644, 1);
if ($semId === false) {
die('Semaphore konnte nicht erstellt werden.');
}
echo 'Warte auf Semaphore ...' . PHP_EOL;
sem_acquire($semId);
echo 'Kritischer Abschnitt betreten.' . PHP_EOL;
// ... kritischer Abschnitt ...
sleep(1);
sem_release($semId);
echo 'Semaphore freigegeben.' . PHP_EOL;
// Wichtig · Fallstricke
Nur Unix/Linux: ftok() ist auf Windows-Systemen nicht verfügbar. Skripte, die diese Funktion verwenden, sind daher nicht portabel.
Schlüssel-Kollisionen: Der erzeugte Schlüssel ist nicht zwingend systemweit eindeutig. Zwei unterschiedliche Dateipfade können theoretisch denselben Schlüssel ergeben, wenn Inode-Nummer, Gerätekennzahl und Projektbezeichner übereinstimmen. Für zuverlässige Eindeutigkeit sollte eine bekannte, kontrollierte Datei verwendet werden.
Inode-Stabilität: Wird die Datei gelöscht und neu erstellt (z. B. durch Log-Rotation), ändert sich die Inode und damit der Schlüssel. Laufende Prozesse greifen dann möglicherweise auf unterschiedliche IPC-Ressourcen zu.
Rückgabewert prüfen: Immer auf -1 prüfen, da ein nicht erreichbarer Dateipfad silent einen ungültigen Schlüssel liefert, der folgende IPC-Aufrufe zum Fehlschlagen bringt.