Ce face proc_open
proc_open este cea mai flexibilă funcție pentru procese. În $descriptor_spec spui ce se face cu fiecare canal: 0 este intrarea, 1 ieșirea, 2 erorile. ["pipe", "r"] creează un canal pe care copilul citește, iar ["pipe", "w"] unul pe care copilul scrie. Capetele tale ajung în $pipes, cu aceleași numere.
Din PHP 7.4, comanda poate fi un tablou: ["sort", "-r", $fisier]. Atunci nu trece prin shell și argumentele nu mai trebuie protejate cu escapeshellarg. La final închizi canalele și apelezi proc_close, care returnează codul de ieșire.
Parametri
| Parametru | Descriere |
|---|---|
$command |
Comanda, ca text (rulată prin shell) sau ca tablou (program și argumente, fără shell). |
$descriptor_spec |
Ce se face cu fiecare canal: ["pipe", "r"|"w"], ["file", $cale, $mod] sau un stream existent. |
$pipes |
Variabilă în care se pun capetele canalelor de tip pipe. |
$cwd |
Opțional. Directorul de lucru al procesului. |
$env_vars |
Opțional. Variabilele de mediu. Dacă îl dai, procesul primește doar aceste variabile. |
$options |
Opțional. Opțiuni pentru Windows, de exemplu bypass_shell. |
Ce returnează
O resursă de proces sau false la eroare.
Exemple
Exemplul 1: Date trimise, rezultat citit
<?php
$proces = proc_open(["sort"], [0 => ["pipe", "r"], 1 => ["pipe", "w"]], $pipes);
fwrite($pipes[0], "Maria\nAna\nIon\n");
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
echo "Cod de ieșire: " . proc_close($proces);
Rezultat
Ana
Ion
Maria
Cod de ieșire: 0
Exemplul 2: Ieșirea și erorile, separat
<?php
$proces = proc_open(
["sh", "-c", "echo Am importat 120 de produse; echo Lipsește prețul la 3 produse >&2; exit 2"],
[1 => ["pipe", "w"], 2 => ["pipe", "w"]],
$pipes
);
$iesire = stream_get_contents($pipes[1]);
$erori = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$cod = proc_close($proces);
echo "Ieșire: $iesire";
echo "Erori: $erori";
echo "Cod: $cod";
Rezultat
Ieșire: Am importat 120 de produse
Erori: Lipsește prețul la 3 produse
Cod: 2
Exemplul 3: Director și variabile de mediu
<?php
mkdir("rapoarte");
touch("rapoarte/octombrie.pdf");
$p = proc_open(["ls"], [1 => ["pipe", "w"]], $pipes, "rapoarte");
echo "În rapoarte: " . stream_get_contents($pipes[1]);
proc_close($p);
$p = proc_open(["sh", "-c", "echo Orașul: \$ORAS"], [1 => ["pipe", "w"]], $pipes, null, ["ORAS" => "Iași"]);
echo stream_get_contents($pipes[1]);
proc_close($p);
Rezultat
În rapoarte: octombrie.pdf
Orașul: Iași
Greșeli frecvente
- Nu închizi
$pipes[0]după ce ai scris. Comenzi casortașteaptă finalul intrării, iar scriptul rămâne blocat la citirea rezultatului. - Citești mai întâi tot
$pipes[1], apoi$pipes[2], iar procesul scrie foarte mult pe canalul de erori. Bufferul canalului de erori se umple, procesul se oprește și așteaptă. Pentru volume mari, citește-le alternativ custream_select. - Dai
$env_varscu o singură variabilă și comanda nu își mai găsește programele. Procesul pierde șiPATH. Pornește de la mediul curent:["ORAS" => "Iași"] + getenv().
Comenzi înrudite
proc_close: Așteaptă terminarea unui proces pornit cu proc_open, îl închide și returnează codul lui de ieșire.proc_get_status: Returnează starea unui proces pornit cu proc_open: dacă mai rulează, PID-ul, codul de ieșire, semnalul care l-a oprit.popen / pclose: Pornește o comandă și returnează un stream din care citești ieșirea ei sau în care îi scrii date; pclose o închide.stream_select: Așteaptă până când unul sau mai multe stream-uri (socket-uri, pipe-uri) au date de citit sau pot primi date.exec: Rulează o comandă a sistemului de operare și returnează ultima linie afișată de ea.