<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Flávio Augusto da Silveira</title>
    <description>The latest articles on Forem by Flávio Augusto da Silveira (@flaviosilveira).</description>
    <link>https://forem.com/flaviosilveira</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F251554%2Fd6b3059c-ccf2-4f35-a946-456227fbe804.jpeg</url>
      <title>Forem: Flávio Augusto da Silveira</title>
      <link>https://forem.com/flaviosilveira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/flaviosilveira"/>
    <language>en</language>
    <item>
      <title>Ferramentas de otimização de imagem via linha de comando</title>
      <dc:creator>Flávio Augusto da Silveira</dc:creator>
      <pubDate>Tue, 18 Aug 2020 15:32:51 +0000</pubDate>
      <link>https://forem.com/flaviosilveira/ferramentas-de-otimizacao-de-imagem-via-linha-de-comando-111</link>
      <guid>https://forem.com/flaviosilveira/ferramentas-de-otimizacao-de-imagem-via-linha-de-comando-111</guid>
      <description>&lt;p&gt;Na última semana durante um trabalho de otimização de performance para um site, chegou a hora das imagens. Muitas imagens antigas de produtos e também peças de layout que tinham bom espaço para ganho. Diminuir o tamanho dos arquivos sem perder tanto as cores e a qualidade gráfica das imagens.&lt;/p&gt;

&lt;p&gt;Eu estava procurando por ferramentas para otimizar as imagens de uma maneira que eu pudesse fazer diretamente no servidor, via terminal. Dessa forma eu não precisaria fazer o download de tudo para minha máquina, depois subir novamente e nem nada similar. Apenas um Backup no próprio servidor e rodar os comandos.&lt;/p&gt;

&lt;p&gt;Haviam imagens das famílias PNG, GIF e JPG e acabei chegando nas seguintes ferramentas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jpegoptim&lt;/li&gt;
&lt;li&gt;optiPNG&lt;/li&gt;
&lt;li&gt;gifsicle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todas as três instaladas via apt-get e similares, super leves, fácéis de instalar e também de usar, como mostro a seguir:&lt;/p&gt;

&lt;h3&gt;
  
  
  jpegoptim
&lt;/h3&gt;

&lt;p&gt;Uso simples:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jpegoptim filename.jpg&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Seu arquivo pode ser jpg, jpeg, JPG, JPEG, ...&lt;/p&gt;

&lt;p&gt;O comando acima, faz a otimização mantendo a qualidade da imagem, o que queremos. Mas você pode também passar um parâmetro para controlar isso.&lt;/p&gt;

&lt;p&gt;Tive excelentes resultados sem muita perda de qualidade e com excelentes ganhos de compressão com o seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jpegoptim --max=80 filename.jpg&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  optiPNG
&lt;/h3&gt;

&lt;p&gt;Uso simples:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;optipng filename.png&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Seu arquivo pode ser png, PNG, etc.&lt;/p&gt;

&lt;p&gt;Diferente da ferramenta anterior para jpg, essa não permite parâmetros considerando perda de qualidade por conta do formato PNG e como ele foi concebido.&lt;/p&gt;

&lt;h3&gt;
  
  
  gifsicle
&lt;/h3&gt;

&lt;p&gt;Uso simples:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gifsicle --batch --optimize=3 filename.gif&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;--batch&lt;/strong&gt; é o parâmetro para dizer que você quer manter o arquivo no mesmo lugar e com o mesmo nome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;--optimize&lt;/strong&gt; é um parâmtro que determina o nível de otimização. 3 é uma opção que tenta vários métodos em cima da imagem. Consulte o manual parr&lt;br&gt;
a as outras opções.&lt;/p&gt;

&lt;p&gt;Seu arquivo pode ser gif, GIF, ..&lt;/p&gt;

&lt;p&gt;Em caso de gifs animados, dê uma lida no manual. Existem alguns parâmetros adicionais para otimização de animações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Várias imagens de uma vez só
&lt;/h3&gt;

