<?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: Danilo Correa</title>
    <description>The latest articles on Forem by Danilo Correa (@dcorrea777).</description>
    <link>https://forem.com/dcorrea777</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%2F39014%2Ffa91d817-5e56-4530-b2d5-fa5099f006ff.jpeg</url>
      <title>Forem: Danilo Correa</title>
      <link>https://forem.com/dcorrea777</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dcorrea777"/>
    <language>en</language>
    <item>
      <title>Compactar arquivos direto no S3 com PHP</title>
      <dc:creator>Danilo Correa</dc:creator>
      <pubDate>Sat, 30 Dec 2023 15:00:56 +0000</pubDate>
      <link>https://forem.com/dcorrea777/compactar-arquivos-direto-no-s3-com-php-47k0</link>
      <guid>https://forem.com/dcorrea777/compactar-arquivos-direto-no-s3-com-php-47k0</guid>
      <description>&lt;p&gt;Olá, pessoal! Tudo bem? Neste artigo, abordarei um assunto que parece simples à primeira vista, mas muitas vezes passa despercebido na forma como o implementamos em nosso código. Antes de começar, quero ressaltar que não há uma abordagem certa ou errada. No entanto, é possível antecipar alguns problemas que podem surgir no futuro.&lt;/p&gt;

&lt;p&gt;Imagine o seguinte cenário: você possui uma coleção de arquivos no S3 e sua aplicação precisa compactar esses arquivos. Existem várias maneiras de implementar essa lógica, e se você está começando na área de desenvolvimento, não se preocupe. Comece com o cenário mais simples e, com o tempo, aprimore o seu código.&lt;/p&gt;

&lt;p&gt;A seguir, vou descrever a Versão 1 do nosso cenário mais simples e, em seguida, a Versão 2 com algumas melhorias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versão 1
&lt;/h2&gt;

&lt;p&gt;Como mencionei, imagine que você tenha uma lista de 10 ou mais arquivos no S3, e sua aplicação ou script precisa criar um arquivo zip com todos esses arquivos. Para esse cenário, apresentarei os passos de forma simplificada. Compartilhe nos comentários se você utiliza algo semelhante em seu trabalho.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Baixar cada arquivo do S3 de forma síncrona.&lt;/li&gt;
&lt;li&gt;Salvar cada arquivo em um diretório do nosso sistema de arquivos.&lt;/li&gt;
&lt;li&gt;Compactar todos os arquivos em um zip e salvar em nosso sistema de arquivos.&lt;/li&gt;
&lt;li&gt;Carregar (upload) o arquivo zip para o S3.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Este é um fluxo comum que funciona bem. Não há nada de errado aqui, mas podemos melhorar muitos aspectos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versão 2
&lt;/h2&gt;

&lt;p&gt;Agora, a brincadeira começa a ficar interessante! Na Versão 2 do nosso script, podemos aprimorar basicamente o seguinte: todos os arquivos podem ser baixados de forma assíncrona, permitindo que nosso script não espere um arquivo ser baixado totalmente para iniciar o próximo. Além disso, em vez de criar um arquivo zip no sistema de arquivos local, podemos criar um arquivo zip diretamente no S3. Isso mesmo! Dessa forma, podemos adicionar o conteúdo baixado de forma assíncrona ao zip que já está no S3, eliminando a necessidade de salvar algo em nosso sistema de arquivos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Baixar o conteúdo de cada arquivo de forma assíncrona.&lt;/li&gt;
&lt;li&gt;Criar um arquivo zip diretamente no S3 usando o SDK da AWS.&lt;/li&gt;
&lt;li&gt;Para cada arquivo baixado de forma assíncrona, adicionar o conteúdo ao zip.&lt;/li&gt;
&lt;li&gt;Quando tudo estiver concluído, fechar o arquivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parece fácil quando explicado assim, não é? Não é tão simples na prática, mas também não é algo impossível. Vamos ver como fazer isso em PHP, certo?&lt;/p&gt;

&lt;p&gt;Para facilitar, criei um repositório &lt;a href="https://github.com/dcorrea777/zipfile-s3"&gt;(clique aqui)&lt;/a&gt; no GitHub com alguns scripts prontos. Você pode clonar o repositório em sua máquina e executar em um ambiente local usando Docker ou conectar-se ao seu próprio ambiente AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparando ambiente
&lt;/h2&gt;

