În ultimele câteva săptămâni NETTUTS a publicat câteva tutoriale minunate despre cum să începeți să utilizați PHP și MySQL pentru a crea aplicații web simple, cum ar fi o casetă de strigăte. Astăzi vom lua cunoștințele noastre despre PHP și MySQL cu un pas înainte creând un blog simplu. Deși există nenumărate platforme excelente de blog, scopul acestui tutorial nu este de a face un blog "mai bun", ci de a folosi procesul de a face un blog pentru a afla despre tehnicile avansate de structură a bazei de date și modul de utilizare mai eficientă a datelor folosind obiecte PHP.
Simple Blog Files.zip
benmillsdesigns.com/simpleblog/
Pentru acest tutorial se presupune că aveți o înțelegere de bază despre PHP, MySQL, XHTML și mai târziu despre jQuery / JavaScript.
Înainte de a ne muta în clientul nostru MySQL și de a începe să creăm tabelele noastre, ar trebui să prezentăm ceea ce dorim în blogul nostru. Evidentul lucru pe care trebuie să-l deținem este posturile pe blog, iar în fiecare post ar trebui să conțină un titlu, un post, un autor și data la care a fost postat.
Acum am putea face doar o masă pentru a ține aceste informații și, cel mai probabil, vom realiza crearea unui blog de bază, dar cu un singur tabel nu vom avea controlul asupra datelor noastre. De exemplu, am putea să stocăm numele autorului în același tabel ca și postarea pe blog, dar ce se întâmplă dacă dorim să stocăm și e-mailul autorului? Sigur! Doar adăugăm un alt câmp la masa noastră ar fi soluția evidentă.
Problema apare atunci când pe drumul pe care doriți să schimbați adresa de e-mail a respectivului autor. Acum trebuie să o schimbați pentru fiecare post pe blog pe care persoana respectivă la creat.
Deci, ceea ce vom face este să creați o tabelă separată numită "Oameni" și, în acest caz, vom stoca toate informațiile de care avem nevoie de la autor - cum ar fi e-mailurile, adresele URL, numele lor și un ID unic. Apoi, în tabelul nostru de postări pe blog, vom indica persoana dorită utilizând ID-ul unic al persoanei respective. Acest id este denumit o cheie străină, iar relația dintre tabela de postări pe blog și tabelul de persoane se numește o relație unu-la-multe.
Un alt lucru pe care dorim să îl avem în blogul nostru este o etichetă pentru fiecare post de blog. Din nou, dorim ca baza noastră de date să fie eficientă, astfel încât să creați un tabel separat pentru etichetele noastre. Acum ce facem? Ar trebui să creăm un câmp în tabela de postări pe blog, care este o cheie străină pentru eticheta noastră? Problema cu folosirea unei relații unu-la-unu este că uneori mesajele de blog au mai multe etichete; astfel încât din nou, vom folosi o relație unu-la-multe. Pentru a face acest lucru, trebuie să creați un alt tabel care va fi numit "blog_post_tags" care va conține două chei străine, unul va fi ID-ul postului de blog, iar celălalt va fi ID-ul tag-ului pe care postul de blog este asociat. În acest fel, putem atribui cât mai multe etichete pe care le dorim unei postări pe blog, dar putem încă să editați informațiile despre eticheta respectivă în toate postările cu o simplă interogare MySQL.
Acum, când am subliniat ceea ce dorim ca baza noastră de date să arate, să o creăm. Voi folosi PhpMyAdmin, deoarece acesta este cel mai utilizat client de administrare MySQL. Există câteva convenții de numire diferite pe care le puteți utiliza când creați baza de date, tabelele și numele câmpurilor. Îmi place personal să folosesc toate literele mici și subliniatele în locul spațiilor.
Notă: Dacă nu aveți PHP și MySQL pe sistemul dvs. sau pe un server care să-l poată rula, vă recomandăm să descărcați o instalare stand-alone de Apache, PHP și MySQL. MAMP este bun pentru Mac și WAMP este bun pentru PC-uri.
Mai întâi trebuie să ne creăm baza de date, o voi numi "nettuts_blog".
Apoi, vom crea mesele noastre; primul va fi "blog_posts".
"blog_posts" va avea cinci câmpuri: "id", "title", "post", "author_id" și "date_posted". Pentru "id" o vom face cheia primară și o vom seta să crească automat. Ceea ce va face aceasta este generarea id-ului nostru unic pentru noi. De fiecare data cand adaugam o postare, ii vom da un numar incepand de la unul si mutandu-ne pana la cat mai multe posturi pe care le avem.
Acum, de asemenea, trebuie să setăm tipul de variabilă pentru fiecare câmp. Id-ul va fi setat să scrie int, scurt pentru întreg, deoarece poate fi doar un număr și vom seta lungimea maximă la 11. Câmpul "title" va fi setat să scrie varchar cu o lungime maximă de 255. " post "va fi de tip" text "și nu vom seta o lungime maximă deoarece postările pot fi foarte lungi. "author_id" va fi identic cu "id", dar nu o vom seta ca cheia primară sau nu avem o creștere automată și vom seta "date_posted" pentru a scrie "Date".
Următoarea noastră masă va fi "oamenii". Noi nu o numim "autori", pentru că pe drumul pe care ne-am putea dori să-i creăm abilitatea de a ne înregistra și de a posta comentarii, acei oameni nu ar fi considerați autori.
"people" va conține și cinci câmpuri: "id", "first_name", "last_name", "url" și "email".
"id" va fi setat ca int, cheia primară și pentru incrementarea automată, la fel cum am setat id-ul "blog_posts". "first_name", "last_name", "url" și "email" vor fi toate setate pentru a tasta varchar cu o lungime maximă de 255.
Tabelul următor va fi "etichete" și va conține acum doar două câmpuri: "id" și "name". Pe drum, am putea face acest lucru mai complex prin adăugarea unei descrieri, dar pentru acest tutorial nu vom. Așa cum am făcut înainte, "id" va fi setat ca int, cheia primară și pentru incrementarea automată. "nume" va fi de tip varchar și va avea o lungime maximă de 255.
Ultimul nostru tabel, "blog_post_tags", va avea doar două câmpuri: "blog_post_id" și "tag_id". Ambele vor fi setate să introducă int cu o lungime maximă de 11. După cum ați observat cel mai probabil, nu am setat o cheie primară pentru acest tabel. Acest lucru se datorează faptului că nu vom primi niciodată date din acest tabel dacă nu solicităm o anumită postare pe blog sau toate postările unui id de etichetă.
Înainte de a începe codul nostru PHP trebuie să creați fișierele și folderele noastre, pentru acest tutorial vom avea index.php în directorul nostru rădăcină, apoi include un folder care va păstra foaia noastră de stil CSS, fișierele noastre JavaScript, include.php care va conține referințe la obiectele și conexiunea MySQL și la blogpost.php care va organiza BlogPost obejct.
Acum, când avem setul de baze de date, trebuie să creăm obiectele din PHP care vor prelua datele pentru noi. Obiectele în programare sunt o modalitate de a trage împreună atribute diferite (ca variabile) și metode care se referă la același lucru. Obiectele ne ajută, de asemenea, să organizăm programele noastre mult mai mult. Înainte de a intra în obiectele noastre pentru blogul nostru, să creăm doar un obiect simplu, astfel încât să putem ilustra ceea ce sunt într-un termen mai "real".
Obiectul nostru va fi numit "Bike", acum există două tipuri de lucruri pe care fiecare obiect le are, proprietăți și metode. Proprietățile definesc obiectul și metodele sunt ceea ce face obiectul. De exemplu, obiectul Bike ar avea proprietăți precum dimensiunea roților, numărul de unelte și, probabil, dimensiunea cadrului. Pentru metode am putea avea ceva de genul "Pedal".
Acum, pentru a ne întoarce la blogul nostru, avem nevoie doar de un obiect denumit acum "BlogPost". BlogPost va avea șase proprietăți, id, titlu, post, autor, etichete și data postate. Deci, vă permite să faceți în PHP.
Pentru a defini un obiect în PHP îl definim ca o "clasă". O clasă este structura fiecărui obiect sau așa cum o descrie wikipedia: "În programarea orientată pe obiecte, o clasă este o construcție a limbajului de programare care este folosită ca un model pentru a crea obiecte. Acest plan include atribute și metode pe care obiectele create acțiune." (Http://en.wikipedia.org/wiki/Concrete_class). Vom deschide pagina blogpost.php și vom defini primul obiect.
Notă: În fiecare secțiune a tutorialului, voi renunța la etichetele PHP de deschidere și închidere; ""va trebui să le includeți la începutul și sfârșitul documentului.
clasa BlogPost
În clasa noastră avem nevoie mai întâi să definim proprietățile noastre. Pentru a face acest lucru, trebuie să creăm variabile - dar cu "public" în fața lor. Doar o notă rapidă, dacă utilizați PHP4 atunci va trebui să utilizați "var" în loc de "public".
clasa BlogPost public $ id; titlu public $; public $ post; public autor $; etichete publice $; public $ datePosted;
Acum, că avem toate proprietățile definite, vrem să definim prima noastră metodă. Metodele sunt, de asemenea, descrise ca funcții, dar principala diferență este că o metodă este o funcție în interiorul unui obiect. Deci, toate metodele sunt, de asemenea, funcții, dar nu toate funcțiile sunt metode.
Prima noastră metodă va fi ceea ce se numește constructor; această metodă este apelată automat de fiecare dată când realizăm o nouă instanță a obiectului BlogPost.
Utilizarea obișnuită a unui constructor este astfel încât să puteți crea un obiect nou și să setați rapid proprietățile acelui obiect.
Deci, ceea ce dorim să facem este să creăm o nouă funcție numită __construct () și vom trece în cinci valori, id, titlu, post, autor id și data postate. Pentru fiecare nume de variabilă pe care o vom pune "în" înainte de cuvânt, astfel încât să putem spune în interiorul funcțiilor noastre ce variabile sunt transmise și ce variabile sunt deja prezente.
clasa BlogPost public $ id; titlu public $; public $ post; public autor $; etichete publice $; public $ datePosted; funcția __construct ($ inId, $ inTitle, $ inPost, $ inAuthorId, $ inDatePosted)
Problema este că, cu acest cod curent, de fiecare dată când creăm o nouă instanță a BlogPost, trebuie să furnizăm toate aceste proprietăți. Dar ce se întâmplă dacă vrem să facem un nou post blog și nu am definit acele variabile încă? Pentru a rezolva acest lucru, trebuie să "supraîncărcați" argumentele pentru funcția noastră, astfel încât dacă apelăm funcția și nu trecem într-unul dintre argumente, aceasta o va seta automat la valoarea implicită.
funcția __construct ($ inId = null, $ inTitle = null, $ inPost = null, $ inPostFull = null, $ inAuthorId = null, $ inDatePosted = null)
După cum puteți vedea, tot ceea ce facem pentru a ne îndeplini sarcina este să setăm fiecare argument la valoarea "null". Acum, în interiorul constructorului nostru, trebuie să setăm fiecare dintre variabilele noastre la valorile noastre transmise. Pentru a face acest lucru vrem să le punem la obiectul în care suntem acum; Putem face acest lucru cu cuvântul cheie "acest". Spre deosebire de multe alte limbi pentru a accesa o proprietate în PHP, folosiți "->" unde în majoritatea limbilor (I.E. JavaScript, ASP.NET) folosiți ".".
funcția __construct ($ inId = null, $ inTitle = null, $ inPost = null, $ inPostFull = null, $ inAuthorId = null, $ inDatePosted = null) $ this-> id = $ inId; $ this-> title = $ inTitle; $ this-> post = $ inPost;
Acest lucru funcționează pentru id, titlu și post. Dar despre celelalte? Pentru data, vom avea nevoie să reformatăm datele pe care le avem de la MySQL pentru a fi mai ușor de citit. Acest lucru este ușor de realizat; Pur și simplu l-am exploda (cunoscută și ca divizare în alte limbi de programare) și apoi l-am pus împreună. MySQL ne-o dă în acest format yyyy-mm-dd, așa că dacă vom exploda folosind "-" ca separator vom obține o matrice care deține trei valori. Primul va ține anul nostru, următorul va ține luna noastră, iar ultima va fi ziua. Acum, tot ce le facem este să le punem împreună în orice formă dorim. Mă duc cu mm / zi / aaaa.
$ splitDate = explode ("-", $ inDatePosted); $ this-> datePosted = $ splitDate [1]. "/". $ splitDate [2]. "/". $ SplitDate [0];
Pentru autor, tot ce trebuie să faceți este să întrebați baza de date pentru persoana care are ID-ul autorului nostru. Putem face acest lucru cu o interogare de bază MySQL.
$ query = mysql_query ("SELECT first_name, last_name DE LA WHERE id =". $ inAuthorId); $ row = mysql_fetch_assoc ($ interogare); $ this-> author = $ row ["first_name"]. "". rândul $ [ "last_name"];
Acum etichetele vor fi ușor mai dificile. Va trebui să vorbim cu baza de date, așa că trebuie să creați o interogare MySQL. Nu ne vom face griji cu privire la conexiunea bazei de date chiar acum, care va fi definită în afara acestei clase. Acum avem doar ID-ul postului de blog. Putem compara acest lucru cu etichetele postărilor blogului din tabelul nostru blog_post_tags, dar vom primi doar ID-ul etichetei și vom avea nevoie să facem o altă interogare pentru a obține informațiile despre etichetă. Nu e bine; Vrem să fim eficienți, așa că să o facem într-o singură interogare!
Pentru a face acest lucru, vom face ceea ce se numește intrare stânga, ceea ce înseamnă că vom selecta, de asemenea, datele dintr-un alt tabel, dar numai atunci când se potrivește cu datele din "stânga" sau celelalte date selectate. Deci, mai întâi, să luăm toate ID-urile de etichete asociate cu ID-ul postării de blog în tabela blog_post_tags.
$ interogare = mysql_query ("SELECT * FROM blog_post_tags WHERE blog_post_tags.blog_post_id =". $ inId);
Acum, să adăugăm intrarea noastră stângă și să ne spuneți că dorim doar datele din tabelul de etichete:
$ query = mysql_query ("Etichete SELECT. * FROM blog_post_tags LEFT JOIN (etichete) ON (blog_post_tags.tag_id = tags.id) WHERE blog_post_tags.blog_post_id =". $ inId);
Deci, acum interogarea selectează toate din tabelele și blog_posts_tags tabelele în care, primul blog_post_tags.blog_post_id este egal cu cel pe care l-am furnizat și apoi returnează, de asemenea, informațiile despre fiecare etichetă care are acel tag_id care se află în același rând de date ca blog_post_id.
Acum vrem să procesăm aceste date în PHP cu o buclă simplă. Vom crea, de asemenea, două matrice care vor păstra datele noastre: una pentru numele etichetei, iar cealaltă pentru id-ul etichetei. Vom face, de asemenea, un șir pentru a ține toate etichetele noastre. Mai întâi vom seta această opțiune la "Nici un etichetă", astfel încât dacă nu vom returna date din interogarea MySQL, se va returna că nu avem etichete, în caz contrar valoarea va fi suprascrisă cu numele etichetelor.
$ postTags = "Nu există etichete"; $ tagArray = array (); $ tagIDArray = array (); în timp ce ($ row = mysql_fetch_assoc ($ query) array_push ($ tagArray, $ row ["nume"]); array_push ($ tagIDArray, $ row ["id"
Acum vom verifica dacă matricea are o lungime mai mare decât zero (nu vrem să realizăm tot acest cod suplimentar dacă nu trebuie să facem asta). În continuare, pentru fiecare etichetă din matricea de etichete, vom concatena un șir de etichete. Vom folosi o declarație simplă dacă altceva.
dacă sizeof ($ tagArray)> 0) foreach ($ tagArray ca $ tag) if ($ postTags == "Fără etichete") $ postTags = $ tag; altceva $ postTags = $ postTags. ",". tag-ul $; $ this-> tags = $ postTags;
Probabil ați observat că nu am folosit matricele de etichete pentru etichete. Vom lăsa singuri pe ei acum și vom reveni la ei mai târziu. Vrem doar să facem prima dată blogul nostru.
Ultimul pas pentru clasa noastră este să adăugăm declarații pentru fiecare proprietate, astfel încât dacă nu trecem în nimic, nu vom încerca să setăm proprietatea obiectului curent la nimic (aceasta va provoca o eroare). Iată întreaga clasă BlogPost cu instrucțiunile if:
id = $ inId; dacă (! empty ($ inTitle)) $ this-> title = $ inTitle; dacă (! empty ($ inPost)) $ this-> post = $ inPost; dacă (! empty ($ inDatePosted)) $ splitDate = explode ("-", $ inDatePosted); $ this-> datePosted = $ splitDate [1]. "/". $ splitDate [2]. "/". $ SplitDate [0]; if (! empty ($ inAuthorId)) $ interogare = mysql_query ("SELECT first_name, last_name FROM persoane WHERE id =". $ inAuthorId); $ row = mysql_fetch_assoc ($ interogare); $ this-> author = $ row ["first_name"]. "". rândul $ [ "last_name"]; $ postTags = "Nici un etichetă"; dacă (! empty ($ inId)) $ interogare = mysql_query ("SELECT etichete. * FROM blog_post_tags PORNIRE JOIN (etichete) ON (blog_post_tags.tag_id = tags.id) WHERE blog_post_tags.blog_post_id =". $ tagArray = array (); $ tagIDArray = array (); în timp ce ($ row = mysql_fetch_assoc ($ interogare)) array_push ($ tagArray, $ row ["nume"]); array_push ($ tagIDArray, $ rând ["id"]); dacă sizeof ($ tagArray)> 0) foreach ($ tagArray ca $ tag) if ($ postTags == "Nicio etichetă") $ postTags = $ tag; altceva $ postTags = $ postTags. ",". tag-ul $; $ this-> tags = $ postTags; ?>
Acum că clasa obiectului este completă, cele mai multe lucruri grele se fac! Acum, tot ce trebuie să faceți este să configurați conexiunea bazei de date și codul HTML pentru a afișa postările noastre!
Înainte de a face ceva, trebuie să configurați fișierul inclus.php pentru a menține o referință la obiectul BlogPost și pentru a vă conecta la baza de date MySQL. Mai întâi permiteți includerea obiectului nostru cu o declarație de includere simplă:
includeți "blogpost.php";
Acum permiteți adăugarea conexiunii bazei noastre de date:
$ connection = mysql_connect ("localhost", "username", "password") sau mor ("Ne pare rău, nu am reușit să ne conectăm la serverul de baze de date.
"); $ database =" nettuts_blog "; mysql_select_db ($ database, $ connection) sau mor ("Ne pare rău, nu am reușit să ne conectăm la baza de date.
„);
Apoi, trebuie să preluăm postările din blogul nostru din baza de date. Pentru a face acest lucru, vom face o funcție care poate dura până la două argumente. Vom supraîncarca pe amândouă; astfel încât să puteți apela funcția cu argumente 0, 1 sau 2.
funcția GetBlogPosts ($ inId = null, $ inTagId = null)
În interiorul funcției noastre trebuie să verificăm pentru a vedea ce argumente au fost transmise și pentru a crea interogarea MySQL în consecință.
funcția GetBlogPosts ($ inId = null, $ inTagId = null) if (! empty ($ inId)) altceva dacă ! empty ($ inTagId) else
Ceea ce facem aici este să ne întrebăm dacă fiecare argument nu este gol, motivul pentru care folosim funcția goală în loc să facem doar comparația standard "! = Null" este că gol nu numai că verifică dacă variabila este nulă, ci dacă și gol (IE ""). Acum vom scrie o interogare în funcție de variabilele pe care le avem. Dacă treceți într-un ID post de blog, dorim doar acea postare de blog, dacă îi dăm funcției o inTagId dorim toate postările care au acea etichetă și în caz contrar vrem doar toate postările de blog din baza noastră de date.
dacă empty ($ inId)) $ interogare = mysql_query ("SELECT * FROM blog_posts WHERE id =". $ inId. "ORDER BY id DESC"); altfel dacă (! empty ($ inTagId)) $ interogare = mysql_query ("SELECT blog_posts." FROM blog_post_tags PORNIT JOIN (blog_posts) ON (blog_post_tags.postID = blog_posts.id) WHERE blog_post_tags.tagID = ". ORDER BY blog_posts.id DESC "); altceva $ query = mysql_query ("SELECT * FROM blog_posts ORDER BY id DESC");
Următorul pas este de a procesa datele returnate de la fiecare interogare, de a crea obiectele și apoi de a le adăuga la un matrice pentru a reveni.
$ postArray = array (); în timp ce ($ row = mysql_fetch_assoc ($ query)) $ myPost = noul BlogPost ($ row ['id'], $ row ['title'], $ row ['nume_name'], $ row ['dateposted']); array_push ($ postArray, $ myPost); return $ postArray;
Aici este codul integral al file.php:
Ne pare rău, nu am reușit să ne conectăm la serverul de baze de date."); $ database =" nettuts_blog "; mysql_select_db ($ database, $ connection) sau mor ("Ne pare rău, nu am reușit să ne conectăm la baza de date.
"), funcția GetBlogPosts ($ inId = null, $ inTagId = null) if (! empty ($ inId)) $ interogare = mysql_query (" SELECT * FROM blog_posts WHERE id = ". "); altfel dacă (! empty ($ inTagId)) $ interogare = mysql_query (" SELECT blog_posts "* FROM blog_post_tags) ($ query = mysql_fetch_assoc ($ query)); $ query = mysql_query ("SELECT * FROM ORDER by blog_posts.id DESC"); ) $ myPost = noul BlogPost ($ row ["id"], $ row ['title'], $ row ['post'], $ row ['postfull' ['dateposted']); array_push ($ postArray, $ myPost); returnați $ postArray;?>
Acum putem trece la afișarea datelor noastre, permite deschiderea fișierului index.php și configurarea unei pagini HTML de bază. În interiorul corpului nostru vom crea o diviziune cu un id de "principală" care va conține blogul nostru. Vom da blogului nostru un titlu și apoi vom avea un al doilea div în principal, care va fi numit "blogPosts".
Blogul meu simplu
În blog-ul nostruPosts div, vom pune în PHP câteva astfel încât să putem afișa postările noastre. Mai întâi vom include fișierul inclus.php și apoi vom apela funcția noastră GetBlogPosts fără argumente pentru a obține toate postările de pe blog și pentru a le seta într-o matrice numită blogPosts.
Acum, vom folosi o buclă foreach pentru a afișa postările din blog. Ceea ce face o buclă foreach pentru noi chiar acum este o matrice și execută codul în buclă pentru fiecare element din matrice, ai putea folosi, de asemenea, o buclă normală pentru a realiza acest lucru, dar o buclă foreach necesită mai puțin cod.
foreach ($ blogPosts ca $ post)
În interiorul buclă, folosim $ post ca element curent pentru matrice și din moment ce $ blogPosts este o serie de obiecte BlogPost, putem folosi pur și simplu "->" pentru a accesa fiecare proprietate pe care o dorim. Începeți prin a reda doar titlul fiecărui post blog pe pagina noastră și adăugați doar o
- ca exemplu.
foreach ($ blogPosts ca $ post) echo $ post-> titlu. "
";
Dacă mergem la baza noastră de date și inserăm niște date false, apoi deschideți index.php într-un browser, vom obține ceva de genul:
Să construim cu adevărat postările noastre în HTML. Fiecare post va fi înfășurat într-un div cu o clasă de "post". Apoi vom avea titlul postului în interiorul unei etichete h1 și postul propriu din interiorul a
etichetă.
foreach ($ blogPosts ca $ post) ecou ""ecou"";"$ post-> title."
"ecou""post post->."
"ecou"
Să dăm, de asemenea, fiecărui post un subsol care va include autorul postării, data postată și etichetele postării. Vom pune toate aceste informații într-o etichetă de span cu o clasă "subsol".
foreach ($ blogPosts ca $ post) ecou ""ecou"";"$ post-> title."
"ecou""post post->.""ecou"Postat de: "$ post-> author." Postat pe: "$ post-> datePosted." Etichete: "$ post-> tags.""ecou"
Acum, să examinăm din nou fișierul index.php într-un browser:
Se pare că lucrează totul! Apoi, să adăugăm un stil.
Mult mai bine; puteți vedea acest lucru online aici sau faceți clic pe butoanele mari "demo". Aceasta este pentru acest tutorial. Într-un tutorial ulterior, vom adăuga mai multe funcționalități în blogul nostru, inclusiv câteva funcții AJAX frumoase!
Sper că aveți acum o mai bună înțelegere a modului în care funcționează programarea orientată pe obiecte. Chiar dacă veți ajunge să faceți majoritatea dezvoltării dvs. folosind un cadru, este foarte important să aveți o înțelegere de bază a fundamentelor. Dacă aveți întrebări specifice cu privire la acest tutorial, nu ezitați să-mi trimiteți un tweet @benemills. Aș dori să-i mulțumesc lui James Padolsey pentru că m-au ajutat cu acest articol.
Rămâi acordat pentru Partea 2!