Sari la conținut
← PHP de la zero
Progres curs 0 / 7 lecții (0%)

Cum rulează PHP

Lectură estimată: 15 minute

Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.

Ce se întâmplă între apăsarea unui link și apariția paginii

Când deschizi o pagină, browserul trimite o cerere către un server și primește un răspuns. Dacă pagina este generată cu PHP, o parte a muncii se face pe server înainte ca răspunsul să ajungă în browser. Codul poate citi date, poate decide ce elemente sunt vizibile și poate construi HTML. Browserul interpretează HTML-ul rezultat; nu execută instrucțiunile PHP din fișierul sursă.

Această diferență este baza cursului. Dacă nu o înțelegi, vei încerca să repari în browser o eroare care apare pe server sau vei aștepta ca o variabilă PHP să se schimbe automat când utilizatorul apasă un buton. În această lecție vom urmări o cerere completă, vom construi o pagină mică și vom verifica ce vede fiecare parte a sistemului. Nu este nevoie să instalezi un framework pentru a înțelege traseul.

La final vei putea porni un laborator local, vei distinge fișierul PHP de răspunsul HTML și vei identifica diferența dintre o eroare de sintaxă, un fișier negăsit și o problemă de afișare. Vom folosi date fictive și un director separat. Exercițiile sunt concepute pentru PHP 8.2 sau mai nou; verifică versiunea instalată înainte să copiezi exemple într-un proiect existent.

Cele trei roluri: browser, server web și interpretor

Browserul este clientul care cere resurse și afișează răspunsurile. Serverul web primește cererea și o direcționează potrivit configurării. Interpretorul PHP execută codul PHP și produce rezultatul. Într-un laborator simplu, serverul integrat în PHP face pornirea mai ușoară, dar rolurile conceptuale rămân distincte. Într-o instalare reală pot exista și un proxy, mai multe procese PHP și alte servicii.

Să presupunem că soliciți /index.php. Serverul găsește fișierul potrivit și îl execută prin PHP. Instrucțiunea echo poate adăuga text în corpul răspunsului. Dacă fișierul conține și HTML în afara blocurilor PHP, acel HTML contribuie la răspuns. După terminarea execuției, browserul primește rezultatul și îl interpretează. O variabilă care a existat în timpul execuției nu este trimisă automat ca variabilă JavaScript.

Într-o configurare corectă, sursa PHP nu este livrată vizitatorului. Aceasta nu este însă o proprietate magică a extensiei fișierului. Dacă un server este configurat greșit și trimite fișierul ca text, sursa poate fi expusă. De aceea verificăm rezultatul prin HTTP și nu punem credențiale în exemple. O extensie .php nu înlocuiește configurarea și verificarea serverului.

Verifică mediul înainte să investighezi codul

Deschide un terminal și rulează php -v. Dacă primești versiunea, interpretorul este disponibil în acel terminal. Dacă primești un mesaj că programul nu este găsit, problema este instalarea sau calea de executare, nu sintaxa fișierului. Nu schimba fișierul de zece ori pentru a repara o comandă care nici nu a început să îl citească.

Comanda php --ini arată configurarea folosită de interpretorul din terminal. În alte instalări, PHP folosit de serverul web poate avea altă configurare sau chiar altă versiune. Pentru laboratorul nostru, serverul integrat este pornit cu aceeași comandă php, ceea ce simplifică această diferență. Mai târziu, când lucrezi cu un server configurat separat, verifică mediul efectiv în care rulează cererea.

Nu copia automat o listă de extensii fără să știi de ce sunt necesare. Prima lecție poate funcționa cu instalarea de bază. Lecția despre șiruri Unicode poate folosi mbstring, iar lecția despre baza de date cere driverul PDO SQLite pentru exemplele respective. Când apare o funcție necunoscută sau un driver absent, verifică cerința lecției și extensiile încărcate.

