Start · Sprachen · PHP · Referenz · shmop_read

shmop_read

Funktion

Liest eine Anzahl von Bytes aus einem gemeinsamen Speicherbereich (Shared Memory) und gibt sie als String zurück.

seit PHP 4.0.4 Kategorie: misc

Signatur

shmop_read(Shmop $shmop, int $offset, int $size): string|false

Beschreibung

shmop_read() ermöglicht das Lesen von Daten aus einem zuvor mit shmop_open() geöffneten Shared-Memory-Block. Der Zugriff erfolgt byteweise, beginnend ab einem definierten Offset, und liefert die gewünschte Anzahl an Bytes als PHP-String zurück.

Shared Memory eignet sich besonders für den schnellen, prozessübergreifenden Datenaustausch auf demselben Server, ohne den Overhead einer Datenbankverbindung oder eines Netzwerk-Sockets. Typische Anwendungsfälle sind Caching-Mechanismen, gemeinsame Konfigurationsdaten oder Statusflags zwischen mehreren PHP-Prozessen (z. B. unter einem Web-Server mit mehreren Worker-Prozessen).

Der gelesene Inhalt ist ein roher Byte-String. Sollen komplexe Datenstrukturen gespeichert werden, müssen diese vorher serialisiert (z. B. mit serialize() oder json_encode()) und nach dem Lesen entsprechend deserialisiert werden.

Ab PHP 8.0 wird das erste Argument als Shmop-Objekt übergeben; in früheren Versionen war es eine Ressource.

Parameter

Name Typ Default Beschreibung
$shmop Pflicht Shmop Das Shmop-Objekt (vor PHP 8.0: eine Ressource), das von shmop_open() zurückgegeben wurde.
$offset Pflicht int Byte-Offset, ab dem im Shared-Memory-Block mit dem Lesen begonnen wird. Muss >= 0 sein und innerhalb des Blocks liegen.
$size Pflicht int Anzahl der zu lesenden Bytes. Darf die Größe des Blocks (abzüglich des Offsets) nicht überschreiten. Der Wert 0 liest bis zum Ende des Blocks.

Rückgabewert

Typ
string|false
Beschreibung
Gibt die gelesenen Daten als String zurück. Bei einem Fehler (z. B. ungültiger Offset oder Größe) wird false zurückgegeben.

Beispiele

Einfaches Schreiben und Lesen aus Shared Memory

<?php
// Shared-Memory-Block erstellen oder öffnen (Key, Flags, Modus, Größe)
$shmId = shmop_open(0x1234, 'c', 0644, 100);

if ($shmId === false) {
    die('Shared-Memory-Block konnte nicht erstellt werden.');
}

$data = 'Hallo Shared Memory!';
$written = shmop_write($shmId, $data, 0);

if ($written === false) {
    die('Schreiben fehlgeschlagen.');
}

// Daten ab Offset 0 lesen, 20 Bytes
$result = shmop_read($shmId, 0, strlen($data));

if ($result === false) {
    die('Lesen fehlgeschlagen.');
}

echo $result . PHP_EOL;

shmop_close($shmId);
Hallo Shared Memory!

Serialisierte PHP-Daten im Shared Memory speichern und lesen

<?php
$key = ftok(__FILE__, 't');
$payload = serialize(['status' => 'aktiv', 'timestamp' => time()]);

// Block mit passender Größe anlegen
$shmId = shmop_open($key, 'c', 0644, 256);

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

// Länge voranstellen, damit wir beim Lesen genau wissen, wieviel Bytes zu lesen sind
$len = strlen($payload);
shmop_write($shmId, pack('N', $len) . $payload, 0);

// Länge auslesen (4 Bytes, Big-Endian-Integer)
$header = shmop_read($shmId, 0, 4);
$dataLen = unpack('N', $header)[1];

// Eigentliche Daten lesen
$raw = shmop_read($shmId, 4, $dataLen);
$data = unserialize($raw);

echo 'Status: ' . $data['status'] . PHP_EOL;

shmop_close($shmId);
Status: aktiv

// Wichtig · Fallstricke

Sicherheit: Shared-Memory-Blöcke sind für alle Prozesse auf dem System zugänglich, die denselben Key kennen und ausreichende Berechtigungen besitzen. Sensible Daten (Passwörter, Tokens) sollten niemals unverschlüsselt in Shared Memory abgelegt werden.

Deserialisierung: Das Deserialisieren von Daten, die aus einem gemeinsam genutzten Speicher kommen und potenziell von einem anderen Prozess geschrieben wurden, birgt Sicherheitsrisiken (Remote Code Execution über unserialize()). Im Zweifelsfall json_decode()/json_encode() verwenden.

Race Conditions: Ohne explizite Synchronisation (z. B. mit Semaphoren via sem_acquire()) können Race Conditions auftreten, wenn mehrere Prozesse gleichzeitig lesen und schreiben.

Größe: Das Lesen über die Blockgröße hinaus schlägt fehl und gibt false zurück. Die Größe des Blocks kann mit shmop_size() ermittelt werden.