Codice Buggy CakePHP: I 6 errori più comuni commessi dagli sviluppatori CakePHP
Pubblicato: 2022-03-11CakePHP è un fantastico framework PHP, ma ha una curva di apprendimento ripida! Per diventare un esperto è necessaria una buona dose di ricerca e formazione.
Ho la fortuna di usare CakePHP da oltre 7 anni e in quel periodo ho avuto l'onore di lavorare con molti membri della community di CakePHP.
In questo tutorial di CakePHP vorrei descrivere alcune cattive pratiche che ho visto negli anni e proporre l'approccio corretto per evitare questi errori. Questo non vuol dire che il mio codice sia perfetto, ma come programmatore impariamo sempre, quindi è importante seguire le migliori pratiche e adattarle man mano che impari!
Il contenuto di questo articolo è ispirato a un post di CakeCoded. Se desideri saperne di più su CakePHP, visita la nostra sezione di apprendimento qui.
Errore comune n. 1: non seguire le convenzioni di codifica CakePHP
Le convenzioni di codifica di CakePHP possono essere visualizzate qui. Evidenzierò alcune cose che noto spesso durante la visualizzazione del codice di altri programmatori.
Strutture di controllo. Così spesso vedi che i programmatori sbagliano e in alcuni casi portano pratiche da altri linguaggi di programmazione. CakePHP prevede la seguente sintassi:
if ((expr_1) || (expr_2)) { // action_1; } elseif (!(expr_3) && (expr_4)) { // action_2; } else { // default_action; }
Dovrebbe esserci 1 (uno) spazio prima della prima parentesi e 1 (uno) spazio tra l'ultima parentesi e la parentesi aperta. Quindi questo significa che quanto segue non è corretto:
if($this->request->data){ }
Nota la spaziatura tra if
e (
, e tra )
e {
Utilizzare sempre parentesi graffe nelle strutture di controllo, anche se non sono necessarie. Aumentano la leggibilità del codice e ti danno meno errori logici.
Quindi, ad esempio, quanto segue non è corretto:
if ($foo) $bar = true
Questo dovrebbe essere formattato in questo modo:
if ($foo) { $bar = true }
Infine, guarda dove metti le parentesi. Le parentesi aperte non dovrebbero iniziare una nuova riga. E assicurati che tutte le parentesi siano allineate in modo che ogni nuova parentesi sia in linea con la parentesi di chiusura.
Ecco alcuni esempi errati:
if ($foo) { $bar = true; }
Questo non è corretto, la parentesi di apertura dovrebbe essere nella prima riga:
if ($foo) { $bar = true; if ($action) { $to = false; } }
Il rientro deve essere allineato correttamente.
Sento spesso i programmatori dire: "Ma sono troppo occupato per rendere il codice pulito..." La mia risposta è: "Fidati di me, il codice pulito resisterà alla prova del tempo". Scrivere un codice CakePHP che non è leggibile sarà un incubo su cui tornare se devi apportare una modifica in pochi mesi.
Errore comune n. 2: uso improprio di comportamenti contenibili e livelli ricorsivi nell'ORM
Di recente ho avuto la fortuna di avere una discussione informale con uno sviluppatore di database di Facebook. Abbiamo iniziato a parlare di CakePHP e lui mi ha detto: "Oh, quello usa ORM, vero? Può essere spaventoso". Gli ho chiesto cosa intendesse e ha commentato che con la mappatura relazionale a oggetti (ORM) è facile che le query SQL diventino inutilmente grandi.
Ha ragione in un certo senso. Parte della magia di CakePHP sta nell'uso di ORM e nel modo in cui raggruppa insieme diverse relazioni tra tabelle di database. Per impostazione predefinita, CakePHP seleziona automaticamente tutti i dati correlati "Appartiene a", "Ha uno" e "Ha molti" e questo può portare a query SQL molto grandi. Queste query potrebbero non essere un problema durante lo sviluppo iniziale di un'applicazione, ma dopo sei mesi di raccolta di dati in tempo reale, è possibile che l'applicazione diventi molto lenta e in alcuni casi si arresti in modo anomalo se le query non sono ottimizzate.
Cerco due cose durante l'audit di un sito Web esistente. Innanzitutto, il livello ricorsivo predefinito è stato modificato? Per impostazione predefinita, CakePHP imposta il livello ricorsivo su 1, che a mio parere è troppo alto. L'ho sempre impostato su -1 e quindi utilizzo il comportamento contenibile per ottenere qualsiasi modello correlato.
Questo porta alla seconda cosa che cerco: è stato utilizzato il comportamento Containable? Spesso ho nuovi clienti che vengono da me e mi dicono che CakePHP è lento. Il motivo è quasi sempre perché Containable non è stato utilizzato! Un buon programmatore CakePHP ottimizzerà le proprie query SQL indipendentemente da quanta "magia automatica" viene eseguita dietro le quinte.
Il comportamento contenibile non è stato aggiunto fino a CakePHP 1.2, ma ragazzo ha fatto la differenza?! Assicurati di utilizzare il più possibile contenibile, poiché è un modo così efficace per ottimizzare il tuo SQL. Per ulteriori informazioni su come implementare e utilizzare il comportamento Containable, fare clic qui.
Errore comune n. 3: mantenere la logica aziendale nei controller anziché nei modelli
Il buon codice CakePHP avrà la logica nei file del modello. Ci vuole un po' per abituarsi, ma una volta imparato non si può guardare indietro! Un file controller dovrebbe essere utilizzato per ciò a cui è destinato nel modello MVC: controllo! Quindi usa il tuo file del controller per gestire le azioni dell'utente, lasciando che la logica di business vada nel file del modello.
Un buon esempio di questo potrebbe essere un semplice CRUD - un'azione quotidiana! Prendiamo come esempio la funzione di aggiunta di post da un tutorial del blog. La funzione di aggiunta predefinita è la seguente:
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.')); } }
Questa azione del controller va bene per una semplice aggiunta, ma cosa accadrebbe se volessi fare cose come inviare un'e-mail all'amministratore quando è stato aggiunto un post o aggiornare un'altra associazione del modello quando è stato aggiunto un post. Questa è una logica aggiuntiva, ma questa logica non dovrebbe entrare nel nostro file del controller.
Invece vorremmo scrivere una funzione per questo nel nostro modello Post.php
. Forse qualcosa del genere:
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; }
Ciò comporterebbe quindi una piccola modifica all'azione del controller come segue:

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.')); } }
Come puoi vedere, la nuova azione è in realtà una riga in meno, perché $this->Post->create()
è stata spostata nel file del modello.
Questo è un perfetto esempio quotidiano di dove spostare la logica nel file modello è una buona idea, e sicuramente crea una base di codice molto più pulita!
Errore comune n. 4: aggiungere troppa complessità al codice, invece di tornare spesso e presto
Questo è sempre un dibattito in corso, ma tornare spesso e tornare presto rende sicuramente il codice molto più pulito. Questo vale per i metodi del modello più di ogni altra cosa.
Ma cosa intendo esattamente? Bene, diamo un'occhiata al metodo che abbiamo aggiunto nel tutorial di CakePHP sopra:
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; }
Tornare spesso e tornare in anticipo significa che mentre eseguiamo la nostra funzione, controlliamo per assicurarci che tutto sia a posto su base regolare. In caso contrario, viene restituito false o viene restituito un errore CakePHP.
Potrebbe essere più semplice mostrarlo con un esempio. Ci sono due modi per scrivere la funzione sopra:
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; } }
Vedi come il codice diventa rapidamente illeggibile? Ci sono if
e else
s dappertutto e la funzione diventa rapidamente una grande rientranza. Non fraintendermi, adoro il rientro pulito, ma guarda come appare la funzione se viene scritta spesso con il ritorno, ritorno principio anticipato.
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; }
Subito, in questo piccolo esempio, puoi vedere che il codice ha un solo rientro ed è molto più leggibile. La logica in realtà ha più senso: lascia che la logica scorra riga per riga e, in caso di problemi lungo il percorso, restituisci l'errore e non passare alla riga successiva.
Ciò consente a un programmatore CakePHP di scrivere nello stesso modo in cui leggiamo noi: leggendo il codice da sinistra a destra, dall'alto verso il basso, anziché in blocchi diversi, il che può creare rapidamente confusione!
Errore comune n. 5: non utilizzare il principio DRY
DRY sta per Don't Repeat Yourself, ed è una filosofia che dovrebbe essere seguita durante la codifica in CakePHP. Con il codice orientato agli oggetti, non ci sono scuse per ripetere lo stesso blocco di codice due volte!
Ecco alcuni consigli CakePHP per assicurarti di non ripeterti:
Come accennato in precedenza, mira a inserire la logica nei file di modello in modo da poter condividere la logica.
Nei file di visualizzazione, se si ripetono le visualizzazioni, creare il codice della visualizzazione come elemento o anche come supporto personalizzato.
Configura alcune impostazioni di configurazione: il file
app/Config/bootstrap.php
è un ottimo posto per questo. Questo aiuta ad assicurarsi che non si stiano codificando cose come il nome dell'applicazione e l'indirizzo e-mail principale. L'ultima cosa che vuoi fare è esaminare centinaia di file solo perché il client ha chiesto di aggiornare un indirizzo email in un'applicazione.Chiediti sempre: "Se sto ripetendo il codice, c'è un modo migliore per scrivere questo codice e sto mettendo questo codice nel posto giusto?" È probabile che, se è necessario ripetere il codice, potrebbe essere scritto meglio.
Errore comune n. 6: non commentare il codice
L'ultimo punto che farò riguarda i commenti. Innanzitutto, il blocco dei documenti. Un blocco doc è quando si documenta un metodo o un'azione. Ci vuole solo un minuto per registrare un po' di ciò che sta facendo una funzione, ma fa una tale differenza in termini di leggibilità del codice.
I CakePHP Doc Blocks devono andare contro il margine sinistro della pagina. Quindi un semplice esempio usando il codice di cui sopra.
/** * 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) {
Come vedrai, non ci vuole molto per scrivere un blocco doc, ma fa un'enorme differenza in termini di longevità del codice. In definitiva, significa che il codice può vivere oltre a te come sviluppatore.
Allo stesso modo con i commenti in linea. Non aver paura di spiegare cosa sta facendo il tuo codice e perché! Rende molto più facile a lungo termine capire il tuo codice, specialmente se un altro sviluppatore lo sta guardando!
Incartare
CakePHP è un framework completo e completo. Dato che segue le convenzioni sulla configurazione, CakePHP è più rigoroso di altri framework basati su PHP, nel senso che un utente è "costretto" a seguire un certo modo di disporre il codice. Questo può essere controverso, ma nella mia esperienza porta a una base di codice più coerente, leggibile e comprensibile - piuttosto che lasciare che uno sviluppatore "scelga" come deve essere scritto il codice, un team di sviluppo scriverà un codice coerente seguendo le convenzioni di Cake .
Seguendo questo tutorial di CakePHP e assicurandoti che il tuo codice sia ben scritto, le applicazioni possono resistere alla prova del tempo. Il codice dovrebbe essere sempre scritto per domani, in modo che se un altro sviluppatore sta esaminando un particolare blocco di codice anni dopo, capirà il codice e si atterrà agli standard previsti. CakePHP non è diverso e speriamo che questa guida aiuti a correggere alcune cattive abitudini.