
Recentemente, tive a oportunidade ocasional de trabalhar com vários aplicativos PHP antigos. Notei alguns antipadrões comuns que precisaram ser corrigidos. Este artigo não é sobre como reescrever um aplicativo PHP antigo para <inserir o nome da estrutura maravilhosa aqui>, mas como torná-lo mais sustentável e menos incômodo de trabalhar.
Antipadrão # 1: credenciais no código
Este é o mais comum dos piores padrões que encontrei. Em muitos projetos, o código com versão é codificado permanentemente com informações importantes, como nomes e senhas para acessar o banco de dados. Obviamente, esta é uma má prática, pois não permite a criação de ambientes locais, pois o código está atrelado a um ambiente específico. Além disso, qualquer pessoa com acesso ao código pode ver as credenciais geralmente apropriadas para o ambiente de produção.
Para corrigir isso, prefiro um método que funcione para qualquer aplicativo: instale o pacote phpdotenv , que permite criar um arquivo de ambiente e acessar variáveis usando supervariáveis de ambiente.
Vamos criar dois arquivos:
.env.example
um que terá uma versão e servirá como modelo para o arquivo.env
, que conterá as credenciais. O arquivo .env
não tem versão, então adicione-o a .gitignore
. Isso está bem explicado na documentação oficial .
Seu arquivo
.env.example
listará as credenciais:
DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
E os próprios dados estarão no arquivo
.env
:
DB_HOST=localhost
DB_DATABASE=mydb
DB_USERNAME=root
DB_PASSWORD=root
Em um arquivo normal, carregue
.env
:
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
Pode então aplicar-se aos dados contábeis usando, digamos
$_ENV['DB_HOST']
.
Não é recomendável usar o pacote em operação "tal como está", para isso é melhor:
- Injete variáveis de ambiente no tempo de execução do seu contêiner, se você tiver uma implantação baseada em Docker, ou na configuração HTTP do lado do servidor, se possível.
- Variáveis de ambiente de cache para evitar a sobrecarga de leitura de .env em cada solicitação. É assim que o Laravel faz .
Os arquivos de credencial podem ser removidos do histórico do Git .
Antipadrão 2: não use o Composer
Costumava ser muito popular ter uma pasta lib com grandes bibliotecas como o PHPMailer. Isso deve ser evitado de todas as maneiras possíveis quando se trata de controle de versão, portanto, essas dependências devem ser gerenciadas com o Composer . Assim, será muito fácil para você ver qual versão do pacote está em uso e atualizá-la se necessário.
Portanto, instale o Composer e use-o para gerenciar.
Antipadrão # 3: nenhum ambiente local
A maioria dos aplicativos com os quais trabalhei tinha apenas um ambiente: produção.

Mas, ao se livrar do anti-padrão nº 1, você pode personalizar facilmente seu ambiente local. Talvez parte de sua configuração tenha sido codificada em seu código, como os caminhos de inicialização, mas agora você pode mover para
.env
.
Eu uso o Docker para criar ambientes locais. Funciona especialmente bem para projetos mais antigos porque eles geralmente usam versões mais antigas do PHP que você não quer ou não pode instalar.
Você pode usar um serviço como o PHPDocker ou usar um pequeno arquivo
docker-compose.yml
.
Antipadrão # 4: não use a pasta Pública
Acontece que a maioria desses projetos antigos pode ser acessada em suas pastas raiz. Ou seja, qualquer arquivo na raiz estará disponível para leitura pública. Isso é especialmente ruim quando os invasores (como um script infantil) tentam acessar os arquivos incluídos diretamente, porque você pode não ser capaz de determinar a saída se o script acessar todos os arquivos incluídos diretamente.
Obviamente, essa situação é incompatível com o uso do
.env
ou Composer, porque abrir a pasta do fornecedor é uma má ideia . Sim, existem alguns truques para fazer isso; mas, se possível, mova todos os arquivos PHP abertos para os clientes para uma pasta Public
e altere a configuração do servidor para que essa pasta se torne a pasta raiz do seu aplicativo.
Eu normalmente faço isso:
- Crie uma pasta
docker
para arquivos relacionados ao Docker (Nginx config, PHP Dockerfile, etc.). - Crio uma pasta
app
na qual armazeno a lógica de negócios (serviços, classes, etc.). - Crio uma pasta
public
na qual armazeno scripts e recursos PHP (JS / CSS) abertos aos clientes. Esta é a pasta raiz do aplicativo do ponto de vista dos clientes. - Eu crio arquivos
.env
e.env.example
.
Antipadrão 5: problemas de segurança flagrantes
Aplicativos PHP, especialmente os mais antigos que não usam estruturas, muitas vezes sofrem de graves problemas de segurança:
- Devido à falta de escape de parâmetros na consulta, existe o perigo de injeção de SQL. Para evitá-los, use o PDO!
- Existe o perigo de injeção de XSS devido à exibição de dados do usuário sem escape. Use htmlspecialchars para evitá-los.
- … . , , , .
- - CSRF-. Anti-CSRF, .
- Criptografia de senha ruim. Já vi muitos projetos ainda usarem SHA-1 e até MD5 para hashing de senha. O PHP 5.5 pronto para uso tem um bom suporte para BCrypt, é uma pena não usá-lo. Para transferir senhas de maneira confortável, prefiro atualizar os hashes no banco de dados à medida que os usuários fazem login. O principal é ter certeza de que a coluna
password
é longa o suficiente para acomodar as senhas do BCrypt, VARCHAR (255) está bem. Aqui está o pseudocódigo para torná-lo mais claro:
<?php // : $ // : if (strpos($oldPasswordHash, '$') !== 0 && hash_equals($oldPasswordHash, sha1($clearPasswordInput))) { $newPasswordHash = password_hash($clearPasswordInput, PASSWORD_DEFAULT); // password // : } // if (password_verify($clearPasswordInput, $currentPasswordHash)) { // : } // :
Antipadrão # 6: sem testes
Isso é muito comum em aplicativos mais antigos. É quase impossível começar a escrever testes de unidade para todo o aplicativo, então você pode escrever testes funcionais.

