smithery.ai

legacy-modernizer

Modernização de código PHP legado para padrões atuais (PHP 7.4-8.3).

First seen Mar 22, 2026

Installation

$ npx skills add https://smithery.ai

Summary

  • Modernização de código PHP legado para padrões atuais (PHP 7.4-8.3).
  • Usar para converter código procedural para OOP, atualizar sintaxe deprecated, implementar type hints, substituir arrays por objetos/collections, modernizar callbacks para closures/arrow functions, converter globals para dependency injection, e preparar código para migração de frameworks.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,935 B
  • docs SUMMARY.md 390 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 5 installs

SKILL.md

Legacy Modernizer

Skill para transformação de código PHP legado em código moderno e maintainable.

Checklist de Modernização

  1. Sintaxe PHP 8.x - Type hints, named arguments, match, enums
  2. OOP - Classes, interfaces, traits, composition
  3. SOLID - Single responsibility, dependency injection
  4. PSR - Autoload, coding style, interfaces
  5. Error Handling - Exceptions em vez de error codes
  6. Testing - Código testável e desacoplado

Transformações Comuns

1. Sintaxe Moderna

// ❌ ANTES: PHP 5.x
function getUser($id) {
    global $db;
    $result = mysql_query("SELECT * FROM users WHERE id = " . $id);
    if ($result) {
        return mysql_fetch_assoc($result);
    }
    return false;
}

// ✅ DEPOIS: PHP 8.x
function getUser(int $id): ?array
{
    return DB::table('users')->find($id)?->toArray();
}

2. Type Declarations

// ❌ ANTES
function calcularTotal($items, $desconto) {
    $total = 0;
    foreach ($items as $item) {
        $total += $item['valor'];
    }
    return $total - $desconto;
}

// ✅ DEPOIS
function calcularTotal(array $items, float $desconto = 0): float
{
    $total = array_sum(array_column($items, 'valor'));
    return max(0, $total - $desconto);
}

// ✅ MELHOR: Com objetos
function calcularTotal(Collection $items, float $desconto = 0): float
{
    return max(0, $items->sum('valor') - $desconto);
}

3. Procedural para OOP

// ❌ ANTES: Funções soltas
function criar_contrato($dados) { ... }
function atualizar_contrato($id, $dados) { ... }
function buscar_contrato($id) { ... }
function listar_contratos($filtros) { ... }

// ✅ DEPOIS: Service Class
class ContractService
{
    public function __construct(
        private ContractRepository $repository,
        private EventDispatcher $events
    ) {}

    public function create(array $data): Contract
    {
        $contract = $this->repository->create($data);
        $this->events->dispatch(new ContractCreated($contract));
        return $contract;
    }

    public function update(int $id, array $data): Contract
    {
        $contract = $this->repository->findOrFail($id);
        $contract->update($data);
        return $contract;
    }

    public function find(int $id): ?Contract
    {
        return $this->repository->find($id);
    }

    public function list(array $filters = []): Collection
    {
        return $this->repository->filter($filters);
    }
}

4. Global State para DI

// ❌ ANTES: Globals
function enviarEmail($para, $assunto, $corpo) {
    global $config;
    $mail = new PHPMailer();
    $mail->Host = $config['smtp_host'];
    // ...
}

// ✅ DEPOIS: Dependency Injection
class EmailService
{
    public function __construct(
        private readonly MailerInterface $mailer,
        private readonly MailConfig $config
    ) {}

    public function send(string $to, string $subject, string $body): void
    {
        $this->mailer
            ->to($to)
            ->subject($subject)
            ->body($body)
            ->send();
    }
}

5. Arrays para Value Objects

// ❌ ANTES: Array associativo
$contrato = [
    'cliente' => 'João',
    'valor' => 1500.00,
    'data' => '2024-01-15',
    'status' => 'ativo'
];

