<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://opensource.byjg.com/pt/blog</id>
    <title>Opensource ByJG Blog</title>
    <updated>2026-10-07T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://opensource.byjg.com/pt/blog"/>
    <subtitle>Opensource ByJG Blog</subtitle>
    <icon>https://opensource.byjg.com/pt/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Um ecossistema completo: do código à produção, com o mesmo método]]></title>
        <id>https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem</id>
        <link href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem"/>
        <updated>2026-10-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Como projetos independentes, unidos por automação, formam um caminho completo: construir, testar localmente, publicar e rodar em produção com o mesmo contêiner. E de onde veio o método, começando em um index.asp no ano 2000.]]></summary>
        <content type="html"><![CDATA[<p>Hoje eu consigo construir uma aplicação, testar na minha máquina, publicar e rodar em produção usando apenas projetos que eu mantenho, e o contêiner que eu testei é o mesmo que vai para produção. Eu nunca planejei um "ecossistema". Ele é o resultado de um método que eu venho repetindo há mais de vinte anos, e este artigo conta de onde esse método veio e como ele funciona hoje.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tudo-começou-com-um-indexasp">Tudo começou com um index.asp<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#tudo-come%C3%A7ou-com-um-indexasp" class="hash-link" aria-label="Link direto para Tudo começou com um index.asp" title="Link direto para Tudo começou com um index.asp" translate="no">​</a></h2>
<p>Tudo começou no ano 2000, quando eu trabalhava na Unitech, uma empresa de outsourcing para o governo. Eu fazia parte do setor de Pesquisa e Desenvolvimento, e uma das nossas missões era validar se o .NET 1.0 era um bom caminho para migrar de VB 6.0 para Web Forms. A Unitech era parceira da Microsoft, e por isso tínhamos acesso às versões beta muito antes do lançamento. Fizemos a pesquisa, os testes e as provas de conceito, treinamos e acompanhamos algumas equipes.</p>
<p>A grande mudança chegou quando fui alocado no projeto SOMAR (Sistema Organizado de Matrícula). Até então o sistema era 100% VB6 com Oracle 7.3 e stored procedures, mas a licitação daquele ano exigia a entrega de uma versão web, algo bastante novo na época. Eu já havia trabalhado em uma empresa de web design e tinha escrito o meu próprio CGI em Delphi (CGI era o mecanismo em que o servidor web executava um programa a cada requisição e devolvia ao navegador o que esse programa escrevesse), então me colocaram no projeto como Plano B. O Plano A era entregar o VB6, que já estava pronto, e ter uma versão web apenas como entregável, sem a expectativa de que fosse usada.</p>
<p>Escolhemos o ASP 3.0, que saiu no mesmo ano que o PHP 4, quando as duas tecnologias ainda eram muito primitivas: basicamente includes e comandos para escrever texto na página, com um JavaScript também muito limitado. Mesmo sem a pressão da entrega, resolvi criar algo que fosse fácil para o desenvolvedor e que escondesse a complexidade de misturar HTML com código. Eu já tinha trabalhado com ColdFusion e com CGI, e tudo era muito técnico, com uma curva de aprendizado alta.</p>
<p>Pensei em como um projeto em C se organiza, com o seu <code>main.c</code> e os seus headers, e adaptei a ideia para a nossa realidade em ASP 3.0. Cada página tinha os seus "headers" e uma função principal:</p>
<div class="language-asp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-asp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">&lt;!-- #include file="bancodedados.inc" --&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">&lt;!-- #include file="seguranca.inc" --&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">&lt;!-- #include file="menu.inc" --&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">&lt;!-- #include virtual="design.inc" --&gt;   &lt;% ' desenha o layout e chama a Main %&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">&lt;%</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Sub Main</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ' o que esta página faz: uma listagem, um cálculo, um download</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">End Sub</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">%&gt;</span><br></div></code></pre></div></div>
<p>Os includes guardavam o código específico de cada assunto, como conectar ao banco ou verificar se o usuário tinha permissão de acesso, e a <code>Main</code> de cada página executava apenas o que aquela página deveria fazer. Quem chamava a <code>Main</code> era o <code>design.inc</code>: ele desenhava o layout, aquele quadradão com topo, menu e rodapé, e sabia em que ponto dele o resultado da página deveria aparecer. Com essa técnica, e reaproveitando as stored procedures que já existiam, o nosso time de quatro pessoas entregou o sistema web, que acabou sendo o protagonista do projeto e o primeiro sistema web da Unitech. Depois eu aprimorei a técnica e a repliquei em outros projetos da empresa, com um ganho enorme de produtividade.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-xmlnuke-e-o-que-ele-me-ensinou">O XMLNuke e o que ele me ensinou<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#o-xmlnuke-e-o-que-ele-me-ensinou" class="hash-link" aria-label="Link direto para O XMLNuke e o que ele me ensinou" title="Link direto para O XMLNuke e o que ele me ensinou" translate="no">​</a></h2>
<p>Ao sair da Unitech resolvi investir no meu "framework". Naquela época o Java difundiu massivamente o uso de XML, que tinha a sua camada de formatação, o XSL. Com os dois eu conseguiria isolar a camada de dados da camada de apresentação. Era uma ideia tentadora, e havia poucas opções na época; na onda dos CMS existiam o PHP-Nuke e o PostNuke.</p>
<p>Criei então o XMLNuke. As classes que você escrevia produziam XML, e uma camada de processamento XSL transformava esse XML em HTML. A primeira versão foi em ASP, continuação natural do que eu tinha feito na Unitech, e o projeto está registrado no SourceForge desde maio de 2002. Em 2003 vieram as versões em Java, C# e PHP, todas com o mesmo jeito de programar. Foi no PHP que eu acabei investindo, porque o ASP era bem mais limitado e porque eu tinha decidido apostar no Linux. A versão de 2003 rodava em PHP 4, depois ficou parada por um bom tempo, e eu só a retomei com o PHP 5, em 2006, que foi a versão que amadureceu. O XMLNuke foi também o meu primeiro código open source: começou em CVS, passou para SVN no SourceForge e, muitos anos depois, foi para o GitHub.</p>
<p>De certa forma o XMLNuke antecipava o que hoje fazemos com APIs REST e JSON, em que o código produz dados e a apresentação fica em outra camada. A diferença é que o JSON é muito mais simples e dispensa um framework para ser lido.</p>
<p>O XMLNuke era um monolito imenso, que precisava de uma estrutura de diretórios específica para rodar. Com ele aprendi que um framework não pode ser monolítico nem engessado, que é mais fácil manter vários componentes pequenos e coesos do que um sistema em que tudo está acoplado, porque nele uma mudança pequena acaba quebrando partes que não tinham nada a ver com ela, e que uma especificação padrão e uma boa documentação são tão importantes quanto o código. Matei o XMLNuke e carreguei as lições.</p>
<p>Essas lições viraram componentes menores. Os componentes me ensinaram a reduzir complexidade e a separar responsabilidades, depois pediram imagens Docker para rodar sempre do mesmo jeito, depois pediram automação para publicar, e assim por diante. Em <a class="" href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects">Como eu consigo manter mais de 30 projetos open source</a> eu contei como isso funcionava quando havia dois pilares, os componentes PHP e as imagens Docker. De lá para cá entraram o DockNimbus, o ByJG Docs MCP, o Parolsh e os repositórios de pacotes, e as peças passaram a cobrir o caminho inteiro.</p>
<p><img decoding="async" loading="lazy" alt="O ecossistema ByJG: construir com Gluo e componentes, testar localmente com as imagens Docker ByJG, publicar o mesmo contêiner com CI/CD e DockNimbus e rodar em produção atrás do EasyHAProxy. Um padrão automatizado cobre testes, releases e a publicação em apt, dnf, brew e helm. A documentação serve a humanos e a assistentes de IA via MCP, e o que se aprende em produção volta para a construção." src="https://opensource.byjg.com/pt/assets/images/byjg-ecosystem-61f542a40956188d1b9af7df4d76851b.png" width="1672" height="941" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="construir-a-aplicação">Construir a aplicação<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#construir-a-aplica%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Construir a aplicação" title="Link direto para Construir a aplicação" translate="no">​</a></h2>
<p>Depois do XMLNuke eu relutei muito em ter um framework de novo. Mantive apenas componentes separados e completamente independentes. Os primeiros eu extraí do próprio XMLNuke, ainda na época da MaxMilhas, e cada um passou a ter vida própria. Com o tempo percebi que, sempre que eu usava esses componentes, eu seguia a mesma metodologia: um jeito próprio de escrever e de conectar as peças.</p>
<p>Primeiro registrei esse jeito no PHP Rest Reference Architecture, uma arquitetura de referência que definia as guidelines, mas ainda deixava muita coisa solta. Foi com ela que fiz o site do KingPanda (kingpanda.com.br). Este ano, finalmente, transformei a arquitetura de referência em um framework chamado <a class="" href="https://opensource.byjg.com/pt/docs/php/gluo">Gluo</a>, que significa "cola" em esperanto, porque é isso que ele faz com os meus componentes.</p>
<p>Um <code>composer create-project byjg/gluo</code> cria um projeto de API REST que é seu, já com autenticação, migrations, ORM, documentação OpenAPI e a estrutura de testes. É a mesma ideia do <code>index.asp</code> de 2000: o desenvolvedor escreve a regra de negócio e encontra o resto resolvido. Hoje o Gluo roda o <a href="https://boletimdeurna.com/" target="_blank" rel="noopener noreferrer" class="">BoletimDeUrna.com</a>, o site da ByJG (<a href="https://byjg.com.br/" target="_blank" rel="noopener noreferrer" class="">byjg.com.br</a>) e o sistema de busca de CEP que fica nele.</p>
<p>A diferença em relação ao XMLNuke está por baixo. O Gluo cola componentes que continuam independentes, como o <a class="" href="https://opensource.byjg.com/pt/docs/php/restserver">RestServer</a>, o <a class="" href="https://opensource.byjg.com/pt/docs/php/micro-orm">MicroOrm</a>, o <a class="" href="https://opensource.byjg.com/pt/docs/php/serializer">Serializer</a>, o <a class="" href="https://opensource.byjg.com/pt/docs/php/migration">Migration</a> e o <a class="" href="https://opensource.byjg.com/pt/docs/php/config">Config</a>. Cada um tem o seu repositório, os seus testes e o seu ciclo de versões, e pode ser usado sozinho em um projeto Laravel ou Symfony. A parte do framework que evolui fica em <code>vendor/</code> e é atualizada com um <code>composer update</code>, enquanto o projeto gerado pode ser alterado à vontade.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testar-localmente-com-as-minhas-imagens">Testar localmente com as minhas imagens<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#testar-localmente-com-as-minhas-imagens" class="hash-link" aria-label="Link direto para Testar localmente com as minhas imagens" title="Link direto para Testar localmente com as minhas imagens" translate="no">​</a></h2>
<p>O projeto já vem com um <code>docker-compose.yml</code>, e um <code>docker compose up -d</code> sobe a API, o banco de dados e o frontend na minha máquina. Os contêineres são construídos a partir das <a class="" href="https://opensource.byjg.com/pt/docs/devops/docker-php">imagens PHP ByJG</a>, que existem nas variantes CLI, FPM, Nginx e Apache para cada versão do PHP. Eu não preciso instalar nada além do Docker.</p>
<p>Essas imagens nasceram de uma dor antiga: a cada troca de máquina eu reconfigurava PHP, extensões e ferramentas, e sempre faltava alguma coisa, além de precisar de várias versões do PHP ao mesmo tempo. Houve também o dia em que eu precisei do PHP 5.6 para um projeto antigo e as distribuições Linux já nem o traziam mais.</p>
<p>O <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a> vem da mesma dor. Com ele eu nem preciso ter o PHP instalado: um <code>load.sh php-docker -- 8.4</code> cria na minha máquina um comando <code>php</code> que, por baixo, roda dentro do contêiner, e eu simplesmente entro no projeto e trabalho. Para ter outra versão ao lado basta repetir o comando com outro número. O Node funciona do mesmo jeito, e para Java e outras ferramentas há scripts que fazem a instalação com um comando. Contei os detalhes em <a class="" href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install">Desenvolvimento PHP Fácil com Docker e VSCode</a>.</p>
<p>Um ponto importante é o contrato OpenAPI, que eu escrevo uma única vez. O próprio código documenta cada endpoint, com atributos acima do método do controller. Um <code>composer openapi</code> extrai esses atributos para um arquivo <code>openapi.json</code>, e a partir daí o mesmo arquivo faz quatro trabalhos: o <a class="" href="https://opensource.byjg.com/pt/docs/php/restserver">RestServer</a> monta as rotas da API a partir dele, o Swagger UI serve as páginas de documentação em que dá para experimentar cada endpoint, o atributo <code>#[ValidateRequest]</code> valida o corpo de cada requisição antes de o método executar e devolve um erro 422 quando ele não segue o contrato, e o <a class="" href="https://opensource.byjg.com/pt/docs/php/swagger-test">Swagger Test</a> roda os testes de contrato, comparando cada resposta com o que foi declarado. Rota, documentação, validação e teste saem da mesma fonte, sem reescrever nem duplicar nada.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="publicar-cicd-e-docknimbus">Publicar: CI/CD e DockNimbus<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#publicar-cicd-e-docknimbus" class="hash-link" aria-label="Link direto para Publicar: CI/CD e DockNimbus" title="Link direto para Publicar: CI/CD e DockNimbus" translate="no">​</a></h2>
<p>O mesmo pipeline que roda os testes constrói a imagem da aplicação. Para os pipelines eu mantenho o <a class="" href="https://opensource.byjg.com/pt/docs/devops/k8s-ci">k8s-ci</a>, uma imagem com as ferramentas necessárias para construir e publicar.</p>
<p>Faltava o lugar para onde publicar, e o <a class="" href="https://opensource.byjg.com/pt/docs/devops/nimbus">DockNimbus</a> surgiu dessa demanda. Ter VMs em uma nuvem é prático e muito rápido, principalmente em projetos grandes. Em projetos pequenos, porém, sai mais barato alugar um servidor dedicado pequeno, conectado à internet e não gerenciado, em que você recebe apenas a máquina. Toda vez eu tinha que configurar a rede, proteger o que ficaria exposto, instalar o Kubernetes e assim por diante, e quando havia mais de uma máquina a comunicação entre elas também passava pela internet.</p>
<p>O DockNimbus faz essa configuração por mim, com os padrões de segurança que eu aplicaria à mão. Ele transforma máquinas físicas e VMs, de um Raspberry Pi a um servidor x86, em uma plataforma com computação, armazenamento e clusters Docker Swarm e K3s, tudo declarado em um único manifesto, e liga as máquinas por uma malha WireGuard, de modo que o tráfego entre elas segue criptografado mesmo atravessando a internet. A documentação resume a diferença em relação ao Kubernetes assim: o Kubernetes responde "tenho um cluster, como orquestro contêineres nele?", e o DockNimbus responde "tenho máquinas, como transformo isso em uma plataforma?".</p>
<p>Ele funciona bem para instalações pequenas, que é o meu caso. Eu uso o DockNimbus para gerenciar o meu ambiente local e as minhas duas ASUS Spark GB10, e ele também faz o deploy em produção do site da ByJG, do BoletimDeUrna e do servidor MCP da documentação.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="produção-o-mesmo-docker-com-load-balancer">Produção: o mesmo Docker, com load balancer<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#produ%C3%A7%C3%A3o-o-mesmo-docker-com-load-balancer" class="hash-link" aria-label="Link direto para Produção: o mesmo Docker, com load balancer" title="Link direto para Produção: o mesmo Docker, com load balancer" translate="no">​</a></h2>
<p>A imagem que roda em produção é a mesma que eu testei localmente e que passou pelo CI, então não existe diferença entre ambientes para investigar quando algo dá errado.</p>
<p>Na frente das aplicações fica o <a class="" href="https://opensource.byjg.com/pt/docs/devops/docker-easy-haproxy">EasyHAProxy</a>. Eu gosto muito do HAProxy: ele é muito rápido e trabalha também na camada TCP, então pode ficar na frente de um MySQL, por exemplo, e não apenas de aplicações web. A configuração, porém, é bem complicada. Eu queria automatizá-la, e em 2018, quando comecei o projeto, a versão community do HAProxy não tinha nada parecido.</p>
<p>O EasyHAProxy gera essa configuração sozinho. Ele descobre os serviços pelas labels do Docker, pelos serviços do Swarm ou pelo Ingress do Kubernetes, emite os certificados TLS e recarrega o HAProxy sem derrubar conexões. O próprio DockNimbus usa o EasyHAProxy como load balancer.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="projetos-independentes-centralizados-por-automação">Projetos independentes, centralizados por automação<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#projetos-independentes-centralizados-por-automa%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Projetos independentes, centralizados por automação" title="Link direto para Projetos independentes, centralizados por automação" translate="no">​</a></h2>
<p>Este é o ponto que o XMLNuke me ensinou pelo caminho mais difícil. Cada projeto tem o seu repositório, os seus testes e os seus releases, e nenhum depende de outro para ser publicado. O que faz deles um ecossistema é a automação.</p>
<p>Quando um projeto recebe um merge ou uma tag, a automação publica o que ele produz, sem nenhum passo manual, e a documentação, os charts e os pacotes vão todos para o mesmo site:</p>
<table><thead><tr><th>O que é publicado</th><th>Como</th><th>Como você instala</th></tr></thead><tbody><tr><td>Documentação</td><td>workflow reutilizável <code>add-doc</code></td><td><a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">opensource.byjg.com</a></td></tr><tr><td>Charts Helm</td><td>workflow reutilizável <code>add-helm</code></td><td><code>helm repo add byjg https://opensource.byjg.com/helm</code></td></tr><tr><td>Pacotes DEB e RPM</td><td>workflow reutilizável <code>add-pkg</code>, assinados</td><td><code>apt install</code> e <code>dnf install</code></td></tr><tr><td>Fórmulas Homebrew</td><td>um workflow diário no tap acompanha as tags de release</td><td><code>brew install byjg/tap/&lt;fórmula&gt;</code></td></tr><tr><td>Imagens Docker</td><td>o <code>build.yml</code> de cada projeto</td><td><code>docker pull byjg/&lt;imagem&gt;</code></td></tr><tr><td>Componentes PHP</td><td>uma tag no Git</td><td><code>composer require byjg/&lt;componente&gt;</code></td></tr></tbody></table>
<p>O padrão é o mesmo em todos os projetos e está descrito nas <a class="" href="https://opensource.byjg.com/pt/docs/opensource/guidelines">Development Guidelines</a>: nada é publicado antes de os testes passarem, releases são tags com versão semântica e o CI é escrito uma vez e chamado por cada projeto. As razões estão em <a class="" href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity">Princípios Simples Para Não Complicar o Complexo</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="documentação-para-humanos-e-para-a-ia">Documentação para humanos e para a IA<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#documenta%C3%A7%C3%A3o-para-humanos-e-para-a-ia" class="hash-link" aria-label="Link direto para Documentação para humanos e para a IA" title="Link direto para Documentação para humanos e para a IA" translate="no">​</a></h2>
<p>A documentação mora no repositório de cada projeto, ao lado do código, e fala apenas daquele projeto. Quem documenta o MicroOrm escreve sobre o MicroOrm, sem precisar conhecer nem descrever o ecossistema. A documentação completa é gerada pela automação: a cada merge o conteúdo de cada projeto é copiado para o <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">opensource.byjg.com</a>, que monta o site inteiro, e o <a class="" href="https://opensource.byjg.com/pt/docs/ai/mcpserver-byjg-docs">ByJG Docs MCP</a> indexa o site com busca semântica e por palavra-chave. Qualquer assistente que fale MCP consulta esse índice e cita a página de onde tirou a resposta.</p>
<p>Com isso a documentação é escrita uma vez e passa a ter dois leitores. Um agente que precisa adicionar persistência a uma aplicação ByJG encontra o MicroOrm e a forma prevista de usá-lo, em vez de inventar uma camada de dados.</p>
<p>Com o XMLNuke eu aprendi que especificação e documentação importam. Hoje elas são também o contexto que a IA usa para trabalhar nos meus projetos, e cada mudança documentada melhora a próxima resposta.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-shell-e-o-agente-no-mesmo-lugar-parolsh">O shell e o agente no mesmo lugar: Parolsh<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#o-shell-e-o-agente-no-mesmo-lugar-parolsh" class="hash-link" aria-label="Link direto para O shell e o agente no mesmo lugar: Parolsh" title="Link direto para O shell e o agente no mesmo lugar: Parolsh" translate="no">​</a></h2>
<p>O <a class="" href="https://opensource.byjg.com/pt/docs/ai/parolsh">Parolsh</a> nasceu de outro motivo. Eu prefiro trabalhar no shell na maior parte do tempo. Quando quero ver os logs de um pod, por exemplo, preciso primeiro listar os pods e depois rodar um <code>kubectl logs</code> para o primeiro, outro para o segundo, o terceiro, o quarto. O Claude Code e o Codex fazem esse tipo de investigação, mas neles tudo parte da linguagem natural e a interface toma conta do terminal, de modo que o trabalho acaba indo todo para a conversa e o shell vira coadjuvante.</p>
<p>No Parolsh as duas coisas convivem no mesmo prompt. Com <code>!+kubectl get pods</code> eu rodo o comando, vejo o resultado e ele já segue junto com a minha próxima pergunta. Aí eu peço os logs, pergunto por que os pods estão reiniciando (o que eu faria com um <code>describe</code>) e ainda posso pedir outras análises, o que acelera muito o processo. O Parolsh roda dentro do terminal de sempre, sem interface em tela cheia, e funciona com qualquer agente ACP, como Claude Code, Codex, Qwen Code e Gemini CLI.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-método-para-quem-quiser-reproduzir">O método, para quem quiser reproduzir<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#o-m%C3%A9todo-para-quem-quiser-reproduzir" class="hash-link" aria-label="Link direto para O método, para quem quiser reproduzir" title="Link direto para O método, para quem quiser reproduzir" translate="no">​</a></h2>
<p>Nada disso depende das ferramentas ByJG. O que eu descrevi é o resultado de um método que serve para qualquer conjunto de projetos:</p>
<ol>
<li class=""><strong>Automatizar o que é repetitivo.</strong> Testes, builds, releases, pacotes e a publicação da documentação rodam no CI.</li>
<li class=""><strong>Centralizar o que é compartilhado.</strong> Um conjunto de workflows, um site de documentação, um conjunto de imagens base.</li>
<li class=""><strong>Isolar o que é independente.</strong> Cada componente tem repositório, testes e ciclo de versões próprios, e só a automação os une.</li>
<li class=""><strong>Usar o mesmo contêiner em todos os ambientes.</strong> Desenvolvimento, CI e produção rodam a mesma imagem.</li>
<li class=""><strong>Escrever a documentação uma vez, para dois leitores.</strong> Cada projeto documenta a si mesmo, e a automação monta a documentação completa. Uma pessoa lê no site e um assistente de IA lê pelo MCP.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="do-indexasp-até-aqui">Do index.asp até aqui<a href="https://opensource.byjg.com/pt/blog/byjg-engineering-ecosystem#do-indexasp-at%C3%A9-aqui" class="hash-link" aria-label="Link direto para Do index.asp até aqui" title="Link direto para Do index.asp até aqui" translate="no">​</a></h2>
<p>O que eu queria em 2000 com um <code>index.asp</code> e meia dúzia de includes é o que eu continuo querendo: que o desenvolvedor escreva o que a página faz e encontre o resto resolvido. O que mudou foi o tamanho do "resto", que hoje inclui o ambiente local, o pipeline, a plataforma, o load balancer, os pacotes e a documentação que a IA consulta.</p>
<p>Cada projeto continua funcionando sozinho, e ninguém precisa adotar tudo. Para começar por uma API, veja o <a class="" href="https://opensource.byjg.com/pt/docs/php/gluo">Gluo</a>. Para colocar HTTPS na frente dos seus serviços, o <a class="" href="https://opensource.byjg.com/pt/docs/devops/docker-easy-haproxy">EasyHAProxy</a>. Para transformar máquinas em plataforma, o <a class="" href="https://opensource.byjg.com/pt/docs/devops/nimbus">DockNimbus</a>. Para dar contexto ao seu assistente de IA, o <a class="" href="https://opensource.byjg.com/pt/docs/ai/mcpserver-byjg-docs">ByJG Docs MCP</a>. O mapa completo está em <a class="" href="https://opensource.byjg.com/pt/docs/opensource/ecosystem">O Ecossistema ByJG</a>.</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="ia" term="ia"/>
        <category label="ecossistema" term="ecossistema"/>
        <category label="arquitetura" term="arquitetura"/>
        <category label="devops" term="devops"/>
        <category label="automacao" term="automacao"/>
        <category label="mcp" term="mcp"/>
        <category label="nimbus" term="nimbus"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Além do Vibe Coding — IA como Par de Programação no Desenvolvimento Real]]></title>
        <id>https://opensource.byjg.com/pt/blog/beyond-vibe-coding</id>
        <link href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding"/>
        <updated>2026-02-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[O termo "Vibe Coding" não faz jus ao trabalho real. Minha experiência usando Claude Code, Lovable e Emergent.sh para modernizar um projeto legado de 2010 — e por que estar no controle faz toda a diferença.]]></summary>
        <content type="html"><![CDATA[<p>Eu escrevo esse artigo para explicar minha jornada com o que chamam de Vibe Coding.
Aliás, esse é um termo péssimo. Ele normalmente me remete a idéia de fazer algo seguindo uma "sensação",
seguindo a onda dos outros — como se você não estivesse realmente no controle. No meu trabalho,
procuro ser pragmático, e "codar na onda" não me parece algo que vai produzir resultados
duradouros. Mas antes que você tire conclusões apressadas, deixa eu explicar alguns pontos.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="produtividade-com-ia-o-que-realmente-funciona">Produtividade com IA: o que realmente funciona<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#produtividade-com-ia-o-que-realmente-funciona" class="hash-link" aria-label="Link direto para Produtividade com IA: o que realmente funciona" title="Link direto para Produtividade com IA: o que realmente funciona" translate="no">​</a></h2>
<p>Faz algum tempo que decidi adotar assistentes de programação, e o ganho de produtividade é absurdo.
Consegui documentar minhas bibliotecas e projetos em dias, não meses. Resolvi bugs e issues muito
mais rápido. Criei até um automatizador de prompts: tenho 50 projetos, todos precisam de
documentação e têm o mesmo prompt — então fiz um script que entra em cada projeto, documenta,
verifica se estou seguindo os padrões corretamente, roda os testes, o lint, conserta o que precisa.
Maravilhoso.</p>
<p>Mas eu sou muito exigente também. Percebi que, quando peço para a IA criar um documento sem qualquer base inicial,
o resultado quase sempre traz frases curtas, muitos parágrafos e vários clichês do tipo
"O problema não é... é sobre...", "Não é aquilo, é isso" — comentários de encaixe que deixam
o conteúdo vazio. Mesmo me incomodando, para documentação técnica o COMO importa mais do que
quantidade de texto, então deixei passar. O melhor fluxo que encontrei foi:
eu escrevo um rascunho e uso a IA como revisora. Ela aponta erros de grafia e concordância,
reescreve trechos que eu sei o que querem dizer, e aí eu posso opinar, questionar e melhorar.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pair-programming-com-ia-não-delegação-total">Pair Programming com IA, não delegação total<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#pair-programming-com-ia-n%C3%A3o-delega%C3%A7%C3%A3o-total" class="hash-link" aria-label="Link direto para Pair Programming com IA, não delegação total" title="Link direto para Pair Programming com IA, não delegação total" translate="no">​</a></h2>
<p>Aqui entra o primeiro ponto importante: eu não delego 100% para a IA. Gostaria muito.
Mas sempre chega um ponto em que ela se perde. Repete código. Quando o teste não passa,
ela escreve <code>assertTrue(true)</code> e anuncia feliz que agora você tem 1.000 testes funcionando.
Vai criando monstrinhos lindos, estilo Gremlins. Quando você percebe, está consumindo recursos
e gastando tudo o que tem.</p>
<p>Por isso, minha primeira regra com a IA é: Pair Programming. Eu defino a atividade,
normalmente com uma especificação, jogo no Claude Code e peço para me dar um plano. A partir daí,
vou ajustando esse plano até ter algo que me atenda. Quando aprovo, vou acompanhando exatamente
o que está sendo codado, paro, intervenho, pergunto por que fez aquilo, peço para olhar a definição,
aponto para a documentação correta.</p>
<p>Não consigo sentar e "relaxar", mas é muito mais rápido e fico 90% satisfeito com o resultado.
Para entender isso fora do contexto de tecnologia: se eu dou um carro para alguém que só quer
dirigir, não importa o que eu entregue, desde que ela dirija. Mas eu não quero só dirigir —
quero tunar o carro, fazer upgrades, integrar sistemas. E é aí que estar lado a lado ajuda muito.</p>
<p>Claro que há situações em que pouco importa como foi feito. Fiz sites no Lovable (vou chegar lá)
completamente por ele — e é isso. Não preciso de mais nada. Mas no âmbito profissional, eu quero
um produto que eu possa manter, que no final eu entenda, que possa evoluir, que seja escalável
e confiável. Nesse momento estou fora da Vibe. Negócio real não é entregar mais por entregar —
é entregar mais com qualidade, onde o resultado seja impecável e eu seja o DONO do processo,
não a IA.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-projeto-real-modernizando-o-byjgcombr">O projeto real: modernizando o ByJG.com.br<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#o-projeto-real-modernizando-o-byjgcombr" class="hash-link" aria-label="Link direto para O projeto real: modernizando o ByJG.com.br" title="Link direto para O projeto real: modernizando o ByJG.com.br" translate="no">​</a></h2>
<p>Então resolvi testar na prática um cenário em que a IA não é apenas meu par de programação.
Tenho o site ByJG.com.br, onde mantenho meu portfólio e alguns serviços — sendo que hoje só o de
CEP WebService está ativo. Ele foi escrito por volta de 2010, saiu do deploy por <code>git pull</code> e hoje
roda em Kubernetes com CI/CD, mas o código é o mesmo de 2010. Nele eu usava meu antigo framework
XMLNuke, que aposentei em 2016, mas cujo código serviu de base para criar minha Arquitetura de
Referência em PHP para Projetos REST.</p>
<p>Minha meta era:</p>
<ul>
<li class="">Migrar do PHP 5.6 para o 8.5</li>
<li class="">MySQL 5.6 para o 9.0</li>
<li class="">Evoluir o layout usando algo mais moderno como Vite ou Next</li>
<li class="">Mudar autenticação para JWT</li>
<li class="">Manter as APIs antigas funcionando, pois ainda tenho usuários que dependem do serviço</li>
</ul>
<p>Parece simples, mas se eu fosse contratar um time eu precisaria de:</p>
<ul>
<li class="">Um backend capaz de trabalhar com o legado e o novo</li>
<li class="">Um frontend que entendesse de design para fazer o site e conectar com as APIs</li>
<li class="">Um redator para ajudar a revisar os textos</li>
</ul>
<p>Então, atuei como Gerente de Produto técnico Hands-On e contratei o seguinte time:</p>
<ul>
<li class=""><strong>Claude Code Max</strong> como meu Backend (e FullStack)</li>
<li class=""><strong>Lovable Pro</strong> como meu Frontend</li>
<li class=""><strong>Emergent.sh</strong> como meu Frontend alternativo</li>
<li class=""><strong>ChatGPT Pro</strong> como Solutions Architect, Revisor e Editor de Imagens</li>
</ul>
<p>Paguei por todos esses serviços.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lovable-vs-emergentsh-o-duelo-de-frontends">Lovable vs Emergent.sh: o duelo de frontends<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#lovable-vs-emergentsh-o-duelo-de-frontends" class="hash-link" aria-label="Link direto para Lovable vs Emergent.sh: o duelo de frontends" title="Link direto para Lovable vs Emergent.sh: o duelo de frontends" translate="no">​</a></h2>
<p>Tanto o Lovable quanto o Emergent.sh fazem design e implementam o website. Passei o mesmo prompt
para ambos. O Emergent.sh, na fase de criação, se saiu melhor: perguntava coisas que não estavam
bem definidas, o que gostei muito. Isso me ajudou a refinar o prompt para que fosse mais claro e
específico, e fiz um novo projeto em ambos. A primeira versão do Emergent, em todas as tentativas,
foi excelente.</p>
<p><strong>Emergent.sh</strong>
<img decoding="async" loading="lazy" alt="Emergent Design" src="https://opensource.byjg.com/pt/assets/images/emergent_design-31916b6b37488c95c46aa1437838a5a3.png" width="1920" height="800" class="img_ev3q"></p>
<p><strong>Lovable</strong>
<img decoding="async" loading="lazy" alt="Lovable Design" src="https://opensource.byjg.com/pt/assets/images/lovable_design-b61cb803f930bebb7900a3164b73240c.png" width="1235" height="777" class="img_ev3q"></p>
<p>Pontos que analisei em cada um:</p>
<table><thead><tr><th>Feature</th><th>Emergent.sh</th><th>Lovable</th></tr></thead><tbody><tr><td>Design</td><td>Excelente</td><td>Bom</td></tr><tr><td>Código Gerado</td><td>Ruim (Craco)</td><td>Excelente (Vite)</td></tr><tr><td>Integração com o Git</td><td>Bom</td><td>Muito Bom</td></tr><tr><td>Edição de Código</td><td>Excelente (usa Coder)</td><td>Boa (proprietário)</td></tr><tr><td>Continuidade do Projeto</td><td>Ruim</td><td>Bom</td></tr><tr><td>Deploy (testei apenas o Front)</td><td>Ruim</td><td>Bom</td></tr></tbody></table>
<p>O código gerado pelo Emergent parece ter saído de um template à moda antiga: tem uma
pasta <code>backend</code>, outra <code>frontend</code>, e exige aquela estrutura para funcionar.
O backend usa Python e o frontend usa Craco — um framework abandonado, com várias dependências
antigas e vulnerabilidades. Quando o Emergent salva o código no git (o bom é que posso enviar
para qualquer repositório e branch), o <code>yarn.lock</code> não era incluído. Quando tentava rodar
<code>yarn install</code>, nada era instalado por conta das dependências quebradas.</p>
<p>Foi aí que chamei meu backend Claude, e percebi que ele também era Full-Stack. Ele recomendou
migrar para o Vite, explicou os motivos e executou a migração rapidamente. No Lovable,
não consegui especificar QUAL repositório git usar, mas ele consegue manter o projeto sincronizado
tanto se eu mexesse fora quanto dentro do Lovable — e se vira bem com qualquer framework, o que
garante boa continuidade. O deploy do front-end no Emergent.sh custa 50 créditos;
no Lovable é gratuito.</p>
<p><strong>Meu veredicto</strong>: Preciso contratar um designer que faça o Figma — ainda vou procurar.
E o Lovable implementa bem. Com o MVP do frontend mais ou menos encaminhado, passo as integrações
e o código mais pesado para meu FullStack, o Claude, e retorno ao Lovable para publicar.
No projeto ByJG, vou publicar na Cloudflare — mas isso é outra história.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-migração-do-código-legado">A migração do código legado<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#a-migra%C3%A7%C3%A3o-do-c%C3%B3digo-legado" class="hash-link" aria-label="Link direto para A migração do código legado" title="Link direto para A migração do código legado" translate="no">​</a></h2>
<p>Na segunda parte, veio a conversão do código legado para o novo. Antes de passar a missão para o
Claude, precisei criar a infraestrutura mínima: instalei o projeto de Referência com algumas
classes e testes, coloquei o ambiente para rodar e defini as instruções de como testar e como era
a arquitetura. Com ambos os ambientes rodando, parti para dar as instruções ao Claude.</p>
<p>A instrução inicial sempre no modo de Planejamento. Em vez de pedir uma conversão total,
identifiquei os blocos comuns e comecei a trabalhar neles. Primeiro pedi para criar o Login,
Registro e "Esqueci minha senha". Era crítico porque definiria todo o resto.
Quando a API estava implementada, pedi para o Claude gerar um Guia de Implementação do Login
com fluxos e como lidar com o JWT. Esse guia usei para implementar as telas no frontend.
Funcionou bem.</p>
<p>Um detalhe importante: cada atividade era uma sessão diferente do Claude. Isso o força a
pesquisar o código, o que, pelo menos para mim, gerou resultados melhores. Depois disso,
repeti o processo nos outros módulos do site.</p>
<p>Muitas vezes, quando ele sugere uma mudança que não entendi ou não achei eficiente, eu rejeito e
começo assim: "Pergunta: por que utilizou isso e não aquilo?" ou "Você olhou a documentação na
pasta X ou no código ABC?" Isso é uma forma de levá-lo a pesquisar mais sobre o código e sugerir
soluções melhores. Há situações em que pesquisei no Google sobre o tema para discutir mais
tecnicamente, especialmente quando estava em dúvida. E muitas vezes eu dava uma solução, mas
deixava aberto para que ele pudesse sugerir alternativas.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="as-situações-irritantes">As situações irritantes<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#as-situa%C3%A7%C3%B5es-irritantes" class="hash-link" aria-label="Link direto para As situações irritantes" title="Link direto para As situações irritantes" translate="no">​</a></h2>
<p>Tem situações bem irritantes: 99% das vezes ele sabe como subir a aplicação e testar, pois isso está nas suas instrucões,
mas em 1% das vezes ele se perde e fica num loop tentando resolver o problema da forma errada.
Nesse caso, eu interrompo, fecho a sessão e começo uma nova dizendo: "Investigue por que isso
não funciona" ou "O código da linha X está com erro; o comportamento esperado é A, B, C."</p>
<p>Algumas vezes ele simplesmente não sabe o que fazer, inventa que completou a tarefa quando
na verdade não completou (ainda bem que não é CLT), faz uma gambiarra para dizer que
os testes passaram. Enfim, tem que vigiar.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusão">Conclusão<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#conclus%C3%A3o" class="hash-link" aria-label="Link direto para Conclusão" title="Link direto para Conclusão" translate="no">​</a></h2>
<p>De qualquer forma, fiquei muito satisfeito com o resultado. E não chamo isso de Vibe Coding —
seria injusto. Faz parecer menor do que é.</p>
<p>No final, transformei um site completamente desatualizado em algo assim:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="antes">Antes<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#antes" class="hash-link" aria-label="Link direto para Antes" title="Link direto para Antes" translate="no">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Home antiga" src="https://opensource.byjg.com/pt/assets/images/old_home-823c525eb1e69751d9ee91ac0cf65c11.png" width="1025" height="816" class="img_ev3q"> <img decoding="async" loading="lazy" alt="Login antigo" src="https://opensource.byjg.com/pt/assets/images/old_login-7704748d8f2fe4806afdcfa840484e4d.png" width="1189" height="773" class="img_ev3q"> <img decoding="async" loading="lazy" alt="Página SOAP antiga" src="https://opensource.byjg.com/pt/assets/images/old_soap_page-88576541f5cf202eec15d38378bd67b3.png" width="1642" height="455" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="depois">Depois<a href="https://opensource.byjg.com/pt/blog/beyond-vibe-coding#depois" class="hash-link" aria-label="Link direto para Depois" title="Link direto para Depois" translate="no">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Nova Home" src="https://opensource.byjg.com/pt/assets/images/new_home-67d1f6c63000887c3231d4af836f1c6c.png" width="1320" height="755" class="img_ev3q"> <img decoding="async" loading="lazy" alt="Novo Login" src="https://opensource.byjg.com/pt/assets/images/new_login-175857b9e808910f69a67ad1359b0c33.png" width="803" height="624" class="img_ev3q"> <img decoding="async" loading="lazy" alt="Nova Página SOAP" src="https://opensource.byjg.com/pt/assets/images/new_soap_page-3b3e49220fcc5918cbe9836aeec43b48.png" width="1252" height="840" class="img_ev3q"></p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="ia" term="ia"/>
        <category label="vibe-coding" term="vibe-coding"/>
        <category label="claude-code" term="claude-code"/>
        <category label="lovable" term="lovable"/>
        <category label="emergent" term="emergent"/>
        <category label="desenvolvimento" term="desenvolvimento"/>
        <category label="produtividade" term="produtividade"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Por Que Criei o `n8n-gitops`]]></title>
        <id>https://opensource.byjg.com/pt/blog/why-i-created-n8n-gitops</id>
        <link href="https://opensource.byjg.com/pt/blog/why-i-created-n8n-gitops"/>
        <updated>2025-12-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[n8n é uma excelente IDE de workflows, mas seu fluxo de produção padrão depende de deploy manual, orientado pela UI. Essa abordagem quebra princípios fundamentais de engenharia em torno de controle de mudanças, auditabilidade e reprodutibilidade.]]></summary>
        <content type="html"><![CDATA[<p>n8n é uma excelente IDE de workflows, mas seu fluxo de produção padrão depende de deploy manual, orientado pela UI. Essa
abordagem quebra princípios fundamentais de engenharia em torno de controle de mudanças, auditabilidade e reprodutibilidade.
<code>n8n-gitops</code> existe para preencher essa lacuna transformando workflows n8n em artefatos versionados, revisáveis e reprodutíveis,
gerenciados através do Git e deployados através de automação. Permite que equipes mantenham a produtividade visual do n8n
enquanto aplicam os mesmos padrões de entrega usados para qualquer outro sistema em produção.</p>
<!-- -->
<p>n8n é uma ferramenta genuinamente forte. Como IDE visual para construção de workflows, ela atinge um raro equilíbrio entre
acessibilidade e poder: você pode modelar fluxos complexos orientados a eventos, reagir a webhooks e agendamentos, integrar
com APIs, plataformas SaaS e bancos de dados, e ainda descer ao nível de Python ou JavaScript real quando a lógica exige.
Do ponto de vista de produtividade e expressividade, é muito bem projetada.</p>
<p>O problema não aparece quando você está criando workflows. Ele aparece no momento em que você tenta rodá-los seriamente em
produção.</p>
<p>A primeira vez que encontrei o workflow de promoção recomendado construa localmente, copie o workflow, cole em produção
eu imediatamente soube que não poderia aceitar esse modelo. Não porque é inconveniente, mas porque quebra alguns dos
princípios mais básicos de operação de sistemas em produção. Deploy manual não é uma preferência estilística; é um
risco sistêmico.</p>
<p>Uma vez que workflows são promovidos por copiar e colar, você perde o controle quase instantaneamente. Não há forma
confiável de entender exatamente o que mudou, nenhum diff significativo, nenhum registro autoritativo de quem deployou o
que e quando, e nenhum estado reprodutível que você possa apontar como "a versão atualmente rodando." Pior ainda, qualquer
um com acesso à UI de produção ganha implicitamente a habilidade de fazer deploy de lógica que pode disparar sistemas
externos, mover dados ou executar código arbitrário. Isso não é apenas desconfortável; é fundamentalmente incompatível com
ambientes que valorizam auditabilidade, rastreabilidade e mudança controlada.</p>
<p>Para mim, isso cruza uma linha firme. Eu opero sob uma regra muito simples: nada chega em produção manualmente. Nem
aplicações, nem infraestrutura, e nem workflows. Se um sistema não pode ser deployado através de um processo controlado,
revisável e repetível, então não é um sistema que eu possa recomendar ou confiar para automação crítica.</p>
<p>A parte frustrante é que n8n não está longe de fazer isso certo. Por baixo dos panos, expõe uma API capaz que permite
que workflows sejam listados, criados, substituídos, ativados e desativados programaticamente. Essa API é poderosa o
suficiente para construir um modelo adequado de entrega um que não dependa da UI como superfície de deployment. Mesmo
a funcionalidade Git Sync disponível nos planos business e enterprise aponta nessa direção, mas permanece largamente
orientada pela UI e não abraça completamente o Git como plano de controle.</p>
<p>O que eu queria era direto e sem novidades pelos padrões modernos de engenharia. Eu queria usar n8n local como IDE,
não como mecanismo de deployment. Eu queria que Git fosse a fonte da verdade. Eu queria que lógica de workflow especialmente
Python e JavaScript vivesse em arquivos reais ao invés de estar enterrada dentro de blobs JSON escapados. Eu queria pull
requests, revisão de código, tags de versão e promoção entre ambientes orientada por CI/CD. Mais importante, eu queria
que deployments fossem entediantes, determinísticos e reversíveis.</p>
<p>Essa combinação não existia, então eu a construí.</p>
<p><code>n8n-gitops</code> não é uma alternativa ao n8n; é uma camada de controle em torno dele. O editor visual permanece exatamente
onde brilha projetando workflows. A partir daí, workflows são exportados em modo mirror, garantindo que o repositório
sempre reflita o verdadeiro estado da instância e que drift seja eliminado ao invés de tolerado. Código é externalizado
em arquivos fonte apropriados, tornando revisões legíveis, ferramentas efetivas e mudanças compreensíveis por humanos.
Git se torna o lugar onde decisões são discutidas, aprovações acontecem e versões são definidas.</p>
<p>Deployment então para de ser um ato executado por uma pessoa clicando botões e se torna uma operação executada por
um pipeline. Uma tag, branch ou commit específico é deployado em uma instância alvo via API. Rollback não é mais um
procedimento especial; é simplesmente fazer redeploy de uma referência anterior. Não há ambiguidade sobre o que está
rodando, como chegou lá ou como desfazer.</p>
<p>Essa mudança é o que tornou n8n usável para mim em ambientes reais. Antes disso, n8n parecia uma ferramenta poderosa de
prototipagem e automação com ressalvas de produção. Depois disso, torna-se um runtime de workflows que pode ser governado
com a mesma disciplina que qualquer outro sistema em produção.</p>
<p>A intenção deste projeto não é competir com n8n ou criticar seu foco em usabilidade. Existe para fazer a ponte entre dois
mundos que frequentemente colidem: produtividade low-code e rigor de infraestrutura. n8n otimiza para velocidade e
acessibilidade; GitOps otimiza para segurança, visibilidade e confiança. <code>n8n-gitops</code> existe para conectar essas prioridades
sem forçá-lo a abrir mão de uma pela outra.</p>
<p>Se um motor de workflows pode disparar movimentação de dinheiro, chamar sistemas externos, mutar dados ou executar código
arbitrário, então merece os mesmos padrões de entrega que qualquer serviço que você faz deploy. Este projeto é simplesmente
uma aplicação dessa realidade.</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="n8n" term="n8n"/>
        <category label="gitops" term="gitops"/>
        <category label="devops" term="devops"/>
        <category label="automação" term="automação"/>
        <category label="workflow" term="workflow"/>
        <category label="ci-cd" term="ci-cd"/>
        <category label="deployment" term="deployment"/>
        <category label="engenharia" term="engenharia"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Conquistando confiança quando ela é questionada]]></title>
        <id>https://opensource.byjg.com/pt/blog/earning-confidence-when-questioned</id>
        <link href="https://opensource.byjg.com/pt/blog/earning-confidence-when-questioned"/>
        <updated>2025-12-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Um instrutor de 17 anos entra no escritório de um diretor para ensinar DOS, WordStar, SuperCalc e dBASE - e precisa conquistar o direito de ficar.]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Capa Seventeen Teaching DOS" src="https://opensource.byjg.com/pt/assets/images/image-b16eb1f86f664f8f0a20e8faf35347e0.png" width="1856" height="2304" class="img_ev3q"></p>
