Monorepositório com PHP: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que um monorepositório em PHP?

\n

O desenvolvimento de aplicações PHP complexas (CRM, SaaS, frameworks) frequentemente enfrenta um dilema: armazenar todo o código em um único repositório (monorepositório) ou dividi-lo em vários microsserviços e pacotes. O monorepositório (monorepo) com PHP é uma estratégia onde vários projetos relacionados (bibliotecas, módulos, aplicações) residem em um único repositório Git.

\n

Na prática, isso oferece:

\n
    \n
  • Histórico unificado de alterações — é mais fácil rastrear como uma mudança em um pacote afetou outro.
  • \n
  • Configuração simplificada de CI/CD — um único pipeline para construir e testar todos os componentes.
  • \n
  • Redução de duplicação — configurações, scripts e dependências compartilhados.
  • \n
  • Iteração rápida — não é necessário publicar pacotes no Packagist para testes locais.
  • \n
\n

No entanto, um monorepositório exige disciplina. Sem uma organização adequada do código, ele se transforma em um "monólito espaguete". Neste artigo, abordaremos etapas práticas para organizar um projeto PHP em um monorepositório.

\n\n

1. Estrutura de diretórios do monorepositório

\n

O princípio fundamental é uma separação clara entre pacotes e aplicações. Vamos considerar um exemplo de arquitetura típica:

\n\n
project-root/\n├── apps/\n│   ├── web/                  # Aplicação web (Symfony/Laravel)\n│   │   ├── public/\n│   │   ├── src/\n│   │   └── composer.json\n│   └── api/                  # Aplicação API (Lumen/Slim)\n│       ├── public/\n│       ├── src/\n│       └── composer.json\n├── packages/\n│   ├── core/                 # Núcleo (interfaces comuns, entidades)\n│   │   ├── src/\n│   │   └── composer.json\n│   ├── billing/              # Módulo de pagamento\n│   │   ├── src/\n│   │   └── composer.json\n│   └── notifications/        # Módulo de notificações\n│       ├── src/\n│       └── composer.json\n├── tools/                    # Scripts de desenvolvimento (PHP-CS-Fixer, PHPStan)\n├── composer.json             # Manifesto raiz\n└── phpstan.neon              # Configurações de análise comuns
\n\n

Observe: cada pacote em packages/ é uma biblioteca Composer completa com seu próprio composer.json. Isso permite isolar dependências e testá-las separadamente.

\n\n

Exemplo de composer.json para o pacote core

\n
{\n    "name": "myproject/core",\n    "type": "library",\n    "autoload": {\n        "psr-4": {\n            "MyProject\\\\Core\\\\": "src/"\n        }\n    },\n    "require": {\n        "php": ">=8.1"\n    },\n    "extra": {\n        "branch-alias": {\n            "dev-main": "1.x-dev"\n        }\n    }\n}
\n\n

2. Gerenciamento de dependências via Composer

\n

O composer.json raiz é o coração do monorepositório. Ele contém:

\n
    \n
  • Lista de todos os pacotes conectados localmente (através do repositório path).
  • \n
  • Dependências de desenvolvimento para todo o projeto (PHPUnit, PHPStan, GrumPHP).
  • \n
  • Scripts para automação (análise estática, testes).
  • \n
\n\n

Exemplo de composer.json raiz

\n
{\n    "name": "myproject/monorepo",\n    "type": "project",\n    "repositories": [\n        {\n            "type": "path",\n            "url": "packages/*",\n            "options": {\n                "symlink": true\n            }\n        }\n    ],\n    "require": {\n        "myproject/core": "@dev",\n        "myproject/billing": "@dev",\n        "myproject/notifications": "@dev"\n    },\n    "require-dev": {\n        "phpunit/phpunit": "^10.0",\n        "phpstan/phpstan": "^1.10",\n        "friendsofphp/php-cs-fixer": "^3.0"\n    },\n    "autoload": {\n        "psr-4": {\n            "MyProject\\\\": "packages/*/src/"\n        }\n    },\n    "scripts": {\n        "test": "phpunit",\n        "analyse": "phpstan analyse",\n        "cs-fix": "php-cs-fixer fix"\n    }\n}
\n\n

Pontos-chave:

\n
    \n
  • symlink: true

Blogs

Book Recommendations