&lt;p&gt;Para começar, faça o clone do &lt;a href="https://github.com/dcorrea777/zipfile-s3"&gt;repositório&lt;/a&gt; e instale todas as dependências.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:dcorrea777/zipfile-s3.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após clonar o &lt;a href="https://github.com/dcorrea777/zipfile-s3"&gt;repositório&lt;/a&gt;, instale todas as dependências do projeto e ajuste as variáveis de ambiente, se necessário, no arquivo .env.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Instalando os pacotes&lt;/span&gt;
composer &lt;span class="nb"&gt;install&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Criando um arquivo .env a partir do .env.example&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abra o arquivo .env e ajuste os valores de acordo com o seu ambiente. As variáveis de ambiente incluem configurações para o serviço que simula o S3 localmente, informações do bucket local e credenciais da AWS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Serviço que simula o S3 em seu ambiente local&lt;/span&gt;
&lt;span class="nv"&gt;STORAGE_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9000"&lt;/span&gt; 
&lt;span class="c"&gt;# Aqui você escolhe qual tipo de driver você quer usar (local, s3)&lt;/span&gt;
&lt;span class="nv"&gt;STORAGE_DRIVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;
&lt;span class="c"&gt;# Nome do bucket que é criado no ambiente local&lt;/span&gt;
&lt;span class="nv"&gt;STORAGE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"zip"&lt;/span&gt; 
&lt;span class="nv"&gt;AWS_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="c"&gt;# Credenciais da AWS&lt;/span&gt;
&lt;span class="nv"&gt;STORAGE_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"fake"&lt;/span&gt;
&lt;span class="nv"&gt;STORAGE_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"fake"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após instalar os pacotes e ajustar as variáveis do seu arquivo .env, vamos executar o docker-compose.yml para subir o serviço do &lt;a href="https://min.io"&gt;minio&lt;/a&gt;. Basicamente o &lt;a href="https://min.io/"&gt;minio&lt;/a&gt; é um s3 rondando localhost, com isso podemos se conectar usando o proprio SDK da AWS para fazer nossos testes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Subir o serviço do minio&lt;/span&gt;
docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# Verificar se o serviço esta sendo executado&lt;/span&gt;
docker-compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após subir o container do &lt;a href="https://min.io/"&gt;minio&lt;/a&gt;, você precisará fazer algumas configurações locais. Acesse o endereço &lt;a href="http://localhost:9001"&gt;http://localhost:9001&lt;/a&gt; e faça login com as credenciais que estão no arquivo docker-compose.yml.&lt;/p&gt;

&lt;p&gt;Exemplo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=supersecret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de fazer login, você precisa gerar uma credencial de acesso em seu ambiente local, então vá em: Access Keys (Menu lateral na esquerda) &amp;gt;&amp;gt; Create access keys (Botão na direita) e clique em Create, use essas credenciais no seu arquivo .env.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env 
STORAGE_ACCESS_KEY="COLOQUE AQUI SUA ACCESS KEY"
STORAGE_SECRET_KEY="COLOQUE AQUI SUA SECRET KEY"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para ambiente local, eu criei um arquivo &lt;code&gt;upload-to-s3.php&lt;/code&gt; que gera 10 arquivos &lt;code&gt;.txt&lt;/code&gt; com o tamanho de 2GB usando um comando do Linux. Lembrando que o docker-compose.yml apenas contém o serviço do minio. Estou partindo do princípio de que você tem o PHP instalado na sua máquina. Caso não tenha, eu escrevi outro artigo sobre como instalar o PHP na sua máquina usando o &lt;a href="https://dev.to/dcorrea777/criando-seu-ambiente-com-asdf-j6d"&gt;ASDF&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php upload-to-s3.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basicamente esse script gera os arquivos e os carrega no minio ou S3. Após executar o script, você pode acessar o minio e verificar se os arquivos existem no bucket zip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mão na massa!
&lt;/h2&gt;