&lt;p&gt;Para rodar os comandos acima em várias imagens, dentro de vários diretórios, use a opção &lt;strong&gt;-exec&lt;/strong&gt; do comando &lt;strong&gt;find&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;find -name '*.png' -exec optipng {} \;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-name&lt;/strong&gt; para buscar por nome dos arquivos&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.png&lt;/strong&gt; irá buscar por arquivos com a extensão .png. Não esqueça das aspas.&lt;/p&gt;

&lt;p&gt;Após o &lt;strong&gt;-exec&lt;/strong&gt; adicione o comando que você quer executar para todas as ocorrências que serão encontradas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;{}&lt;/strong&gt; As chaves representam as ocorrências encontradas.&lt;/p&gt;

&lt;p&gt;Feche com &lt;strong&gt;\;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes de sair executando essa combinação, teste com um &lt;em&gt;ls -l&lt;/em&gt; no lugar do comando. Assim você verá o que o &lt;strong&gt;find&lt;/strong&gt; vai retornar. E claro, faço um backup das imagens em outra pasta para evitar maiores problemas.&lt;/p&gt;

&lt;h3&gt;
  
  
  man
&lt;/h3&gt;

&lt;p&gt;Todas as ferramentas acima possuem um manual bem completo e fácil de compreender. Basta digitar &lt;strong&gt;man&lt;/strong&gt; e o nome da ferramenta para acessar.&lt;/p&gt;

&lt;p&gt;Grande Abraço!&lt;/p&gt;

</description>
      <category>shell</category>
      <category>jpegoptim</category>
      <category>optipng</category>
      <category>gifsicle</category>
    </item>
    <item>
      <title>Entenda como funciona o PHP! (Do código fonte até a renderização)</title>
      <dc:creator>Flávio Augusto da Silveira</dc:creator>
      <pubDate>Tue, 18 Aug 2020 15:12:35 +0000</pubDate>
      <link>https://forem.com/flaviosilveira/entenda-como-funciona-o-php-do-codigo-fonte-ate-a-renderizacao-3h8k</link>
      <guid>https://forem.com/flaviosilveira/entenda-como-funciona-o-php-do-codigo-fonte-ate-a-renderizacao-3h8k</guid>
      <description>&lt;p&gt;Esse artigo é quase uma tradução fiel do artigo &lt;a href="https://www.sitepoint.com/how-php-executes-from-source-code-to-render"&gt;How PHP Executes from Source Code to Render&lt;/a&gt; de &lt;a href="https://twitter.com/tpunt94"&gt;Thomas Punt&lt;/a&gt;, revisado por &lt;a href="https://twitter.com/rafieyounes"&gt;Younes Rafie&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;No original o autor coloca os pedaços de códigos para você testar por conta. Aqui, além disso, adicionei como rodar os mesmos com um único comando, usando docker. Assim você não precisa de muito esforço para ver os exemplos. &lt;/p&gt;

&lt;p&gt;Criei uma imagem no dockerhub com tudo necessário para rodar os exemplos desse artigo. Basta ter o docker instalado e rodar os comandos como mostrados.&lt;/p&gt;

&lt;p&gt;Acaba não sendo uma tradução fiel, pois tomei a liberdade de adicionar e tirar algumas partes de texto em relação ao original. E por ter muitos termos técnicos, posso ter pisado na bola ao traduzir ou manter no inglês algum termo em específico. Fiz isso para tentar deixar mais didático do meu ponto de vista. E isso não foi tão simples. Então, não deixe de comentar caso veja algo errado / estranho...&lt;/p&gt;

&lt;h2&gt;
  
  
  4 etapas
&lt;/h2&gt;

&lt;p&gt;Bastante coisa acontece quando você executa um pequeno trecho de código PHP. De maneira geral podemos dizer que o Interpretador do PHP passa por 4 etapas quando o código é executado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokenização (Ou Lexing ou Scanning)&lt;/li&gt;
&lt;li&gt;Parsing&lt;/li&gt;
&lt;li&gt;Compilação&lt;/li&gt;
&lt;li&gt;Interpretação&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Abaixo vamos passar por cada um dessas etapas e ver como podemos checar a saída de cada um deles para entender o que realmente acontece. Para isso vamos usar algumas extensões que já vem com PHP nativamente (como Tokenizer e o OPCache) e outras que não (como php-ast e o VLD). &lt;/p&gt;

