Welcome file # Protocolul HTTP si PHP ## Client/Server ![enter image description here](https://i.ibb.co/G02THKN/HTTP.png) Clientul si serverul sunt calculatoare din reteaua web ( de exemplu ) pe care sunt instalate anumite programe necesare comunicarii acestora. Comunicarae dintre client si server se face prin intermediul protocolului HTTP. Clientul trimite o **cerere** catre server, iar in schimb, serverului trimite un **raspuns** catre client. ### Ce este un URL? Ce este un DNS? Ce este un IP? Stim ca fiecare website web are o adresa web, un URL ( Uniform Resource Locator ), acesta este folosit pentru a accesa site-ul respectiv sau diferitele pagini web ale acelui site. Un URL este format, in general, din 3 componente: 1. Protocolu folosit, `http`. 2. DNS ( Domain Name System ) sau mai bine zis, domeniul website-ului, numele site-ului sau adresa site-ului web. 3. Resursa, pagina web ce incercam sa o accesam, de obicei, pagina home nu se mai scrie in URL, orice fisier `index.html` sau `index.php` este incarcat automat, fara a fi necesar scrierea acestuia in URL. ![enter image description here](https://i.ibb.co/SsS4BxC/URL.png) Fiecare calculator in retea are o **adresa IP**, este modul prin care putem identifica calculatoarele ( si nu numai ) in reteaua web, de exemplu. Acesta este formata din 4 numere, fiecare luand valori de la 0 la 255 separate prin punct. Exemplu de adresa web: `172.154.0.1` Comunicarea intre client si server se face prin intermediul acestor adrese IP. Doi oameni care comunica prin scrisori, comunica prin intermediul adreselor postale, acelasi principiu se aplica si aici. Pentru a evita scrierea adresei IP in URL ( imaginati-va cat de greu e sa retinem minte adresa uni website, memorand toate acele numere ), oamenii au inventat domeniile web, acestea sunt nume date adreselor IP. Atunci cand adresa unui website in navigatorul web, numele site-ului accesat este inlocuit cu adresa IP a acestuia. Domeniul sau numele unui website este cunoscut sub numele de DNS ( Domain Name System ), iar pentru achizitionarea unui domeniu se plateste o suma de bani anual sau doar o singura data. # Ce este HTTP? HTTP este un acronim pentru Hypertext Transfer Protocol, iar acesta este protocolul ( regulile ) folosit pentru comunicarea intre un client si un server in reteaua web. 1. Clientul ( chrome, opera, firefox ) trimite o **cerere** catre un server web. 2. Serverul web primeste **cererea**. 3. Cerea este gestionata de o aplicatie ( site web ) 4. Serverul web trimite un **raspuns** ( rezultatul oferit de aplicatia web ) catre client. 5. Clientul ( navigatorul web ) primeste **raspunsul** si-l afiseaza utilizatorului. Atat cererea cat si raspunsul au un format text astfel incat sa putem gestiona comunicare dintre client/server in mod direct din intermediul aplicatiilor web. De fiecare data cand trimitem o cerere catre un server web ( accesam o pagina web, completam un formular ), se specifica si o metoda. Metoda ii spune serverului web ce actiune vrem sa facem asupra resursei ( paginii web ) accesate. De exemplu, daca pur si simplu vrem sa accesam o pagina web, atunci metoda folosita este **GET**, insa daca completam un formular si vrem ca aceste date sa fie stocate in baza de date a site-ului web, atunci folosim metoda _**POST**_. Aplicatia web verifica daca accepta metoda ( actiunea ) asupra resursei dorite si in functie de acest lucru se decid pasii urmatori. Atunci cand serverul trimite un raspuns catre client, acesta mentionaza si un cod de status ( numere, de exemplu 200, totul a fost ok, 404 resursa nu a fost gasita etc ). Pe langa aceste lucruri, atat cererea cat si raspunsul trimit o lista, de perechi, de forma, `nume: valoare` ce sunt folosit pentru a oferi mai multe detalii despre cerere/raspuns sau corpul acestora. Cand vorbim de corpul acestora, fie ne referim la raspunsul oferit de server ( pagina html sau rezultatul executarii unui script php ) fie ne referim la datele trimise de noi catre server ( de exemplu, in urma completarii unui formular ). ### Cum arata o cerere HTTP? ![enter image description here](https://i.ibb.co/bmcFy4q/REQUEST-1.png) ### Cum arata o cerere cand trimitem date catre server? ![enter image description here](https://i.ibb.co/R3Wqgq8/REQUEST-2.png) ### Cum arata un raspuns HTTP? ![enter image description here](https://i.ibb.co/25cpR9z/RESPONSE.png) ### Cum accesam informatii despre cererea HTTP in PHP? Pentru a putea face acest lucru, avem la dispozitie variabilele globale, `$_SERVER` (aceasta oferindu-ne informatii despre cerere, headers, metoda folosit etc ) `$_GET` si `$_POST`, aceste ultime doua variabile globale stocand datele trimise catre server in functie de metoda folosita. Pentru a putea accesa continutul acestor variabile globale putem folosi functia `var_dump()`. ``` echo '<pre> ' , var_dump($_SERVER) , '</pre>'; ``` Am folosit `<pre></pre>` pentru a formata mai bine ce se fiseaza. Observam ca aveam de-a face cu o matrice, printre informatiile prezentate, observam cheia`REQUEST_METHOD` ce ne spune ce metoda HTTP ( GET, POST, DELETE etc ) a fost folosita. Mai putem observa `REMOTE_ADDR` ce stocheaza adresa IP a clientului, in cazul in care lucrati pe local, aceasta nu apare. Mai putem observa `QUERY_STRING`, acesata afiseaza stringul de interogare, daca acesta exista. De exemplu `www.nume.com?nume=Cata&&age=26`. Acesta parte din URL este uneori folosita pentru a specifica mai multe informatii aplicatiei web folosind metoda GET, de exemplu atunci cand vrem sa afisam utilizatorul “Cata” ce area varsta “26”. Atentie daca afisam aceste date in pagina web folosind PHP, atunci trebuie sa folosim functia `htmlspecialchars($_GET['nume'])` asta deoarece cineva poate introduce cod malitios ( Javascript ), ce poate fi folosit pentru a furma informatii depsre utilizatori. Mai putem observa `PHP_SELF`, de asemenea, daca dorim sa afisam undeva acesta valoare, trebuie sa folosim `htmlspecialchars($_SERVER['PHP_SELF'])`, acesta avand ca valoare locatia resursei curente. Mai putem observa `REQUEST_URI`, acesta contine absolut tot ce se afla dupa numele site-ului. ### Cum modificam raspunsul HTTP in PHP? In PHP aveam o serie de functii ce ne permite sa modificam raspunsul HTTP. Printre acestea, avem `headers_list()` ce contine o lista co toate perechiile de forma `nume:valoare` ( informatii despre raspuns, headers ) ce au fost trimise sau urmeaza sa fie trimise. Avem functia `headers_sent()` ce verifica daca acele informatii ( informatiile despre raspuns, headers ) au fost trimise. Si mai avem, poate cea mai importanta functie, `header()` ce ne permite sa scriem noi acele informatii despre raspuns in mod direct. De exemplu, daca vrem sa facem redirect catre o alta pagina, folosim: ``` header('Location: about.php', 302); exit; ``` Am adaugat functia `exit;` deoarece nu vrem ca scriptul PHP sa continue dupa ce facem redirect. Observam ca acesta functie accepta doi parametri, header-ul ce vrem sa-l scriem la raspunsul HTTP si codul de status, acesta nefiind chiar necesar insa pentru o mai buna folosirea a protocolului HTTP este necesar. #### Cum arata un raspuns pentru o pagina care nu exista? ``` header("HTTP/1.0 404 Not Found"); ``` Acesta este header-ul pe care-l scriem atunci cand o pagina nu este gasita. Atentie, folosim functia `header();` inainte de a afisa ceva in pagina, asta deoarece corpul cereri HTTP vine dupa lista de headers. ``` <form action="" method="POST"> <input name="name" value=""> <input type="submit" value="Send"> </form> <?php echo 3; header('Location: test.php'); ?> ``` Desi cest cod, functioneaza, nu este corect, corect trebuie sa scriem astfel: ``` <?php header('Location: test.php'); echo 3; ?> <form action="" method="POST"> <input name="name" value=""> <input type="submit" value="Send"> </form> ``` ### Mai multe despre HTTP folosind PHP #### Verificam daca o cerere a fost trimisa cu metoda POST ``` // register.php CORECT <?php session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { // scriem codul aici // daca datele nu exista facem redirect catre aceeasi pagina // stocam erorile in sesiune if (!isset($_POST['name']) || empty($_POST['name'])) { $_SESSION['error'] = 'Datele nu au fost trimise'; header('Location: register.php'); exit; } } ?> <?php if ($_SESSION['error']): ?> <p><?php echo $_SESSION['error']; ?> <?php endif; ?> <form action="" method="POST"> <input name="name" value=""> <input type="submit" value="Send"> </form> <?php // daca exista, stergem eroarea deoarece acestea persista si se afiseaza mereu if (isset($_SESSION['error'])) { unset($_SESSION['error']); } ?> ``` Atunci cand lucram cu POST si se intampla ca datele sa nu fie trimise sau valide, facem redirect catre aceeasi pagina, nu stocam erorile in variabile si le afisam, o cerere POST inseamna ca vrem sa stocam date in baza de date, nu are nici o legatura cu ceea ce face GET, adica afiseaza continutul unei pagini web. Facem acelasi lucru si pentru mesajele de success. ``` // register.php NU E CORECT!!!!!!! <?php $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { // scriem codul aici // daca datele nu exista if (!isset($_POST['name']) || empty($_POST['name'])) { $error = 'Datele nu au fost trimise'; } } ?> <?php if ($error): ?> <p><?php echo $error; ?> <?php endif; ?> <form action="" method="POST"> <input name="name" value=""> <input type="submit" value="Send"> </form> ```