&lt;p&gt;Agora vamos para o que interessa. Antes de você executar o arquivo &lt;code&gt;zip.php&lt;/code&gt;, vou explicar cada arquivo e pasta e no final você pode executar para testar, ok? Antes de falar do arquivo &lt;code&gt;zip.php&lt;/code&gt;, que é o arquivo principal, vou comentar sobre a pasta config e seus arquivos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Config &amp;gt; storage.php
&lt;/h2&gt;

&lt;p&gt;Na pasta config, temos alguns arquivos de configuração para auxiliar na organização de nosso projeto. O arquivo storage.php basicamente é um arquivo de configuração, onde você escolhe se quer que seu código execute no minio ou no próprio S3 da AWS. Esse arquivo é carregado em nosso container de dependência.&lt;/p&gt;

&lt;h2&gt;
  
  
  Config &amp;gt; container.php
&lt;/h2&gt;

&lt;p&gt;Como o nome já diz, é nosso arquivo de container de dependência. Todas as instâncias do nosso projeto estão aqui. Eu sei que a gente só tem uma, mas isso deixa o código mais organizado hahaha. Enfim, aqui estamos usando o pacote &lt;a href="https://php-di.org/"&gt;php-di&lt;/a&gt; para nosso container de dependência.&lt;/p&gt;

&lt;h2&gt;
  
  
  Config &amp;gt; bootstrap.php
&lt;/h2&gt;

&lt;p&gt;E, por fim, nosso arquivo &lt;code&gt;bootstrap.php&lt;/code&gt; instancia nosso container de dependência e retorna a própria instância. Além disso, carrega as variáveis de ambiente usando o pacote &lt;a href="https://github.com/vlucas/phpdotenv"&gt;phpdotenv&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zip.php
&lt;/h2&gt;

