Buggy CakePHP Code: Os 6 erros mais comuns que os desenvolvedores do CakePHP cometem
Publicados: 2022-03-11CakePHP é um framework PHP incrível, mas tem uma curva de aprendizado íngreme! Requer uma boa quantidade de pesquisa e treinamento para se tornar um especialista.
Tive a sorte de usar o CakePHP por mais de 7 anos, e nesse tempo tive a honra de trabalhar com muitos membros da comunidade CakePHP.
Neste tutorial do CakePHP eu gostaria de descrever algumas más práticas que tenho visto ao longo dos anos, e propor a abordagem correta para evitar esses erros. Isso não quer dizer que meu código seja perfeito, mas como programadores estamos sempre aprendendo, por isso é importante seguir as melhores práticas e ajustar conforme você aprende!
O conteúdo deste artigo é inspirado em um post do CakeCoded. Se você quiser saber mais sobre o CakePHP, visite nossa seção de aprendizado aqui.
Erro comum nº 1: não seguir as convenções de codificação do CakePHP
As convenções de codificação do CakePHP podem ser vistas aqui. Vou destacar algumas coisas que observo com frequência ao visualizar o código de outros programadores.
Estruturas de controle. Muitas vezes você vê os programadores errarem e, em alguns casos, trazem práticas de outras linguagens de codificação. O CakePHP espera a seguinte sintaxe:
if ((expr_1) || (expr_2)) { // action_1; } elseif (!(expr_3) && (expr_4)) { // action_2; } else { // default_action; }
Deve haver 1 (um) espaço antes do primeiro parêntese e 1 (um) espaço entre o último parêntese e o colchete de abertura. Portanto, isso significa que o seguinte está incorreto:
if($this->request->data){ }
Observe o espaçamento entre o if
e (
, e entre )
e {
Sempre use colchetes em estruturas de controle, mesmo que não sejam necessários. Eles aumentam a legibilidade do código e fornecem menos erros lógicos.
Então, por exemplo, o seguinte está incorreto:
if ($foo) $bar = true
Isso deve ser formatado assim:
if ($foo) { $bar = true }
Por fim, observe onde você coloca os colchetes. Os colchetes de abertura não devem iniciar uma nova linha. E certifique-se de que todos os seus colchetes estejam alinhados para que cada novo colchete esteja alinhado com o colchete de fechamento.
Aqui estão alguns exemplos incorretos:
if ($foo) { $bar = true; }
Isso está incorreto, o colchete de abertura deve estar na primeira linha:
if ($foo) { $bar = true; if ($action) { $to = false; } }
O recuo precisa alinhar corretamente.
Muitas vezes ouço programadores dizerem: “Mas estou muito ocupado para deixar o código limpo…”. Minha resposta é: “Confie em mim, um código limpo resistirá ao teste do tempo”. Escrever código do CakePHP que não seja legível será um pesadelo para voltar se você precisar fazer uma alteração em alguns meses.
Erro comum nº 2: uso impróprio de comportamentos contidos e níveis recursivos no ORM
Recentemente, tive a sorte de ter uma discussão informal com um desenvolvedor de banco de dados do Facebook. Começamos a falar sobre o CakePHP e ele me disse: “Ah, isso usa ORM não é? Isso pode ser assustador.” Perguntei a ele o que ele queria dizer, e ele comentou que com o mapeamento relacional de objeto (ORM) é fácil que as consultas SQL se tornem desnecessariamente grandes.
Ele está certo de certa forma. Parte da mágica do CakePHP está no uso do ORM e na maneira como ele agrupa diferentes relações de tabelas de banco de dados. Por padrão, o CakePHP seleciona automaticamente qualquer dado relacionado 'Pertence a', 'Tem um' e 'Tem muitos', e isso pode levar a consultas SQL muito grandes. Essas consultas podem não ser uma preocupação quando você está desenvolvendo inicialmente um aplicativo, mas após seis meses de coleta de dados ao vivo, você pode descobrir que o aplicativo fica muito lento e, em alguns casos, trava se as consultas não forem otimizadas.
Eu procuro duas coisas ao auditar um site existente. Em primeiro lugar, o nível recursivo padrão foi alterado? Por padrão, o CakePHP define o nível recursivo como 1, que na minha opinião é muito alto. Eu sempre defino como -1 e, em seguida, uso o comportamento contido para obter qualquer modelo relacionado.
Isso leva à segunda coisa que procuro - o comportamento Containable foi usado? Muitas vezes, novos clientes vêm até mim e dizem que o CakePHP é lento. A razão é quase sempre porque o Containable não foi usado! Um bom programador do CakePHP otimizará suas consultas SQL independentemente de quanta “mágica automática” é feita nos bastidores.
O comportamento de contenção não foi adicionado até o CakePHP 1.2, mas cara, isso fez diferença?! Certifique-se de usar o conteiner tanto quanto possível, pois é uma maneira tão eficaz de otimizar seu SQL. Para obter mais informações sobre como implementar e usar o comportamento Containable, clique aqui.
Erro comum nº 3: manter a lógica de negócios em controladores em vez de modelos
Um bom código do CakePHP terá a lógica nos arquivos de modelo. Isso demora um pouco para se acostumar, mas uma vez dominado, não há como voltar atrás! Um arquivo de controlador deve ser usado para o que se destina no padrão MVC - controlar! Portanto, use o arquivo do controlador para lidar com as ações do usuário, deixando a lógica de negócios no arquivo de modelo.
Um bom exemplo disso seria um simples CRUD - uma ação cotidiana! Vamos usar a função adicionar postagens de um tutorial de blog como exemplo. A função de adição padrão é a seguinte:
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.')); } }
Essa ação do controlador é boa para uma adição simples, mas o que aconteceria se você quisesse fazer coisas como enviar um e-mail para o administrador quando uma postagem fosse adicionada ou atualizar outra associação de modelo quando uma postagem fosse adicionada. Essa é uma lógica adicional, mas essa lógica não deve entrar em nosso arquivo de controlador.
Em vez disso, escreveríamos uma função para isso em nosso modelo Post.php
. Talvez algo assim:
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; }
Isso resultaria em uma pequena alteração na ação do controlador da seguinte maneira:

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.')); } }
Como você pode ver, a nova ação é na verdade uma linha a menos, porque $this->Post->create()
foi movido para o arquivo de modelo.
Este é um exemplo diário perfeito de onde mover a lógica para o arquivo de modelo é uma boa ideia - e certamente contribui para uma base de código muito mais limpa!
Erro comum nº 4: adicionar muita complexidade ao código, em vez de retornar com frequência e cedo
Este é sempre um debate contínuo, mas retornar com frequência e retornar mais cedo certamente contribui para um código com aparência muito mais limpa. Isso se aplica aos métodos de modelo mais do que qualquer outra coisa.
Mas o que exatamente quero dizer? Bem, vamos dar uma olhada no método que adicionamos no tutorial do CakePHP acima:
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; }
Retornar com frequência e retornar mais cedo significa que, à medida que executamos nossa função, verificamos se está tudo bem regularmente. Se não for, então retornamos false, ou retornamos um erro do CakePHP.
Pode ser mais fácil mostrar isso com um exemplo. Existem duas maneiras de escrever a função acima:
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; } }
Veja como o código rapidamente se torna ilegível? Existem if
s e else
s por toda parte, e a função rapidamente se torna um grande recuo. Não me interpretem mal, eu adoro recuo limpo, mas observe como a função fica se for escrita com o retorno com frequência, retorne o princípio inicial.
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; }
Imediatamente, neste pequeno exemplo, você pode ver que o código tem apenas um recuo e é muito mais legível. A lógica realmente faz mais sentido - deixe a lógica percorrer linha por linha e, se houver algum problema ao longo do caminho, retorne o erro e não prossiga para a próxima linha.
Isso permite que um programador do CakePHP escreva da mesma maneira que nós lemos - lendo o código da esquerda para a direita, de cima para baixo, em vez de em blocos diferentes, o que pode rapidamente se tornar confuso!
Erro comum nº 5: não usar o princípio DRY
DRY significa Don't Repeat Yourself, e é uma filosofia que deve ser seguida ao codificar no CakePHP. Com código orientado a objetos, não há desculpa para repetir o mesmo bloco de código duas vezes!
Aqui estão algumas dicas do CakePHP para garantir que você não se repita:
Como mencionado acima, tente colocar a lógica nos arquivos de modelo para que você possa compartilhar a lógica.
Em seus arquivos de visualização, se você estiver repetindo visualizações, crie o código de visualização como um elemento ou até mesmo um auxiliar personalizado.
Defina algumas configurações - o arquivo
app/Config/bootstrap.php
é um ótimo lugar para isso. Isso ajuda a garantir que você não esteja codificando coisas como o nome do aplicativo e o endereço de e-mail principal. A última coisa que você quer fazer é passar por centenas de arquivos só porque o cliente pediu para atualizar um endereço de e-mail em um aplicativo.Sempre pergunte a si mesmo: “Se estou repetindo código, existe uma maneira melhor de escrever esse código e estou colocando esse código no lugar certo?” As chances são de que, se você precisar repetir o código, ele poderia ser escrito melhor.
Erro comum nº 6: não comentar o código
O último ponto que farei é em relação aos comentários. Em primeiro lugar, o bloqueio de documentos. Um bloco doc é quando você documenta um método ou uma ação. Leva apenas um minuto para gravar um pouco sobre o que uma função está fazendo, mas faz muita diferença em termos de legibilidade do código.
CakePHP Doc Blocks precisam ir contra a margem esquerda da página. Então, um exemplo simples usando o código acima.
/** * 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) {
Como você verá, não demora muito para escrever um bloco doc, mas faz uma grande diferença em termos de longevidade do código. Em última análise, isso significa que o código pode viver além de você como desenvolvedor.
Da mesma forma com comentários em linha. Não tenha medo de explicar o que seu código está fazendo e por quê! A longo prazo, fica muito mais fácil entender seu código, especialmente se outro desenvolvedor estiver olhando para ele!
Embrulhar
O CakePHP é um framework extenso e completo. Dado que segue a convenção sobre a configuração, o CakePHP é mais rigoroso do que outros frameworks baseados em PHP, no sentido de que um usuário é “forçado” a seguir uma certa maneira de definir o código. Isso pode ser controverso, mas na minha experiência leva a uma base de código que é mais consistente, legível e compreensível - em vez de deixar um desenvolvedor “escolher” como o código deve ser escrito, uma equipe de desenvolvimento escreverá um código consistente seguindo as convenções do Cake .
Seguindo este tutorial do CakePHP e garantindo que seu código esteja bem escrito, os aplicativos podem resistir ao teste do tempo. O código deve sempre ser escrito para amanhã - para que, se outro desenvolvedor estiver analisando um bloco de código específico anos depois, ele entenderá o código e seguirá os padrões esperados. O CakePHP não é diferente e espero que este guia ajude a corrigir alguns maus hábitos.