stream_wrapper_register în PHP

Stream-uri PHP 4.3.2+

Înregistrează un protocol propriu (de exemplu mem://), implementat de o clasă, pentru fopen, file_get_contents și celelalte.

Sintaxă
stream_wrapper_register(string $protocol, string $class, int $flags = 0): bool

Ce face stream_wrapper_register

Cu stream_wrapper_register poți inventa un tip nou de adresă. După înregistrare, file_get_contents("mem://nota") nu mai citește de pe disc, ci apelează metodele clasei tale: stream_open, stream_read, stream_write, stream_eof, stream_stat și altele, după nevoie.

Se folosește pentru teste (fișiere simulate în memorie), pentru acces la stocare în cloud sau la baze de date cu funcțiile obișnuite de fișier. Numele vechi stream_register_wrapper este un alias.

Parametri

Parametru Descriere
$protocol Numele protocolului, fără ://, de exemplu "mem".
$class Numele clasei care implementează metodele wrapperului.
$flags Opțional. STREAM_IS_URL dacă protocolul este de rețea (atunci se aplică allow_url_fopen).

Ce returnează

true la succes, false dacă protocolul există deja.

Exemple

Exemplul 1: Fișiere ținute în memorie

Clasa păstrează conținutul fiecărui „fișier” într-un tablou static. file_put_contents apelează stream_open și stream_write. file_get_contents apelează stream_open, stream_stat și stream_read până când stream_eof spune că s-a terminat.

<?php
class Memorie
{
    public static array $date = [];
    public $context;
    private string $cheie;
    private int $pozitie = 0;

    public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
    {
        $this->cheie = substr($path, strlen("mem://"));
        if (str_contains($mode, "w") || !isset(self::$date[$this->cheie])) {
            self::$date[$this->cheie] = "";
        }
        return true;
    }

    public function stream_read(int $count): string
    {
        $bucata = substr(self::$date[$this->cheie], $this->pozitie, $count);
        $this->pozitie += strlen($bucata);
        return $bucata;
    }

    public function stream_write(string $data): int
    {
        self::$date[$this->cheie] .= $data;
        return strlen($data);
    }

    public function stream_eof(): bool
    {
        return $this->pozitie >= strlen(self::$date[$this->cheie]);
    }

    public function stream_stat(): array
    {
        return ["size" => strlen(self::$date[$this->cheie])];
    }
}

stream_wrapper_register("mem", "Memorie");

file_put_contents("mem://nota", "Cumpără lapte");
file_put_contents("mem://oras", "Iași");

echo file_get_contents("mem://nota") . "\n";
print_r(Memorie::$date);

Rezultat

Cumpără lapte
Array
(
    [nota] => Cumpără lapte
    [oras] => Iași
)

Exemplul 2: Înregistrare o singură dată

Al doilea apel pentru același protocol ar returna false cu un avertisment. Verifică lista înainte.

<?php
class Gol
{
    public $context;
}

foreach ([1, 2] as $incercare) {
    if (in_array("gol", stream_get_wrappers())) {
        echo "Încercarea $incercare: există deja\n";
        continue;
    }
    var_dump(stream_wrapper_register("gol", "Gol"));
}

Rezultat

bool(true)
Încercarea 2: există deja

Greșeli frecvente

  • Nu declari proprietatea public $context în clasă. PHP o setează singur, iar din PHP 8.2 primești Deprecated: Creation of dynamic property.
  • Nu scrii metoda stream_stat. file_get_contents merge, dar afișează Warning: ... stream_stat is not implemented!. Pentru file_exists și is_file este nevoie de url_stat.
  • Încerci să înregistrezi "file" sau "http" direct. Protocolul există deja; scoate-l mai întâi cu stream_wrapper_unregister.

Comenzi înrudite

  • stream_wrapper_unregister / stream_wrapper_restore: Dezactivează un protocol (de exemplu http) pentru funcțiile de fișier și, cu stream_wrapper_restore, îl readuce.
  • stream_get_wrappers: Returnează lista protocoalelor pe care funcțiile de fișier le înțeleg (file, http, https, php, data, phar…).
  • file_get_contents: Citește tot conținutul unui fișier (sau al unei adrese URL) într-un text.
  • fopen / fclose: Deschide un fișier pentru citire sau scriere și returnează o resursă; fclose îl închide.