&lt;p&gt;O nosso arquivo zip.php, que está na raiz do projeto, é onde contém todo o código que gera o arquivo zip no S3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;require_once&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/config/bootstrap.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$storage&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3ClientInterface&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'files'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui carregamos nosso container de dependência e pegamos a instância do AWS S3. Depois, carregamos todos os nomes de arquivos que fizemos upload no script &lt;code&gt;upload-to-s3.php&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;registerStreamWrapper&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$zipStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"s3://zip/example.zip"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'w'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos prestar bastante atenção, porque aqui é onde acontece o pulo do gato hahah. A primeira linha basicamente cria um wrapper de todas as funções de arquivo do PHP, dessa forma você pode usar as próprias funções &lt;code&gt;built-in&lt;/code&gt; do PHP para interagir com o S3. Basicamente, o fopen da segunda linha está criando um arquivo zip diretamente no S3 e não no sistema de arquivos local. Caso você tenha interesse em entender mais sobre isso, siga a documentação da própria AWS: S3 Stream Wrapper.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$zip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ZipStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;outputStream&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$zipStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sendHttpHeaders&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima, estamos criando uma instância do nosso zip usando a biblioteca &lt;a href="https://github.com/maennchen/ZipStream-PHP"&gt;maennchen/zipstream-php&lt;/a&gt;. Aqui é apenas uma instância, e perceba que estamos passando o stream do nosso arquivo zip que foi criado no S3 para ela como parâmetro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$fulfilled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ResultInterface&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;PromiseInterface&lt;/span&gt; &lt;span class="nv"&gt;$aggregatePromise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$zip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Downloaded file: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$zip&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addFileFromPsr7Stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Body'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Added in zip: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$item&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;$before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CommandInterface&lt;/span&gt; &lt;span class="nv"&gt;$cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$iterKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$objectsToZip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Starting download: '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$cmd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s1"&gt;'Key'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos criando duas callbacks que serão executadas como eventos quando o processo do SDK da AWS for executado. Basicamente, estamos utilizando a classe &lt;code&gt;CommandPool&lt;/code&gt; da AWS para executar de forma assíncrona vários comandos. Essas callbacks são executadas em determinada ação do nosso processo.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;callback&lt;/em&gt; &lt;code&gt;$before&lt;/code&gt; é acionada quando o processo de carregar o arquivo é iniciado. No nosso exemplo, vamos executar o método &lt;code&gt;GetObject&lt;/code&gt;, então toda vez que o método &lt;code&gt;GetObject&lt;/code&gt; for executado, essa callback é acionada.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;callback&lt;/em&gt; &lt;code&gt;$fulfilled&lt;/code&gt; é acionada quando um arquivo é carregado (Download for concluído). Toda vez que um arquivo for carregado, estou adicionando o conteúdo via stream &lt;code&gt;$result-&amp;gt;get('Body')&lt;/code&gt;, para o método &lt;code&gt;$zip-&amp;gt;addFileFromPsr7Stream(stream: $result-&amp;gt;get('Body'))&lt;/code&gt; da nossa instância do zip. Com isso, toda vez que um arquivo é carregado, o mesmo já é adicionado no zip que já está no S3. Coisa linda, não é?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$commands&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$objectsToZip&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$objectKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$commands&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'getObject'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'Bucket'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'zip'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'Key'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$objectKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse trecho, precisamos montar uma lista de comandos que vão ser passados para um Pool de Comandos no SDK da AWS. Com isso, podemos executar vários processos de forma assíncrona. Veja que estou criando um Pool de Comandos &lt;code&gt;GetObject&lt;/code&gt; e passando o nome do bucket e o nome do arquivo que quero baixar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CommandPool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$commands&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'fulfilled'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$fulfilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'before'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$before&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nv"&gt;$promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$pool&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$promise&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$zip&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nb"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$zipStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E, por fim, criamos uma instância de &lt;code&gt;CommandPool&lt;/code&gt;. Para o objeto &lt;code&gt;CommandPool&lt;/code&gt;, você precisa passar a instância do serviço que será executado (que é o S3 no nosso caso). Depois, você passa uma lista de comandos que serão executados, que no nosso caso é o &lt;code&gt;getObject&lt;/code&gt;. E então, você tem uma lista onde define vários tipos de eventos que serão acionados. Por exemplo, você tem &lt;code&gt;fulfilled&lt;/code&gt;, que é uma &lt;code&gt;callback&lt;/code&gt; que será executada após cada comando ser finalizado; você tem o before, que é uma &lt;code&gt;callback&lt;/code&gt; que é acionada antes de cada comando. Para ver todos os tipos de eventos que são suportados, acesse esta documentação: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_commands.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_commands.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar a instância do &lt;code&gt;CommandPool&lt;/code&gt;, nós executamos o método &lt;code&gt;$promise-&amp;gt;wait()&lt;/code&gt;. Com isso, a lista de comandos é executada de forma assíncrona e o processo do PHP é bloqueado. Quando todos os comandos forem executados, o processo é desbloqueado e, por fim, a instância do zip é finalizada &lt;code&gt;$zip-&amp;gt;finish()&lt;/code&gt; e o arquivo no S3 é fechado &lt;code&gt;fclose($zipStream)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, execute o script &lt;code&gt;zip.php&lt;/code&gt; em sua máquina e verifique se tudo ocorreu como o esperado. Caso ocorra algum erro ou tenha alguma dúvida, deixe-me saber nos comentários. Outro ponto que não comentei ao longo deste artigo é que todo conteúdo baixado e compactado é processado via stream. Isso permite que você execute esse processo em arquivos grandes, utilizando pouca memória em PHP. Como prova disso, execute o arquivo com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;memory_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;128M zip.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estamos executando nosso script com apenas 128MB, mesmo lidando com arquivos que têm 2GB cada. Legal, não é?"&lt;/p&gt;

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

&lt;p&gt;Partindo de um cenário simples em que executamos tudo de forma síncrona, esse segundo cenário trouxe-nos muitas melhorias. Agora podemos ter um script que pode ser executado na metade do tempo, sem a necessidade de armazenar nada em disco. Este é um caso de uso que implementei na empresa em que trabalhava. Todo esse processo era executado de forma assíncrona usando Lambda, Eventbridge e, é claro, PHP.&lt;/p&gt;

&lt;p&gt;Ao executar isso em um ambiente Lambda, podemos enfrentar algumas limitações em relação ao tempo de execução e espaço em disco. No entanto, como no nosso segundo cenário não utilizamos o disco para baixar os arquivos, não enfrentamos mais esse problema.&lt;/p&gt;

&lt;p&gt;Bom, acho que é isso, pessoal. Se gostou do artigo, não esqueça de compartilhar e deixar seu comentário =)&lt;/p&gt;

