<h2>Estrutura de Projeto e Padrões Modernos</h2>
<p>PHP moderno em produção começa com uma arquitetura sólida. A maioria dos projetos sérios utiliza <strong>PSR-4 para autoloading</strong>, <strong>namespaces</strong> e o padrão <strong>MVC ou Clean Architecture</strong>. Isso não é opcional — é a base para manutenibilidade e escalabilidade. Usamos Composer como gerenciador de dependências, que padroniza a forma como importamos bibliotecas.</p>
<pre><code class="language-php"><?php
// composer.json
{
"name": "meu-projeto/app",
"require": {
"php": ">=8.1",
"symfony/http-foundation": "^6.0",
"doctrine/orm": "^2.14"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
// src/User/UserRepository.php
namespace App\User;
class UserRepository
{
public function findById(int $id): ?User
{
// Implementação
return null;
}
}
// src/User/User.php
namespace App\User;
class User
{
public function __construct(
private int $id,
private string $email,
private string $password
) {}
public function getId(): int
{
return $this->id;
}
}</code></pre>
<p>A estrutura de diretórios é essencial. Separe <strong>src/</strong> (código), <strong>tests/</strong> (testes), <strong>config/</strong> (configurações) e <strong>public/</strong> (entrada web). Nunca coloque lógica no public; use um único entry point.</p>
<h2>Segurança e Boas Práticas de Código</h2>
<p>Segurança em produção não é "algo a mais" — é fundamental. <strong>SQL injection, XSS, CSRF e validação inadequada</strong> continuam sendo os principais culpados de vazamentos. Use prepared statements sempre, valide inputs agressivamente e implemente rate limiting.</p>
<pre><code class="language-php"><?php
// Errado: vulnerável a SQL injection
$user = $pdo->query("SELECT * FROM users WHERE email = '{$_POST['email']}'");
// Correto: prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST['email']]);
$user = $stmt->fetch();
// Validação robusta com filter_var
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Email inválido');
}
// Proteção CSRF com tokens
session_start();
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Verificar no formulário
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
throw new RuntimeException('Token CSRF inválido');
}
// Hashing seguro de senhas
$hash = password_hash($_POST['password'], PASSWORD_ARGON2ID, ['memory_cost' => 65536]);
if (!password_verify($input_password, $hash)) {
throw new RuntimeException('Senha incorreta');
}
// Headers de segurança
header('Content-Security-Policy: default-src \'self\'');
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('Strict-Transport-Security: max-age=31536000; includeSubDomains');</code></pre>
<p>Use <strong>type hints</strong> agressivamente (PHP 8.1+). Eles não são apenas boas práticas — são proteção contra bugs. Implemente <strong>early returns</strong> para reduzir complexidade ciclomática e sempre trate erros com exceções bem definidas.</p>
<h2>Testes, Logs e Monitoramento</h2>
<p>Código em produção sem testes é código quebrado que você ainda não descobriu. Implemente <strong>testes unitários, de integração e end-to-end</strong>. Use PHPUnit para testes estruturados e mantenha cobertura acima de 80%. Logs estruturados com Monolog permitem rastrear problemas em produção; use níveis apropriados (DEBUG, INFO, WARNING, ERROR, CRITICAL).</p>
<pre><code class="language-php"><?php
// tests/User/UserRepositoryTest.php
namespace Tests\User;
use App\User\UserRepository;
use PHPUnit\Framework\TestCase;
class UserRepositoryTest extends TestCase
{
private UserRepository $repository;
protected function setUp(): void
{
$this->repository = new UserRepository();
}
public function testFindByIdReturnsNullWhenNotFound(): void
{
$result = $this->repository->findById(999);
$this->assertNull($result);
}
public function testFindByIdReturnsUserInstance(): void
{
$user = $this->repository->findById(1);
$this->assertInstanceOf(User::class, $user);
$this->assertEquals(1, $user->getId());
}
}
// src/Logger/ApplicationLogger.php
namespace App\Logger;
use Monolog\Logger;
use Monolog\Handlers\StreamHandler;
class ApplicationLogger
{
private Logger $logger;
public function __construct()
{
$this->logger = new Logger('app');
$this->logger->pushHandler(
new StreamHandler('var/logs/app.log', Logger::DEBUG)
);
}
public function logUserLogin(int $userId): void
{
$this->logger->info('User login', ['user_id' => $userId]);
}
public function logException(\Throwable $e): void
{
$this->logger->error('Exception occurred', [
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
}
}</code></pre>
<p>Configure <strong>APM (Application Performance Monitoring)</strong> como Sentry ou NewRelic. Logs locais são insuficientes em produção — você precisa visibilidade em tempo real sobre performance, erros e comportamento do usuário.</p>
<h2>Deploy, Variáveis de Ambiente e Performance</h2>
<p>Nunca commite credenciais ou configurações no Git. Use <strong>dotenv</strong> para gerenciar variáveis de ambiente. Separe claramente configuração (que muda entre ambientes) de código.</p>
<pre><code class="language-php"><?php
// .env.example (commitar no repositório)
DATABASE_URL=mysql://user:pass@localhost/dbname
REDIS_URL=redis://localhost:6379
LOG_LEVEL=DEBUG
APP_ENV=development
// .env (NÃO commitar — apenas local/produção)
DATABASE_URL=mysql://prod_user:prod_pass@prod-db:3306/prod_db
REDIS_URL=redis://prod-cache:6379
LOG_LEVEL=WARNING
APP_ENV=production
// config/Database.php
namespace App\Config;
use Dotenv\Dotenv;
class Database
{
public static function connect(): \PDO
{
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();
$url = $_ENV['DATABASE_URL'];
return new \PDO($url);
}
}</code></pre>
<p>Para performance, implemente <strong>caching em múltiplas camadas</strong>: Redis para sessão e dados quentes, APCu para dados estáticos, e HTTP caching via headers. Use <strong>lazy loading</strong>, evite N+1 queries com eager loading em ORMs, e perfil seu código com Xdebug ou Blackfire.</p>
<pre><code class="language-php"><?php
// Cache com Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$cacheKey = 'user:' . $userId;
$user = $redis->get($cacheKey);
if ($user === false) {
$user = $repository->findById($userId); // Query ao BD
$redis->setex($cacheKey, 3600, serialize($user)); // Cache por 1h
}
// Eager loading para evitar N+1
$users = $repository->findAllWithPosts(); // JOINs no SQL</code></pre>
<h2>Conclusão</h2>
<p>Dominar PHP moderno em produção exige três pilares: <strong>(1) Arquitetura sólida</strong> com padrões, namespaces e estrutura clara; <strong>(2) Segurança rigorosa</strong> com validação, prepared statements e headers apropriados; <strong>(3) Observabilidade</strong> via testes, logs estruturados e monitoramento real-time. Não pule essas etapas por "ganho de tempo" — código inseguro ou difícil de debugar custará muito mais depois.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://phptherightway.com/" target="_blank" rel="noopener noreferrer">PHP: The Right Way</a></li>
<li><a href="https://www.php.net/manual/pt_BR/" target="_blank" rel="noopener noreferrer">Documentação Oficial PHP 8.1+</a></li>
<li><a href="https://symfony.com/doc/current/best_practices.html" target="_blank" rel="noopener noreferrer">Symfony Best Practices</a></li>
<li><a href="https://owasp.org/www-project-web-security-testing-guide/" target="_blank" rel="noopener noreferrer">OWASP Security Testing Guide</a></li>
<li><a href="https://www.php-fig.org/" target="_blank" rel="noopener noreferrer">PHP Standards Recommendations (PSR)</a></li>
</ul>