// ✅ DEPOIS: DTO/Value Object
readonly class Contract
{
    public function __construct(
        public string $cliente,
        public float $valor,
        public DateTimeImmutable $data,
        public ContractStatus $status
    ) {}

    public static function fromArray(array $data): self
    {
        return new self(
            cliente: $data['cliente'],
            valor: (float) $data['valor'],
            data: new DateTimeImmutable($data['data']),
            status: ContractStatus::from($data['status'])
        );
    }
}

enum ContractStatus: string
{
    case Ativo = 'ativo';
    case Cancelado = 'cancelado';
    case Finalizado = 'finalizado';

    public function label(): string
    {
        return match($this) {
            self::Ativo => 'Ativo',
            self::Cancelado => 'Cancelado',
            self::Finalizado => 'Finalizado',
        };
    }
}

6. Callbacks para Arrow Functions

// ❌ ANTES: Callback verbose
$ativos = array_filter($contratos, function($c) {
    return $c['status'] == 'ativo';
});

$valores = array_map(function($c) {
    return $c['valor'];
}, $ativos);

$total = array_reduce($valores, function($carry, $v) {
    return $carry + $v;
}, 0);

// ✅ DEPOIS: Arrow functions + Collection
$total = collect($contratos)
    ->filter(fn($c) => $c['status'] === 'ativo')
    ->sum('valor');

7. Switch para Match

// ❌ ANTES
switch ($status) {
    case 'pending':
        $label = 'Pendente';
        $color = 'yellow';
        break;
    case 'active':
        $label = 'Ativo';
        $color = 'green';
        break;
    case 'cancelled':
        $label = 'Cancelado';
        $color = 'red';
        break;
    default:
        $label = 'Desconhecido';
        $color = 'gray';
}

// ✅ DEPOIS
[$label, $color] = match($status) {
    'pending' => ['Pendente', 'yellow'],
    'active' => ['Ativo', 'green'],
    'cancelled' => ['Cancelado', 'red'],
    default => ['Desconhecido', 'gray'],
};

8. Error Handling

// ❌ ANTES: Error codes
function processarPagamento($dados) {
    if (!isset($dados['valor'])) {
        return ['erro' => true, 'mensagem' => 'Valor obrigatório'];
    }
    if ($dados['valor'] <= 0) {
        return ['erro' => true, 'mensagem' => 'Valor inválido'];
    }
    // processar...
    return ['erro' => false, 'id' => 123];
}

// ✅ DEPOIS: Exceptions
class PaymentService
{
    public function process(PaymentData $data): Payment
    {
        $this->validate($data);
        
        try {
            return $this->gateway->charge($data);
        } catch (GatewayException $e) {
            throw new PaymentFailedException(
                "Falha no pagamento: {$e->getMessage()}",
                previous: $e
            );
        }
    }

    private function validate(PaymentData $data): void
    {
        if ($data->valor <= 0) {
            throw new InvalidArgumentException('Valor deve ser positivo');
        }
    }
}

Padrão de Migração Incremental

1. Criar interfaces para código existente
2. Implementar nova versão atrás da interface
3. Usar feature flags para alternar
4. Remover código antigo após validação
// Interface de abstração
interface ContractRepositoryInterface
{
    public function find(int $id): ?Contract;
    public function save(Contract $contract): void;
}

// Implementação legada (wrapper)
class LegacyContractRepository implements ContractRepositoryInterface
{
    public function find(int $id): ?Contract
    {
        $data = buscar_contrato($id); // função legada
        return $data ? Contract::fromArray($data) : null;
    }
}

// Nova implementação
class EloquentContractRepository implements ContractRepositoryInterface
{
    public function find(int $id): ?Contract
    {
        return ContractModel::find($id)?->toDomain();
    }
}

// Service Provider com feature flag
$this->app->bind(
    ContractRepositoryInterface::class,
    config('features.new_repository') 
        ? EloquentContractRepository::class 
        : LegacyContractRepository::class
);

Scripts Úteis

  • scripts/analyze-legacy.php - Análise de código legado
  • scripts/convert-array-to-dto.php - Converter arrays em DTOs