Pregătește un director de laborator cu o rădăcină publică

Creează un director php-laborator și în el un director public. Fișierul care trebuie servit browserului va sta în public. Alte fișiere, de exemplu date demonstrative sau un script executat numai din terminal, pot sta în afara lui. Această separare te învață de la început că nu orice fișier al proiectului trebuie să poată fi descărcat printr-un URL.

Din directorul php-laborator pornește serverul cu php -S 127.0.0.1:8001 -t public. Opțiunea -t indică rădăcina servită, iar adresa 127.0.0.1 limitează laboratorul la calculatorul local. Lasă terminalul deschis cât timp testezi. Pentru oprire folosește Ctrl+C în acel terminal. Dacă portul este ocupat, alege alt port și folosește aceeași valoare în adresa din browser.

Serverul integrat este un instrument de dezvoltare. Nu este configurația pe care o publici pentru clienți. În acest curs îl folosim pentru a observa cereri și răspunsuri fără configurarea unui server complet. Când ai nevoie de publicare reală, separă acea etapă și verifică serverul, HTTPS, permisiunile și gestionarea erorilor potrivit proiectului.

Prima pagină și locul unde se execută expresiile

Salvează următorul fragment în public/index.php. Fișierul începe cu un bloc PHP care pregătește datele, apoi continuă cu documentul HTML. Expresia scurtă de afișare este folosită numai pentru a introduce o valoare în textul paginii. Datele sunt definite local, astfel încât primul experiment nu depinde de un formular sau de o bază de date.