</description>
      <category>php</category>
      <category>s3</category>
      <category>aws</category>
      <category>zip</category>
    </item>
    <item>
      <title>Criando seu ambiente com ASDF</title>
      <dc:creator>Danilo Correa</dc:creator>
      <pubDate>Fri, 29 Dec 2023 17:20:00 +0000</pubDate>
      <link>https://forem.com/dcorrea777/criando-seu-ambiente-com-asdf-j6d</link>
      <guid>https://forem.com/dcorrea777/criando-seu-ambiente-com-asdf-j6d</guid>
      <description>&lt;p&gt;Fala, galera, beleza? Neste artigo, vamos criar um ambiente utilizando uma ferramenta super poderosa chamada ASDF. Esta é uma ferramenta extremamente útil que utilizo no meu dia a dia. Basicamente, você consegue gerenciar múltiplas versões de aplicativos ou runtimes na sua máquina. Imagine que você está trabalhando no desenvolvimento de uma aplicação usando a nova versão do PHP 8.3, e também precisa fazer a manutenção daquele legadinho gostoso (quem nunca, né?). Com o ASDF, você consegue ter várias versões do PHP instaladas na sua máquina, e não apenas o PHP. Você pode ter Node.js, Docker Composer, .NET Core, Python, Terraform, AWS CLI, e muito mais.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que é o ASDF ?&lt;/li&gt;
&lt;li&gt;Vantagens&lt;/li&gt;
&lt;li&gt;Mão na massa!&lt;/li&gt;
&lt;li&gt;Instalando dependências para o ASDF&lt;/li&gt;
&lt;li&gt;Instalando o ASDF&lt;/li&gt;
&lt;li&gt;Instalando PHP 8.1, 8.2 e 8.3&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O que é o ASDF?
&lt;/h2&gt;

&lt;p&gt;&lt;a id="link-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ASDF é um gerenciador de versão de ferramentas. Todas as definições de versão estão contidas em um arquivo .tool-versions que você pode adicionar ao seu projeto Git para compartilhar com sua equipe, garantindo que todos estejam na mesma versão.&lt;/p&gt;

&lt;p&gt;A maneira antiga de trabalhar exigia vários gerenciadores (nvm, n, rben, e phpbrew) de versão CLI, cada um com sua API, arquivos de configuração e implementação (por exemplo, manipulação de $PATH, variáveis de ambiente, etc.). ASDF fornece uma interface única e um arquivo de configuração para simplificar os fluxos de desenvolvimento e pode ser estendido a todas as ferramentas e runtimes por meio de uma interface simples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vantagens
&lt;/h2&gt;

&lt;p&gt;&lt;a id="link-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ASDF garante que as equipes usem exatamente as mesmas versões de ferramentas, com suporte para muitas ferramentas por meio de um sistema de plugin e a simplicidade e familiaridade de ser um único script shell.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizar apenas uma ferramenta para gerenciar as versões&lt;/li&gt;
&lt;li&gt;Plugins escritos pela comunidade&lt;/li&gt;
&lt;li&gt;Arquivo de configuração para gerenciar versões a partir de um diretório&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mão na massa!
&lt;/h2&gt;

&lt;p&gt;&lt;a id="link-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste artigo, vou preparar um ambiente de desenvolvimento do zero utilizando o ASDF. Bora lá então! Para nosso ambiente, vamos instalar as seguintes ferramentas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP 8.3&lt;/li&gt;
&lt;li&gt;PHP 8.2&lt;/li&gt;
&lt;li&gt;PHP 8.1&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Instalando dependências do ASDF
&lt;/h2&gt;

&lt;p&gt;&lt;a id="link-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para este ambiente, vamos seguir a instalação via Linux. Para instalar o ASDF, acesse a página oficial da documentação: &lt;a href="https://asdf-vm.com/"&gt;https://asdf-vm.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de começar, precisamos instalar as dependências para o ASDF. &lt;a href="https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies"&gt;https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;curl git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Instalando ASDF
&lt;/h2&gt;

&lt;p&gt;&lt;a id="link-5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A instalação do ASDF é bastante simples, utilizando o comando git clone.&lt;/p&gt;

&lt;p&gt;Nota: O comando abaixo está usando a versão v0.13.1. Talvez esta versão esteja desatualizada; acesse o seguinte link e veja qual é a versão mais recente: &lt;a href="https://asdf-vm.com/guide/getting-started.html#official-download"&gt;https://asdf-vm.com/guide/getting-started.html#official-download&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/asdf-vm/asdf.git ~/.asdf &lt;span class="nt"&gt;--branch&lt;/span&gt; v0.13.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você utiliza algum shell como zsh, fish e PowerShell, siga as configurações corretas para cada shell &lt;a href="https://asdf-vm.com/guide/getting-started.html#_3-install-asdf"&gt;https://asdf-vm.com/guide/getting-started.html#_3-install-asdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após a instalação do ASDF, você pode executar o seguinte comando para verificar se tudo ocorreu bem na instalação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="c"&gt;#v0.13.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que temos o ASDF instalado em nosso ambiente, precisamos entender como ele funciona.&lt;/p&gt;

&lt;p&gt;Basicamente, você precisa adicionar os plugins das ferramentas que você deseja instalar. Neste cenário, queremos instalar o PHP, então precisamos procurar um plugin do ASDF para o PHP, e assim por diante para outras ferramentas ou linguagens de programação.&lt;/p&gt;

&lt;p&gt;&lt;a id="link-6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando PHP 8.1, 8.2, 8.3
&lt;/h2&gt;

&lt;p&gt;Para instalar o PHP, vamos utilizar o asdf-php, que é um plugin do ASDF para o PHP. &lt;a href="https://github.com/asdf-community/asdf-php"&gt;https://github.com/asdf-community/asdf-php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de tudo, precisamos registrar esse plugin em nosso ASDF com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf plugin-add php https://github.com/asdf-community/asdf-php.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após adicionar como plugin, precisamos instalar algumas dependências em nosso sistema operacional. No próprio repositório do plugin asdf-php, o autor fala sobre as dependências que precisam ser instaladas antes.&lt;/p&gt;

&lt;p&gt;Nota: Essas dependências são do PHP e não do ASDF, pois o ASDF compila o PHP na sua máquina. Para facilitar, vou listá-las aqui.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    autoconf &lt;span class="se"&gt;\&lt;/span&gt;
    bison &lt;span class="se"&gt;\&lt;/span&gt;
    build-essential &lt;span class="se"&gt;\&lt;/span&gt;
    gettext &lt;span class="se"&gt;\&lt;/span&gt;
    libgd-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libcurl4-openssl-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libedit-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libicu-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libjpeg-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libmysqlclient-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libonig-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libpng-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libpq-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libreadline-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libsqlite3-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libssl-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libxml2-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libzip-dev &lt;span class="se"&gt;\&lt;/span&gt;
    openssl &lt;span class="se"&gt;\&lt;/span&gt;
    pkg-config &lt;span class="se"&gt;\&lt;/span&gt;
    re2c &lt;span class="se"&gt;\&lt;/span&gt;
    zlib1g-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois que terminar a instalação de todas as dependências, podemos instalar o PHP em nossa máquina. Para verificar quais versões existem, execute o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf list all php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando acima retornará uma lista de todas as versões disponíveis no PHP. O interessante é que ele também retorna as versões que estão em desenvolvimento, permitindo testar recursos em desenvolvimento. Para começar, vamos instalar a versão &lt;code&gt;8.1.26&lt;/code&gt;, então execute o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf &lt;span class="nb"&gt;install &lt;/span&gt;php 8.1.26
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A instalação pode demorar um pouco, pois o PHP será compilado na sua máquina. Além disso, é importante observar que o gerenciador de pacotes Composer e o PECL também serão instalados em cada versão.&lt;/p&gt;

