Cod Buggy CakePHP: Cele mai frecvente 6 greșeli pe care le fac dezvoltatorii CakePHP
Publicat: 2022-03-11CakePHP este un cadru PHP uimitor, dar are o curbă de învățare abruptă! Este nevoie de o cantitate bună de cercetare și pregătire pentru a deveni un expert.
Am fost norocos să folosesc CakePHP de peste 7 ani și în acel timp am avut onoarea de a lucra cu mulți membri ai comunității CakePHP.
În acest tutorial CakePHP, aș dori să descriu câteva practici proaste pe care le-am văzut de-a lungul anilor și să propun abordarea corectă pentru a evita aceste greșeli. Acest lucru nu înseamnă că codul meu este perfect, dar ca programator învățăm mereu, așa că este important să urmați cele mai bune practici și să vă ajustați pe măsură ce învățați!
Conținutul acestui articol este inspirat de o postare de la CakeCoded. Dacă doriți să aflați mai multe despre CakePHP, vă rugăm să vizitați secțiunea noastră de învățare aici.
Greșeala comună # 1: Nu respectați convențiile de codificare CakePHP
Convențiile de codare CakePHP pot fi vizualizate aici. Voi evidenția câteva lucruri pe care le observ adesea când văd codul altor programatori.
Structuri de control. Atât de des vezi că programatorii greșesc acest lucru și, în unele cazuri, aduc practici din alte limbaje de codare. CakePHP se așteaptă la următoarea sintaxă:
if ((expr_1) || (expr_2)) { // action_1; } elseif (!(expr_3) && (expr_4)) { // action_2; } else { // default_action; }Ar trebui să existe 1 (un) spațiu înaintea primei paranteze și 1 (un) spațiu între ultima paranteză și paranteza de deschidere. Deci, aceasta înseamnă că următoarele sunt incorecte:
if($this->request->data){ } Observați distanța dintre if și ( , și între ) și {
Utilizați întotdeauna paranteze în structurile de control, chiar dacă nu sunt necesare. Acestea măresc lizibilitatea codului și vă oferă mai puține erori logice.
Deci, de exemplu, următoarele sunt incorecte:
if ($foo) $bar = trueAcesta ar trebui să fie formatat astfel:
if ($foo) { $bar = true }În cele din urmă, urmăriți unde plasați parantezele. Parantezele de deschidere nu ar trebui să înceapă o nouă linie. Și asigurați-vă că toate suporturile dvs. sunt aliniate, astfel încât fiecare suport nou să fie în linie cu suportul de închidere.
Iată câteva exemple incorecte:
if ($foo) { $bar = true; }Acest lucru este incorect, paranteza de deschidere ar trebui să fie în prima linie:
if ($foo) { $bar = true; if ($action) { $to = false; } }Indentarea trebuie să se alinieze corect.
Aud adesea programatori spunând: „Dar sunt prea ocupat ca să fac codul ordonat...”. Răspunsul meu este: „Aveți încredere în mine, un cod ordonat va rezista testului timpului”. Scrierea unui cod CakePHP care nu poate fi citit va fi un coșmar la care să reveniți dacă trebuie să faceți o schimbare în câteva luni.
Greșeala obișnuită #2: Utilizarea necorespunzătoare a comportamentelor care pot fi conținute și a nivelurilor recursive în ORM
Am avut norocul recent să am o discuție informală cu un dezvoltator de baze de date de la Facebook. Am început să vorbim despre CakePHP și mi-a spus: „Oh, asta folosește ORM, nu-i așa? Asta poate fi înfricoșător.” L-am întrebat ce vrea să spună și a comentat că, cu maparea relațională obiect (ORM) este ușor ca interogările SQL să devină inutil de mari.
Are dreptate într-un fel. O parte din magia lui CakePHP constă în utilizarea ORM și în modul în care grupează diferite relații de tabele de baze de date. În mod implicit, CakePHP selectează automat orice date legate de „Aparține”, „Are una” și „Are multe”, iar acest lucru poate duce la interogări SQL foarte mari. Este posibil ca aceste interogări să nu fie o problemă atunci când dezvoltați inițial o aplicație, dar după șase luni de colectare a datelor în timp real, este posibil să descoperiți că aplicația devine foarte lentă și, în unele cazuri, se blochează dacă interogările nu sunt optimizate.
Mă uit la două lucruri atunci când auditez un site web existent. În primul rând, a fost schimbat nivelul recursiv implicit? În mod implicit, CakePHP setează nivelul recursiv la 1, care după părerea mea este prea mare. Întotdeauna l-am setat la -1 și apoi folosesc comportamentul de conținut pentru a obține orice modele înrudite.
Asta duce la al doilea lucru pe care îl caut - a fost folosit comportamentul Containable? Am adesea clienți noi care vin la mine și spun că CakePHP este lent. Motivul este aproape întotdeauna că Containable nu a fost folosit! Un bun programator CakePHP își va optimiza interogările SQL, indiferent de cât de multă „magie automată” se face în culise.
Comportamentul care poate fi controlat nu a fost adăugat până la CakePHP 1.2, dar băiete, a făcut diferența?! Asigurați-vă că utilizați conținutul cât mai mult posibil, deoarece este o modalitate atât de eficientă de a vă optimiza SQL. Pentru mai multe informații despre cum să implementați și să utilizați comportamentul Conținut, faceți clic aici.
Greșeala comună #3: Păstrarea logicii de afaceri în controlere în loc de modele
Codul CakePHP bun va avea logica în fișierele model. Este nevoie de puțin pentru a te obișnui, dar odată stăpânit, nu se mai poate privi înapoi! Un fișier controler ar trebui să fie folosit pentru ceea ce este destinat în modelul MVC - control! Așadar, utilizați fișierul controlerului pentru a gestiona acțiunile utilizatorului, în timp ce lăsați logica de afaceri să intre în fișierul model.
Un bun exemplu în acest sens ar fi un simplu CRUD - o acțiune de zi cu zi! Să luăm ca exemplu funcția de adăugare a postărilor dintr-un tutorial de blog. Funcția de adăugare implicită este următoarea:
public function add() { if ($this->request->is('post')) { $this->Post->create(); if ($this->Post->save($this->request->data)) { $this->Session->setFlash(__('Your post has been saved.')); return $this->redirect(array('action' => 'index')); } $this->Session->setFlash(__('Unable to add your post.')); } }Această acțiune a controlerului este în regulă pentru o simplă adăugare, dar ce s-ar întâmpla dacă ați dori să faceți lucruri cum ar fi să trimiteți un e-mail administratorului atunci când a fost adăugată o postare sau să actualizați o altă asociere de model atunci când a fost adăugată o postare. Aceasta este o logică suplimentară, dar această logică nu ar trebui să intre în fișierul controlerului nostru.
În schimb, am scrie o funcție pentru aceasta în modelul nostru Post.php . Poate ceva de genul asta:
public function addPost($data = array(), $emailAdmin = true) { $this->create(); $this->save($data); // update any other tables // send the email to the admin user if ($emailAdmin) { } // if all is successful return true; }Acest lucru ar duce apoi la o mică modificare a acțiunii controlerului, după cum urmează:

public function add() { if ($this->request->is('post')) { if ($this->Post->addPost($this->request->data)) { $this->Session->setFlash(__('Your post has been saved.')); return $this->redirect(array('action' => 'index')); } $this->Session->setFlash(__('Unable to add your post.')); } } După cum puteți vedea, noua acțiune este de fapt o linie mai puțin, deoarece $this->Post->create() a fost mutat în fișierul model.
Acesta este un exemplu perfect, de zi cu zi, în care mutarea logicii în fișierul model este o idee bună - și cu siguranță face o bază de cod mult mai curată!
Greșeala comună #4: Adăugarea prea multă complexitate codului, în loc să reveniți des și devreme
Aceasta este întotdeauna o dezbatere în curs de desfășurare, dar revenirea des și revenirea devreme cu siguranță face ca un cod cu aspect mult mai curat. Acest lucru se aplică metodelor model mai mult decât orice altceva.
Dar ce vreau să spun mai exact? Ei bine, să aruncăm o privire la metoda pe care am adăugat-o în tutorialul CakePHP de mai sus:
public function addPost($data = array(), $emailAdmin = true) { $this->create(); $this->save($data); // update any other tables // send the email to the admin user if ($emailAdmin) { } // if all is successful return true; }A reveni des și a reveni mai devreme înseamnă că, pe măsură ce parcurgem funcția noastră, ne verificăm pentru a ne asigura că totul este OK în mod regulat. Dacă nu este, atunci returnăm false sau returnăm o eroare CakePHP.
Ar putea fi cel mai ușor să arăți acest lucru cu un exemplu. Există două moduri în care funcția de mai sus poate fi scrisă:
public function addPost($data = array(), $emailAdmin = true) { if ($data) { $this->create(); $result = $this->save($data); if ($result) { // update any other tables // send the email to the admin user if ($emailAdmin) { // send the admin email } } else { // problem saving the data return false; } // if all is successful return true; } else { // no data submitted return false; } } Vedeți cum codul devine rapid ilizibil? Există if s și else s peste tot, iar funcția devine rapid o indentare mare. Nu mă înțelege greșit, îmi place indentarea curată, dar uitați-vă cum arată funcția dacă este scrisă cu returnarea des, principiul return early.
public function addPost($data = array(), $emailAdmin = true) { if (!$data) { // no data submitted return false; } $this->create(); $result = $this->save($data); if (!$result) { // problem saving the data return false; } // update any other tables // send the email to the admin user if ($emailAdmin) { // send the admin email } // if all is successful return true; }Imediat, în acest mic exemplu, puteți vedea că codul are doar o singură indentație și este mult mai ușor de citit. Logica are de fapt mai mult sens - lăsați logica să treacă prin linie cu linie și, dacă există vreo problemă pe parcurs, returnați eroarea și nu treceți la următoarea linie.
Acest lucru permite unui programator CakePHP să scrie în același mod în care citim noi - citind codul de la stânga la dreapta, de sus în jos, mai degrabă decât în blocuri diferite, ceea ce poate deveni rapid confuz!
Greșeala comună #5: Nu folosiți principiul DRY
DRY înseamnă Don’t Repeat Yourself și este o filozofie care ar trebui urmată atunci când se codifică în CakePHP. Cu codul orientat pe obiecte, nu există nicio scuză pentru a repeta același bloc de cod de două ori!
Iată câteva sfaturi CakePHP pentru a vă asigura că nu vă repetați:
După cum s-a menționat mai sus, urmăriți să puneți logica în fișierele model, astfel încât să puteți partaja logica.
În fișierele de vizualizare, dacă repetați vizualizări, creați codul de vizualizare ca Element sau chiar ca ajutor personalizat.
Configurați câteva setări de configurare - fișierul
app/Config/bootstrap.phpeste un loc grozav pentru aceasta. Acest lucru vă ajută să vă asigurați că nu codificați greu lucruri precum numele aplicației și adresa de e-mail principală. Ultimul lucru pe care vrei să-l faci este să treci prin sute de fișiere doar pentru că clientul a cerut să actualizeze o adresă de e-mail într-o aplicație.Întrebați-vă întotdeauna: „Dacă repet codul, există o modalitate mai bună de a scrie acest cod și pun acest cod în locul potrivit?” Sunt șanse, dacă trebuie să repetați codul, acesta ar putea fi scris mai bine.
Greșeala comună #6: Nu comentați codul
Ultimul punct pe care îl voi face este în ceea ce privește comentariile. În primul rând, blocarea documentelor. Un bloc document este atunci când documentați o metodă sau o acțiune. Este nevoie de doar un minut pentru a înregistra puțin despre ceea ce face o funcție, dar face o astfel de diferență în ceea ce privește lizibilitatea codului.
CakePHP Doc Blocks trebuie să meargă împotriva marginii din stânga a paginii. Deci un exemplu simplu folosind codul de mai sus.
/** * Adds & saves a post as well as emails the admin to let them know the post has been added. * Also performs some saving to another table * * @param array $data The post data * @param bool $emailAdmin If set to true, will email the website admin * @return bool Returns true if successful */ public function addPost($data = array(), $emailAdmin = true) {După cum veți vedea, nu durează mult să scrieți un bloc document, dar face o diferență uriașă în ceea ce privește longevitatea codului. În cele din urmă, înseamnă că codul poate trăi dincolo de tine ca dezvoltator.
La fel și cu comentariile în linie. Nu vă speriați să explicați ce face codul dvs. și de ce! Pe termen lung, este mult mai ușor să înțelegeți codul dvs., mai ales dacă un alt dezvoltator se uită la el!
Învelire
CakePHP este un cadru extins, cu funcții complete. Având în vedere că respectă convenția asupra configurației, CakePHP este mai strict decât alte cadre bazate pe PHP, în sensul că un utilizator este „forțat” să urmeze un anumit mod de aranjare a codului. Acest lucru poate fi controversat, dar din experiența mea duce la o bază de cod mai consistentă, mai lizibilă și mai înțeleasă - în loc să-l lase pe dezvoltator să „alege” cum trebuie scris codul, o echipă de dezvoltare va scrie cod consistent urmând convențiile lui Cake. .
Urmând acest tutorial CakePHP și asigurându-vă că codul dvs. este bine scris, aplicațiile pot rezista testului timpului. Codul ar trebui să fie scris întotdeauna pentru mâine - astfel încât, dacă un alt dezvoltator se uită la un anumit bloc de cod ani mai târziu, el va înțelege codul și va respecta standardele așteptate. CakePHP nu este diferit și sperăm că acest ghid va ajuta la corectarea unor obiceiuri proaste.
