Start · Sprachen · PHP · Referenz · Shmop

Shmop

Klasse

Repräsentiert ein POSIX-Shared-Memory-Segment und ermöglicht prozessübergreifenden Datenaustausch über gemeinsamen Hauptspeicher.

seit PHP 8.0.0 Kategorie: misc

Signatur

class Shmop

Beschreibung

Shmop ist eine interne PHP-Klasse, die seit PHP 8.0 als Objekt-Wrapper für POSIX-Shared-Memory-Segmente dient. Vor PHP 8.0 wurden Shared-Memory-Handles als Ressource (resource) zurückgegeben; seit PHP 8.0 liefern die shmop_*-Funktionen stattdessen Instanzen dieser Klasse.

Shared Memory erlaubt es mehreren Prozessen (z. B. mehreren PHP-Worker-Prozessen hinter einem Webserver), auf denselben Speicherbereich zuzugreifen, ohne Daten über Dateien, Datenbanken oder Sockets übertragen zu müssen. Dies macht es ideal für hochperformante Inter-Prozess-Kommunikation (IPC) und gemeinsam genutzte Caches.

Ein Shmop-Objekt wird ausschließlich durch shmop_open() erzeugt. Es kann nicht manuell instanziiert werden. Über das Objekt lassen sich anschließend shmop_read(), shmop_write(), shmop_size() und shmop_delete() aufrufen. Wird das Objekt nicht mehr referenziert, schließt PHP das Segment automatisch (entspricht shmop_close()).

Die Klasse implementiert keine öffentlichen Methoden oder Properties; sie dient lediglich als typsicherer Container für das interne Handle. Alle Operationen erfolgen über die prozeduralen shmop_*-Funktionen, denen das Objekt als erstes Argument übergeben wird.

Beispiele

Shared-Memory-Segment erstellen, beschreiben und lesen

<?php
// Segment erstellen (oder öffnen, falls vorhanden)
// shmop_open(key, flags, mode, size)
// 'c' = create or open; 0644 = Zugriffsrechte; 1024 = Größe in Byte
$shm = shmop_open(0x1A2B3C4D, 'c', 0644, 1024);

if ($shm === false) {
    die('Shared Memory konnte nicht geöffnet werden.');
}

// Daten in das Segment schreiben
$data = 'Hallo, Shared Memory!';
shmop_write($shm, $data, 0);

// Daten lesen (Offset 0, Länge = Länge der gespeicherten Zeichenkette)
$gelesen = shmop_read($shm, 0, strlen($data));
echo $gelesen . PHP_EOL;

// Größe des Segments ermitteln
echo 'Segmentgröße: ' . shmop_size($shm) . ' Byte' . PHP_EOL;

// Segment löschen und schließen
shmop_delete($shm);
// $shm wird am Ende des Scopes automatisch geschlossen
Hallo, Shared Memory! Segmentgröße: 1024 Byte

Daten zwischen zwei PHP-Prozessen austauschen

<?php
// Prozess A: Schreibt Daten in das Shared-Memory-Segment
$key = ftok(__FILE__, 'R'); // Schlüssel aus Dateiname ableiten

$shm = shmop_open($key, 'c', 0644, 256);
if ($shm === false) {
    die('Segment konnte nicht erstellt werden.');
}

$payload = json_encode(['status' => 'bereit', 'wert' => 42]);
shmop_write($shm, str_pad($payload, 256, "\0"), 0);
echo 'Prozess A hat geschrieben: ' . $payload . PHP_EOL;

// -- In einem anderen PHP-Prozess (Prozess B) --
$shmB = shmop_open($key, 'w', 0, 0); // 'w' = nur öffnen, nicht anlegen
if ($shmB === false) {
    die('Segment nicht gefunden.');
}

$raw   = shmop_read($shmB, 0, 256);
$daten = json_decode(rtrim($raw, "\0"), true);
echo 'Prozess B hat gelesen: status=' . $daten['status'] . ', wert=' . $daten['wert'] . PHP_EOL;

shmop_delete($shmB);
Prozess A hat geschrieben: {"status":"bereit","wert":42} Prozess B hat gelesen: status=bereit, wert=42

// Wichtig · Fallstricke

Ressource vs. Objekt: Vor PHP 8.0 lieferten die shmop_*-Funktionen einen resource-Wert. Code, der is_resource() prüfte, muss für PHP 8.0+ auf $shm instanceof Shmop umgestellt werden.

Speicherlecks & Betriebssystem-Limits: Shared-Memory-Segmente existieren im Kernel, bis sie explizit mit shmop_delete() entfernt werden – auch nach Beendigung des PHP-Prozesses. Nicht gelöschte Segmente belegen dauerhaft Systemressourcen und können unter Linux mit ipcs -m / ipcrm -m inspiziert und entfernt werden.

Synchronisation: Shmop bietet keine eingebaute Synchronisation. Bei gleichzeitigem Schreiben aus mehreren Prozessen müssen externe Sperrmechanismen (z. B. sem_get()/sem_acquire() aus der Semaphore-Erweiterung) eingesetzt werden, um Race Conditions zu vermeiden.

Sicherheit: Shared-Memory-Schlüssel sollten nicht aus Benutzereingaben abgeleitet werden. Der Schlüssel sollte konstant und anwendungsspezifisch sein, um unbeabsichtigten Zugriff durch andere Prozesse zu verhindern.