Błędny kod CakePHP: 6 najczęstszych błędów popełnianych przez twórców CakePHP
Opublikowany: 2022-03-11CakePHP jest niesamowitym frameworkiem PHP, ale ma stromą krzywą uczenia się! Stanie się ekspertem wymaga sporej ilości badań i szkoleń.
Miałem szczęście używać CakePHP od ponad 7 lat iw tym czasie miałem zaszczyt pracować z wieloma członkami społeczności CakePHP.
W tym samouczku CakePHP chciałbym opisać kilka złych praktyk, które widziałem na przestrzeni lat i zaproponować właściwe podejście, aby uniknąć tych błędów. Nie oznacza to, że mój kod jest doskonały, ale jako programista zawsze się uczymy, dlatego ważne jest, aby postępować zgodnie z najlepszymi praktykami i dostosowywać się w miarę nauki!
Treść tego artykułu jest inspirowana postem z CakeCoded. Jeśli chcesz dowiedzieć się więcej o CakePHP, odwiedź naszą sekcję nauki tutaj.
Powszechny błąd nr 1: nieprzestrzeganie konwencji kodowania CakePHP
Konwencje kodowania CakePHP można zobaczyć tutaj. Podkreślę kilka rzeczy, które często zauważam podczas przeglądania kodu innych programistów.
Struktury kontrolne. Tak często widzisz, że programiści się mylą, aw niektórych przypadkach wprowadzają praktyki z innych języków kodowania. CakePHP oczekuje następującej składni:
if ((expr_1) || (expr_2)) { // action_1; } elseif (!(expr_3) && (expr_4)) { // action_2; } else { // default_action; }
Powinna być 1 (jedna) spacja przed pierwszym nawiasem i 1 (jedna) spacja między ostatnim nawiasem a otwierającym nawiasem. Oznacza to, że poniższe jest nieprawidłowe:
if($this->request->data){ }
Zwróć uwagę na odstępy między if
i (
, oraz między )
i {
Zawsze używaj nawiasów klamrowych w strukturach kontrolnych, nawet jeśli nie są potrzebne. Zwiększają czytelność kodu i dają mniej błędów logicznych.
Na przykład niepoprawne jest:
if ($foo) $bar = true
Powinno to być sformatowane w następujący sposób:
if ($foo) { $bar = true }
Na koniec obserwuj, gdzie umieszczasz wsporniki. Nawiasy otwierające nie powinny rozpoczynać nowej linii. I upewnij się, że wszystkie nawiasy są wyrównane, tak aby każdy nowy nawias był w jednej linii z nawiasem zamykającym.
Oto kilka niepoprawnych przykładów:
if ($foo) { $bar = true; }
To jest niepoprawne, nawias otwierający powinien znajdować się w pierwszym wierszu:
if ($foo) { $bar = true; if ($action) { $to = false; } }
Wcięcie musi być prawidłowo wyrównane.
Często słyszę, jak programiści mówią: „Ale jestem zbyt zajęty, aby uporządkować kod…”. Moja odpowiedź brzmi: „Zaufaj mi, zgrabny kod przetrwa próbę czasu”. Pisanie kodu CakePHP, który nie jest czytelny, będzie koszmarem, do którego trzeba będzie wrócić, jeśli za kilka miesięcy trzeba będzie dokonać zmian.
Powszechny błąd nr 2: Niewłaściwe użycie możliwych do opanowania zachowań i poziomów rekurencyjnych w ORM
Ostatnio miałem szczęście odbyć nieformalną dyskusję z programistą baz danych z Facebooka. Zaczęliśmy rozmawiać o CakePHP, a on powiedział do mnie: „Och, to używa ORM, czyż nie? To może być przerażające. Zapytałem go, co miał na myśli, a on skomentował, że dzięki mapowaniu obiektowo-relacyjnemu (ORM) zapytania SQL łatwo stają się niepotrzebnie duże.
W pewnym sensie ma rację. Częścią magii CakePHP jest użycie ORM i sposób, w jaki grupuje różne relacje tabel bazy danych. Domyślnie CakePHP automatycznie wybiera wszystkie powiązane dane 'Należy do', 'Ma jeden' i 'Ma wiele', co może prowadzić do bardzo dużych zapytań SQL. Te zapytania mogą nie stanowić problemu podczas początkowego tworzenia aplikacji, ale po sześciu miesiącach zbierania danych na żywo może się okazać, że aplikacja działa bardzo wolno, aw niektórych przypadkach ulega awarii, jeśli zapytania nie są zoptymalizowane.
Podczas audytu istniejącej strony internetowej zwracam uwagę na dwie rzeczy. Po pierwsze, czy zmieniono domyślny poziom rekurencyjny? Domyślnie CakePHP ustawia poziom rekurencji na 1, co moim zdaniem jest zbyt wysokie. Zawsze ustawiam go na -1, a następnie używam zachowania z możliwością zawierania, aby uzyskać powiązane modele.
To prowadzi do drugiej rzeczy, której szukam - czy zastosowano zachowanie Containable? Często przychodzą do mnie nowi klienci i mówią, że CakePHP działa wolno. Powodem jest prawie zawsze to, że Containable nie został użyty! Dobry programista CakePHP zoptymalizuje swoje zapytania SQL bez względu na to, ile „auto-magii” jest wykonywane za kulisami.
Zachowanie do przechowywania nie zostało dodane do CakePHP 1.2, ale chłopcze, czy to coś zmieniło?! Upewnij się, że używasz jak największej liczby elementów zawieralnych, ponieważ jest to tak skuteczny sposób na optymalizację twojego SQL. Aby uzyskać więcej informacji na temat implementacji i używania zachowania Containable, kliknij tutaj.
Powszechny błąd nr 3: utrzymywanie logiki biznesowej w kontrolerach zamiast w modelach
Dobry kod CakePHP będzie miał logikę w plikach modelu. Przyzwyczajenie się do tego zajmuje trochę czasu, ale po opanowaniu nie ma co się oglądać! Plik kontrolera powinien być używany do tego, do czego jest przeznaczony we wzorcu MVC - sterowanie! Dlatego użyj pliku kontrolera do obsługi działań użytkownika, jednocześnie pozwalając logice biznesowej przejść do pliku modelu.
Dobrym tego przykładem może być prosty CRUD - codzienna akcja! Jako przykład weźmy funkcję dodawania postów z samouczka bloga. Domyślna funkcja dodawania jest następująca:
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.')); } }
Ta akcja kontrolera jest dobra w przypadku prostego dodawania, ale co by się stało, gdybyś chciał zrobić takie rzeczy, jak wysłanie e-maila do administratora po dodaniu wpisu lub zaktualizowanie innego powiązania modelu po dodaniu wpisu. To jest dodatkowa logika, ale ta logika nie powinna trafiać do naszego pliku kontrolera.
Zamiast tego napisalibyśmy funkcję do tego w naszym modelu Post.php
. Może coś takiego:
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; }
Spowodowałoby to wtedy niewielką zmianę akcji kontrolera w następujący sposób:

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.')); } }
Jak widać, nowa akcja to tak naprawdę jedna linia mniej, ponieważ $this->Post->create()
została przeniesiona do pliku modelu.
Jest to doskonały, codzienny przykład tego, gdzie przeniesienie logiki do pliku modelu jest dobrym pomysłem - i na pewno zapewnia znacznie czystszą bazę kodu!
Powszechny błąd nr 4: dodawanie zbyt dużej złożoności do kodeksu, zamiast powracania często i wcześnie
Jest to zawsze trochę tocząca się debata, ale częste powracanie, a powrót wcześnie z pewnością sprawia, że kod wygląda znacznie czyściej. Dotyczy to metod modelowych bardziej niż czegokolwiek innego.
Ale co dokładnie mam na myśli? Cóż, spójrzmy na metodę, którą dodaliśmy w powyższym samouczku CakePHP:
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; }
Często powracać i wracać wcześnie oznacza, że gdy przechodzimy przez naszą funkcję, regularnie sprawdzamy, czy wszystko jest w porządku. Jeśli tak nie jest, zwracamy false lub zwracamy błąd CakePHP.
Najłatwiej byłoby pokazać to na przykładzie. Istnieją dwa sposoby napisania powyższej funkcji:
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; } }
Widzisz, jak szybko kod staje się nieczytelny? Wszędzie jest wiele różnych else
if
a funkcja szybko staje się jednym wielkim wcięciem. Nie zrozum mnie źle, uwielbiam czyste wcięcia, ale obserwuj, jak wygląda funkcja, jeśli jest pisana często ze zwrotem, zasada powrotu wcześnie.
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; }
Od razu, w tym małym przykładzie widać, że kod ma tylko jedno wcięcie i jest znacznie bardziej czytelny. Logika ma więcej sensu - niech logika przechodzi przez linię po linii, a jeśli po drodze pojawi się jakiś problem, zwróć błąd i nie przechodź do następnej linii.
Pozwala to programiście CakePHP pisać w ten sam sposób, w jaki czytamy - czytając kod od lewej do prawej, od góry do dołu, a nie w różnych blokach, co może szybko stać się mylące!
Powszechny błąd nr 5: niestosowanie zasady DRY
DRY to skrót od Don't Repeat Yourself i jest to filozofia, której należy przestrzegać podczas kodowania w CakePHP. W przypadku kodu zorientowanego obiektowo nie ma usprawiedliwienia dla dwukrotnego powtórzenia tego samego bloku kodu!
Oto kilka wskazówek dotyczących CakePHP, dzięki którym nie będziesz się powtarzać:
Jak wspomniano powyżej, staraj się umieścić logikę w plikach modelu, aby móc udostępniać logikę.
W plikach widoków, jeśli powtarzasz widoki, utwórz kod widoku jako Element lub nawet niestandardowego pomocnika.
Ustaw kilka ustawień konfiguracyjnych — plik
app/Config/bootstrap.php
jest do tego świetnym miejscem. Pomaga to upewnić się, że nie kodujesz na sztywno rzeczy, takich jak nazwa aplikacji i główny adres e-mail. Ostatnią rzeczą, którą chcesz zrobić, to przejrzeć setki plików tylko dlatego, że klient poprosił o aktualizację adresu e-mail w aplikacji.Zawsze zadawaj sobie pytanie: „Jeśli powtarzam kod, czy istnieje lepszy sposób na napisanie tego kodu i czy umieszczam go we właściwym miejscu?” Są szanse, że jeśli musisz powtórzyć kod, można go napisać lepiej.
Powszechny błąd nr 6: nie komentowanie kodeksu
Ostatni punkt, który poruszę, dotyczy komentarzy. Po pierwsze, blokowanie dokumentów. Blok dokumentu ma miejsce, gdy dokumentujesz metodę lub akcję. Wystarczy minuta, aby nagrać trochę o tym, co robi funkcja, ale ma to duże znaczenie pod względem czytelności kodu.
Bloki Doc CakePHP muszą być dopasowane do lewego marginesu strony. A więc prosty przykład z wykorzystaniem powyższego kodu.
/** * 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) {
Jak zobaczysz, napisanie bloku dokumentacji nie zajmuje dużo czasu, ale ma ogromne znaczenie pod względem trwałości kodu. Ostatecznie oznacza to, że kod może żyć w przeszłości, jako programista.
Podobnie z komentarzami w tekście. Nie bój się wyjaśniać, co robi Twój kod i dlaczego! Na dłuższą metę znacznie ułatwia zrozumienie kodu, zwłaszcza jeśli patrzy na niego inny programista!
Zakończyć
CakePHP to rozbudowany, w pełni funkcjonalny framework. Biorąc pod uwagę, że jest zgodny z konwencją nad konfiguracją, CakePHP jest bardziej rygorystyczny niż inne frameworki oparte na PHP, w tym sensie, że użytkownik jest „zmuszany” do przestrzegania określonego sposobu układania kodu. Może to być kontrowersyjne, ale z mojego doświadczenia wynika, że baza kodu jest bardziej spójna, czytelna i zrozumiała – zamiast pozwolić programiście „wybrać” sposób napisania kodu, zespół programistów napisze spójny kod zgodnie z konwencjami Cake .
Postępując zgodnie z tym samouczkiem CakePHP i upewniając się, że Twój kod jest dobrze napisany, aplikacje mogą wytrzymać próbę czasu. Kod powinien być zawsze napisany na jutro — tak aby inny programista, który lata później przyglądał się konkretnemu blokowi kodu, zrozumiał kod i trzymał się oczekiwanych standardów. CakePHP nie jest inny i miejmy nadzieję, że ten przewodnik pomoże skorygować niektóre złe nawyki.