<p>Meu primeiro emprego profissional foi como instrutor em uma pequena escola de informática, ensinando DOS, WordStar, SuperCalc e dBASE. Um dia me enviaram para treinar o diretor de uma empresa. Ele olhou para mim - um garoto de 17 anos - e perguntou: "Você veio me treinar? Não acha que é jovem demais?"</p>
<p>Eu respirei fundo e respondi: "Eles me mandaram porque acreditam que sou capaz. Vamos fazer assim: já estou aqui e você reservou o tempo. Vou dar a aula de hoje. Se você não gostar, não paga e outra pessoa vem na próxima semana. Se gostar, eu volto." Ele ficou surpreso, deu um meio sorriso e disse: "Fechado!" No final perguntei: "Posso voltar semana que vem?" A resposta dele: "Sim."</p>
<!-- -->
<p>Naquele dia aprendi a transformar um momento difícil em uma oportunidade para provar meu valor. Eu poderia ter aceitado a dúvida dele como derrota; em vez disso, usei para mostrar do que era capaz.</p>
<p>Quando estamos procurando um novo emprego, com contas para pagar e família para cuidar, qualquer desafio pode parecer uma ameaça. É fácil encolher. Mas o mundo não define nossos limites - nós definimos. A confiança para se manter firme, entregar e deixar o resultado falar por si é um músculo. Às vezes a gente esquece. Eu esqueci. Revisitar essa memória me lembra que coragem e preparo vencem a dúvida sempre.</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="carreira" term="carreira"/>
        <category label="ensino" term="ensino"/>
        <category label="confiança" term="confiança"/>
        <category label="soft-skills" term="soft-skills"/>
        <category label="início-de-carreira" term="início-de-carreira"/>
        <category label="mindset" term="mindset"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Entendendo o Sistema de Versionamento dos Componentes PHP ByJG]]></title>
        <id>https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning</id>
        <link href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning"/>
        <updated>2025-11-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Um guia completo para entender como os componentes PHP ByJG são versionados e como usá-los efetivamente em seus projetos]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Entendendo o Sistema de Versionamento dos Componentes PHP ByJG" src="https://opensource.byjg.com/pt/assets/images/frontpage-8b52bb8d8f2a3f9ee3d9ed4a6486c159.png" width="2848" height="1504" class="img_ev3q"></p>