&lt;p&gt;Agora, precisamos repetir o processo para as outras versões do PHP. Vamos lá:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf &lt;span class="nb"&gt;install &lt;/span&gt;php 8.2.13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf &lt;span class="nb"&gt;install &lt;/span&gt;php 8.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando a instalação da última versão terminar, precisamos configurar qual será a versão padrão instalada em nosso ambiente. Para isso, execute o seguinte comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asdf global php 8.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esse comando, definimos a versão padrão do PHP em nosso ambiente. Após executar o comando acima, você pode executar o &lt;code&gt;php -v&lt;/code&gt; em qualquer lugar do seu sistema operacional, obtendo a seguinte saída.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PHP 8.3.0 &lt;span class="o"&gt;(&lt;/span&gt;cli&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;built: Dec 17 2023 11:09:15&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;NTS&lt;span class="o"&gt;)&lt;/span&gt;
Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; The PHP Group
Zend Engine v4.3.0, Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; Zend Technologies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, a cereja do bolo: vamos criar em nosso sistema de arquivo três pastas, imaginando que cada pasta é um projeto que você está trabalhando, e cada projeto precisa executar em uma versão diferente do PHP.&lt;/p&gt;

&lt;p&gt;Vamos acessar a raiz do nosso usuário e criar uma pasta Code. Dentro dessa pasta, vamos criar as pastas para cada projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Acessar o diretório raiz do nosso usuário&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~

&lt;span class="c"&gt;# Criar a pasta Code&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;Code

&lt;span class="c"&gt;# Acessar a pasta Code&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;Code

&lt;span class="c"&gt;# Criar as pastas de cada projeto&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;projeto-1
&lt;span class="nb"&gt;mkdir &lt;/span&gt;projeto-2
&lt;span class="nb"&gt;mkdir &lt;/span&gt;projeto-3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de criar todas as pastas de todos os projetos, vamos acessar cada pasta e configurar nossa versão do PHP desejada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Acessar o projeto-1&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Code/projeto-1

&lt;span class="c"&gt;# Configurar a versão 8.1.26 para o projeto-1&lt;/span&gt;
asdf &lt;span class="nb"&gt;local &lt;/span&gt;php 8.1.26

&lt;span class="c"&gt;# Verificar a versão do PHP&lt;/span&gt;
php &lt;span class="nt"&gt;-v&lt;/span&gt; 

&lt;span class="c"&gt;# Saída&lt;/span&gt;
PHP 8.1.26 &lt;span class="o"&gt;(&lt;/span&gt;cli&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;built: Dec 17 2023 11:09:15&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;NTS&lt;span class="o"&gt;)&lt;/span&gt;
Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; The PHP Group
Zend Engine v4.3.0, Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; Zend Technologies

&lt;span class="c"&gt;# Acessar o projeto-2&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Code/projeto-2

&lt;span class="c"&gt;# Configurar a versão 8.2.13 para o projeto-2&lt;/span&gt;
asdf &lt;span class="nb"&gt;local &lt;/span&gt;php 8.2.13

&lt;span class="c"&gt;# Verificar a versão do PHP&lt;/span&gt;
php &lt;span class="nt"&gt;-v&lt;/span&gt; 

&lt;span class="c"&gt;# Saída&lt;/span&gt;
PHP 8.2.13 &lt;span class="o"&gt;(&lt;/span&gt;cli&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;built: Dec 17 2023 11:09:15&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;NTS&lt;span class="o"&gt;)&lt;/span&gt;
Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; The PHP Group
Zend Engine v4.3.0, Copyright &lt;span class="o"&gt;(&lt;/span&gt;c&lt;span class="o"&gt;)&lt;/span&gt; Zend Technologies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você pode ver, ao executar o comando &lt;code&gt;php -v&lt;/code&gt;, ele retorna uma versão específica para a pasta e, ao executar de outra pasta qualquer, retorna a versão padrão do PHP (8.3.0). Dessa forma, podemos configurar uma versão para cada pasta específica.&lt;/p&gt;

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

&lt;p&gt;&lt;a id="link-7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ASDF é uma ferramenta fantástica. Sempre que preciso instalar algum componente no meu SO, eu verifico se existe algum plugin ASDF. Lembrando que existem muitos plugins escritos para o ASDF, com certeza há algum para sua linguagem favorita. Adicionei um repositório Git que centraliza uma lista de plugins para o ASDF: &lt;a href="https://github.com/asdf-vm/asdf-plugins"&gt;https://github.com/asdf-vm/asdf-plugins&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Obrigado, galera!!! Qualquer dúvida ou crítica é muito bem-vinda; fiquem à vontade para adicionar comentários.&lt;/p&gt;

</description>
      <category>php</category>
      <category>asdf</category>
      <category>shell</category>
      <category>zsh</category>
    </item>
  </channel>
</rss>