&lt;h2&gt;
  
  
  Tokenização
&lt;/h2&gt;

&lt;p&gt;Também chamada de Lexing ou de Scanning por alguns outros autores.&lt;/p&gt;

&lt;p&gt;Essa etapa faz um processo de pegar um texto (um código PHP nesse caso) e transformar ele em uma sequência de tokens. Um token é simplesmente um identificador, e esse identificador vai indicar um valor. &lt;/p&gt;

&lt;p&gt;O PHP usa o &lt;a href="http://re2c.org/"&gt;re2c&lt;/a&gt; para gerar esses tokens a partir do arquivo de configuração &lt;a href="https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l"&gt;zend_language_scanner.l&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vamos ver a saída dessa etapa usando a extensão &lt;a href="http://php.net/manual/en/book.tokenizer.php"&gt;Tokenizer&lt;/a&gt;, nativa no PHP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$code = &amp;lt;&amp;lt;&amp;lt;'code'
&amp;lt;?php
$a = 1;
code;

$tokens = token_get_all($code);

foreach ($tokens as $token) {
    if (is_array($token)) {
        echo "Line {$token[2]}: ", token_name($token[0]), " ('{$token[1]}')", PHP_EOL;
    } else {
        var_dump($token);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Salve o código acima em um arquivo (por exemplo, tokenizer.php), em seguida rode o container para executar ele.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --rm -v "$PWD":/myapp -w /myapp flaviosilveira/php-source-to-render php tokenizer.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Explicando rapidamente o comando docker acima:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--rm&lt;/strong&gt; para remover o container automaticamente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-v "$PWD":/myapp&lt;/strong&gt; para compartilhar seu diretório atual com o diretório 'myapp' do container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-w /myapp&lt;/strong&gt; é uma opção para indicar o local de trabalho para o php, workspace, o document root.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;flaviosilveira/php-source-to-render&lt;/strong&gt; é a imagem para construir o container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Line 1: T_OPEN_TAG ('&amp;lt;?php
')
Line 2: T_VARIABLE ('$a')
Line 2: T_WHITESPACE (' ')
string(1) "="
Line 2: T_WHITESPACE (' ')
Line 2: T_LNUMBER ('1')
string(1) ";"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Coisas para considerarmos da saída acima: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nem todos os pedaços do código se transformam em Tokens. Alguns símbolos já são considerados tokens por si só (=, ;, :, ?, e outros). &lt;/li&gt;
&lt;li&gt;Será armazenado o valor correspondente do token e o número da linha desse token para o stack trace. Aquele mesmo que vemos em algumas mensagens de erro tentando nos ajudar quando temos problemas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Parsing
&lt;/h2&gt;

&lt;p&gt;Essa etapa de parsing, pega a saÃ­da da etapa de tokenização e executa duas tarefas:&lt;/p&gt;

&lt;p&gt;A primeira tarefa: Valida a ordem dos tokens com as regras da linguagem definidas no &lt;a href="https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y"&gt;BNF grammar file&lt;/a&gt;. Isso garante que as regras de sintaxe da linguagem estão sendo seguidas. Essa etapa conta com o &lt;a href="https://www.gnu.org/software/bison/"&gt;Bison&lt;/a&gt; (Não é Street Fighter, é Open Source) e usa o contexto &lt;strong&gt;LARL&lt;/strong&gt;, Look Ahead, Left to right, ou seja, faz a leitura em frente, enquanto achar tokens, da esquerda para a direita.&lt;/p&gt;

&lt;p&gt;A segunda tarefa: Gerar uma árvore de sintaxe abstrata, no inglês AST (Abstract Sintaxe Tree), uma árvore do código fonte que será usada durante a próxima etapa.&lt;/p&gt;

&lt;p&gt;Podemos ver a forma dessa AST produzida pelo parser usando a extensão &lt;a href="https://github.com/nikic/php-ast"&gt;php-ast&lt;/a&gt; do excelente &lt;a href="https://github.com/nikic"&gt;Nikita Popov&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$code = &amp;lt;&amp;lt;&amp;lt;'code'
&amp;lt;?php
$a = 1;
code;

print_r(ast\parse_code($code, 60));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  Importante
&lt;/h5&gt;

&lt;p&gt;O número 60 dentro do print_r acima, se refere a versão. 60 é a versão no momento de escrita dese artigo (Na versão original em inglês era 30). Caso dê erro, a saída do mesmo te mostrará a versão atual. Basta trocar.&lt;/p&gt;

&lt;p&gt;Salve o código acima em um arquivo (por exemplo, parsing.php), em seguida rode o container para executar ele:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --rm -v "$PWD":/myapp -w /myapp flaviosilveira/php-source-to-render php parsing.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ast\Node Object (
    [kind] =&amp;gt; 132
    [flags] =&amp;gt; 0
    [lineno] =&amp;gt; 1
    [children] =&amp;gt; Array (
        [0] =&amp;gt; ast\Node Object (
            [kind] =&amp;gt; 517
            [flags] =&amp;gt; 0
            [lineno] =&amp;gt; 2
            [children] =&amp;gt; Array (
                [var] =&amp;gt; ast\Node Object (
                    [kind] =&amp;gt; 256
                    [flags] =&amp;gt; 0
                    [lineno] =&amp;gt; 2
                    [children] =&amp;gt; Array (
                        [name] =&amp;gt; a
                    )
                )
                [expr] =&amp;gt; 1
            )
        )
    )
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A árvore de nós, que geralmente são do tipo &lt;strong&gt;ast\Node&lt;/strong&gt;, tem várias propriedades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kind - Um valor inteiro para representar o tipo de nó. Cada um tem uma constante correspondente (AST_STMT_LIST =&amp;gt; 132, AST_ASSIGN =&amp;gt; 517, AST_VAR =&amp;gt; 256).&lt;/li&gt;
&lt;li&gt;flags - Um inteiro que específico comportamento de sobrecarga. Por exemplo, um nó ast\AST_BINARY_OP terá flags para diferenciar qual operação binária está ocorrendo.&lt;/li&gt;
&lt;li&gt;lineno - O número da linha, como visto na informação do token anteriormente.&lt;/li&gt;
&lt;li&gt;children - Sub-Nós. Por exemplo uma função vai apresentar como children: parâmetros, tipo do retorno, corpo, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa saída AST dessa etapa é útil para ferramentas como analisadores de código, por exemplo o &lt;a href="https://github.com/phan/phan"&gt;Phan&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilação
&lt;/h2&gt;

&lt;p&gt;A etapa de compilação consome a AST gerada acima. Gerando Opcodes (Operation Codes) recursivamente enquanto percorre a árvore. Opcodes são operações a serem executadas.&lt;/p&gt;

&lt;p&gt;Essa etapa também executa algumas otimizações. Isso inclui resolver algumas chamadas de função com argumentos literais (strlen("abc") para int(3)) e expressões matemáticas (60 * 60 * 24 para int(86400)).&lt;/p&gt;

&lt;p&gt;Há algumas maneiras de vermos os Opcodes gerados nessa etapa. Mas hoje vamos de &lt;a href="https://derickrethans.nl/projects.html#vld"&gt;VLD&lt;/a&gt;, criada pelo &lt;a href="https://twitter.com/derickr"&gt;Derick Rethans&lt;/a&gt;. Essa ferramenta mostra a saída de uma maneira mais amigável do que as demais, e isso ajuda no nosso entendimento.&lt;/p&gt;

&lt;p&gt;Vamos ver a saída para o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (PHP_VERSION == '7.2.15') {
    echo 'Yay', PHP_EOL;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Salve o código acima em um arquivo (por exemplo, compilation.php), em seguida rode o container para executar ele:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --rm -v "$PWD":/myapp -w /myapp flaviosilveira/php-source-to-render php -dvld.active=1 compilation.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   3     0  E &amp;gt; &amp;gt; JMPZ                                                     &amp;lt;true&amp;gt;, -&amp;gt;3
   4     1    &amp;gt;   ECHO                                                     'Yay'
         2        ECHO                                                     '%0A'
   6     3    &amp;gt; &amp;gt; RETURN                                                   1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;De certa forma os Opcodes se parecem com o código fonte original, permitindo acompanhar as operações básicas. (Esse artigo não tem a pretensão de detalhar Opcodes.) Nenhuma otimização foi aplicada no nível do código de operação no script acima, mas podemos ver que essa etapa de compilação resolveu por exemplo a condição (1 == '1') para true.&lt;/p&gt;

&lt;p&gt;Nessa etapa também, entram em ação ferramentas que fazem o cache dos Opcodes, evitando assim refazer as etapas de tokenização, parsing e compilação com frequência. Entre essas ferramentas temos o apc e o OPCache.&lt;/p&gt;

&lt;p&gt;O OPCache, além de fazer isso também tem alguns passos de otimização. Alterando o parâmetro dopcache.optimization_level, podemos aumentar o nível de otimização e ver o que acontece:&lt;/p&gt;

&lt;h5&gt;
  
  
  Importante
&lt;/h5&gt;

&lt;p&gt;Precisamos também habilitar o OPCache para cli, com o parâmetro dopcache.enable_cli para vermos a saída.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --rm -v "$PWD":/myapp -w /myapp flaviosilveira/php-source-to-render php -dopcache.enable_cli=1 -dopcache.optimization_level=1111 -dvld.active=1 -dvld.execute=0 code/compilation.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   4     0  E &amp;gt;   ECHO                                                     'Yay%0A'
   6     1      &amp;gt; RETURN                                                   1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Vemos que a condicional foi removida e as duas instruções com ECHO se tornaram uma só. Isso é só um gostinho das otimizações que o OPCache aplica. Esse artigo não vai entrar nos detalhes dos níveis de otimização por ser um assunto extenso.&lt;/p&gt;

&lt;h5&gt;
  
  
  Importante
&lt;/h5&gt;

&lt;p&gt;Você pode adicionar os parâmetros -dvld.save_paths e -dvld.save_dir para salvar essa saída com os Opcodes em um arquivo que você poderá abrir com o &lt;a href="http://graphviz.org/"&gt;Graphiz&lt;/a&gt;. Fica muito legal para estudar!&lt;/p&gt;

&lt;h2&gt;
  
  
  Interpretação
&lt;/h2&gt;

&lt;p&gt;A última etapa é a interpretação dos Opcodes. Aqui os Opcodes são executados na VM Zend Engine (ZE). Não há muito o que dizer sobre essa etapa (ao menos de um ponto de vista de alto nível). A saída é praticamente igual a saída de seus códigos usando comandos como echo, print, var_dump e etc.&lt;/p&gt;

&lt;p&gt;Então, ao invés de entrar em algo muito complexo nessa etapa, aqui está um fato divertido: o PHP chama a si mesmo como uma dependência quando gera sua própria VM. Isso porque a VM é gerada por um script PHP, para ser mais simples de escrever e mais fácil de manter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Demos aqui uma rápida olhada pelas 4 etapas que o interpretador do PHP passa quando executa um código. Isso envolveu o uso de algumas extensões como Tokenizer, OPCache, php-ast e VLD para manipular e ver a saída de cada etapa.&lt;/p&gt;

&lt;p&gt;Que esse artigo ajude a espalhar um melhor entendimento sobre o interpretador do PHP, e também que mostre a importância do estágio de cache na etapa de compilação.&lt;/p&gt;

&lt;p&gt;Abraço!&lt;/p&gt;

</description>
      <category>php</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
