Start · Sprachen · PHP · Referenz · stream_filter_register

stream_filter_register

Funktion

Registriert eine benutzerdefinierte PHP-Klasse als Stream-Filter unter einem angegebenen Namen.

seit PHP 5.0.0 Kategorie: io

Signatur

stream_filter_register(string $filter_name, string $class): bool

Beschreibung

stream_filter_register() erlaubt es, eigene Stream-Filter zu definieren und zu registrieren, indem eine Klasse angegeben wird, die php_user_filter erweitert. Nach der Registrierung kann der Filter mit stream_filter_append(), stream_filter_prepend() oder direkt in einem Stream-Kontext über php://filter verwendet werden.

Die angegebene Klasse muss von php_user_filter erben und mindestens die Methode filter(resource $in, resource $out, int &$consumed, bool $closing): int implementieren. Optional können onCreate() und onClose() überschrieben werden, um Initialisierungs- und Aufräumarbeiten durchzuführen.

Stream-Filter sind besonders nützlich, wenn Datenstromtransformationen wie Verschlüsselung, Komprimierung, Zeichensatzkonvertierung oder benutzerdefinierte Protokollierung transparent in Lese- und Schreiboperationen auf Streams eingebettet werden sollen – ohne die eigentliche I/O-Logik zu verändern.

Ein Filter-Name kann Wildcards enthalten (z. B. myapp.*), sodass mehrere verwandte Filter mit einer einzigen Klasse bedient werden können; der konkret angeforderte Name ist dann über $this->filtername in der Filterklasse abrufbar.

Parameter

Name Typ Default Beschreibung
$filter_name Pflicht string Der Name, unter dem der Filter registriert wird (z. B. myfilter oder myapp.*). Dieser Name wird später beim Anhängen des Filters angegeben.
$class Pflicht string Der vollständige Klassenname (als String) der Filter-Implementierung. Die Klasse muss php_user_filter erweitern und die filter()-Methode implementieren.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn der Filter erfolgreich registriert wurde. Gibt false zurück, wenn der angegebene filter_name bereits registriert ist oder die Klasse nicht existiert.

Beispiele

Einfacher ROT13-Stream-Filter

<?php
class Rot13Filter extends php_user_filter
{
    public function filter($in, $out, &$consumed, $closing): int
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            $bucket->data = str_rot13($bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

// Filter registrieren
stream_filter_register('rot13.transform', 'Rot13Filter');

// Filter auf einen Datei-Stream anwenden
$fp = fopen('php://temp', 'w+');
stream_filter_append($fp, 'rot13.transform');

fwrite($fp, 'Hallo Welt');
rewind($fp);
echo fread($fp, 100); // Ausgabe: Unyyb Jryg
fclose($fp);
Unyyb Jryg

Wildcard-Filter mit Parameterzugriff über php://filter

<?php
class PrefixFilter extends php_user_filter
{
    private string $prefix = '';

    public function onCreate(): bool
    {
        // Konkreten Filternamen auswerten, z. B. 'prefix.INFO'
        $parts = explode('.', $this->filtername, 2);
        $this->prefix = isset($parts[1]) ? '[' . $parts[1] . '] ' : '[LOG] ';
        return true;
    }

    public function filter($in, $out, &$consumed, $closing): int
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            $lines = explode("\n", $bucket->data);
            $bucket->data = implode("\n", array_map(
                fn($line) => $line !== '' ? $this->prefix . $line : $line,
                $lines
            ));
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

stream_filter_register('prefix.*', 'PrefixFilter');

// Über php://filter-URL verwenden
$url = 'php://filter/write=prefix.WARNING/resource=php://output';
$fp = fopen($url, 'w');
fwrite($fp, "Speicher fast voll\nBitte prüfen");
fclose($fp);
[WARNING] Speicher fast voll [WARNING] Bitte prüfen

// Wichtig · Fallstricke

Doppelte Registrierung: Ein bereits registrierter Filtername kann nicht erneut registriert werden; stream_filter_register() gibt dann false zurück. Mit stream_get_filters() lässt sich prüfen, welche Filter bereits registriert sind.

Bucket-Brigade: Die Methode filter() arbeitet mit Bucket-Brigaden (stream_bucket_make_writeable(), stream_bucket_append()). Der Rückgabewert muss eine der Konstanten PSFS_PASS_ON, PSFS_FEED_ME oder PSFS_ERR_FATAL sein.

Autoloading: Die Filterklasse muss zum Zeitpunkt des Aufrufs von stream_filter_register() bereits geladen oder über Autoloading verfügbar sein. Es empfiehlt sich, die Registrierung früh im Bootstrap-Prozess durchzuführen.

Sicherheit: Eigene Stream-Filter, die Benutzerdaten verarbeiten, sollten niemals unkontrolliert Daten durchleiten – Validierung und Sanitierung der Daten im Filter sind Pflicht, um Injection-Angriffe zu verhindern.