<?php
declare(strict_types=1);
$titlu = 'Atelier PHP';
$participanti = 3;
?>
<!doctype html>
<html lang="ro">
<meta charset="utf-8">
<title>Prima pagină PHP</title>
<h1><?= htmlspecialchars($titlu, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></h1>
<p>Participanți înscriși: <?= $participanti ?></p>
</html>

Deschide http://127.0.0.1:8001/ și verifică titlul și numărul. Apoi folosește opțiunea de vizualizare a sursei răspunsului. Vei vedea documentul HTML cu valorile introduse, nu atribuirea lui $titlu. Acum schimbă numărul în fișier și reîncarcă pagina. Rezultatul nou apare pentru că browserul a făcut o cerere nouă, iar PHP a executat din nou fișierul.

Instrucțiunea declare stabilește o regulă privind anumite conversii pentru declarațiile de tip; nu este necesară pentru simpla afișare a unui titlu și nu validează automat datele externe. O folosim consecvent în exemple pentru a face contractele funcțiilor mai clare în lecțiile următoare. Nu o trata ca pe un comutator care face întregul program corect sau sigur.

De ce protejăm textul la afișare

Titlul este introdus într-un context HTML. Dacă valoarea lui conține caractere precum < sau &, browserul le poate interpreta ca parte a marcajului dacă sunt trimise direct. Funcția htmlspecialchars transformă caracterele relevante pentru acest context. În exemplu, un titlu precum „Atelier <începători>” trebuie să apară ca text, nu să creeze un element HTML nou.

Această transformare se aplică la ieșire, când construiești HTML-ul. Nu înseamnă validarea unui email, protejarea unei interogări SQL sau escaparea corectă pentru orice limbaj. Mai târziu vom separa validarea intrării, calculul, stocarea și afișarea. Pentru moment, reține doar că locul unde introduci o valoare determină felul în care trebuie pregătită pentru ieșire.

Compară textul vizibil cu sursa răspunsului după ce introduci caractere speciale. În sursă poți vedea entități HTML, iar în pagină vezi caracterele originale. Nu este o corupere a datelor. Este reprezentarea prin care browserul înțelege că acele caractere sunt text. Dacă vezi entitățile scrise literal în pagină, verifică dacă ai aplicat transformarea de două ori.

Execuția din terminal și execuția prin HTTP

Poți rula un fișier cu php fisier.php direct din terminal. În acel caz, rezultatul este scris în terminal, nu într-un browser. Această formă este utilă pentru calcule, verificări și scripturi de întreținere. Nu există automat aceeași cerere HTTP, aceleași antete sau aceleași date de formular ca într-o pagină accesată prin server.

Dacă execuți prima pagină din terminal, vei vedea HTML-ul rezultat ca text. Terminalul nu îl transformă într-o pagină. Acesta este un experiment bun pentru a separa generarea răspunsului de afișarea lui. PHP produce conținutul; consumatorul decide cum îl interpretează. O aplicație PHP poate produce și JSON sau alte tipuri de răspuns, nu doar HTML.

Nu presupune că toate variabilele din $_SERVER există în orice mediu. O valoare legată de metoda cererii are sens în contextul HTTP. În scripturi reutilizabile, evită să citești direct mediul peste tot. Poți transmite funcțiilor datele necesare, ceea ce le face mai ușor de verificat din terminal.

Cererile sunt separate: ce se păstrează și ce dispare

În modelul obișnuit al unei pagini PHP, variabilele obișnuite ale cererii sunt inițializate din nou la următoarea execuție. Dacă scrii $numar = 0 și apoi îl mărești, fiecare reîncărcare poate afișa din nou 1. Browserul nu retrimite automat valoarea internă de la cererea anterioară, iar procesul serverului nu reprezintă memoria aplicației tale pentru acel utilizator.

Pentru a păstra informații între cereri folosești mecanisme explicite: o sesiune pentru anumite date ale vizitatorului, o bază de date pentru informații persistente sau alte forme de stocare potrivite. Nu confunda o variabilă cu o înregistrare persistentă. În lecțiile despre sesiuni și PDO vom construi aceste legături și vom preciza cine poate citi sau modifica datele.

Există și medii PHP cu procese de aplicație de lungă durată, dar nu acesta este modelul laboratorului. Este important să știi că explicația noastră se referă la scriptul de cerere pe care îl rulăm aici. Nu transforma o simplificare utilă pentru început într-o afirmație universală despre orice infrastructură PHP.

Corpul răspunsului și antetele

Un răspuns HTTP are un status, antete și corp. HTML-ul este corpul. Tipul conținutului și o eventuală redirecționare sunt comunicate prin antete. În PHP, antetele trebuie pregătite înainte să trimiți efectiv corpul în configurația obișnuită fără buffering care să amâne ieșirea. Un spațiu sau un mesaj de diagnostic trimis prea devreme poate produce eroarea „headers already sent”.

Când apare această eroare, citește locul primei ieșiri indicat de mesaj. Poate fi un echo, un fragment HTML sau un fișier inclus care are spații în afara blocului PHP. Nu rezolva problema ascunzând mesajul. Mută pregătirea antetelor înaintea afișării și păstrează fișierele care conțin numai PHP fără eticheta finală de închidere, pentru a evita ieșirea accidentală după ea.

O redirecționare nu oprește singură execuția scriptului. Dacă trimiți un antet Location și trebuie să închei cererea, folosește exit după el. Altfel codul de mai jos poate continua să ruleze, chiar dacă browserul va naviga spre altă adresă. Această diferență va conta în formulare și în protejarea paginilor autentificate.

Cum depanezi în ordine

Dacă nu se conectează browserul, verifică dacă serverul este pornit, adresa și portul. Dacă primești 404, verifică rădăcina publică și numele fișierului. Dacă primești o eroare de parsare, verifică sintaxa și linia indicată, inclusiv linia precedentă. Dacă pagina se încarcă, dar valoarea este greșită, inspectează calculul și datele. Aceste situații nu au aceeași cauză.

Comanda php -l public/index.php verifică sintaxa fără să execute aplicația. Este utilă pentru un punct și virgulă lipsă sau o acoladă neînchisă. Nu dovedește că rezultatul este corect și nu înlocuiește cererea HTTP. Un fișier poate fi sintactic valid și poate încerca să apeleze o funcție absentă numai când ajunge pe o anumită ramură.

Pentru laborator poți inspecta valori cu var_dump, dar nu lăsa asemenea ieșiri într-o pagină publică. Ele pot strica antetele și pot expune date. Într-un sistem public, detaliile tehnice trebuie să ajungă în jurnalele potrivite, iar utilizatorul trebuie să primească un mesaj controlat. Nu publica phpinfo ca pagină de diagnostic permanentă: ea dezvăluie multe detalii despre mediu.

Exercițiu ghidat: o pagină care depinde de date

Adaugă o listă de trei nume fictive și afișează numărul lor cu count. Apoi parcurge lista cu foreach și construiește câte un element li. Aplică escaparea fiecărui nume la afișare. Testează un nume cu ampersand și unul cu semnele < și >. Numărul trebuie să corespundă listei, iar caracterele speciale să apară literal.

Înainte să rulezi, scrie HTML-ul pe care te aștepți să îl primească browserul. După rulare, compară cu sursa răspunsului. Dacă numărul de nume este corect, dar elementele nu apar, inspectează bucla și marcajul. Dacă apar trei elemente cu aceeași valoare, verifică variabila afișată în interiorul buclei. Nu modifica datele doar pentru a face rezultatul să pară corect.

Ca a doua variantă, golește lista. Definește mesajul pentru această situație: „Nu există participanți încă”. O listă goală nu este automat o eroare a serverului. Cererea poate fi reușită, dar fără elemente. Această diferență se va repeta în interogările de bază de date și în formulare, de aceea merită înțeleasă de la prima lecție.

Rezolvare explicată și criterii de acceptare

O rezolvare completă are o singură sursă pentru lista de nume. Numărul este calculat din acea listă, iar elementele sunt construite din aceeași listă. Nu scrie manual numărul 3 într-un loc și trei elemente în altul, deoarece la următoarea modificare se pot desincroniza. Condiția pentru lista goală este evaluată înainte de afișarea elementelor sau într-o ramură clară.

Verifică patru lucruri: serverul pornește în directorul corect, pagina răspunde la adresa corectă, sursa răspunsului nu conține atribuiri PHP și numele speciale sunt afișate ca text. Păstrează fișierul și notițele cu rezultatele. Acesta este primul tău ciclu complet de lucru: cerință, implementare, execuție, inspecție și corectură.

În lecția următoare vom analiza valorile folosite în această pagină: numere, texte, booleeni și absența unei valori. Vei vedea de ce două valori care arată la fel în HTML pot avea tipuri diferite în program și de ce această diferență contează înainte să faci calcule sau să accepți date de la utilizator.

Laborator suplimentar: lista participanților, de la date la HTML

Construiește pagina public/participanti.php într-un director nou de laborator. Cerința este să afișeze numărul participanților și numele lor, iar pentru o listă goală să afișeze un mesaj explicit. Numărul trebuie calculat din aceeași listă folosită la afișare. În acest fel, dacă introduci sau elimini un participant, nu trebuie să corectezi manual două zone ale paginii.

Înainte de implementare, scrie rezultatul pentru trei intrări: lista cu Ana și Mihai, lista goală și lista care conține numele Atelier <A&B>. Prima intrare trebuie să genereze două elemente li. A doua nu trebuie să genereze un participant fictiv cu numele „nimeni”. A treia trebuie să păstreze semnele speciale ca parte a numelui, fără să construiască un element HTML din ele.

<?php
declare(strict_types=1);
$participanti = ['Ana', 'Mihai', 'Atelier <A&B>'];
function h(string $text): string {
    return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
?>
<!doctype html>
<html lang="ro"><meta charset="utf-8"><title>Participanți</title>
<h1>Participanți: <?= count($participanti) ?></h1>
<?php if ($participanti === []): ?>
  <p>Nu există participanți încă.</p>
<?php else: ?>
  <ul>
  <?php foreach ($participanti as $nume): ?>
    <li><?= h($nume) ?></li>
  <?php endforeach; ?>
  </ul>
<?php endif; ?>
</html>

Nu memora toate instrucțiunile din prima încercare. Urmărește traseul: array-ul furnizează datele, count calculează numărul, condiția decide dacă există elemente, iar foreach repetă marcajul pentru fiecare nume. Funcția h pregătește numele pentru contextul HTML. Niciunul dintre acești pași nu schimbă lista originală. În lecțiile următoare vei putea verifica separat fiecare operație.

Compară trei feluri de a privi aceeași pagină

Fișierul din editor este sursa programului. Răspunsul HTTP este rezultatul execuției. DOM-ul din browser este structura construită de browser din acel răspuns. Aceste trei lucruri sunt legate, dar nu sunt identice. Dacă inspectorul arată un element adăugat automat de browser, nu înseamnă că PHP l-a scris explicit în fișier. Pentru a verifica ce a trimis serverul, examinează răspunsul din fila de rețea sau sursa paginii.

În sursa răspunsului caută textul Atelier și observă entitățile folosite pentru semnele speciale. În pagina vizuală trebuie să vezi numele original. Acesta nu este un defect de codificare: entitățile sunt reprezentarea potrivită pentru ca browserul să trateze semnele ca text. Dacă vezi entitățile literal în pagină, este posibil să fi aplicat escaparea de două ori.

Rulează același fișier și cu php public/participanti.php din terminal. Vei vedea HTML-ul ca text, deoarece terminalul nu îl interpretează ca browserul. Acest experiment demonstrează că PHP poate produce același tip de ieșire fără o interfață grafică. Totuși, execuția din terminal nu testează antete, cookie-uri sau comportamentul unui server HTTP, deci nu înlocuiește verificarea în contextul paginii.

Găsește cauza înainte să modifici programul

Dacă primești 404, verifică adresa și rădăcina publică a serverului. Dacă primești o eroare de sintaxă, verifică fișierul indicat și linia din jurul erorii. Dacă pagina apare, dar lista este goală, inspectează datele și condiția. Aceste simptome apar în etape diferite: rezolvarea adresei, interpretarea PHP și logica programului. Nu încerca să repari o adresă greșită schimbând funcția de escapare.

Pentru un experiment controlat, introdu deliberat un nume de fișier greșit în URL și notează răspunsul. Revino la adresa corectă, apoi schimbă lista în array gol. Compară cele două rezultate: în primul caz resursa nu a fost găsită, în al doilea pagina funcționează și descrie o colecție fără elemente. Diferența te ajută să scrii mesaje corecte și în aplicațiile cu baze de date.

La final, păstrează trei dovezi simple: adresa testată, numărul elementelor li și numele special afișat literal. Repetă testul după adăugarea unui al patrulea nume. Dacă titlul arată patru participanți, dar lista are trei, ai două surse de adevăr sau o condiție care exclude un element. Corectează cauza, apoi repetă cazul gol pentru a verifica și ramura care nu produce listă.

Documentație oficială pentru aprofundare

Referințe verificate pentru această ediție. Exemplele sunt exerciții originale de laborator.

Ți-a plăcut lecția? Continuă cursul complet

Ai citit o lecție gratuită. Celelalte lecții, aplicațiile practice și materialele se deblochează odată cu cursul.

99 lei

Plată unică, acces pe viață la toate cele 7 lecții.

Vezi ce conține cursul →

Folosim cookie-uri esențiale pentru funcționarea site-ului și, cu acordul tău, cookie-uri de analiză și publicitate. Partenerii noștri, inclusiv Google, pot folosi cookie-uri pentru a afișa reclame relevante. Detalii în Politica de cookie-uri.