O PHP continua sendo uma das linguagens de programação mais utilizadas no desenvolvimento web, alimentando aproximadamente 86% das aplicações web em todo o mundo [1]. Apesar de sua popularidade duradoura, muitos desenvolvedores ainda cometem erros básicos que podem comprometer a segurança, performance e manutenibilidade de suas aplicações. Este guia abrangente apresenta as principais boas práticas que todo desenvolvedor PHP deve conhecer e implementar em 2025.
Por que as Boas Práticas Importam?
Como bem disse Harrison Ford: “Meça duas vezes, corte uma vez só” [2]. Esta filosofia se aplica perfeitamente ao desenvolvimento de software. Implementar boas práticas desde o início do projeto pode economizar horas preciosas de depuração, melhorar significativamente a performance da aplicação e reduzir drasticamente vulnerabilidades de segurança.
O PHP evoluiu consideravelmente ao longo dos anos, incorporando recursos modernos de programação orientada a objetos, tipagem estrita, e ferramentas avançadas de desenvolvimento. Contudo, essa evolução também trouxe a necessidade de atualizar nossas práticas de desenvolvimento para aproveitar ao máximo essas melhorias.
1. Utilizando Versões Atualizadas do PHP
A Importância de Manter-se Atualizado
Uma das práticas mais fundamentais, porém frequentemente negligenciada, é utilizar versões atualizadas do PHP. Atualmente, a versão estável recomendada é o PHP 8.4, que oferece melhorias significativas em performance, segurança e funcionalidades [3].
Cada versão do PHP é oficialmente suportada por três anos, após os quais entra no fim do ciclo de vida. Utilizar versões desatualizadas expõe sua aplicação a vulnerabilidades de segurança conhecidas e impede o aproveitamento de otimizações de performance e novos recursos da linguagem.
Benefícios das Versões Modernas
O PHP 8.x introduziu recursos revolucionários como:
•JIT Compilation: Melhora significativa na performance de aplicações computacionalmente intensivas
•Union Types: Maior flexibilidade na tipagem de parâmetros e retornos
•Named Arguments: Código mais legível e manutenível
•Match Expressions: Alternativa mais poderosa ao switch tradicional
•Nullsafe Operator: Redução de verificações verbosas de null
Estes recursos não apenas tornam o código mais eficiente, mas também mais legível e menos propenso a erros.
2. Padrões de Codificação PSR
Compreendendo os PHP Standards Recommendations
O Framework Interop Group (PHP-FIG) desenvolveu uma série de recomendações de padrões conhecidas como PSR (PHP Standards Recommendations) [4]. Estes padrões estabelecem convenções uniformes que facilitam a colaboração entre desenvolvedores e a integração de diferentes bibliotecas e frameworks.
PSR-1: Padrão Básico de Codificação
O PSR-1 estabelece as regras fundamentais para a estrutura do código PHP:
•Arquivos PHP devem usar apenas as tags <?php e <?=
•Arquivos PHP devem usar apenas UTF-8 sem BOM para código PHP
•Arquivos devem declarar símbolos (classes, funções, constantes) OU causar efeitos colaterais, mas não ambos
•Namespaces e classes devem seguir um PSR de autoloading
•Nomes de classes devem ser declarados em StudlyCaps
•Constantes de classe devem ser declaradas em maiúsculas com separadores underscore
•Nomes de métodos devem ser declarados em camelCase
PSR-12: Guia de Estilo de Código
O PSR-12 expande o PSR-1 com regras mais detalhadas sobre formatação:
<?php
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use function Vendor\Package\{functionA, functionB, functionC};
use const Vendor\Package\{CONSTANT_A, CONSTANT_B, CONSTANT_C};
class Foo extends Bar implements FooInterface
{
public function sampleFunction(int $a, int $b = null): array
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// corpo do método
}
}
PSR-4: Autoloading
O PSR-4 define como implementar autoloading de classes a partir de caminhos de arquivo. Esta prática elimina a necessidade de includes manuais e melhora significativamente a organização do código:
// Estrutura de diretórios
src/
Acme/
Log/
Writer/
File_Writer.php # Acme\Log\Writer\File_Writer
Logger.php # Acme\Log\Logger
Foo.php # Acme\Foo
3. Segurança: Protegendo Sua Aplicação
Validação e Sanitização de Dados
A segurança deve ser uma preocupação primária em qualquer aplicação PHP. Todos os dados provenientes de usuários ou fontes externas devem ser rigorosamente validados e sanitizados antes do processamento [5].
Utilizando filter_var() e filter_input()
O PHP oferece funções nativas poderosas para validação e sanitização:
// Validação de email
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email === false) {
throw new InvalidArgumentException('Email inválido');
}
// Sanitização de string
$nome = filter_var($_POST['nome'], FILTER_SANITIZE_STRING);
// Validação direta do input
$idade = filter_input(INPUT_POST, 'idade', FILTER_VALIDATE_INT, [
'options' => [
'min_range' => 1,
'max_range' => 120
]
]);
Prevenção de SQL Injection
SQL Injection continua sendo uma das vulnerabilidades mais comuns e perigosas. A utilização de prepared statements é essencial:
// INCORRETO - Vulnerável a SQL Injection
$query = "SELECT * FROM users WHERE email = '" . $_POST['email'] . "'";
$result = mysqli_query($connection, $query);
// CORRETO - Usando prepared statements
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND status = ?");
$stmt->execute([$email, $status]);
$user = $stmt->fetch();
Prevenção de Cross-Site Scripting (XSS)
Sempre escape dados ao exibi-los na interface:
// Escapando output para HTML echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8'); // Para contextos específicos echo htmlentities($userInput, ENT_QUOTES | ENT_HTML5, 'UTF-8');
Implementação de CSRF Protection
// Gerando token CSRF
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Validando token CSRF
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
throw new Exception('Token CSRF inválido');
}
4. Princípios SOLID: Fundamentos da Programação Orientada a Objetos
Os princípios SOLID, popularizados por Robert C. Martin em seu livro “Código Limpo”, constituem a base para escrever código orientado a objetos de alta qualidade [6]. Estes cinco princípios trabalham em conjunto para criar sistemas mais flexíveis, manuteníveis e testáveis.
Single Responsibility Principle (SRP) – Princípio da Responsabilidade Única
Cada classe deve ter apenas uma razão para mudar, ou seja, deve ter apenas uma responsabilidade. Este princípio facilita enormemente os testes e a manutenção do código.
// INCORRETO - Classe com múltiplas responsabilidades
class User
{
private $name;
private $email;
public function save()
{
// Validação
if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Email inválido');
}
// Persistência no banco
$pdo = new PDO('mysql:host=localhost;dbname=app', $user, $pass);
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$this->name, $this->email]);
// Envio de email
mail($this->email, 'Bem-vindo', 'Obrigado por se cadastrar');
}
}
// CORRETO - Responsabilidades separadas
class User
{
private $name;
private $email;
public function getName(): string
{
return $this->name;
}
public function getEmail(): string
{
return $this->email;
}
}
class UserValidator
{
public function validate(User $user): bool
{
return filter_var($user->getEmail(), FILTER_VALIDATE_EMAIL) !== false;
}
}
class UserRepository
{
private $pdo;
public function save(User $user): void
{
$stmt = $this->pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$user->getName(), $user->getEmail()]);
}
}
class EmailService
{
public function sendWelcomeEmail(User $user): void
{
mail($user->getEmail(), 'Bem-vindo', 'Obrigado por se cadastrar');
}
}
Open/Closed Principle (OCP) – Princípio Aberto/Fechado
Classes devem estar abertas para extensão, mas fechadas para modificação. Isso significa que devemos poder adicionar novas funcionalidades sem alterar o código existente.
// Interface base
interface PaymentProcessor
{
public function processPayment(float $amount): bool;
}
// Implementações específicas
class CreditCardProcessor implements PaymentProcessor
{
public function processPayment(float $amount): bool
{
// Lógica específica para cartão de crédito
return true;
}
}
class PayPalProcessor implements PaymentProcessor
{
public function processPayment(float $amount): bool
{
// Lógica específica para PayPal
return true;
}
}
// Classe que usa os processadores
class PaymentService
{
public function process(PaymentProcessor $processor, float $amount): bool
{
return $processor->processPayment($amount);
}
}
// Adicionando novo processador sem modificar código existente
class BitcoinProcessor implements PaymentProcessor
{
public function processPayment(float $amount): bool
{
// Lógica específica para Bitcoin
return true;
}
}
Liskov Substitution Principle (LSP) – Princípio da Substituição de Liskov
Objetos de uma classe derivada devem poder substituir objetos da classe base sem alterar a funcionalidade do programa. Este princípio garante que a herança seja usada corretamente.
// Exemplo problemático que viola LSP
class Rectangle
{
protected $width;
protected $height;
public function setWidth(float $width): void
{
$this->width = $width;
}
public function setHeight(float $height): void
{
$this->height = $height;
}
public function getArea(): float
{
return $this->width * $this->height;
}
}
class Square extends Rectangle
{
public function setWidth(float $width): void
{
$this->width = $width;
$this->height = $width; // Viola LSP
}
public function setHeight(float $height): void
{
$this->height = $height;
$this->width = $height; // Viola LSP
}
}
// Solução que respeita LSP
interface Shape
{
public function getArea(): float;
}
class Rectangle implements Shape
{
private $width;
private $height;
public function __construct(float $width, float $height)
{
$this->width = $width;
$this->height = $height;
}
public function getArea(): float
{
return $this->width * $this->height;
}
}
class Square implements Shape
{
private $side;
public function __construct(float $side)
{
$this->side = $side;
}
public function getArea(): float
{
return $this->side * $this->side;
}
}
Interface Segregation Principle (ISP) – Princípio da Segregação de Interfaces
Clientes não devem ser forçados a depender de interfaces que não utilizam. É melhor ter várias interfaces específicas do que uma interface geral.
// INCORRETO - Interface muito ampla
interface Worker
{
public function work(): void;
public function eat(): void;
public function sleep(): void;
}
class Human implements Worker
{
public function work(): void { /* implementação */ }
public function eat(): void { /* implementação */ }
public function sleep(): void { /* implementação */ }
}
class Robot implements Worker
{
public function work(): void { /* implementação */ }
public function eat(): void { /* Robôs não comem! */ }
public function sleep(): void { /* Robôs não dormem! */ }
}
// CORRETO - Interfaces segregadas
interface Workable
{
public function work(): void;
}
interface Eatable
{
public function eat(): void;
}
interface Sleepable
{
public function sleep(): void;
}
class Human implements Workable, Eatable, Sleepable
{
public function work(): void { /* implementação */ }
public function eat(): void { /* implementação */ }
public function sleep(): void { /* implementação */ }
}
class Robot implements Workable
{
public function work(): void { /* implementação */ }
}
Dependency Inversion Principle (DIP) – Princípio da Inversão de Dependência
Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.
// INCORRETO - Dependência direta de implementação concreta
class EmailService
{
private $mailer;
public function __construct()
{
$this->mailer = new SMTPMailer(); // Dependência rígida
}
public function sendEmail(string $to, string $subject, string $body): void
{
$this->mailer->send($to, $subject, $body);
}
}
// CORRETO - Dependência de abstração
interface MailerInterface
{
public function send(string $to, string $subject, string $body): void;
}
class SMTPMailer implements MailerInterface
{
public function send(string $to, string $subject, string $body): void
{
// Implementação SMTP
}
}
class SendGridMailer implements MailerInterface
{
public function send(string $to, string $subject, string $body): void
{
// Implementação SendGrid
}
}
class EmailService
{
private $mailer;
public function __construct(MailerInterface $mailer)
{
$this->mailer = $mailer; // Dependência flexível
}
public function sendEmail(string $to, string $subject, string $body): void
{
$this->mailer->send($to, $subject, $body);
}
}
5. Gerenciamento de Dependências com Composer
O Composer revolucionou o ecossistema PHP ao fornecer uma ferramenta robusta para gerenciamento de dependências [7]. Utilizar o Composer adequadamente é essencial para projetos PHP modernos.
Configuração Básica do composer.json
{
"name": "vendor/projeto",
"description": "Descrição do projeto",
"type": "project",
"require": {
"php": ">=8.1",
"monolog/monolog": "^3.0",
"guzzlehttp/guzzle": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"squizlabs/php_codesniffer": "^3.7"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"cs-check": "phpcs",
"cs-fix": "phpcbf"
}
}
Boas Práticas com Composer
1.Versionamento Semântico: Use constraints apropriadas (^, ~, *) para permitir atualizações seguras
2.Lock File: Sempre commite o composer.lock para garantir builds reproduzíveis
3.Scripts Personalizados: Defina scripts para automatizar tarefas comuns
4.Otimização: Use composer install –optimize-autoloader –no-dev em produção
6. Tratamento de Erros e Exceções
Hierarquia de Exceções Personalizada
Criar uma hierarquia bem estruturada de exceções melhora significativamente o tratamento de erros:
// Exceção base da aplicação
abstract class AppException extends Exception
{
protected $context = [];
public function __construct(string $message = "", int $code = 0, Throwable $previous = null, array $context = [])
{
parent::__construct($message, $code, $previous);
$this->context = $context;
}
public function getContext(): array
{
return $this->context;
}
}
// Exceções específicas por domínio
class ValidationException extends AppException {}
class DatabaseException extends AppException {}
class AuthenticationException extends AppException {}
class AuthorizationException extends AppException {}
// Uso prático
class UserService
{
public function createUser(array $data): User
{
try {
$this->validateUserData($data);
return $this->userRepository->create($data);
} catch (InvalidArgumentException $e) {
throw new ValidationException(
'Dados de usuário inválidos',
0,
$e,
['data' => $data]
);
} catch (PDOException $e) {
throw new DatabaseException(
'Erro ao criar usuário no banco de dados',
0,
$e,
['data' => $data]
);
}
}
}
Logging Estruturado
Implementar logging estruturado facilita a depuração e monitoramento:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\JsonFormatter;
class AppLogger
{
private static $instance;
private $logger;
private function __construct()
{
$this->logger = new Logger('app');
$handler = new StreamHandler('php://stdout', Logger::DEBUG);
$handler->setFormatter(new JsonFormatter());
$this->logger->pushHandler($handler);
}
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function logException(Throwable $e, array $context = []): void
{
$this->logger->error($e->getMessage(), [
'exception' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'context' => $context
]);
}
}
7. Otimização de Performance
OPcache: Aceleração Fundamental
O OPcache é uma extensão que melhora significativamente a performance do PHP ao armazenar bytecode compilado na memória [8]. Sua configuração adequada é essencial para aplicações em produção:
; Configurações recomendadas para OPcache opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=20000 opcache.validate_timestamps=0 opcache.save_comments=1 opcache.fast_shutdown=1
Strict Types: Melhor Performance e Segurança
Declarar tipos estritos no início dos arquivos PHP melhora tanto a performance quanto a detecção precoce de erros:
<?php
declare(strict_types=1);
class Calculator
{
public function add(int $a, int $b): int
{
return $a + $b;
}
public function divide(float $a, float $b): float
{
if ($b === 0.0) {
throw new InvalidArgumentException('Divisão por zero não permitida');
}
return $a / $b;
}
}
Otimização de Consultas ao Banco de Dados
class OptimizedUserRepository
{
private $pdo;
private $cache;
public function findActiveUsers(): array
{
$cacheKey = 'active_users';
// Verificar cache primeiro
if ($cached = $this->cache->get($cacheKey)) {
return $cached;
}
// Query otimizada com índices apropriados
$stmt = $this->pdo->prepare("
SELECT id, name, email
FROM users
WHERE status = 'active'
AND last_login > DATE_SUB(NOW(), INTERVAL 30 DAY)
ORDER BY last_login DESC
LIMIT 100
");
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Armazenar no cache por 5 minutos
$this->cache->set($cacheKey, $users, 300);
return $users;
}
}
Memory Management e Profiling
class MemoryOptimizedProcessor
{
public function processLargeDataset(string $filename): void
{
$handle = fopen($filename, 'r');
if (!$handle) {
throw new RuntimeException("Não foi possível abrir o arquivo: {$filename}");
}
try {
while (($line = fgets($handle)) !== false) {
$this->processLine($line);
// Liberar memória periodicamente
if (memory_get_usage() > 50 * 1024 * 1024) { // 50MB
gc_collect_cycles();
}
}
} finally {
fclose($handle);
}
}
private function processLine(string $line): void
{
// Processar linha individual
$data = json_decode($line, true);
// ... lógica de processamento
// Limpar variáveis grandes explicitamente
unset($data);
}
}
8. Testes Automatizados
Estrutura de Testes com PHPUnit
Testes automatizados são fundamentais para manter a qualidade do código. O PHPUnit é o framework de testes mais popular para PHP:
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase
{
private Calculator $calculator;
protected function setUp(): void
{
$this->calculator = new Calculator();
}
public function testAddition(): void
{
$result = $this->calculator->add(2, 3);
$this->assertEquals(5, $result);
}
public function testDivision(): void
{
$result = $this->calculator->divide(10.0, 2.0);
$this->assertEquals(5.0, $result);
}
public function testDivisionByZeroThrowsException(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Divisão por zero não permitida');
$this->calculator->divide(10.0, 0.0);
}
/**
* @dataProvider additionProvider
*/
public function testAdditionWithDataProvider(int $a, int $b, int $expected): void
{
$result = $this->calculator->add($a, $b);
$this->assertEquals($expected, $result);
}
public function additionProvider(): array
{
return [
[1, 2, 3],
[0, 0, 0],
[-1, 1, 0],
[100, 200, 300]
];
}
}
Testes de Integração
class UserServiceIntegrationTest extends TestCase
{
private UserService $userService;
private PDO $pdo;
protected function setUp(): void
{
// Configurar banco de dados de teste
$this->pdo = new PDO('sqlite::memory:');
$this->pdo->exec('
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
email VARCHAR(255) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
');
$userRepository = new UserRepository($this->pdo);
$emailService = $this->createMock(EmailService::class);
$this->userService = new UserService($userRepository, $emailService);
}
public function testCreateUserSuccessfully(): void
{
$userData = [
'name' => 'João Silva',
'email' => 'joao@example.com'
];
$user = $this->userService->createUser($userData);
$this->assertInstanceOf(User::class, $user);
$this->assertEquals('João Silva', $user->getName());
$this->assertEquals('joao@example.com', $user->getEmail());
// Verificar se foi salvo no banco
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute(['joao@example.com']);
$savedUser = $stmt->fetch(PDO::FETCH_ASSOC);
$this->assertNotFalse($savedUser);
$this->assertEquals('João Silva', $savedUser['name']);
}
}
Mocks e Stubs
class PaymentServiceTest extends TestCase
{
public function testProcessPaymentWithMockedProcessor(): void
{
// Criar mock do processador de pagamento
$mockProcessor = $this->createMock(PaymentProcessor::class);
$mockProcessor
->expects($this->once())
->method('processPayment')
->with(100.0)
->willReturn(true);
$paymentService = new PaymentService();
$result = $paymentService->process($mockProcessor, 100.0);
$this->assertTrue($result);
}
public function testProcessPaymentFailure(): void
{
$mockProcessor = $this->createMock(PaymentProcessor::class);
$mockProcessor
->method('processPayment')
->willThrowException(new PaymentException('Cartão recusado'));
$this->expectException(PaymentException::class);
$paymentService = new PaymentService();
$paymentService->process($mockProcessor, 100.0);
}
}
9. Ferramentas de Qualidade de Código
PHP_CodeSniffer: Verificação de Padrões
O PHP_CodeSniffer verifica se o código segue padrões estabelecidos:
# Instalar via Composer composer require --dev squizlabs/php_codesniffer # Verificar código contra PSR-12 ./vendor/bin/phpcs --standard=PSR12 src/ # Corrigir automaticamente problemas ./vendor/bin/phpcbf --standard=PSR12 src/
PHPStan: Análise Estática
PHPStan detecta bugs potenciais sem executar o código:
# Instalar PHPStan composer require --dev phpstan/phpstan # Executar análise ./vendor/bin/phpstan analyse src/ --level=8
Configuração phpstan.neon:
parameters:
level: 8
paths:
- src
excludePaths:
- src/legacy
ignoreErrors:
- '#Call to an undefined method#'
Psalm: Verificação de Tipos
# Instalar Psalm composer require --dev vimeo/psalm # Inicializar configuração ./vendor/bin/psalm --init # Executar verificação ./vendor/bin/psalm
Configuração de CI/CD
Exemplo de configuração GitHub Actions:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: [8.1, 8.2, 8.3]
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite
coverage: xdebug
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run code style check
run: ./vendor/bin/phpcs
- name: Run static analysis
run: ./vendor/bin/phpstan analyse
- name: Run tests
run: ./vendor/bin/phpunit --coverage-clover coverage.xml
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
10. Estrutura de Projeto e Organização
Estrutura de Diretórios Recomendada
projeto/ ├── config/ │ ├── app.php │ ├── database.php │ └── services.php ├── public/ │ ├── index.php │ └── assets/ ├── src/ │ ├── Controller/ │ ├── Model/ │ ├── Service/ │ ├── Repository/ │ └── Exception/ ├── tests/ │ ├── Unit/ │ ├── Integration/ │ └── Functional/ ├── vendor/ ├── .env.example ├── .gitignore ├── composer.json ├── phpunit.xml └── README.md
Configuração de Ambiente
// config/app.php
<?php
declare(strict_types=1);
return [
'app' => [
'name' => $_ENV['APP_NAME'] ?? 'Minha Aplicação',
'env' => $_ENV['APP_ENV'] ?? 'production',
'debug' => filter_var($_ENV['APP_DEBUG'] ?? false, FILTER_VALIDATE_BOOLEAN),
'url' => $_ENV['APP_URL'] ?? 'http://localhost',
],
'database' => [
'default' => $_ENV['DB_CONNECTION'] ?? 'mysql',
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => $_ENV['DB_HOST'] ?? '127.0.0.1',
'port' => $_ENV['DB_PORT'] ?? '3306',
'database' => $_ENV['DB_DATABASE'] ?? 'app',
'username' => $_ENV['DB_USERNAME'] ?? 'root',
'password' => $_ENV['DB_PASSWORD'] ?? '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
],
],
],
'cache' => [
'default' => $_ENV['CACHE_DRIVER'] ?? 'file',
'stores' => [
'file' => [
'driver' => 'file',
'path' => __DIR__ . '/../storage/cache',
],
'redis' => [
'driver' => 'redis',
'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1',
'port' => $_ENV['REDIS_PORT'] ?? 6379,
],
],
],
];
11. Documentação e Comentários
PHPDoc: Documentação Padrão
<?php
declare(strict_types=1);
/**
* Serviço responsável pelo gerenciamento de usuários
*
* Esta classe fornece métodos para criar, atualizar, buscar e deletar
* usuários do sistema, incluindo validações e notificações.
*
* @package App\Service
* @author Manus AI <contato@manus.ai>
* @version 1.0.0
* @since 1.0.0
*/
class UserService
{
/**
* Repositório de usuários
*
* @var UserRepositoryInterface
*/
private UserRepositoryInterface $userRepository;
/**
* Serviço de email
*
* @var EmailServiceInterface
*/
private EmailServiceInterface $emailService;
/**
* Construtor do serviço de usuários
*
* @param UserRepositoryInterface $userRepository Repositório de usuários
* @param EmailServiceInterface $emailService Serviço de email
*/
public function __construct(
UserRepositoryInterface $userRepository,
EmailServiceInterface $emailService
) {
$this->userRepository = $userRepository;
$this->emailService = $emailService;
}
/**
* Cria um novo usuário no sistema
*
* Este método valida os dados fornecidos, cria o usuário no banco de dados
* e envia um email de boas-vindas.
*
* @param array<string, mixed> $userData Dados do usuário a ser criado
* @return User O usuário criado
*
* @throws ValidationException Quando os dados são inválidos
* @throws DatabaseException Quando ocorre erro na persistência
* @throws EmailException Quando falha o envio do email
*
* @example
* ```php
* $userData = [
* 'name' => 'João Silva',
* 'email' => 'joao@example.com',
* 'password' => 'senha123'
* ];
* $user = $userService->createUser($userData);
* ```
*/
public function createUser(array $userData): User
{
$this->validateUserData($userData);
$user = new User(
$userData['name'],
$userData['email'],
password_hash($userData['password'], PASSWORD_ARGON2ID)
);
$savedUser = $this->userRepository->save($user);
$this->emailService->sendWelcomeEmail($savedUser);
return $savedUser;
}
/**
* Valida os dados do usuário
*
* @param array<string, mixed> $userData Dados a serem validados
* @return void
*
* @throws ValidationException Quando os dados são inválidos
*/
private function validateUserData(array $userData): void
{
$required = ['name', 'email', 'password'];
foreach ($required as $field) {
if (empty($userData[$field])) {
throw new ValidationException("Campo obrigatório: {$field}");
}
}
if (!filter_var($userData['email'], FILTER_VALIDATE_EMAIL)) {
throw new ValidationException('Email inválido');
}
if (strlen($userData['password']) < 8) {
throw new ValidationException('Senha deve ter pelo menos 8 caracteres');
}
}
}
Conclusão
As boas práticas apresentadas neste guia representam o estado da arte do desenvolvimento PHP moderno. Implementar essas práticas não é apenas uma questão de seguir convenções, mas sim de construir aplicações mais seguras, performáticas e manuteníveis.
O PHP evoluiu significativamente desde suas primeiras versões, transformando-se em uma linguagem robusta e adequada para projetos de qualquer escala. Contudo, essa evolução também trouxe a responsabilidade de acompanhar as melhores práticas e utilizar adequadamente os recursos disponíveis.
Pontos-Chave para Implementação
- 1.Comece com o Básico: Utilize versões atualizadas do PHP e siga os padrões PSR
- 2.Priorize a Segurança: Implemente validação rigorosa e use prepared statements
- 3.Estruture Bem o Código: Aplique os princípios SOLID e mantenha responsabilidades bem definidas
- 4.Automatize Testes: Invista em testes automatizados desde o início do projeto
- 5.Use Ferramentas de Qualidade: Integre análise estática e verificação de padrões no seu workflow
- 6.Documente Adequadamente: Mantenha documentação clara e atualizada
O Futuro do PHP
O PHP continua evoluindo com releases anuais que trazem melhorias de performance, novos recursos e maior robustez. Manter-se atualizado com essas evoluções e adaptar suas práticas de desenvolvimento é essencial para aproveitar ao máximo o potencial da linguagem.
Lembre-se de que boas práticas não são regras rígidas, mas sim diretrizes que devem ser adaptadas ao contexto específico de cada projeto. O importante é manter sempre o foco na qualidade, segurança e manutenibilidade do código.
Referências
[1] PHP Usage Statistics – W3Techs. Disponível em:
https://w3techs.com/technologies/details/pl-php
[2] Blog GeekHunter – Boas práticas de programação em PHP. Disponível em:
[3] PHP: The Right Way – Use the Current Stable Version. Disponível em:
https://phptherightway.com/#use_the_current_stable_version
[4] PHP-FIG – PHP Standards Recommendations. Disponível em:
[5] PHP: The Right Way – Security. Disponível em:
https://phptherightway.com/#security
[6] Martin, Robert C. “Clean Code: A Handbook of Agile Software Craftsmanship”. Prentice Hall, 2008.
[7] Composer – Dependency Manager for PHP. Disponível em:
[8] PHP Manual – OPcache. Disponível em: