stream_copy_to_stream în PHP

Stream-uri PHP 5.0+

Copiază datele dintr-un stream în altul, pe bucăți, fără să încarce tot conținutul în memorie.

Sintaxă
stream_copy_to_stream($from, $to, ?int $length = null, int $offset = 0): int|false

Ce face stream_copy_to_stream

stream_copy_to_stream citește din $from și scrie în $to până la final. Datele trec prin memorie în bucăți mici, așa că poți copia și fișiere de câțiva GB fără să depășești memory_limit.

Merge între orice tipuri de stream: fișier către fișier, fișier către arhivă compress.zlib://, răspuns HTTP către fișier, ieșirea unui proces către php://output.

Parametri

Parametru Descriere
$from Stream-ul sursă, deschis pentru citire.
$to Stream-ul destinație, deschis pentru scriere.
$length Opțional. Câți octeți să copieze. null înseamnă tot.
$offset Opțional. Poziția din sursă de la care începe copierea.

Ce returnează

Numărul de octeți copiați sau false la eroare.

Exemple

Exemplul 1: Copierea unui fișier

<?php
file_put_contents("raport.txt", "Vânzări octombrie: 12.400 lei\n");

$sursa = fopen("raport.txt", "r");
$copie = fopen("raport-copie.txt", "w");
$octeti = stream_copy_to_stream($sursa, $copie);
fclose($sursa);
fclose($copie);

echo "Copiați: $octeti octeți\n";
echo file_get_contents("raport-copie.txt");

Rezultat

Copiați: 32 octeți
Vânzări octombrie: 12.400 lei

Exemplul 2: Arhivare gzip din mers

Destinația este un fișier deschis prin compress.zlib://, deci datele sunt comprimate pe măsură ce se scriu. Citirea prin același wrapper le decomprimă.

<?php
file_put_contents("jurnal.log", str_repeat("2026-10-19 cerere OK\n", 500));

$sursa = fopen("jurnal.log", "r");
$arhiva = fopen("compress.zlib://jurnal.log.gz", "w");
stream_copy_to_stream($sursa, $arhiva);
fclose($sursa);
fclose($arhiva);

echo "Original: " . filesize("jurnal.log") . " octeți\n";
echo "Arhivă mai mică: " . (filesize("jurnal.log.gz") < 1000 ? "da" : "nu") . "\n";
echo "Prima linie: " . strtok(file_get_contents("compress.zlib://jurnal.log.gz"), "\n");

Rezultat

Original: 10500 octeți
Arhivă mai mică: da
Prima linie: 2026-10-19 cerere OK

Exemplul 3: Doar o parte din sursă

<?php
$sursa = fopen("php://memory", "r+");
fwrite($sursa, "ANTET|Ana,Ion,Maria");

$dest = fopen("php://memory", "r+");
stream_copy_to_stream($sursa, $dest, null, 6);

rewind($dest);
echo stream_get_contents($dest);

Rezultat

Ana,Ion,Maria

Greșeli frecvente

  • Copiezi dintr-un stream în care tocmai ai scris, fără rewind și fără $offset. Poziția e la final și se copiază 0 octeți.
  • Citești tot cu file_get_contents și scrii cu file_put_contents un fișier foarte mare. Tot conținutul ajunge în memorie. stream_copy_to_stream lucrează pe bucăți.

Comenzi înrudite

  • stream_get_contents: Citește tot ce a rămas într-un stream deschis (fișier, memorie, socket, proces) și returnează ca text.
  • fopen / fclose: Deschide un fișier pentru citire sau scriere și returnează o resursă; fclose îl închide.
  • copy: Copiază un fișier într-o locație nouă.