<p>Gerenciar dependências entre múltiplos componentes PHP costumava ser um pesadelo.
Quando você tem um ecossistema de mais de 30 pacotes interconectados, manter o controle de qual versão funciona com qual versão do PHP — e quais versões são compatíveis entre si — pode rapidamente se tornar algo incontrolável.</p>
<p>Foi por isso que redesenhei completamente a estratégia de versionamento para todos os componentes PHP ByJG.
Este post explica a evolução do sistema de versionamento, como ele funciona hoje e como você pode usá-lo efetivamente em seus projetos.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-problema-antes-do-php-74">O Problema: Antes do PHP 7.4<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#o-problema-antes-do-php-74" class="hash-link" aria-label="Link direto para O Problema: Antes do PHP 7.4" title="Link direto para O Problema: Antes do PHP 7.4" translate="no">​</a></h2>
<p>Antes do PHP 7.4, cada componente do ecossistema ByJG tinha <strong>seu próprio esquema de versionamento independente</strong>.</p>
<p>Isso criava diversos desafios:</p>
<ul>
<li class=""><strong>Inferno de Dependências</strong>: Era extremamente difícil identificar quais versões de diferentes componentes eram compatíveis entre si</li>
<li class=""><strong>Confusão de Versões PHP</strong>: Não havia uma maneira clara de saber quais versões do PHP uma versão específica de componente suportava</li>
<li class=""><strong>Pesadelo de Manutenção</strong>: Gerenciar patches e atualizações entre componentes com números de versão diferentes era complexo e propenso a erros</li>
<li class=""><strong>Experiência Ruim para o Desenvolvedor</strong>: Usuários tinham que pesquisar manualmente matrizes de compatibilidade antes de instalar componentes</li>
</ul>
<p>Por exemplo, você poderia ter:</p>
<ul>
<li class=""><code>byjg/anydataset</code> na versão 3.2.1</li>
<li class=""><code>byjg/serializer</code> na versão 2.5.0</li>
<li class=""><code>byjg/migration</code> na versão 4.1.2</li>
</ul>
<p>E tentar descobrir quais versões funcionavam juntas — e com qual versão do PHP — exigia vasculhar documentação ou tentativa e erro.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-solução-versionamento-padronizado">A Solução: Versionamento Padronizado<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#a-solu%C3%A7%C3%A3o-versionamento-padronizado" class="hash-link" aria-label="Link direto para A Solução: Versionamento Padronizado" title="Link direto para A Solução: Versionamento Padronizado" translate="no">​</a></h2>
<p>A partir do <strong>PHP 7.4</strong>, introduzi um <strong>sistema de versionamento padronizado</strong> em todos os componentes ByJG.</p>
<p>O princípio chave é simples:</p>
<blockquote>
<p><strong>A versão principal do componente indica quais versões do PHP ele suporta.</strong></p>
</blockquote>
<p>Isso cria um padrão claro e previsível que torna o gerenciamento de dependências significativamente mais fácil.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="matriz-de-versão-para-suporte-php">Matriz de Versão para Suporte PHP<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#matriz-de-vers%C3%A3o-para-suporte-php" class="hash-link" aria-label="Link direto para Matriz de Versão para Suporte PHP" title="Link direto para Matriz de Versão para Suporte PHP" translate="no">​</a></h3>
<table><thead><tr><th>Versão do Componente</th><th>Versões PHP Suportadas</th><th>Status</th></tr></thead><tbody><tr><td><strong>4.9.x</strong></td><td>PHP 7.4, 8.0, 8.1, 8.2</td><td>Apenas manutenção (patches)</td></tr><tr><td><strong>5.0.x</strong></td><td>PHP 8.1, 8.2, 8.3</td><td>Apenas manutenção (patches)</td></tr><tr><td><strong>6.0.x</strong></td><td>PHP 8.3, 8.4, 8.5</td><td>Desenvolvimento ativo</td></tr></tbody></table>
<p>Isso significa:</p>
<ul>
<li class="">Se você está rodando <strong>PHP 8.4</strong>, deve usar a versão <strong>6.0</strong> dos componentes ByJG</li>
<li class="">Se ainda está no <strong>PHP 8.2</strong>, pode usar a versão <strong>4.9</strong> ou <strong>5.0</strong></li>
<li class="">Se precisa suportar <strong>PHP 7.4</strong>, a versão <strong>4.9</strong> é sua única opção</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="benefícios-dessa-abordagem">Benefícios Dessa Abordagem<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#benef%C3%ADcios-dessa-abordagem" class="hash-link" aria-label="Link direto para Benefícios Dessa Abordagem" title="Link direto para Benefícios Dessa Abordagem" translate="no">​</a></h3>
<ol>
<li class=""><strong>Clareza Instantânea</strong>: Apenas olhando o número da versão, você sabe quais versões do PHP são suportadas</li>
<li class=""><strong>Dependências Consistentes</strong>: Todos os componentes com a mesma versão principal são projetados para trabalhar juntos</li>
<li class=""><strong>Upgrades Simplificados</strong>: Ao atualizar o PHP, você atualiza todos os componentes para a versão correspondente</li>
<li class=""><strong>Melhor Manutenção</strong>: Separação clara entre linhas de versão torna o patch de versões específicas algo direto</li>
</ol>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="workflow-de-desenvolvimento-e-estratégia-de-branches">Workflow de Desenvolvimento e Estratégia de Branches<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#workflow-de-desenvolvimento-e-estrat%C3%A9gia-de-branches" class="hash-link" aria-label="Link direto para Workflow de Desenvolvimento e Estratégia de Branches" title="Link direto para Workflow de Desenvolvimento e Estratégia de Branches" translate="no">​</a></h2>
<p>Entender como releases e patches funcionam é crucial tanto para contribuidores quanto para usuários do ecossistema.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-estratégia-da-branch-principal">A Estratégia da Branch Principal<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#a-estrat%C3%A9gia-da-branch-principal" class="hash-link" aria-label="Link direto para A Estratégia da Branch Principal" title="Link direto para A Estratégia da Branch Principal" translate="no">​</a></h3>
<p>O workflow de desenvolvimento segue um padrão direto:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">branch main/master</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ↓</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Sempre contém a versão mais recente (atualmente 6.0.x)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ↓</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Releases são tagueados diretamente dessa branch</span><br></div></code></pre></div></div>
<p><strong>Pontos-Chave</strong>:</p>
<ul>
<li class="">A branch <code>main</code> (ou <code>master</code>) <strong>sempre</strong> contém a versão mais recente do componente</li>
<li class="">Todo desenvolvimento de novas funcionalidades acontece na branch main</li>
<li class="">Quando um release está pronto, é tagueado diretamente da main (ex: <code>v6.0.0</code>, <code>v6.0.1</code>, etc.)</li>
<li class="">Isso garante que a branch main está sempre estável e pronta para release</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="branches-específicas-de-versão-para-patches">Branches Específicas de Versão para Patches<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#branches-espec%C3%ADficas-de-vers%C3%A3o-para-patches" class="hash-link" aria-label="Link direto para Branches Específicas de Versão para Patches" title="Link direto para Branches Específicas de Versão para Patches" translate="no">​</a></h3>
<p>Quando um bug é descoberto em uma versão antiga que ainda precisa de suporte, usamos <strong>branches específicas de versão</strong>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Branch 4.9  →  Para patches da versão 4.9.x (PHP 7.4-8.2)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Branch 5.0  →  Para patches da versão 5.0.x (PHP 8.1-8.3)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Branch 6.0  →  Para patches da versão 6.0.x (PHP 8.3-8.5)</span><br></div></code></pre></div></div>
<p><strong>Exemplo de Workflow</strong>:</p>
<ol>
<li class="">Um bug crítico é encontrado na versão 5.0.x</li>
<li class="">Crie uma branch de correção a partir da branch <code>5.0</code></li>
<li class="">Aplique a correção e faça merge de volta para a branch <code>5.0</code></li>
<li class="">Tagueie um novo patch release (ex: <code>v5.0.8</code>)</li>
<li class="">Se aplicável, porte a correção para versões mais novas (<code>6.0</code> ou <code>main</code>)</li>
</ol>
<p>Essa abordagem garante:</p>
<ul>
<li class=""><strong>Versões antigas permanecem estáveis</strong> e podem receber correções críticas</li>
<li class=""><strong>Sem interferência</strong> com o desenvolvimento ativo na branch main</li>
<li class=""><strong>Separação clara</strong> entre manutenção e novas funcionalidades</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="melhores-práticas-usando-componentes-em-seu-projeto">Melhores Práticas: Usando Componentes em Seu Projeto<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#melhores-pr%C3%A1ticas-usando-componentes-em-seu-projeto" class="hash-link" aria-label="Link direto para Melhores Práticas: Usando Componentes em Seu Projeto" title="Link direto para Melhores Práticas: Usando Componentes em Seu Projeto" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="recomendação-1-use-a-mesma-versão-em-todos-os-componentes">Recomendação #1: Use a Mesma Versão em Todos os Componentes<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#recomenda%C3%A7%C3%A3o-1-use-a-mesma-vers%C3%A3o-em-todos-os-componentes" class="hash-link" aria-label="Link direto para Recomendação #1: Use a Mesma Versão em Todos os Componentes" title="Link direto para Recomendação #1: Use a Mesma Versão em Todos os Componentes" translate="no">​</a></h3>
<p>Para garantir máxima compatibilidade e evitar conflitos de dependência, <strong>sempre use componentes da mesma versão principal</strong>.</p>
<p><strong>Má Prática</strong> ❌:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^5.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/serializer"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/migration"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^4.9"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><strong>Boa Prática</strong> ✅:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/serializer"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/migration"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="recomendação-2-use-o-operador-circunflexo-">Recomendação #2: Use o Operador Circunflexo (^)<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#recomenda%C3%A7%C3%A3o-2-use-o-operador-circunflexo-" class="hash-link" aria-label="Link direto para Recomendação #2: Use o Operador Circunflexo (^)" title="Link direto para Recomendação #2: Use o Operador Circunflexo (^)" translate="no">​</a></h3>
<p>O <strong>operador circunflexo</strong> (<code>^</code>) é a maneira recomendada de especificar restrições de versão:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><strong>O que <code>^6.0</code> significa</strong>:</p>
<ul>
<li class="">Permite qualquer versão <code>&gt;= 6.0.0</code> e <code>&lt; 7.0.0</code></li>
<li class="">Você receberá <strong>atualizações de patch</strong> (6.0.1, 6.0.2, etc.) automaticamente</li>
<li class="">Você receberá <strong>atualizações menores</strong> (6.1.0, 6.2.0, etc.) automaticamente</li>
<li class="">Você <strong>não</strong> será automaticamente atualizado para a versão 7.0.0, que seria uma mudança com quebra de compatibilidade</li>
</ul>
<p>Isso lhe dá o melhor equilíbrio de:</p>
<ul>
<li class=""><strong>Estabilidade</strong>: Sem mudanças com quebra de compatibilidade de upgrades de versão principal</li>
<li class=""><strong>Segurança</strong>: Atualizações automáticas de patch para correções de bugs</li>
<li class=""><strong>Funcionalidades</strong>: Acesso a novas funcionalidades de versões menores sem intervenção manual</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testando-versões-de-desenvolvimento">Testando Versões de Desenvolvimento<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#testando-vers%C3%B5es-de-desenvolvimento" class="hash-link" aria-label="Link direto para Testando Versões de Desenvolvimento" title="Link direto para Testando Versões de Desenvolvimento" translate="no">​</a></h2>
<p>Às vezes você precisa testar funcionalidades não lançadas ou ajudar com o desenvolvimento. Existem duas abordagens:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="opção-1-definir-estabilidade-mínima-todo-o-projeto">Opção 1: Definir Estabilidade Mínima (Todo o Projeto)<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#op%C3%A7%C3%A3o-1-definir-estabilidade-m%C3%ADnima-todo-o-projeto" class="hash-link" aria-label="Link direto para Opção 1: Definir Estabilidade Mínima (Todo o Projeto)" title="Link direto para Opção 1: Definir Estabilidade Mínima (Todo o Projeto)" translate="no">​</a></h3>
<p>Essa abordagem diz ao Composer para permitir versões de desenvolvimento para <strong>todos</strong> os pacotes:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/serializer"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"minimum-stability"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"dev"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"prefer-stable"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><strong>Como funciona</strong>:</p>
<ul>
<li class=""><code>"minimum-stability": "dev"</code> permite ao Composer instalar versões dev</li>
<li class=""><code>"prefer-stable": false"</code> diz ao Composer para preferir versões de desenvolvimento sobre estáveis quando disponíveis</li>
<li class="">A restrição <code>^6.0</code> agora vai corresponder a branches <code>6.0.x-dev</code></li>
</ul>
<p><strong>Quando usar</strong>:</p>
<ul>
<li class="">Quando você está ativamente desenvolvendo ou testando múltiplos componentes</li>
<li class="">Quando você quer testar o estado mais recente de todo o ecossistema</li>
</ul>
<p><strong>Cuidado</strong>: Isso afeta <strong>todas</strong> as dependências, não apenas componentes ByJG. Use com cuidado em ambientes de produção.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="opção-2-fixar-componentes-específicos-em-versões-dev">Opção 2: Fixar Componentes Específicos em Versões Dev<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#op%C3%A7%C3%A3o-2-fixar-componentes-espec%C3%ADficos-em-vers%C3%B5es-dev" class="hash-link" aria-label="Link direto para Opção 2: Fixar Componentes Específicos em Versões Dev" title="Link direto para Opção 2: Fixar Componentes Específicos em Versões Dev" translate="no">​</a></h3>
<p>Essa abordagem é mais direcionada e afeta apenas pacotes específicos:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"6.0.x-dev"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/serializer"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/migration"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><strong>Como funciona</strong>:</p>
<ul>
<li class=""><code>"6.0.x-dev"</code> explicitamente solicita a versão de desenvolvimento da branch <code>6.0</code></li>
<li class="">Outros pacotes continuam usando versões estáveis</li>
<li class="">Você pode misturar: testar a versão dev de um componente enquanto mantém outros estáveis</li>
</ul>
<p><strong>Quando usar</strong>:</p>
<ul>
<li class="">Quando testando uma funcionalidade ou correção de bug específica em um único componente</li>
<li class="">Quando contribuindo para um componente específico</li>
<li class="">Quando você precisa de mais controle sobre quais pacotes usam versões dev</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="comandos-de-update-do-composer">Comandos de Update do Composer<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#comandos-de-update-do-composer" class="hash-link" aria-label="Link direto para Comandos de Update do Composer" title="Link direto para Comandos de Update do Composer" translate="no">​</a></h3>
<p>Após alterar as restrições de versão:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Atualizar todos os pacotes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Atualizar apenas pacotes específicos</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer update byjg/anydataset</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Atualizar todos os pacotes byjg</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer update byjg/*</span><br></div></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="estratégia-de-migração-entre-versões">Estratégia de Migração Entre Versões<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#estrat%C3%A9gia-de-migra%C3%A7%C3%A3o-entre-vers%C3%B5es" class="hash-link" aria-label="Link direto para Estratégia de Migração Entre Versões" title="Link direto para Estratégia de Migração Entre Versões" translate="no">​</a></h2>
<p>Quando é hora de atualizar para uma nova versão do PHP (e consequentemente uma nova versão de componente), siga esta abordagem:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-1-verifique-sua-versão-atual-do-php">Passo 1: Verifique Sua Versão Atual do PHP<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#passo-1-verifique-sua-vers%C3%A3o-atual-do-php" class="hash-link" aria-label="Link direto para Passo 1: Verifique Sua Versão Atual do PHP" title="Link direto para Passo 1: Verifique Sua Versão Atual do PHP" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">php -v</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-2-atualize-seu-composerjson">Passo 2: Atualize Seu composer.json<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#passo-2-atualize-seu-composerjson" class="hash-link" aria-label="Link direto para Passo 2: Atualize Seu composer.json" title="Link direto para Passo 2: Atualize Seu composer.json" translate="no">​</a></h3>
<p>Altere todas as versões de componentes ByJG para corresponder à sua versão alvo do PHP:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"php"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.4"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/serializer"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/migration"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/rest"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-3-execute-composer-update">Passo 3: Execute Composer Update<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#passo-3-execute-composer-update" class="hash-link" aria-label="Link direto para Passo 3: Execute Composer Update" title="Link direto para Passo 3: Execute Composer Update" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">composer update</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-4-teste-sua-aplicação">Passo 4: Teste Sua Aplicação<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#passo-4-teste-sua-aplica%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Passo 4: Teste Sua Aplicação" title="Link direto para Passo 4: Teste Sua Aplicação" translate="no">​</a></h3>
<p>Execute sua suite de testes para capturar quaisquer mudanças com quebra de compatibilidade:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">./vendor/bin/phpunit</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-5-revise-os-changelogs">Passo 5: Revise os Changelogs<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#passo-5-revise-os-changelogs" class="hash-link" aria-label="Link direto para Passo 5: Revise os Changelogs" title="Link direto para Passo 5: Revise os Changelogs" translate="no">​</a></h3>
<p>Verifique os changelogs de cada componente para mudanças com quebra de compatibilidade:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">https://opensource.byjg.com/docs/php/[nome-do-componente]/</span><br></div></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ciclo-de-vida-de-suporte-de-versões">Ciclo de Vida de Suporte de Versões<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#ciclo-de-vida-de-suporte-de-vers%C3%B5es" class="hash-link" aria-label="Link direto para Ciclo de Vida de Suporte de Versões" title="Link direto para Ciclo de Vida de Suporte de Versões" translate="no">​</a></h2>
<p>Entender o ciclo de vida de suporte ajuda você a planejar upgrades:</p>
<table><thead><tr><th>Versão</th><th>Data de Release</th><th>Desenvolvimento Ativo</th><th>Patches de Segurança</th><th>Fim de Vida</th></tr></thead><tbody><tr><td>4.9.x</td><td>2020</td><td>❌ Encerrado</td><td>✅ Não</td><td>2023</td></tr><tr><td>5.0.x</td><td>2022</td><td>❌ Encerrado</td><td>✅ Não</td><td>2025</td></tr><tr><td>6.0.x</td><td>2025</td><td>✅ Ativo</td><td>✅ Sim</td><td>TBD</td></tr></tbody></table>
<p><strong>Desenvolvimento Ativo</strong>: Novas funcionalidades, melhorias e otimizações
<strong>Patches de Segurança</strong>: Apenas correções de bugs críticos e atualizações de segurança</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="exemplo-do-mundo-real">Exemplo do Mundo Real<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#exemplo-do-mundo-real" class="hash-link" aria-label="Link direto para Exemplo do Mundo Real" title="Link direto para Exemplo do Mundo Real" translate="no">​</a></h2>
<p>Vamos supor que você está construindo uma nova aplicação de API REST:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="sua-versão-do-php">Sua Versão do PHP<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#sua-vers%C3%A3o-do-php" class="hash-link" aria-label="Link direto para Sua Versão do PHP" title="Link direto para Sua Versão do PHP" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">$ php -v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">PHP 8.4.1</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="seu-composerjson">Seu composer.json<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#seu-composerjson" class="hash-link" aria-label="Link direto para Seu composer.json" title="Link direto para Seu composer.json" translate="no">​</a></h3>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"name"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"minhaempresa/api"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"php"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.4"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/rest"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/anydataset"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/migration"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/jwt-session"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"byjg/authuser"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^6.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"require-dev"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"phpunit/phpunit"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^11.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="instalar-dependências">Instalar Dependências<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#instalar-depend%C3%AAncias" class="hash-link" aria-label="Link direto para Instalar Dependências" title="Link direto para Instalar Dependências" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">composer install</span><br></div></code></pre></div></div>
<p><strong>Resultado</strong>: Composer instala as versões 6.0.x mais recentes de todos os componentes, garantindo:</p>
<ul>
<li class="">✅ Compatibilidade total com PHP 8.4</li>
<li class="">✅ Todos os componentes funcionam juntos perfeitamente</li>
<li class="">✅ Atualizações automáticas para patches e versões menores</li>
<li class="">✅ Ecossistema estável e testado</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusão">Conclusão<a href="https://opensource.byjg.com/pt/blog/2025/11/22/understanding-php-components-versioning#conclus%C3%A3o" class="hash-link" aria-label="Link direto para Conclusão" title="Link direto para Conclusão" translate="no">​</a></h2>
<p>O sistema de versionamento padronizado para componentes PHP ByJG transforma o gerenciamento de dependências de um quebra-cabeça complexo em um processo direto.</p>
<p><strong>Principais Conclusões</strong>:</p>
<ol>
<li class=""><strong>Versão do componente = compatibilidade de versão PHP</strong> — Versão 6.0 = PHP 8.3/8.4/8.5</li>
<li class=""><strong>Sempre use a mesma versão principal</strong> em todos os componentes ByJG</li>
<li class=""><strong>Use o operador circunflexo</strong> (<code>^6.0</code>) para estabilidade e atualizações ótimas</li>
<li class=""><strong>Branch main = versão mais recente</strong>, branches de versão para patches</li>
<li class=""><strong>Duas maneiras de testar versões dev</strong>: configurações de estabilidade para todo o projeto ou fixação por pacote</li>
</ol>
<p>Seguindo essas diretrizes, você terá uma configuração de dependências sustentável e previsível que escala com sua aplicação.</p>
<p>Quer explorar todo o ecossistema?
👉 Visite <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com</a></p>
<p>Precisa verificar quais componentes estão disponíveis?
👉 Navegue pelo <a href="https://opensource.byjg.com/docs/php/" target="_blank" rel="noopener noreferrer" class="">catálogo de componentes</a></p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="php" term="php"/>
        <category label="versionamento" term="versionamento"/>
        <category label="composer" term="composer"/>
        <category label="boas-praticas" term="boas-praticas"/>
        <category label="ecossistema" term="ecossistema"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Construindo uma Aplicação PHP Completa: Do Zero à Produção]]></title>
        <id>https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production</id>
        <link href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production"/>
        <updated>2025-11-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Um guia abrangente para construir aplicações PHP prontas para produção usando o ecossistema ByJG - desde a instalação do Docker em uma máquina vazia até a implantação de uma aplicação API completa com autenticação, logging e CI/CD]]></summary>
        <content type="html"><![CDATA[<p>Você já se perguntou como ir de uma máquina completamente vazia para uma aplicação PHP totalmente funcional e pronta para produção? Talvez você tenha herdado um VPS vazio, ou sua equipe queira criar um novo serviço sem gastar semanas montando ferramentas. Neste artigo, vou guiá-lo através de todo o ecossistema PHP ByJG—um conjunto abrangente de ferramentas e componentes que trabalham juntos perfeitamente para ajudá-lo a construir aplicações PHP modernas com confiança.</p>
<p>Seja você trabalhando com Laravel, Symfony, ou construindo do zero, esses componentes podem ajudá-lo a acelerar o desenvolvimento mantendo qualidade de nível de produção. Pense nisso como uma equipe de pit curada: cada utilitário é leve por si só, mas projetado para se encaixar quando você precisa de todo o pipeline.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-vamos-cobrir">O Que Vamos Cobrir<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#o-que-vamos-cobrir" class="hash-link" aria-label="Link direto para O Que Vamos Cobrir" title="Link direto para O Que Vamos Cobrir" translate="no">​</a></h3>
<ul>
<li class="">Configurar uma estação de trabalho em uma máquina Linux vazia (ou WSL) em minutos</li>
<li class="">Entender o catálogo de componentes PHP e quando usar cada peça</li>
<li class="">Usar a Arquitetura de Referência PHP REST para criar uma API</li>
<li class="">Selecionar imagens Docker fortalecidas para cargas de trabalho de produção</li>
<li class="">Operar um fluxo de trabalho realista do dia zero à manutenção contínua</li>
</ul>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-jornada-de-uma-máquina-vazia-à-produção">A Jornada: De uma Máquina Vazia à Produção<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#a-jornada-de-uma-m%C3%A1quina-vazia-%C3%A0-produ%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para A Jornada: De uma Máquina Vazia à Produção" title="Link direto para A Jornada: De uma Máquina Vazia à Produção" translate="no">​</a></h2>
<p>Vamos começar do início - uma máquina sem nada instalado - e trabalhar até uma aplicação API completa e pronta para produção.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-1-configurando-seu-ambiente-de-desenvolvimento">Passo 1: Configurando seu Ambiente de Desenvolvimento<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#passo-1-configurando-seu-ambiente-de-desenvolvimento" class="hash-link" aria-label="Link direto para Passo 1: Configurando seu Ambiente de Desenvolvimento" title="Link direto para Passo 1: Configurando seu Ambiente de Desenvolvimento" translate="no">​</a></h3>
<p>Quando você tem uma máquina Linux vazia (ou WSL no Windows), o primeiro desafio é instalar o Docker e PHP sem gastar uma tarde copiando trechos de posts de blog. É aqui que entra o <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a>. É um único script de carregamento que fornece instaladores opinativos para que sua equipe possa padronizar toda a stack com comandos de uma linha.</p>
<p><strong>Primeiro, instale o script de carregamento (idempotente e seguro para executar novamente):</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">/bin/bash -c "$(curl -fsSL https://shellscript.download/install/loader)"</span><br></div></code></pre></div></div>
<p>Com o <code>load.sh</code> instalado, você pode instalar ferramentas em etapas separadas. Cada comando verifica pré-requisitos, fixa versões conhecidas e estáveis, e configura serviços da mesma forma em cada servidor.</p>
<p><strong>Instalando o Docker:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh docker</span><br></div></code></pre></div></div>
<p><strong>Instalando o PHP 8.4 via Docker:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.4</span><br></div></code></pre></div></div>
<p><strong>Instalando o Node.js 22 (para ferramentas modernas de desenvolvimento como Claude Code, Codex, etc.):</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh node-docker -- 22</span><br></div></code></pre></div></div>
<p>É isso! Em apenas três comandos, você agora tem:</p>
<ul>
<li class="">Docker instalado e executando</li>
<li class="">PHP 8.4 pronto para usar via containers Docker</li>
<li class="">Node.js 22 para ferramentas modernas de desenvolvimento</li>
</ul>
<p>A beleza desta abordagem é que tudo roda em containers—sem conflitos de versão, sem inferno de dependências, apenas ambientes limpos e reproduzíveis. Se alguém da sua equipe precisar reconstruir sua estação de trabalho ou se você mudar entre laptops, você está a poucos comandos de ter paridade.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-ecossistema-de-componentes-php">O Ecossistema de Componentes PHP<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#o-ecossistema-de-componentes-php" class="hash-link" aria-label="Link direto para O Ecossistema de Componentes PHP" title="Link direto para O Ecossistema de Componentes PHP" translate="no">​</a></h2>
<p>Uma vez que seu ambiente está pronto, você ganha acesso a uma extensa coleção de <a href="https://opensource.byjg.com/docs/php" target="_blank" rel="noopener noreferrer" class="">componentes PHP testados em produção</a> que podem ser usados com <strong>QUALQUER framework PHP</strong>—Laravel, Symfony, Slim, ou sua própria solução customizada. Esses pacotes surgiram de projetos reais de clientes, então cada um resolve um problema operacional específico: configuração, cache, persistência, mensageria, e mais.</p>
<p>Abaixo está um tour guiado agrupado por camada. Use-o como um menu; você pode pegar apenas o que precisa, ou montar a stack completa ao criar um novo serviço.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="componentes-de-infraestrutura-essenciais">Componentes de Infraestrutura Essenciais<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#componentes-de-infraestrutura-essenciais" class="hash-link" aria-label="Link direto para Componentes de Infraestrutura Essenciais" title="Link direto para Componentes de Infraestrutura Essenciais" translate="no">​</a></h3>
<p>Comece com os blocos de construção que mantêm configuração, cache e migrações previsíveis em todos os ambientes.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/cache-engine" target="_blank" rel="noopener noreferrer" class="">Cache Engine</a></strong> - Cache compatível com PSR-6 e PSR-16 com múltiplos backends:</p>
<ul>
<li class="">Sistema de arquivos, Redis, Memcached, Session</li>
<li class="">Memória compartilhada (ShmOp), TmpFS</li>
<li class="">Coleta de lixo integrada e operações atômicas</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/config" target="_blank" rel="noopener noreferrer" class="">Config Management</a></strong> - Configuração baseada em ambiente com suporte a injeção de dependência</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/migration" target="_blank" rel="noopener noreferrer" class="">Migration</a></strong> - Controle de versão de banco de dados com migrações up/down suportando MySQL, PostgreSQL, SQLite, Oracle e SQL Server</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="acesso-a-dados--orm">Acesso a Dados &amp; ORM<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#acesso-a-dados--orm" class="hash-link" aria-label="Link direto para Acesso a Dados &amp; ORM" title="Link direto para Acesso a Dados &amp; ORM" translate="no">​</a></h3>
<p>Em seguida, configure a persistência de dados. A camada AnyDataset oferece acesso unificado a múltiplos bancos de dados, e o Micro-ORM adiciona estrutura suficiente sem prendê-lo em um framework pesado.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/micro-orm" target="_blank" rel="noopener noreferrer" class="">Micro-ORM</a></strong> - Mapeamento Objeto-Relacional leve com:</p>
<ul>
<li class="">Query builder</li>
<li class="">Suporte ao padrão Active Record</li>
<li class="">Suporte ao padrão Repository</li>
<li class="">Mapeamento de relacionamentos sem sobrecarga pesada</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/anydataset-db" target="_blank" rel="noopener noreferrer" class="">AnyDataset-DB</a></strong> - Camada de abstração de banco de dados universal suportando múltiplos bancos de dados com uma API consistente</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="api-rest--web-services">API REST &amp; Web Services<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#api-rest--web-services" class="hash-link" aria-label="Link direto para API REST &amp; Web Services" title="Link direto para API REST &amp; Web Services" translate="no">​</a></h3>
<p>Com os dados cobertos, exponha-os através de APIs que seguem os contratos que você publica.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/restserver" target="_blank" rel="noopener noreferrer" class="">RestServer</a></strong> - Crie serviços RESTful com:</p>
<ul>
<li class="">Auto-geração a partir de definições OpenAPI/Swagger</li>
<li class="">Múltiplos manipuladores de saída (JSON, XML, HTML)</li>
<li class="">Suporte integrado a middleware (CORS, JWT, Static Server)</li>
<li class="">Cache de rotas para performance</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/swagger-test" target="_blank" rel="noopener noreferrer" class="">Swagger Test</a></strong> - Testes de contrato para garantir que sua API corresponda à sua especificação OpenAPI</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="segurança--autenticação">Segurança &amp; Autenticação<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#seguran%C3%A7a--autentica%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Segurança &amp; Autenticação" title="Link direto para Segurança &amp; Autenticação" translate="no">​</a></h3>
<p>A autenticação está integrada ao invés de apenas acoplada, para que você possa construir funcionalidades sem reinventar armazenamento de sessão ou fluxos JWT.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/authuser" target="_blank" rel="noopener noreferrer" class="">AuthUser</a></strong> - Sistema completo de autenticação e autorização de usuários com:</p>
<ul>
<li class="">Gerenciamento de sessões</li>
<li class="">Propriedades customizadas</li>
<li class="">Múltiplos backends de armazenamento (Database, XML)</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/jwt-wrapper" target="_blank" rel="noopener noreferrer" class="">JWT Wrapper</a></strong> - Manipulação de JSON Web Token para autenticação stateless</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/jwt-session" target="_blank" rel="noopener noreferrer" class="">JWT Session</a></strong> - Gerenciamento de sessão baseado em JWT</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/crypto" target="_blank" rel="noopener noreferrer" class="">Crypto</a></strong> - Criptografia simétrica sem senha com geração dinâmica de chaves</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="comunicação">Comunicação<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#comunica%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Comunicação" title="Link direto para Comunicação" translate="no">​</a></h3>
<p>Aplicações modernas raramente operam isoladamente. Esses clientes mantêm a comunicação externa (mail, filas, SMS) consistente.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/mailwrapper" target="_blank" rel="noopener noreferrer" class="">MailWrapper</a></strong> - Envie e-mails através de múltiplos provedores:</p>
<ul>
<li class="">SMTP (SSL/TLS)</li>
<li class="">Amazon SES API</li>
<li class="">Mailgun API</li>
<li class="">Sendmail</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/message-queue-client" target="_blank" rel="noopener noreferrer" class="">Message Queue Client</a></strong> - Interface unificada para filas de mensagens:</p>
<ul>
<li class="">Suporte a RabbitMQ via <a href="https://github.com/byjg/rabbitmq-client" target="_blank" rel="noopener noreferrer" class="">rabbitmq-client</a></li>
<li class="">Suporte a Redis Queue via <a href="https://github.com/byjg/redis-queue-client" target="_blank" rel="noopener noreferrer" class="">redis-queue-client</a></li>
<li class="">Fácil de implementar conectores customizados</li>
</ul>
<p><strong><a href="https://opensource.byjg.com/docs/php/sms-client" target="_blank" rel="noopener noreferrer" class="">SMS Client</a></strong> - Envie SMS através de vários provedores</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="utilitários">Utilitários<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#utilit%C3%A1rios" class="hash-link" aria-label="Link direto para Utilitários" title="Link direto para Utilitários" translate="no">​</a></h3>
<p>Finalmente, um conjunto de ajudantes focados para tarefas do dia a dia—geração de IDs, manipulação de imagens, conversão e manipulação de URI.</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/shortid" target="_blank" rel="noopener noreferrer" class="">ShortId</a></strong> - Gere IDs curtos, únicos e seguros para URL</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/imageutil" target="_blank" rel="noopener noreferrer" class="">ImageUtil</a></strong> - Manipulação e processamento de imagens</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/convert" target="_blank" rel="noopener noreferrer" class="">Convert</a></strong> - Utilitários de conversão de dados</p>
<p><strong><a href="https://opensource.byjg.com/docs/php/uri" target="_blank" rel="noopener noreferrer" class="">URI</a></strong> - Manipulação e análise de URI</p>
<p>E <a href="https://opensource.byjg.com/docs/php" target="_blank" rel="noopener noreferrer" class="">muitos mais componentes</a> cobrindo várias necessidades...</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="principais-vantagens">Principais Vantagens<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#principais-vantagens" class="hash-link" aria-label="Link direto para Principais Vantagens" title="Link direto para Principais Vantagens" translate="no">​</a></h3>
<ul>
<li class=""><strong>Agnóstico de Framework</strong>: Use qualquer componente independentemente em seus projetos existentes</li>
<li class=""><strong>Compatível com PSR</strong>: Segue os padrões PHP-FIG (PSR-6, PSR-7, PSR-11, PSR-16)</li>
<li class=""><strong>Bem Documentado</strong>: Cada componente tem documentação abrangente com exemplos</li>
<li class=""><strong>Testado em Produção</strong>: Usado em ambientes de produção reais</li>
<li class=""><strong>Pronto para Composer</strong>: Instalação simples via <code>composer require byjg/component-name</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="construindo-uma-aplicação-completa-do-zero">Construindo uma Aplicação Completa do Zero<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#construindo-uma-aplica%C3%A7%C3%A3o-completa-do-zero" class="hash-link" aria-label="Link direto para Construindo uma Aplicação Completa do Zero" title="Link direto para Construindo uma Aplicação Completa do Zero" translate="no">​</a></h2>
<p>Embora você possa usar componentes individuais com qualquer framework, e se você quiser criar uma aplicação API completa do zero e manter alta velocidade? É aqui que entra a <strong><a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">Arquitetura de Referência PHP REST</a></strong>. Intencionalmente não é outro framework—é um conjunto de opiniões capturadas como código para que você possa fazer fork, adaptá-lo e ainda reconhecer cada parte móvel.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Atualização (julho de 2026)</div><div class="admonitionContent_BuS1"><p>A PHP REST Reference Architecture evoluiu para o <strong><a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">Gluo</a></strong>: um iniciador de projetos (<code>composer create-project byjg/gluo</code>) apoiado por um núcleo de framework atualizável (<a href="https://github.com/byjg/php-gluo-core" target="_blank" rel="noopener noreferrer" class="">byjg/gluo-core</a>) — a mesma arquitetura, mas as melhorias do framework agora chegam via <code>composer update</code> em vez de copiar e colar.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-é-a-arquitetura-de-referência-php-rest">O Que é a Arquitetura de Referência PHP REST?<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#o-que-%C3%A9-a-arquitetura-de-refer%C3%AAncia-php-rest" class="hash-link" aria-label="Link direto para O Que é a Arquitetura de Referência PHP REST?" title="Link direto para O Que é a Arquitetura de Referência PHP REST?" translate="no">​</a></h3>
<p>A Arquitetura de Referência PHP REST é um <strong>template pronto para produção</strong> (não um framework) que reúne os melhores componentes do ecossistema ByJG em uma estrutura de aplicação coesa e pronta para uso.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-está-incluído">O Que Está Incluído<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#o-que-est%C3%A1-inclu%C3%ADdo" class="hash-link" aria-label="Link direto para O Que Está Incluído" title="Link direto para O Que Está Incluído" translate="no">​</a></h3>
<p>O template é dividido em camadas para que você possa continuar ajustando ou afrouxando abstrações dependendo do estágio do seu produto.</p>
<p><strong>Geração de Código &amp; Arquitetura:</strong></p>
<ul>
<li class="">Geração automática de CRUD a partir de tabelas do banco de dados</li>
<li class="">Escolha entre Padrão Repository (separação limpa) ou Padrão ActiveRecord (prototipagem rápida)</li>
<li class="">Modelos, repositórios, serviços, controllers e testes auto-gerados</li>
</ul>
<p><strong>Segurança Integrada:</strong></p>
<ul>
<li class="">Sistema de autenticação baseado em JWT</li>
<li class="">Controle de Acesso Baseado em Funções (RBAC)</li>
<li class="">Endpoints de login prontos para uso</li>
</ul>
<p><strong>Documentação da API:</strong></p>
<ul>
<li class="">Documentação OpenAPI auto-gerada sincronizada com o código</li>
<li class="">Interface Swagger UI interativa para exploração da API</li>
<li class="">Testes de contrato para manter os docs sincronizados</li>
</ul>
<p><strong>Gerenciamento de Banco de Dados:</strong></p>
<ul>
<li class="">Sistema de migração integrado</li>
<li class="">MicroORM para acesso leve a dados</li>
<li class="">Query builder e mapeamento de relacionamentos</li>
</ul>
<p><strong>Experiência de Desenvolvimento:</strong></p>
<ul>
<li class="">Containerização Docker (MySQL, PHP-FPM, Nginx)</li>
<li class="">Scriptify: terminal PHP interativo e executor de CLI</li>
<li class="">Suite abrangente de testes funcionais</li>
<li class="">Hot reload durante o desenvolvimento</li>
</ul>
<p><strong>Pronto para Produção:</strong></p>
<ul>
<li class="">Workflows de CI/CD pré-configurados (GitHub Actions, GitLab CI, Bitbucket Pipelines)</li>
<li class="">Configuração baseada em ambiente</li>
<li class="">Logging estruturado</li>
<li class="">Tratamento e relatório de erros</li>
<li class="">Conformidade com padrões PSR-7, PSR-11, PSR-6/16</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="começando-com-a-arquitetura-de-referência">Começando com a Arquitetura de Referência<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#come%C3%A7ando-com-a-arquitetura-de-refer%C3%AAncia" class="hash-link" aria-label="Link direto para Começando com a Arquitetura de Referência" title="Link direto para Começando com a Arquitetura de Referência" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Instale o template</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-rest-api -- my-api \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --namespace=MyCompany \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --name=mycompany/my-api \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --install-examples=y</span><br></div></code></pre></div></div>
<p>Este único comando cria uma aplicação API completa com:</p>
<ul>
<li class="">Estrutura de projeto seguindo arquitetura limpa</li>
<li class="">Migrações de banco de dados prontas</li>
<li class="">Sistema de autenticação configurado</li>
<li class="">Documentação OpenAPI gerada</li>
<li class="">Ambiente Docker configurado</li>
<li class="">Pipelines de CI/CD prontos</li>
<li class="">Testes configurados</li>
</ul>
<p>Você pode começar a desenvolver imediatamente com:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">cd my-api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker-compose up -d</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer codegen -- --env=dev --table=users all --save</span><br></div></code></pre></div></div>
<p>A partir daqui, você não está procurando stubs ou copiando controllers de projetos anteriores. A geração de código cria scaffolds de endpoints, migrações mantêm o banco de dados sincronizado, e o arquivo OpenAPI permanece acoplado aos handlers reais. Como tudo é compatível com PSR, você pode adicionar qualquer middleware adicional ou reutilizar pacotes familiares.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="implantação-em-produção">Implantação em Produção<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#implanta%C3%A7%C3%A3o-em-produ%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Implantação em Produção" title="Link direto para Implantação em Produção" translate="no">​</a></h2>
<p>O sucesso local é apenas metade da história. Enviar para produção significa escolher imagens em que você pode confiar e uma estratégia de ingress que não vai acordá-lo durante picos de tráfego. O ecossistema inclui imagens Docker curadas e uma camada HAProxy auto-atualizável para que as peças operacionais sejam tão coesas quanto a experiência do desenvolvedor.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="imagens-docker-php-fortalecidas">Imagens Docker PHP Fortalecidas<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#imagens-docker-php-fortalecidas" class="hash-link" aria-label="Link direto para Imagens Docker PHP Fortalecidas" title="Link direto para Imagens Docker PHP Fortalecidas" translate="no">​</a></h3>
<p>Para implantação em produção, o ecossistema fornece <a href="https://opensource.byjg.com/docs/devops/docker-php" target="_blank" rel="noopener noreferrer" class="">imagens Docker PHP curadas e fortalecidas em segurança</a> suportando:</p>
<ul>
<li class=""><strong>Versões PHP</strong>: De 5.6 a 8.5 (edge)</li>
<li class=""><strong>Multi-Arquitetura</strong>: AMD64 e ARM64 (Raspberry Pi, AWS Graviton)</li>
<li class=""><strong>Variantes de Imagem</strong>:<!-- -->
<ul>
<li class=""><code>base</code> - Mínima com mais de 45 extensões PHP (~135MB)</li>
<li class=""><code>cli</code> - Ferramentas de desenvolvimento incluídas (~154MB)</li>
<li class=""><code>fpm</code> - PHP-FPM para configurações customizadas (~139MB)</li>
<li class=""><code>fpm-nginx</code> - Stack LEMP completa (~154MB)</li>
<li class=""><code>fpm-apache</code> - Stack LAMP completa (~154MB)</li>
</ul>
</li>
</ul>
<p><strong>Recursos de Segurança:</strong></p>
<ul>
<li class="">Executa como usuário não-root (<code>app</code>)</li>
<li class="">Inclui SBOM &amp; proveniência de build</li>
<li class="">Releases mensais marcadas para estabilidade</li>
<li class="">Atualizações regulares de segurança</li>
</ul>
<p><strong>Exemplo:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">docker pull byjg/php:8.4-fpm-nginx-2025.11</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="balanceamento-de-carga--ingress">Balanceamento de Carga &amp; Ingress<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#balanceamento-de-carga--ingress" class="hash-link" aria-label="Link direto para Balanceamento de Carga &amp; Ingress" title="Link direto para Balanceamento de Carga &amp; Ingress" translate="no">​</a></h3>
<p>Para gerenciamento de tráfego em produção, <a href="https://opensource.byjg.com/docs/devops/docker-easy-haproxy" target="_blank" rel="noopener noreferrer" class="">EasyHAProxy</a> fornece configuração dinâmica do HAProxy através de descoberta de serviços. Seja você implantando em Docker Swarm, Kubernetes, ou uma única VM, os mesmos labels configuram certificados, roteamento e estatísticas, o que mantém as operações entediantes (da melhor maneira possível).</p>
<p><strong>Plataformas Suportadas:</strong></p>
<ul>
<li class="">Docker standalone</li>
<li class="">Clusters Docker Swarm</li>
<li class="">Kubernetes</li>
<li class="">Configuração estática manual</li>
</ul>
<p><strong>Recursos:</strong></p>
<ul>
<li class="">SSL/TLS automático com Let's Encrypt (protocolo ACME)</li>
<li class="">Certificados SSL customizados</li>
<li class="">Balanceamento de carga entre réplicas</li>
<li class="">Recarregamentos de configuração sem downtime</li>
<li class="">Suporte a modo TCP</li>
<li class="">Painel de estatísticas integrado</li>
</ul>
<p><strong>Exemplo para Docker Swarm:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">docker service create \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --name my-api \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --label easyhaproxy.host=api.example.com \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --label easyhaproxy.ssl.type=letsencrypt \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  mycompany/my-api:latest</span><br></div></code></pre></div></div>
<p>O EasyHAProxy detecta automaticamente o serviço, configura o HAProxy, obtém certificados SSL e começa a rotear o tráfego - nenhuma configuração manual necessária!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-fluxo-completo-do-ecossistema">O Fluxo Completo do Ecossistema<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#o-fluxo-completo-do-ecossistema" class="hash-link" aria-label="Link direto para O Fluxo Completo do Ecossistema" title="Link direto para O Fluxo Completo do Ecossistema" translate="no">​</a></h2>
<p>Veja como tudo se encaixa. O diagrama destaca como um único comando de carregamento se transforma em um template de aplicação, imagens Docker base e, eventualmente, ingress automatizado. Trace as setas para ver como cada peça alimenta o próximo estágio do ciclo de vida:</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fluxo-de-trabalho-do-mundo-real">Fluxo de Trabalho do Mundo Real<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#fluxo-de-trabalho-do-mundo-real" class="hash-link" aria-label="Link direto para Fluxo de Trabalho do Mundo Real" title="Link direto para Fluxo de Trabalho do Mundo Real" translate="no">​</a></h2>
<p>Vamos percorrer um cenário completo do mundo real. Imagine que você tem a tarefa de lançar uma API de comércio antes da próxima sessão de planejamento trimestral. A linha do tempo abaixo espelha como a maioria das equipes realmente se move—há uma explosão de configuração, um bloco de trabalho de funcionalidades, um sprint em automação e, finalmente, uma transferência para operações.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dia-1-configuração-do-projeto">Dia 1: Configuração do Projeto<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#dia-1-configura%C3%A7%C3%A3o-do-projeto" class="hash-link" aria-label="Link direto para Dia 1: Configuração do Projeto" title="Link direto para Dia 1: Configuração do Projeto" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Configure o ambiente (uma vez)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">/bin/bash -c "$(curl -fsSL https://shellscript.download/install/loader)"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">load.sh docker</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.4</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Crie um novo projeto</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-rest-api -- my-shop-api \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --namespace=MyShop \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --name=mycompany/shop-api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cd my-shop-api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker-compose up -d</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dia-2-10-desenvolvimento">Dia 2-10: Desenvolvimento<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#dia-2-10-desenvolvimento" class="hash-link" aria-label="Link direto para Dia 2-10: Desenvolvimento" title="Link direto para Dia 2-10: Desenvolvimento" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Gere CRUD completo para a tabela de produtos</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer codegen -- --env=dev --table=products all --save</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Adicione notificações por e-mail usando MailWrapper</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer require byjg/mailwrapper</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Adicione processamento de fila para tarefas assíncronas</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer require byjg/redis-queue-client</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Execute os testes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">composer test</span><br></div></code></pre></div></div>
<p>Durante esta fase você está iterando rapidamente: adicione capacidades via Composer, apoie-se no CRUD gerado para evitar trabalho repetitivo e mantenha a confiança alta com a suite de testes integrada.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="semana-2-configuração-de-cicd">Semana 2: Configuração de CI/CD<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#semana-2-configura%C3%A7%C3%A3o-de-cicd" class="hash-link" aria-label="Link direto para Semana 2: Configuração de CI/CD" title="Link direto para Semana 2: Configuração de CI/CD" translate="no">​</a></h3>
<ul>
<li class="">Envie para GitHub</li>
<li class="">Workflows de CI/CD já configurados (GitHub Actions)</li>
<li class="">Testes automáticos em cada PR</li>
<li class="">Build da imagem Docker no merge para main</li>
</ul>
<p>Não há correria para montar workflows—o template já incluiu <code>.github/workflows</code> (e equivalentes para GitLab/Bitbucket), então habilitar CI é uma questão de conectar secrets e deixar o pipeline executar.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="mês-1-implantação-em-produção">Mês 1: Implantação em Produção<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#m%C3%AAs-1-implanta%C3%A7%C3%A3o-em-produ%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Mês 1: Implantação em Produção" title="Link direto para Mês 1: Implantação em Produção" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Baixe a imagem pronta para produção</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker pull byjg/php:8.4-fpm-nginx-2025.11</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Construa a imagem da sua aplicação usando-a como base</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker build -t mycompany/shop-api:1.0.0 .</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Implante no Docker Swarm com EasyHAProxy</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker service create \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --name shop-api \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --replicas 3 \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --label easyhaproxy.host=api.shop.com \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --label easyhaproxy.ssl.type=letsencrypt \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  --label easyhaproxy.port=8080 \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  mycompany/shop-api:1.0.0</span><br></div></code></pre></div></div>
<p>No momento em que você implanta, você já sabe qual tag de imagem Docker está mirando, e o EasyHAProxy mantém a configuração de ingress consistente. Escalar para mais réplicas ou apontar um hostname de staging para o mesmo serviço é uma mudança de label, não uma edição manual do HAProxy.</p>
<p>Sua API agora está:</p>
<ul>
<li class="">Executando com 3 réplicas para alta disponibilidade</li>
<li class="">Balanceamento de carga automático</li>
<li class="">Protegida com SSL Let's Encrypt</li>
<li class="">Monitorada via estatísticas do HAProxy</li>
<li class="">Pronta para escalar</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="por-que-este-ecossistema">Por Que Este Ecossistema?<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#por-que-este-ecossistema" class="hash-link" aria-label="Link direto para Por Que Este Ecossistema?" title="Link direto para Por Que Este Ecossistema?" translate="no">​</a></h2>
<p>Depois de seguir o fluxo de trabalho vale a pena dar um passo atrás. Por que investir nesta coleção ao invés de misturar pacotes aleatórios do Packagist? Estas são as âncoras que mantêm a experiência coesa:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-consistência-entre-ambientes">1. <strong>Consistência Entre Ambientes</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#1-consist%C3%AAncia-entre-ambientes" class="hash-link" aria-label="Link direto para 1-consistência-entre-ambientes" title="Link direto para 1-consistência-entre-ambientes" translate="no">​</a></h3>
<p>As mesmas imagens Docker rodam em desenvolvimento, CI/CD e produção - eliminando problemas de "funciona na minha máquina".</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-desenvolvimento-rápido">2. <strong>Desenvolvimento Rápido</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#2-desenvolvimento-r%C3%A1pido" class="hash-link" aria-label="Link direto para 2-desenvolvimento-rápido" title="Link direto para 2-desenvolvimento-rápido" translate="no">​</a></h3>
<p>Vá da ideia para uma API funcionando em minutos, não dias. A geração de código cuida do boilerplate enquanto você foca na lógica de negócio.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-qualidade-de-nível-de-produção">3. <strong>Qualidade de Nível de Produção</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#3-qualidade-de-n%C3%ADvel-de-produ%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para 3-qualidade-de-nível-de-produção" title="Link direto para 3-qualidade-de-nível-de-produção" translate="no">​</a></h3>
<p>Autenticação, autorização, logging, tratamento de erros e testes integrados significam que você começa com melhores práticas, não dívida técnica.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-liberdade-de-framework">4. <strong>Liberdade de Framework</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#4-liberdade-de-framework" class="hash-link" aria-label="Link direto para 4-liberdade-de-framework" title="Link direto para 4-liberdade-de-framework" translate="no">​</a></h3>
<p>Use componentes individualmente em projetos existentes ou adote a arquitetura de referência completa para novos projetos.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-práticas-modernas-de-devops">5. <strong>Práticas Modernas de DevOps</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#5-pr%C3%A1ticas-modernas-de-devops" class="hash-link" aria-label="Link direto para 5-práticas-modernas-de-devops" title="Link direto para 5-práticas-modernas-de-devops" translate="no">​</a></h3>
<p>Pronto para CI/CD, containerizado, com infraestrutura como código. Implante em qualquer plataforma de orquestração de containers.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-sem-aprisionamento-de-fornecedor">6. <strong>Sem Aprisionamento de Fornecedor</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#6-sem-aprisionamento-de-fornecedor" class="hash-link" aria-label="Link direto para 6-sem-aprisionamento-de-fornecedor" title="Link direto para 6-sem-aprisionamento-de-fornecedor" translate="no">​</a></h3>
<p>É um template, não um framework. Você é dono do código. Modifique qualquer coisa que precisar.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-documentação-abrangente">7. <strong>Documentação Abrangente</strong><a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#7-documenta%C3%A7%C3%A3o-abrangente" class="hash-link" aria-label="Link direto para 7-documentação-abrangente" title="Link direto para 7-documentação-abrangente" translate="no">​</a></h3>
<p>Cada componente está documentado com exemplos em <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">opensource.byjg.com</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="resumo-dos-componentes-do-ecossistema">Resumo dos Componentes do Ecossistema<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#resumo-dos-componentes-do-ecossistema" class="hash-link" aria-label="Link direto para Resumo dos Componentes do Ecossistema" title="Link direto para Resumo dos Componentes do Ecossistema" translate="no">​</a></h2>
<p>Se você só puder lembrar de cinco links, faça-os serem estes:</p>
<table><thead><tr><th>Componente</th><th>Propósito</th><th>Recursos Principais</th></tr></thead><tbody><tr><td><a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a></td><td>Configuração de Ambiente</td><td>Instalação de Docker, PHP, Node com um comando</td></tr><tr><td><a href="https://opensource.byjg.com/docs/php" target="_blank" rel="noopener noreferrer" class="">Componentes ByJG</a></td><td>Bibliotecas Reutilizáveis</td><td>Mais de 30 componentes PHP testados em produção</td></tr><tr><td><a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">Arquitetura de Referência PHP REST</a></td><td>Template de Aplicação</td><td>Scaffold completo de API com auth, docs, CI/CD</td></tr><tr><td><a href="https://opensource.byjg.com/docs/devops/docker-php" target="_blank" rel="noopener noreferrer" class="">Imagens Docker PHP</a></td><td>Runtime de Container</td><td>Imagens fortalecidas, multi-arch PHP 5.6-8.5</td></tr><tr><td><a href="https://opensource.byjg.com/docs/devops/docker-easy-haproxy" target="_blank" rel="noopener noreferrer" class="">EasyHAProxy</a></td><td>Controlador de Ingress</td><td>Balanceamento de carga auto-configurado &amp; SSL</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="começando">Começando<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#come%C3%A7ando" class="hash-link" aria-label="Link direto para Começando" title="Link direto para Começando" translate="no">​</a></h2>
<p>Pronto para construir sua próxima aplicação PHP com este ecossistema? Veja como começar, dependendo de onde seu projeto está atualmente:</p>
<ol>
<li class="">
<p><strong>Para Projetos Existentes</strong>: Navegue pela <a href="https://opensource.byjg.com/docs/php" target="_blank" rel="noopener noreferrer" class="">biblioteca de componentes</a> e adicione componentes individuais via Composer</p>
</li>
<li class="">
<p><strong>Para Novas APIs</strong>: Use o template <a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">Arquitetura de Referência PHP REST</a></p>
</li>
<li class="">
<p><strong>Para Configuração de Ambiente</strong>: Visite <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a> para scripts de instalação</p>
</li>
<li class="">
<p><strong>Para Produção</strong>: Confira <a href="https://opensource.byjg.com/docs/devops/docker-php" target="_blank" rel="noopener noreferrer" class="">Imagens Docker PHP</a> e <a href="https://opensource.byjg.com/docs/devops/docker-easy-haproxy" target="_blank" rel="noopener noreferrer" class="">EasyHAProxy</a></p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusão">Conclusão<a href="https://opensource.byjg.com/pt/blog/2025/11/17/complete-php-ecosystem-zero-to-production#conclus%C3%A3o" class="hash-link" aria-label="Link direto para Conclusão" title="Link direto para Conclusão" translate="no">​</a></h2>
<p>O ecossistema PHP ByJG fornece uma solução completa e coesa para desenvolvimento PHP moderno - do seu primeiro comando em uma máquina vazia até uma aplicação API escalável e pronta para produção.</p>
<p>Ao combinar:</p>
<ul>
<li class="">Configuração de ambiente simples</li>
<li class="">Componentes modulares e reutilizáveis</li>
<li class="">Templates prontos para produção</li>
<li class="">Imagens Docker fortalecidas</li>
<li class="">Balanceamento de carga automatizado</li>
</ul>
<p>Você pode focar em construir funcionalidades ao invés de infraestrutura, mantendo qualidade de nível profissional ao longo de todo o ciclo de vida do desenvolvimento.</p>
<p>Seja você construindo um pequeno microsserviço ou uma aplicação complexa, este ecossistema tem as ferramentas que você precisa para ter sucesso.</p>
<hr>
<p><strong>Explore o ecossistema:</strong></p>
<ul>
<li class="">Documentação: <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com</a></li>
<li class="">GitHub: <a href="https://github.com/byjg" target="_blank" rel="noopener noreferrer" class="">https://github.com/byjg</a></li>
<li class="">Scripts de Configuração: <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">https://shellscript.download</a></li>
</ul>
<p>Boa codificação!</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="php" term="php"/>
        <category label="docker" term="docker"/>
        <category label="devops" term="devops"/>
        <category label="ecosystem" term="ecosystem"/>
        <category label="rest-api" term="rest-api"/>
        <category label="production" term="production"/>
        <category label="architecture" term="architecture"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Como eu Consigo Manter Mais de 30 Projetos Open Source (e Continuar Sano 😄)]]></title>
        <id>https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects</id>
        <link href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects"/>
        <updated>2025-11-09T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="How I Manage 30+ Open Source Projects" src="https://opensource.byjg.com/pt/assets/images/frontpage-ad613a6ca8d3c630203ba985781bdafc.png" width="1024" height="1024" class="img_ev3q"></p>
<p>Manter mais de <strong>30 projetos open source</strong> é quase como tocar uma orquestra sozinho. Cada projeto tem suas particularidades, dependências, pipelines, documentações e testes — e, ainda assim, todos precisam funcionar em harmonia.<br>
<!-- -->Em uma empresa com 30 microserviços, é comum ter algo como <strong>2 a 4 DevOps</strong>, <strong>3 a 5 Product Owners</strong> e <strong>50 a 100 desenvolvedores</strong>.<br>
<!-- -->Eu faço isso praticamente <strong>sozinho</strong>.</p>
<p>Parece impossível? Vamos entender como esse ecossistema funciona, e como a automação, padronização e um bom uso de Inteligência Artificial tornam isso não apenas viável, mas prazeroso.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-eu-mantenho">O Que Eu Mantenho<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#o-que-eu-mantenho" class="hash-link" aria-label="Link direto para O Que Eu Mantenho" title="Link direto para O Que Eu Mantenho" translate="no">​</a></h2>
<p>Meu foco é em dois grandes pilares:</p>
<ul>
<li class="">Um <strong>ecossistema de componentes PHP</strong> — que inclui desde micro-ORMs e serializers até integrações REST completas.</li>
<li class="">Um <strong>conjunto de imagens Docker</strong> — utilizadas tanto em desenvolvimento quanto em produção, que garantem consistência e reprodutibilidade em qualquer ambiente.</li>
</ul>
<p>Esses projetos se interconectam, formando uma arquitetura modular e reutilizável. Assim, qualquer componente pode ser usado de forma independente em outros frameworks, mas também todos podem trabalhar juntos dentro do meu ecossistema principal.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="criando-um-ambiente-de-developer-experience">Criando um Ambiente de Developer Experience<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#criando-um-ambiente-de-developer-experience" class="hash-link" aria-label="Link direto para Criando um Ambiente de Developer Experience" title="Link direto para Criando um Ambiente de Developer Experience" translate="no">​</a></h2>
<p>O primeiro passo foi resolver o que mais me atrapalhava: o <strong>setup</strong> de desenvolvimento.<br>
<!-- -->Cada nova máquina exigia configurar dezenas de dependências — PHP, extensões, Composer, ferramentas de teste, etc. Sempre faltava alguma coisa.</p>
<p>A solução foi criar <strong>imagens Docker padronizadas</strong>.<br>
<!-- -->Hoje eu mantenho imagens PHP para diferentes usos:</p>
<ul>
<li class="">CLI</li>
<li class="">FPM</li>
<li class="">FPM com Nginx</li>
<li class="">Exemplos prontos com Docker Compose</li>
</ul>
<p>Essas imagens são utilizadas em <strong>ambientes de desenvolvimento, CI/CD e produção</strong>, o que elimina variações e “works on my machine”.</p>
<p>Mas o desafio maior era lidar com <strong>várias versões do PHP</strong> em uma mesma máquina. Como já usava Docker, decidi: o ambiente de desenvolvimento <strong>também rodaria em containers</strong>.<br>
<!-- -->Padronizei tudo em Linux e fui testando ferramentas até criar o projeto <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a>.</p>
<p>Hoje, para preparar meu ambiente, basta rodar:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.4</span><br></div></code></pre></div></div>
<p>E tudo está pronto — do PHP ao Composer e extensões, em minutos.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="automação-e-padronização-de-processos">Automação e Padronização de Processos<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#automa%C3%A7%C3%A3o-e-padroniza%C3%A7%C3%A3o-de-processos" class="hash-link" aria-label="Link direto para Automação e Padronização de Processos" title="Link direto para Automação e Padronização de Processos" translate="no">​</a></h2>
<p>Ter 30 projetos é como ter 30 microserviços: cada um com sua documentação, arquitetura, dependências e ciclo de vida.<br>
<!-- -->A chave é <strong>automação</strong>.</p>
<p>Desde 2013, venho aperfeiçoando cada projeto individualmente, mantendo <strong>testes automatizados</strong>, cobertura de código significativa e integração contínua.</p>
<p>Mas havia um problema: a <strong>documentação</strong>.<br>
<!-- -->Manter docs espalhadas entre repositórios é um pesadelo. Precisava centralizar tudo <strong>sem duplicar trabalho</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-solução">A Solução<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#a-solu%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para A Solução" title="Link direto para A Solução" translate="no">​</a></h3>
<p>Criei um pipeline que, ao dar merge em um PR, <strong>copia automaticamente a documentação do projeto</strong> para um repositório central — o <code>byjg.github.io</code>.<br>
<!-- -->Esse repositório organiza o conteúdo dentro da estrutura do <strong><a href="https://docusaurus.io/" target="_blank" rel="noopener noreferrer" class="">Docusaurus</a></strong> e dispara um build automático no <strong>Cloudflare Pages</strong>, publicando tudo em <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com</a>.</p>
<p>Assim, <strong>cada commit documentado já atualiza o site principal automaticamente</strong> — sem manutenção manual e sem custo adicional.</p>
<p>No final, foquei em três princípios:</p>
<ol>
<li class=""><strong>Automatizar o que é repetitivo</strong></li>
<li class=""><strong>Centralizar o que é compartilhado</strong></li>
<li class=""><strong>Isolar o que é independente</strong></li>
</ol>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="criando-um-ecossistema-sustentável">Criando um Ecossistema Sustentável<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#criando-um-ecossistema-sustent%C3%A1vel" class="hash-link" aria-label="Link direto para Criando um Ecossistema Sustentável" title="Link direto para Criando um Ecossistema Sustentável" translate="no">​</a></h2>
<p>Meus componentes PHP seguem rigorosamente os padrões <strong>PSR</strong>, usam <strong>Composer</strong> para versionamento e podem ser integrados em qualquer framework.<br>
<!-- -->Cada projeto possui exemplos, testes e instruções de uso.</p>
<p>Com o tempo, percebi que a soma desses componentes formava uma base sólida para algo maior.<br>
<!-- -->Assim nasceu o <strong><a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">PHP Rest Reference Architecture</a></strong> — um projeto que combina os principais componentes do ecossistema em uma estrutura pronta para uso:</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Atualização (julho de 2026)</div><div class="admonitionContent_BuS1"><p>A PHP REST Reference Architecture evoluiu para o <strong><a href="https://github.com/byjg/php-gluo" target="_blank" rel="noopener noreferrer" class="">Gluo</a></strong>: um iniciador de projetos (<code>composer create-project byjg/gluo</code>) apoiado por um núcleo de framework atualizável (<a href="https://github.com/byjg/php-gluo-core" target="_blank" rel="noopener noreferrer" class="">byjg/gluo-core</a>) — a mesma arquitetura, mas as melhorias do framework agora chegam via <code>composer update</code> em vez de copiar e colar.</p></div></div>
<ul>
<li class="">CI/CD configurado</li>
<li class="">Suporte completo a OpenAPI</li>
<li class="">Autenticação e autorização integradas</li>
<li class="">Migração de banco de dados</li>
<li class="">Injeção de dependência</li>
<li class="">Docker e scripts de build</li>
</ul>
<p>Com um único comando, posso criar um projeto PHP REST funcional em minutos:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-rest-api -- &lt;folder&gt; --namespace=&lt;name&gt; --name=&lt;name/name&gt; --install-examples=n</span><br></div></code></pre></div></div>
<p>Essa automação permite que qualquer pessoa crie uma API completa com base em boas práticas e arquitetura limpa — sem reinventar a roda.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="preparando-para-produção">Preparando para Produção<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#preparando-para-produ%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Preparando para Produção" title="Link direto para Preparando para Produção" translate="no">​</a></h2>
<p>As <strong>imagens Docker</strong> que uso em desenvolvimento são as mesmas usadas em CI/CD e produção.<br>
<!-- -->Elas são publicadas no <strong>Container Registry</strong>, o que me permite promover versões entre ambientes (<code>dev → staging → production</code>) com total rastreabilidade.</p>
<p>Para o balanceamento de carga, criei o projeto <strong><a href="https://github.com/byjg/easyhaproxy" target="_blank" rel="noopener noreferrer" class="">Easy HAProxy</a></strong> — uma versão simplificada e poderosa do HAProxy que <strong>se auto-configura com base nos labels Docker</strong>.</p>
<p>Ele suporta SSL, evita downtime, e elimina a necessidade de editar manualmente arquivos de configuração.<br>
<!-- -->Basta subir o container e deixar ele cuidar do resto.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="inteligência-artificial-o-meu-novo-estagiário">Inteligência Artificial: O Meu Novo “Estagiário”<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#intelig%C3%AAncia-artificial-o-meu-novo-estagi%C3%A1rio" class="hash-link" aria-label="Link direto para Inteligência Artificial: O Meu Novo “Estagiário”" title="Link direto para Inteligência Artificial: O Meu Novo “Estagiário”" translate="no">​</a></h2>
<p>A IA tem sido minha aliada em várias frentes — e, honestamente, um verdadeiro <em>game changer</em>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="documentação">Documentação<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#documenta%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Documentação" title="Link direto para Documentação" translate="no">​</a></h3>
<p>Criei prompts personalizados que cobrem 95% das minhas necessidades: desde gerar guias consistentes até evitar erros de formatação que quebram o Docusaurus.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="design-e-frontend">Design e Frontend<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#design-e-frontend" class="hash-link" aria-label="Link direto para Design e Frontend" title="Link direto para Design e Frontend" translate="no">​</a></h3>
<p>Meu foco sempre foi backend, e antes a criação de interfaces era lenta.<br>
<!-- -->Hoje descrevo o que quero, e a IA gera a base da interface — me permitindo focar em lógica e integração.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="desenvolvimento-assistido">Desenvolvimento Assistido<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#desenvolvimento-assistido" class="hash-link" aria-label="Link direto para Desenvolvimento Assistido" title="Link direto para Desenvolvimento Assistido" translate="no">​</a></h3>
<p>Uso o <strong>Claude Code</strong> como meu principal assistente técnico, o <strong>ChatGPT</strong> como segunda opinião, e o <strong>Junie (PHPStorm)</strong> para refino de código.<br>
<!-- -->Nunca deixo a IA agir totalmente sozinha — eu a trato como um <em>pair programmer</em> júnior: reviso, oriento e ajusto o caminho.<br>
<!-- -->Peço planos, discuto soluções e tomo as decisões finais.</p>
<p>Isso multiplicou minha produtividade sem comprometer a qualidade.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-está-por-trás-de-tudo-isso">O Que Está Por Trás de Tudo Isso<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#o-que-est%C3%A1-por-tr%C3%A1s-de-tudo-isso" class="hash-link" aria-label="Link direto para O Que Está Por Trás de Tudo Isso" title="Link direto para O Que Está Por Trás de Tudo Isso" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="infraestrutura">Infraestrutura<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#infraestrutura" class="hash-link" aria-label="Link direto para Infraestrutura" title="Link direto para Infraestrutura" translate="no">​</a></h3>
<ul>
<li class="">Imagens Docker otimizadas</li>
<li class="">Balanceamento de carga com Easy HAProxy</li>
<li class="">Imagem Builder para CI/CD</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="automação">Automação<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#automa%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Automação" title="Link direto para Automação" translate="no">​</a></h3>
<ul>
<li class="">Pipelines CI/CD padronizados</li>
<li class="">Reaproveitamento de workflows entre projetos</li>
<li class="">Ansible e Terraform para provisionamento</li>
<li class="">Scripts Python para gerenciamento do GitHub</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusão">Conclusão<a href="https://opensource.byjg.com/pt/blog/2025/11/09/how-i-manage-30-open-source-projects#conclus%C3%A3o" class="hash-link" aria-label="Link direto para Conclusão" title="Link direto para Conclusão" translate="no">​</a></h2>
<p>Manter dezenas de projetos open source <strong>não é uma questão de tempo, é uma questão de sistema</strong>.<br>
<!-- -->Quando cada parte do processo é automatizada, documentada e integrada, o trabalho escala naturalmente.</p>
<p>O segredo está em <strong>criar um ecossistema coeso</strong>, onde cada componente se apoia no outro — e onde o desenvolvedor se torna não apenas o autor, mas o orquestrador de um ambiente autossustentável.</p>
<p>No final do dia, eu foco em <strong>um projeto por vez</strong>, faço o melhor possível, e deixo que <strong>a automação e a padronização cuidem do resto</strong>.<br>
<!-- -->E é assim que, quase sozinho, mantenho 30+ projetos vivos, documentados e evoluindo continuamente.</p>
<hr>
<p>Quer ver tudo isso em ação?<br>
<!-- -->👉 Explore em <a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com</a></p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="opensource" term="opensource"/>
        <category label="automacao" term="automacao"/>
        <category label="php" term="php"/>
        <category label="devops" term="devops"/>
        <category label="docker" term="docker"/>
        <category label="inteligencia-artificial" term="inteligencia-artificial"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Desenvolvimento PHP Fácil com Docker e VSCode]]></title>
        <id>https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install</id>
        <link href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install"/>
        <updated>2025-10-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Aprenda a configurar um ambiente completo de desenvolvimento PHP usando apenas Docker e VSCode. Nenhuma instalação local de PHP necessária]]></summary>
        <content type="html"><![CDATA[<p>Configurar um ambiente de desenvolvimento PHP pode ser desafiador, especialmente quando você precisa gerenciar múltiplas versões do PHP ou evitar poluir seu sistema com instalações locais. Neste guia, vou mostrar como criar um ambiente completo de desenvolvimento PHP usando apenas Docker e VSCode. Nenhuma instalação local de PHP necessária!</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o-que-você-vai-conseguir">O Que Você Vai Conseguir<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#o-que-voc%C3%AA-vai-conseguir" class="hash-link" aria-label="Link direto para O Que Você Vai Conseguir" title="Link direto para O Que Você Vai Conseguir" translate="no">​</a></h2>
<p>Ao final deste tutorial, você terá:</p>
<ul>
<li class="">PHP rodando inteiramente em containers Docker</li>
<li class="">Suporte completo de debugging com Xdebug no VSCode</li>
<li class="">Capacidade de executar scripts PHP individuais</li>
<li class="">Servidor de desenvolvimento PHP embutido</li>
<li class="">Zero instalação de PHP no seu sistema host</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pré-requisitos">Pré-requisitos<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#pr%C3%A9-requisitos" class="hash-link" aria-label="Link direto para Pré-requisitos" title="Link direto para Pré-requisitos" translate="no">​</a></h2>
<ul>
<li class="">Docker instalado e rodando</li>
<li class="">Visual Studio Code instalado</li>
<li class="">Familiaridade básica com linha de comando</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-1-instalar-php-via-docker-wrapper">Passo 1: Instalar PHP via Docker Wrapper<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#passo-1-instalar-php-via-docker-wrapper" class="hash-link" aria-label="Link direto para Passo 1: Instalar PHP via Docker Wrapper" title="Link direto para Passo 1: Instalar PHP via Docker Wrapper" translate="no">​</a></h2>
<p>Vamos usar o <a href="https://shellscript.download/" target="_blank" rel="noopener noreferrer" class="">shellscript.download</a>, uma coleção de scripts prontos para uso que facilitam a instalação.</p>
<p>Primeiro, instale o Loader:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">/bin/bash -c "$(curl -fsSL https://shellscript.download/install/loader)"</span><br></div></code></pre></div></div>
<p>E então execute este único comando para instalar o PHP 8.4 via Docker:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.4</span><br></div></code></pre></div></div>
<p>Isso cria um script wrapper em <code>~/.shellscript/bin/php8.4</code> que executa o PHP dentro de um container Docker.
A beleza desta abordagem é que o PHP roda em completo isolamento.
Seu sistema host permanece limpo!</p>
<p>O script também adiciona <code>~/.shellscript/bin</code> ao seu PATH, então você pode:</p>
<ul>
<li class="">Chamar <code>php8.4</code> diretamente de qualquer lugar no seu terminal</li>
<li class="">Usar <code>php</code> como um alias (automaticamente aponta para sua versão padrão do PHP)</li>
</ul>
<p>Teste:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">php8.4 --version</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">php --version  # Usa o alias</span><br></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Dica</div><div class="admonitionContent_BuS1"><p>Você pode instalar múltiplas versões do PHP lado a lado:</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.3</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">load.sh php-docker -- 8.2</span><br></div></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-2-instalar-extensões-do-vscode">Passo 2: Instalar Extensões do VSCode<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#passo-2-instalar-extens%C3%B5es-do-vscode" class="hash-link" aria-label="Link direto para Passo 2: Instalar Extensões do VSCode" title="Link direto para Passo 2: Instalar Extensões do VSCode" translate="no">​</a></h2>
<p>Você precisa de duas extensões para desenvolvimento PHP com debugging:</p>
<ol>
<li class="">
<p><strong>PHP Debug</strong> por Xdebug</p>
<ul>
<li class="">ID da Extensão: <code>xdebug.php-debug</code></li>
<li class="">Fornece integração com Xdebug para debugging de código PHP</li>
</ul>
</li>
<li class="">
<p><strong>PHP Intelephense</strong> (recomendado) ou <strong>PHP IntelliSense</strong></p>
<ul>
<li class="">ID da Extensão: <code>bmewburn.vscode-intelephense-client</code></li>
<li class="">Fornece inteligência de código, autocompletar e mais</li>
</ul>
</li>
</ol>
<p>Instale-as via VSCode:</p>
<ol>
<li class="">Pressione <code>Ctrl+Shift+X</code> (ou <code>Cmd+Shift+X</code> no Mac) para abrir Extensões</li>
<li class="">Busque por "PHP Debug" e instale</li>
<li class="">Busque por "PHP Intelephense" e instale</li>
</ol>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Dica</div><div class="admonitionContent_BuS1"><p>Existe uma outra extensão que contém todos os pacotes que precisa. Ele tem um período trial que você pode usar
se quiser.</p><p>O ID da extensão é <code>devsense.phptools-vscode</code></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-3-configurar-as-definições-do-vscode">Passo 3: Configurar as Definições do VSCode<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#passo-3-configurar-as-defini%C3%A7%C3%B5es-do-vscode" class="hash-link" aria-label="Link direto para Passo 3: Configurar as Definições do VSCode" title="Link direto para Passo 3: Configurar as Definições do VSCode" translate="no">​</a></h2>
<p>Abra suas configurações do VSCode (<code>.vscode/settings.json</code> no seu projeto ou configurações globais) e adicione:</p>
<div class="language-jsonc codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-jsonc codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">{</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "php.executables": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        "8.4": "/home/SEU_USUARIO/.shellscript/bin/php8.4"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "php.version": "8.4",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "php.debug.port": [9003]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Importante</div><div class="admonitionContent_BuS1"><p>Substitua <code>/home/SEU_USUARIO/</code> pelo caminho real do seu diretório home. Você pode descobrir executando <code>echo ~</code> no seu terminal.</p><p>Se você instalou uma versão diferente do PHP, atualize tanto a chave (<code>"8.4"</code>) quanto o caminho adequadamente:</p><div class="language-jsonc codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-jsonc codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">"php.executables": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "8.3": "/home/SEU_USUARIO/.shellscript/bin/php8.3"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">},</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">"php.version": "8.3",</span><br></div></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-4-configurar-as-configurações-de-launch">Passo 4: Configurar as Configurações de Launch<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#passo-4-configurar-as-configura%C3%A7%C3%B5es-de-launch" class="hash-link" aria-label="Link direto para Passo 4: Configurar as Configurações de Launch" title="Link direto para Passo 4: Configurar as Configurações de Launch" translate="no">​</a></h2>
<p>Crie ou atualize <code>.vscode/launch.json</code> na raiz do seu projeto:</p>
<div class="language-jsonc codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-jsonc codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">{</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "version": "0.2.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "configurations": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "Listen for Xdebug",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "port": 9003,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHP Debug Current Script",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${file}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${fileDirname}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "port": 9003,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "runtimeArgs": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "-dxdebug.start_with_request=yes"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "env": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_MODE": "debug,develop",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_CONFIG": "client_port=9003"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHP Run Open Script",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${file}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${fileDirname}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "noDebug": true,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHP Built-in Server",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "runtimeArgs": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "-S",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "localhost:8080",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "-t",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "port": 9003,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "noDebug": false,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "serverReadyAction": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "uriFormat": "http://localhost:%s",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "action": "openExternally"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHP Built-in Server (no debug)",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "runtimeArgs": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "-S",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "localhost:8080",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "-t",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "noDebug": true,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "serverReadyAction": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "action": "openExternally"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHPUnit All Tests",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${workspaceFolder}/vendor/bin/phpunit",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${workspaceFolder}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "port": 9003,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "env": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_MODE": "debug,develop",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_CONFIG": "client_port=9003"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHPUnit Current File",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${workspaceFolder}/vendor/bin/phpunit",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "args": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "${file}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${workspaceFolder}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "port": 9003,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "env": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_MODE": "debug,develop",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "XDEBUG_CONFIG": "client_port=9003"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHPUnit All Tests (no debug)",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${workspaceFolder}/vendor/bin/phpunit",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${workspaceFolder}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "noDebug": true,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "name": "PHPUnit Current File (no debug)",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "type": "php",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "request": "launch",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "program": "${workspaceFolder}/vendor/bin/phpunit",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "args": [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "${file}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "cwd": "${workspaceFolder}",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "noDebug": true,</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            "pathMappings": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                "/workdir": "${workspaceFolder}"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passo-5-testar-sua-configuração">Passo 5: Testar Sua Configuração<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#passo-5-testar-sua-configura%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Passo 5: Testar Sua Configuração" title="Link direto para Passo 5: Testar Sua Configuração" translate="no">​</a></h2>
<p>Crie um arquivo de teste simples <code>test.php</code>:</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">greet</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$greeting</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Olá, </span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$name</span><span class="token string double-quoted-string" style="color:#e3116c">!"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$greeting</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">calculate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$sum</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$a</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$b</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$product</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$a</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$b</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'sum'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$sum</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'product'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$product</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'average'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$sum</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"=== Testando Configuração PHP ===\n\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Desenvolvedor"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">greet</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">.</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"\n\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$result</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">calculate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Cálculos para 10 e 5:\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Soma: </span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">{</span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$result</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">[</span><span class="token string double-quoted-string interpolation string single-quoted-string" style="color:#e3116c">'sum'</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">]</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">}</span><span class="token string double-quoted-string" style="color:#e3116c">\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Produto: </span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">{</span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$result</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">[</span><span class="token string double-quoted-string interpolation string single-quoted-string" style="color:#e3116c">'product'</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">]</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">}</span><span class="token string double-quoted-string" style="color:#e3116c">\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Média: </span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">{</span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$result</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">[</span><span class="token string double-quoted-string interpolation string single-quoted-string" style="color:#e3116c">'average'</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">]</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">}</span><span class="token string double-quoted-string" style="color:#e3116c">\n\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Versão do PHP: "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">.</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">phpversion</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">.</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"Xdebug carregado: "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">.</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">extension_loaded</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string single-quoted-string" style="color:#e3116c">'xdebug'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'Sim'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'Não'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">.</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"\n"</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="usando-sua-nova-configuração">Usando Sua Nova Configuração<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#usando-sua-nova-configura%C3%A7%C3%A3o" class="hash-link" aria-label="Link direto para Usando Sua Nova Configuração" title="Link direto para Usando Sua Nova Configuração" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="executando-um-script-sem-debugging">Executando um Script Sem Debugging<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#executando-um-script-sem-debugging" class="hash-link" aria-label="Link direto para Executando um Script Sem Debugging" title="Link direto para Executando um Script Sem Debugging" translate="no">​</a></h3>
<ol>
<li class="">Abra <code>test.php</code></li>
<li class="">Pressione <code>F5</code> ou clique no botão Run</li>
<li class="">Selecione <strong>"PHP Run Open Script"</strong></li>
<li class="">Veja a saída no Debug Console</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="fazendo-debug-de-um-script">Fazendo Debug de um Script<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#fazendo-debug-de-um-script" class="hash-link" aria-label="Link direto para Fazendo Debug de um Script" title="Link direto para Fazendo Debug de um Script" translate="no">​</a></h3>
<ol>
<li class="">Defina um breakpoint clicando à esquerda do número da linha (tente na linha com <code>$greeting = ...</code>)</li>
<li class="">Pressione <code>F5</code></li>
<li class="">Selecione <strong>"PHP Debug Current Script"</strong></li>
<li class="">A execução pausará no seu breakpoint</li>
<li class="">Inspecione variáveis, avance no código passo a passo, etc.</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="executando-o-servidor-embutido">Executando o Servidor Embutido<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#executando-o-servidor-embutido" class="hash-link" aria-label="Link direto para Executando o Servidor Embutido" title="Link direto para Executando o Servidor Embutido" translate="no">​</a></h3>
<ol>
<li class="">Crie um arquivo <code>index.php</code> na raiz do seu projeto</li>
<li class="">Pressione <code>F5</code></li>
<li class="">Selecione <strong>"PHP Built-in Server"</strong> ou <strong>"PHP Built-in Server (no debug)"</strong></li>
<li class="">Seu navegador abrirá automaticamente em <code>http://localhost:8080</code></li>
<li class="">Defina breakpoints nos seus arquivos PHP e atualize a página para fazer debug</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="como-funciona">Como Funciona<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#como-funciona" class="hash-link" aria-label="Link direto para Como Funciona" title="Link direto para Como Funciona" translate="no">​</a></h2>
<p>A mágica acontece no script wrapper criado pelo shellscript.download. Ele:</p>
<ol>
<li class="">Converte caminhos de arquivo absolutos para caminhos relativos</li>
<li class="">Monta seu diretório de projeto como <code>/workdir</code> no container Docker</li>
<li class="">Executa o PHP dentro do container com Xdebug configurado</li>
<li class="">Usa <code>--network host</code> para que o Xdebug possa se conectar de volta ao VSCode</li>
</ol>
<p>Tudo isso acontece de forma transparente. Você apenas escreve código PHP e faz debug como se o PHP estivesse instalado localmente!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="benefícios-desta-abordagem">Benefícios Desta Abordagem<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#benef%C3%ADcios-desta-abordagem" class="hash-link" aria-label="Link direto para Benefícios Desta Abordagem" title="Link direto para Benefícios Desta Abordagem" translate="no">​</a></h2>
<p>✅ <strong>Sistema Limpo</strong>: Nenhuma instalação de PHP poluindo seu sistema<br>
<!-- -->✅ <strong>Múltiplas Versões</strong>: Execute diferentes versões do PHP para diferentes projetos<br>
<!-- -->✅ <strong>Ambiente Consistente</strong>: Mesmo ambiente PHP em diferentes máquinas<br>
<!-- -->✅ <strong>Debug Completo</strong>: Suporte completo ao Xdebug com breakpoints, inspeção de variáveis, etc.<br>
<!-- -->✅ <strong>Atualizações Fáceis</strong>: Atualize o PHP apenas mudando o script wrapper<br>
<!-- -->✅ <strong>Dependências Isoladas</strong>: Cada container é isolado com suas próprias extensões</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="solução-de-problemas">Solução de Problemas<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#solu%C3%A7%C3%A3o-de-problemas" class="hash-link" aria-label="Link direto para Solução de Problemas" title="Link direto para Solução de Problemas" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="could-not-connect-to-debugging-client">"Could not connect to debugging client"<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#could-not-connect-to-debugging-client" class="hash-link" aria-label="Link direto para &quot;Could not connect to debugging client&quot;" title="Link direto para &quot;Could not connect to debugging client&quot;" translate="no">​</a></h3>
<p>Certifique-se de que o VSCode está escutando o Xdebug. Você deve ver "Listening to Xdebug on port 0.0.0.0:9003" no Debug Console quando iniciar o debugging.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="address-already-in-use-ao-iniciar-o-servidor">"Address already in use" ao iniciar o servidor<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#address-already-in-use-ao-iniciar-o-servidor" class="hash-link" aria-label="Link direto para &quot;Address already in use&quot; ao iniciar o servidor" title="Link direto para &quot;Address already in use&quot; ao iniciar o servidor" translate="no">​</a></h3>
<p>O servidor ainda está rodando de uma execução anterior. Pare-o clicando no ícone de lixeira no terminal onde ele está rodando, ou pressione <code>Ctrl+C</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="problemas-de-caminho">Problemas de caminho<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#problemas-de-caminho" class="hash-link" aria-label="Link direto para Problemas de caminho" title="Link direto para Problemas de caminho" translate="no">​</a></h3>
<p>Certifique-se de que seu <code>pathMappings</code> mapeia corretamente <code>/workdir</code> para a pasta do seu workspace. Isso diz ao Xdebug como traduzir caminhos do container para seus caminhos locais.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusão">Conclusão<a href="https://opensource.byjg.com/pt/blog/2025/10/22/using-php-and-vscode-without-install#conclus%C3%A3o" class="hash-link" aria-label="Link direto para Conclusão" title="Link direto para Conclusão" translate="no">​</a></h2>
<p>Com esta configuração, você tem um ambiente profissional de desenvolvimento PHP que é:</p>
<ul>
<li class="">Fácil de configurar (apenas alguns minutos!)</li>
<li class="">Fácil de manter</li>
<li class="">Portável entre máquinas</li>
<li class="">Completamente isolado do seu sistema host</li>
</ul>
<p>Sem mais conflitos de dependências, sem mais problemas de "funciona na minha máquina", e sem mais instalações complexas de PHP. Apenas puro desenvolvimento PHP containerizado e eficiente!</p>
<p>Bom código! 🚀</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="PHP" term="PHP"/>
        <category label="Docker" term="Docker"/>
        <category label="VSCode" term="VSCode"/>
        <category label="Desenvolvimento" term="Desenvolvimento"/>
        <category label="Xdebug" term="Xdebug"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Princípios Simples Para Não Complicar o Complexo]]></title>
        <id>https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity</id>
        <link href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity"/>
        <updated>2025-09-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Lições aprendidas ao longo de anos construindo sistemas complexos: se está difícil, provavelmente está errado. Mantenha simples, não se repita, entenda suas ferramentas e teste sem medo. Princípios que parecem triviais, mas evitam muita dor de cabeça no futuro.
]]></summary>
        <content type="html"><![CDATA[<p>Quando a gente fala de sistemas complexos, a tentação de criar soluções ainda mais complexas é enorme. Já vi isso se
repetir muitas vezes: começa com um problema simples, e em pouco tempo você tem um Frankenstein de código cheio de puxadinhos.
Por isso eu gosto de pregar alguns princípios que parecem óbvios, mas que a maioria esquece.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="elime-tudo-o-que-é-desnecessário---easy">Elime tudo o que é desnecessário - EASY<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#elime-tudo-o-que-%C3%A9-desnecess%C3%A1rio---easy" class="hash-link" aria-label="Link direto para Elime tudo o que é desnecessário - EASY" title="Link direto para Elime tudo o que é desnecessário - EASY" translate="no">​</a></h2>
<p>EASY é um mantra que carrego comigo. Código tem que ser EASY. EASY é um jogo de palavras em ingles que eu criei e que significa FACIL e também a sigla
de Eliminate all Stupidy Yields. Se está difícil, está errado. Se você está quebrando a cabeça horas e horas para fazer algo funcionar,
provavelmente o problema não é a sua persistência, é a sua abordagem.
Complexidade excessiva não é sinônimo de genialidade, é só desperdício de energia. Quando percebo que entrei nesse ciclo,
eu paro. Literalmente. Fecho a IDE, vou descansar, e no dia seguinte volto zerado. Muitas vezes com <code>git checkout -- .</code>
e uma tela em branco. E não tenho vergonha de dizer: foi assim que encontrei algumas das minhas melhores soluções.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kiss--keep-it-stupidly-simple">KISS – Keep It Stupidly Simple<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#kiss--keep-it-stupidly-simple" class="hash-link" aria-label="Link direto para KISS – Keep It Stupidly Simple" title="Link direto para KISS – Keep It Stupidly Simple" translate="no">​</a></h2>
<p>KISS significa "mantenha isso estupidamente simples". Existe uma beleza em soluções simples que só quem já lutou contra a complexidade
consegue enxergar. O pipe no Linux é uma dessas obras de arte: a saída de um comando vira a entrada de outro.
Nada mais elegante. O mesmo vale para uma hash function que resolve problemas enormes em O(1).
Então, não se engane: mais linhas de código não significam mais robustez. Muitas vezes, é só sinal de que você não quis
simplificar.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dry--dont-repeat-yourself">DRY – Don’t Repeat Yourself<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#dry--dont-repeat-yourself" class="hash-link" aria-label="Link direto para DRY – Don’t Repeat Yourself" title="Link direto para DRY – Don’t Repeat Yourself" translate="no">​</a></h2>
<p>Aqui não tem meio termo. "não repita você mesmo". Código duplicado é uma dívida que cobra juros altos. Se você copia e cola,
está plantando uma bomba-relógio para a manutenção futura.
E não é só uma questão técnica, é uma questão de postura: você está dizendo para si mesmo que prefere o atalho ao invés de
encarar a arquitetura de frente. O preço vem depois, e geralmente é você mesmo que paga.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pra-sorrir-tem-que-fazer-sorrir">Pra sorrir, tem que fazer sorrir<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#pra-sorrir-tem-que-fazer-sorrir" class="hash-link" aria-label="Link direto para Pra sorrir, tem que fazer sorrir" title="Link direto para Pra sorrir, tem que fazer sorrir" translate="no">​</a></h2>
<p>Essa frase do filme Tropa de Elite pode soar estranha aqui, mas faz todo sentido. Quer que o banco de dados te dê respostas
rápidas? Então aprenda a fazer ele sorrir também. Conheça os índices, entenda como os dados são armazenados,
como as queries são otimizadas.
O ponto é simples: se você não entende a ferramenta que usa, não adianta esperar que ela resolva seus problemas. É como
colocar um novato para pilotar um avião: não vai acabar bem.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testes-testes-testes">Testes, testes, testes<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#testes-testes-testes" class="hash-link" aria-label="Link direto para Testes, testes, testes" title="Link direto para Testes, testes, testes" translate="no">​</a></h2>
<p>Se tem algo que separa programadores medianos de programadores confiáveis é o hábito de testar. Não estou falando de
“rodar em staging” ou “mandar pra produção e ver se funciona”. Estou falando de criar testes que garantam a saúde do seu código.
Ter bons testes é dormir tranquilo. É poder refatorar sem medo. Eu já fiz mudanças gigantes em código legado com confiança
total porque sabia que a bateria de testes estava lá para me proteger. E vou te dizer: não existe liberdade maior para um
programador do que essa.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="problema-é-covarde">Problema é Covarde<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#problema-%C3%A9-covarde" class="hash-link" aria-label="Link direto para Problema é Covarde" title="Link direto para Problema é Covarde" translate="no">​</a></h2>
<p>O problema é covarde porque ele nunca aparece sozinho. Ele sempre vem em bando. O bug que estourou na aplicação pode estar
ligado a uma query lenta, que por sua vez está ligada a um índice mal configurado, que na verdade começou quando o
servidor de logs estava atrasado em processar eventos.
Quando isso acontece, não basta olhar só para a sua parte do código. É preciso ter domínio do sistema como um todo:
do código à infraestrutura, dos logs aos gráficos de monitoramento. E mais do que isso, é preciso ter uma equipe preparada
para atuar junto, cada um enxergando o pedaço que domina, mas com a visão coletiva de onde está a raiz.
Resolver problemas não é sobre ser herói sozinho. É sobre ter consciência de que o problema é covarde. E por isso você
precisa estar preparado para enfrentá-lo em grupo.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fechando-a-conta">Fechando a conta<a href="https://opensource.byjg.com/pt/blog/simple-principles-avoid-complexity#fechando-a-conta" class="hash-link" aria-label="Link direto para Fechando a conta" title="Link direto para Fechando a conta" translate="no">​</a></h2>
<p>No fundo, nada disso é revolucionário. São princípios simples, quase banais. Mas se você os ignora, é questão de tempo
até cair no buraco da complexidade desnecessária.
Escrever sistemas complexos não é sobre mostrar que você sabe complicar. É sobre ter disciplina para simplificar,
clareza para enxergar o essencial e coragem para recomeçar quando o caminho está errado.</p>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="software-engineering" term="software-engineering"/>
        <category label="clean-code" term="clean-code"/>
        <category label="simplicity" term="simplicity"/>
        <category label="best-practices" term="best-practices"/>
        <category label="programming" term="programming"/>
        <category label="developer-mindset" term="developer-mindset"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Simple components, big superpowers: byjg/serializer and ObjectCopy]]></title>
        <id>https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers</id>
        <link href="https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers"/>
        <updated>2025-09-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Highlighting how byjg/serializer and ObjectCopy turn everyday data transformations into one-liners—with arrays, YAML, PHP serialize, DTO mapping, case conversions, and value transformations.]]></summary>
        <content type="html"><![CDATA[<p>In this post I’ll showcase two tiny-but-mighty pieces: the byjg/serializer’s Serialize and ObjectCopy utilities. Together, they make it trivial to convert, reshape, and map data across formats and DTOs.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers#introduction" class="hash-link" aria-label="Link direto para Introduction" title="Link direto para Introduction" translate="no">​</a></h2>
<p>OpenSource ByJG is a toolbox of small, framework-agnostic components you can mix and match as you like.
The project leans heavily into the KISS principle (“keep it simple”), prioritizing short, composable libraries over
heavyweight frameworks — you can see that spirit across its PHP component catalog and philosophy pages.</p>
<p>Among these, byjg/serializer shines as a pragmatic way to move data between objects, arrays and
wire formats (JSON, XML, YAML) — including handy copy/mapping helpers when shapes don’t match 1:1.</p>
<p>It installs with one line:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">composer require byjg/serialize</span><br></div></code></pre></div></div>
<p>The library converts any object/array/stdClass to array, and then formats that to JSON, XML, YAML, or plain text. It also parses from JSON/YAML/PHP-serialized strings into arrays, and lets you filter/transform fields and even read PHP 8 attributes on the fly. Under the hood, it sticks to lean dependencies (json, symfony/yaml, simplexml).
<a href="https://opensource.byjg.com/" target="_blank" rel="noopener noreferrer" class="">Opensource ByJG</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="basic-from-anything-to-anything">Basic: from anything to anything<a href="https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers#basic-from-anything-to-anything" class="hash-link" aria-label="Link direto para Basic: from anything to anything" title="Link direto para Basic: from anything to anything" translate="no">​</a></h2>
<p>Let’s start with a tiny model and go through the everyday moves.</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serialize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">final</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">User</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">__construct</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token keyword type-hint" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$email</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">getId</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword return-type" style="color:#00009f">int</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$this</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token property" style="color:#36acaa">id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">getName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword return-type" style="color:#00009f">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$this</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token property" style="color:#36acaa">name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">getEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token keyword return-type" style="color:#00009f">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$this</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token property" style="color:#36acaa">email</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$user</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'João'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 1) Object → array</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$asArray</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 2) Array → YAML (JSON/XML similar)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$yaml</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$asArray</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toYaml</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 3) PHP’s own serialized string (use PHP core for output)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$phpSerialized</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">serialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$asArray</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 4) Back from a PHP-serialized string → array</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$backToArray</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">fromPhpSerialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$phpSerialized</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>The calls above mirror the documented API for converting “from anything to array”, formatting arrays and objects to JSON/XML/YAML,
and parsing from JSON/YAML/PHP serialized strings back to arrays.</p>
<p>Another examples:</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serialize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// From PHP's native serialize()</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$serialized</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">serialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'a'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'b'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$parsed</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">fromPhpSerialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$serialized</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// [ 'a' =&gt; 1, 'b' =&gt; 2 ]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// From JSON</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$json</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'{"foo": "bar"}'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$parsedJson</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">fromJson</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$json</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toYaml</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// foo: bar</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// From YAML</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$yaml</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"foo: bar\nanswer: 42\n"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$parsedYaml</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">fromYaml</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$yaml</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toJson</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// {"foo":"bar","answer":42}</span><br></div></code></pre></div></div>
<p>Useful modifiers at a glance</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serialize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$result</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$customer</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">withDoNotParseNullValues</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// drop nulls</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">withOnlyString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// coerce values to strings</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">withMethodPattern</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string single-quoted-string" style="color:#e3116c">'/([^A-Za-z0-9])/'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// customize getter-&gt;property mapping</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Other outputs</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serialize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'k'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'v'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toJson</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'k'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'v'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toXml</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">echo</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'k'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'v'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">toPlainText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="read-php-8-attributes-and-transform-values">Read PHP 8 Attributes and transform values<a href="https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers#read-php-8-attributes-and-transform-values" class="hash-link" aria-label="Link direto para Read PHP 8 Attributes and transform values" title="Link direto para Read PHP 8 Attributes and transform values" translate="no">​</a></h3>
<p>You can parse attributes and transform each property as you go — a powerful hook for masking, formatting, or adding metadata.</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serialize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute delimiter punctuation" style="color:#393A34">#[</span><span class="token attribute attribute-content attribute-class-name class-name">Attribute</span><span class="token attribute delimiter punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">final</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Label</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">__construct</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$text</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">final</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Product</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute delimiter punctuation" style="color:#393A34">#[</span><span class="token attribute attribute-content attribute-class-name class-name">Label</span><span class="token attribute attribute-content punctuation" style="color:#393A34">(</span><span class="token attribute attribute-content string single-quoted-string" style="color:#e3116c">'SKU'</span><span class="token attribute attribute-content punctuation" style="color:#393A34">)</span><span class="token attribute delimiter punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'A-123'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute delimiter punctuation" style="color:#393A34">#[</span><span class="token attribute attribute-content attribute-class-name class-name">Label</span><span class="token attribute attribute-content punctuation" style="color:#393A34">(</span><span class="token attribute attribute-content string single-quoted-string" style="color:#e3116c">'Pretty name'</span><span class="token attribute attribute-content punctuation" style="color:#393A34">)</span><span class="token attribute delimiter punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'Fuzzy Panda'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$prod</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Product</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$out</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token class-name static-context">Serialize</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$prod</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">parseAttributes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Callback receives ($attributeInstance, $value, $keyName, $propertyName, $getterName)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$attr</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$prop</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$getter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// If the attribute exists, append its label</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$attr</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token string double-quoted-string" style="color:#e3116c">"</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">{</span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$value</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">}</span><span class="token string double-quoted-string" style="color:#e3116c"> (</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">{</span><span class="token string double-quoted-string interpolation variable" style="color:#36acaa">$attr</span><span class="token string double-quoted-string interpolation operator" style="color:#393A34">-&gt;</span><span class="token string double-quoted-string interpolation property" style="color:#36acaa">text</span><span class="token string double-quoted-string interpolation punctuation" style="color:#393A34">}</span><span class="token string double-quoted-string" style="color:#e3116c">)"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name static-context">Label</span><span class="token operator" style="color:#393A34">::</span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Only parse this attribute type</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// , $flags (optional)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">print_r</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$out</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// [ 'id' =&gt; 'A-123 (SKU)', 'name' =&gt; 'Fuzzy Panda (Pretty name)' ]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>This callback-based attribute parsing is part of the Serialize API.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="objectcopy-move-data-between-arrays-and-objects">ObjectCopy: move data between arrays and objects<a href="https://opensource.byjg.com/pt/blog/byjg-serializer-objectcopy-superpowers#objectcopy-move-data-between-arrays-and-objects" class="hash-link" aria-label="Link direto para ObjectCopy: move data between arrays and objects" title="Link direto para ObjectCopy: move data between arrays and objects" translate="no">​</a></h2>
<p>ObjectCopy moves data between arrays/objects, even when property names differ.
You can rename properties, switch case styles, and alter values on the fly.</p>
<p>Here a basic example:</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">UserDto</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$payload</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'id'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'name'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'Ana'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$dto</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserDto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$payload</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$dto</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// $dto-&gt;id === 10; $dto-&gt;name === 'Ana'</span><br></div></code></pre></div></div>
<p>And another copying from one DTO into another DTO</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">SourceDto</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$idModel</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$clientName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'John'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">TargetDto</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$idModel</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$clientName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$source</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">SourceDto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$target</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">TargetDto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$target</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Advanced: camelCase to snake_case</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Property</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">CamelToSnakeCase</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Source</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$idModel</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$clientName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'John'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Target</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id_model</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$client_name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$age</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$source</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$target</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Target</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">CamelToSnakeCase</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Advanced: snake_case to camelCase</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Property</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">SnakeToCamelCase</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Source</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id_model</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$client_name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'John'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Target</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$idModel</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$clientName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$age</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$source</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$target</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Target</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">SnakeToCamelCase</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Advanced: map different property names explicitly</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Property</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">DifferentTargetProperty</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Source</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$id_model</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$client_name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'John'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">Target</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$SomeId</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$SomeName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$SomeAge</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$source</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Source</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$target</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Target</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$source</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token variable" style="color:#36acaa">$target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">DifferentTargetProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'id_model'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'SomeId'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'client_name'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'SomeName'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string single-quoted-string" style="color:#e3116c">'age'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'SomeAge'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Advanced: apply value conversions while copying</p>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$payload</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string single-quoted-string" style="color:#e3116c">'birth_date'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'2024-12-31'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string single-quoted-string" style="color:#e3116c">'amount'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">123.45</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string single-quoted-string" style="color:#e3116c">'name'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'john'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">InvoiceDto</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token class-name class-name-fully-qualified type-declaration punctuation" style="color:#393A34">\</span><span class="token class-name class-name-fully-qualified type-declaration">DateTimeImmutable</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$birthDate</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">int</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$amountCents</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword type-declaration" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$target</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">InvoiceDto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$changeValue</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword type-hint" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$sourceName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword type-hint" style="color:#00009f">string</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$targetName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$targetName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'birthDate'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name class-name-fully-qualified punctuation" style="color:#393A34">\</span><span class="token class-name class-name-fully-qualified">DateTimeImmutable</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$targetName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'amountCents'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword type-casting" style="color:#00009f">int</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">round</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$targetName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'name'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ucfirst</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name static-context">ObjectCopy</span><span class="token operator" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">copy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$payload</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$changeValue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Other special conversion cases</p>
<ul>
<li class="">Provide your own property pattern callback to dynamically match names (prefixes, different setters, etc.).</li>
<li class="">Combine a property pattern and a value transformer in the same copy call.</li>
<li class="">Use ObjectCopyInterface to add copyFrom/copyTo to your DTOs, so they can ingest/emit data directly.</li>
</ul>
<div class="language-php codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-php codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token delimiter important">&lt;?php</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token package">ByJG</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">Serializer</span><span class="token package punctuation" style="color:#393A34">\</span><span class="token package">ObjectCopy</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ObjectCopyBase</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// if you prefer extending</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name-definition class-name">MyDto</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">ObjectCopyBase</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$dto</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">MyDto</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$dto</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">copyFrom</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string single-quoted-string" style="color:#e3116c">'id'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'name'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token string single-quoted-string" style="color:#e3116c">'Alice'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// from array/object to this DTO</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token variable" style="color:#36acaa">$dto</span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token function" style="color:#d73a49">copyTo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token variable" style="color:#36acaa">$another</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">                           </span><span class="token comment" style="color:#999988;font-style:italic">// from this DTO into another object/array</span><br></div></code></pre></div></div>
<p>Wrap-up</p>
<p>If you need pragmatic, framework-agnostic data shaping in PHP, byjg/serializer delivers:</p>
<ul>
<li class="">Serialize to read and emit arrays/JSON/YAML/XML and parse PHP-serialized data—with handy modifiers.</li>
<li class="">ObjectCopy to move data between arrays and objects, rename or retarget fields, switch case styles, and transform values inline.</li>
</ul>
<p>Explore the full docs for more patterns and edge cases:</p>
<ul>
<li class=""><a href="https://opensource.byjg.com/docs/php/serializer/serialize" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com/docs/php/serializer/serialize</a></li>
<li class=""><a href="https://opensource.byjg.com/docs/php/serializer/objectcopy" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com/docs/php/serializer/objectcopy</a></li>
<li class=""><a href="https://opensource.byjg.com/docs/php/serializer/objectcopyinterface" target="_blank" rel="noopener noreferrer" class="">https://opensource.byjg.com/docs/php/serializer/objectcopyinterface</a></li>
</ul>]]></content>
        <author>
            <name>Joao Gilberto Magalhaes</name>
            <uri>https://github.com/byjg</uri>
        </author>
        <category label="php" term="php"/>
        <category label="serializer" term="serializer"/>
        <category label="objectcopy" term="objectcopy"/>
        <category label="dto" term="dto"/>
        <category label="byjg" term="byjg"/>
        <category label="opensource" term="opensource"/>
    </entry>
</feed>