Esses são testes de alto nível para ajudá-lo a garantir que a refatoração subsequente de seu aplicativo não o interrompa. Os testes podem ser simples, por exemplo, iniciamos o navegador e entramos no aplicativo, a seguir aguardamos o código HTTP sobre o sucesso da operação e / ou a mensagem correspondente na página final. Para testes, você pode usar PHPUnit ou Cypress ou codeception .
Antipadrão nº 7: Tratamento de erros insatisfatório
Se (ou provavelmente quando) algo quebrar, você precisa descobrir rapidamente. Mas muitos aplicativos antigos não lidam bem com os erros, dependendo da leniência do PHP.
Você precisa ser capaz de detectar e registrar o máximo de erros possível para corrigi-los. Existem bons artigos sobre este assunto .
Além disso, será mais fácil encontrar locais onde ocorrem erros se o sistema lançar exceções específicas.
Antipadrão # 8: variáveis globais
Achei que nunca mais os veria até começar a trabalhar com projetos antigos. Variáveis globais tornam a leitura e compreensão do comportamento do código imprevisível. Resumindo, é mau .
É melhor usar injeção de dependência , porque permite controlar quais instâncias são usadas e onde. Por exemplo, o pacote Pimple teve um bom desempenho .
O que mais pode ser melhorado?
Dependendo do destino do aplicativo ou do orçamento, existem várias outras etapas que você pode seguir para melhorar seu projeto.
Primeiro, se o aplicativo estiver rodando em uma versão anterior do PHP (abaixo de 7), tente atualizá-lo. Na maioria das vezes, isso não causa grandes problemas e, acima de tudo, levará a maior parte do tempo para se livrar das ligações
mysql_ calls
, se houver. Para corrigir isso rapidamente, você pode usar uma biblioteca semelhante , mas é melhor reescrever todas as solicitações de PDO para que todos os parâmetros tenham escape ao mesmo tempo.
Se o aplicativo não usa o padrão MVC, ou seja, a lógica de negócios e os modelos são separados, então é hora de adicionar uma biblioteca de modelos (eu sei que PHP é uma linguagem de modelos, mas as bibliotecas modernas são muito mais convenientes), por exemplo, Smarty, Twig ou Blade.
Finalmente, a longo prazo, é melhor reescrever seu aplicativo em uma estrutura PHP moderna como Laravel ou Symfony. Você terá todas as ferramentas de que precisa para um desenvolvimento de PHP seguro e inteligente. Se o aplicativo for grande, eu recomendo usar o padrão strangler para evitar a reescrita big bang , que pode (e provavelmente terminará) mal. Portanto, você pode migrar aquelas partes do código nas quais está trabalhando atualmente para o novo sistema, mantendo as partes de trabalho antigas intactas até que cheguem até elas.
Esta é uma abordagem eficaz que permite criar um ambiente PHP moderno para o seu dia a dia de trabalho, sem congelar recursos por semanas ou meses, dependendo do projeto.