Signatur
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
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);
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);
// 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.