<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Blog do Van Neves]]></title><description><![CDATA[Dicas e tutoriais sobre desenvolvimento web, mobile e desktop.]]></description><link>https://blog.vaneves.com/</link><image><url>https://blog.vaneves.com/favicon.png</url><title>Blog do Van Neves</title><link>https://blog.vaneves.com/</link></image><generator>Ghost 4.48</generator><lastBuildDate>Wed, 06 May 2026 04:50:15 GMT</lastBuildDate><atom:link href="https://blog.vaneves.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Trabalhando com Coleções em PHP]]></title><description><![CDATA[Descubra como criar coleções robustas no PHP usando interfaces como Iterator e ArrayAccess. Aprenda a estruturar suas classes para manipular listas de objetos com segurança, integridade e maior legibilidade, indo além das limitações dos arrays tradicionais.]]></description><link>https://blog.vaneves.com/trabalhando-com-colecoes-em-php/</link><guid isPermaLink="false">65208a57015ccf729c8c27b9</guid><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Wed, 18 Dec 2024 20:56:54 GMT</pubDate><content:encoded><![CDATA[<p>O PHP &#xE9; uma linguagem &quot;tipada&quot;, por&#xE9;m &#xE9; de tipagem fraca. Durante muito tempo, para trabalharmos com cole&#xE7;&#xF5;es no PHP era necess&#xE1;rio utilizar apenas arrays (chave-valor) sem tipo. Isso funciona bem para dados simples, como uma lista de IDs, mas quando lidamos com listas de objetos ou queremos garantir a integridade de dados, o uso de arrays pode trazer algumas limita&#xE7;&#xF5;es.</p><p>Por exemplo, imagine que voc&#xEA; est&#xE1; implementando a classe <code>ShoppingCart</code>, que deve manipular uma lista de <code>Product</code>. Se voc&#xEA; usar um array, ele ser&#xE1; transportado apenas como um array em qualquer lugar do c&#xF3;digo, sem restri&#xE7;&#xF5;es sobre o que pode ser adicionado. Al&#xE9;m disso, arrays no PHP s&#xE3;o passados por c&#xF3;pia, e n&#xE3;o por refer&#xEA;ncia, o que pode impactar a performance e dificultar o controle de estado.</p><p>Aqui est&#xE1; um exemplo b&#xE1;sico da classe <code>Product</code>:</p><pre><code class="language-php">&lt;?php

class Product
{
    public function __construct(
    	public readonly string $name,
        public readonly float $price
    ) {}
}</code></pre><p>Agora, veja como poderia ser a classe <code>ShoppingCart</code>:</p><pre><code class="language-php">&lt;?php

class ShoppingCart
{
    private array $products = [];
    
    public function __construct(array $products = [])
    {
        $this-&gt;products = $products;
    }
    
    public function add(Product $product): void
    {
    	$this-&gt;products[] = $product;
    }
    
    public function all(): array
    {
    	return $this-&gt;products;
    }
}</code></pre><p>Embora o m&#xE9;todo <code>add()</code> garanta que apenas inst&#xE2;ncias de <code>Product</code> sejam adicionadas, o mesmo n&#xE3;o acontece no construtor ou no m&#xE9;todo <code>all()</code>. Esse problema pode ser parcialmente resolvido com valida&#xE7;&#xF5;es adicionais, mas isso leva a redund&#xE2;ncia de c&#xF3;digo e ainda n&#xE3;o resolve o problema da aus&#xEA;ncia de refer&#xEA;ncia.</p><h2 id="criando-cole%C3%A7%C3%B5es">Criando cole&#xE7;&#xF5;es</h2><p>O PHP fornece interfaces que permitem criar classes que atuam como cole&#xE7;&#xF5;es com comportamento mais robusto, como <code>Iterator</code> e <code>ArrayAccess</code>. Vamos explorar como elas podem ser utilizadas para resolver os problemas mencionados.</p><h3 id="interface-iterator">Interface <em>Iterator</em></h3><p>A interface <code>Iterator</code> &#xE9; &#xFA;til quando voc&#xEA; deseja que um objeto seja percorrido com um <code>foreach</code>. Ela exige a implementa&#xE7;&#xE3;o de cinco m&#xE9;todos:</p><ul><li><code>current()</code>: Retorna o elemento atual.</li><li><code>key()</code>: Retorna a chave (&#xED;ndice) atual.</li><li><code>next()</code>: Move para o pr&#xF3;ximo elemento.</li><li><code>rewind()</code>: Reinicia a itera&#xE7;&#xE3;o.</li><li><code>valid()</code>: Verifica se a posi&#xE7;&#xE3;o atual &#xE9; v&#xE1;lida.</li></ul><p>Veja como implementar a interface <code>Iterator</code> para criar uma cole&#xE7;&#xE3;o de <code>Product</code>:</p><pre><code class="language-php">&lt;?php

class ProductCollection implements \Iterator
{
    private array $items = [];
    private int $position = 0;

    public function add(Product $item): void
    {
    	$this-&gt;items[] = $item;
    }

    public function current(): mixed
    {
        return $this-&gt;items[$this-&gt;position];
    }

    public function key(): int
    {
        return $this-&gt;position;
    }

    public function next(): void
    {
        $this-&gt;position++;
    }

    public function rewind(): void
    {
        $this-&gt;position = 0;
    }

    public function valid(): bool
    {
        return isset($this-&gt;items[$this-&gt;position]);
    }
}</code></pre><p>Agora, <code>ProductCollection</code> pode ser usada de forma segura e iter&#xE1;vel:</p><pre><code class="language-php">&lt;?php

$collection = new ProductCollection();
$collection-&gt;add(new Product(&apos;Item 1&apos;));
$collection-&gt;add(new Product(&apos;Item 2&apos;));
$collection-&gt;add(new Product(&apos;Item 3&apos;));

foreach ($collection as $product) {
    echo $product-&gt;name . PHP_EOL;
}</code></pre><h3 id="interface-arrayaccess">Interface <em>ArrayAccess</em></h3><p>A interface <code>ArrayAccess</code> permite que um objeto seja tratado como um array. Isso &#xE9; &#xFA;til se voc&#xEA; prefere a sintaxe de colchetes (<code>[]</code>) para manipular os dados da cole&#xE7;&#xE3;o. Os m&#xE9;todos obrigat&#xF3;rios s&#xE3;o:</p><ul><li><code>offsetExists($offset)</code>: Verifica se &#xED;ndice existe.</li><li><code>offsetGet($offset)</code>: Retorna de um &#xED;ndice.</li><li><code>offsetSet($offset, $value)</code>: Define um valor para um &#xED;ndice.</li><li><code>offsetUnset($offset)</code>: Remove um &#xED;ndice.</li></ul><p>Agora vamos implementar a interface <code>ArrayAccess</code> na nossa classe <code>ProductCollection</code>:</p><pre><code class="language-php">&lt;?php

class ProductCollection implements \Iterator, \ArrayAccess
{
    private array $products = [];
    private int $position = 0;

    public function current(): mixed
    {
        return $this-&gt;products[$this-&gt;position];
    }

    public function key(): int
    {
        return $this-&gt;position;
    }

    public function next(): void
    {
        $this-&gt;position++;
    }

    public function rewind(): void
    {
        $this-&gt;position = 0;
    }

    public function valid(): bool
    {
        return isset($this-&gt;products[$this-&gt;position]);
    }

    public function offsetExists($offset): bool
    {
        return isset($this-&gt;products[$offset]);
    }

    public function offsetGet($offset): mixed
    {
        return $this-&gt;products[$offset] ?? null;
    }

    public function offsetSet($offset, $value): void
    {
        if (! $value instanceof Product) {
            throw new \InvalidArgumentException(&apos;Only instances of Product are allowed.&apos;);
        }

        if ($offset === null) {
            $this-&gt;products[] = $value;
        } else {
            $this-&gt;products[$offset] = $value;
        }
    }

    public function offsetUnset($offset): void
    {
        unset($this-&gt;products[$offset]);
    }
}</code></pre><p>A nossa classe <code>ProductCollection</code> agora pode ter tratada como um <em>array</em>, mas ela tem restri&#xE7;&#xE3;o de permitir somente <code>Product</code>. Veja como fica a utiliza&#xE7;&#xE3;o dela:</p><pre><code class="language-php">&lt;?php

$collection = new ProductCollection();

$collection[] = new Product(&quot;Produto 1&quot;);
$collection[] = new Product(&quot;Produto 2&quot;);

foreach ($collection as $product) {
    echo $product-&gt;name . PHP_EOL;
}

echo $collection[0]-&gt;name . PHP_EOL;

unset($collection[1]);
var_dump(isset($collection[1]));

try {
    $collection[] = &quot;Texto inv&#xE1;lido&quot;;
} catch (InvalidArgumentException $e) {
    echo $e-&gt;getMessage();
}</code></pre><h2 id="refatorando-shoppingcart">Refatorando ShoppingCart</h2><p>Com a <code>ProductCollection</code>, a classe <code>ShoppingCart</code> pode ser reescrita para ser mais robusta e confi&#xE1;vel:</p><pre><code class="language-php">&lt;?php 

class ShoppingCart
{
    private ProductCollection $productCollection;
    
    public function __construct(
        ?ProductCollection $productCollection = null
    ) {
        $this-&gt;productCollection = $productCollection ?? new ProductCollection();
    }
    
    public function add(Product $product): void
    {
    	$this-&gt;productCollection[] = $product;
    }
    
    public function all(): ProductCollection
    {
    	return $this-&gt;productCollection;
    }
}</code></pre><p>Agora, o <code>ShoppingCart</code> utiliza <code>ProductCollection</code>, garantindo a integridade da lista de produtos. Sua aplica&#xE7;&#xE3;o se torna mais confi&#xE1;vel, leg&#xED;vel e compat&#xED;vel com IDEs para autocompletar e an&#xE1;lise de c&#xF3;digo.</p><h2 id="conclus%C3%A3o">Conclus&#xE3;o</h2><p>O uso de cole&#xE7;&#xF5;es no PHP, com o suporte de interfaces como <code>Iterator</code> e <code>ArrayAccess</code>, permite criar estruturas de dados mais seguras e flex&#xED;veis. Essas pr&#xE1;ticas ajudam a evitar erros comuns, aumentam a legibilidade do c&#xF3;digo e garantem a integridade dos dados, especialmente em projetos complexos. Considere usar essas abordagens sempre que poss&#xED;vel para melhorar a qualidade do seu c&#xF3;digo.</p>]]></content:encoded></item><item><title><![CDATA[Como criar Enum em PHP]]></title><description><![CDATA[<p>Antes de mais nada, o PHP n&#xE3;o tem suporte nativo ao <em>enum</em> como estamos acostumados em outras linguagens, como em Java ou C#. Mas &#xE9; poss&#xED;vel um c&#xF3;digo que funciona de forma semelhante. </p><p>A forma que eu utilizo para criar <em>enums </em>&#xE9; simples, eu</p>]]></description><link>https://blog.vaneves.com/como-criar-enum-em-php/</link><guid isPermaLink="false">5eb711fb16e94252022174e3</guid><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Sat, 09 May 2020 20:46:12 GMT</pubDate><content:encoded><![CDATA[<p>Antes de mais nada, o PHP n&#xE3;o tem suporte nativo ao <em>enum</em> como estamos acostumados em outras linguagens, como em Java ou C#. Mas &#xE9; poss&#xED;vel um c&#xF3;digo que funciona de forma semelhante. </p><p>A forma que eu utilizo para criar <em>enums </em>&#xE9; simples, eu crio uma classe com constantes, como no exemplo abaixo:</p><pre><code class="language-php">&lt;?php

abstract class UserStatus
{
    const BLOQUED = 0;
    const ACTIVE = 1;
}</code></pre><p>Ent&#xE3;o, para utilizar o &quot;<em>enum</em>&quot;, tamb&#xE9;m &#xE9; simples:</p><pre><code class="language-php">&lt;?php

if ($user-&gt;status === UserStatus::ACTIVE) {
    //
}</code></pre><!--kg-card-begin: markdown--><p>J&#xE1; que o PHP n&#xE3;o tem enum de verdade, ent&#xE3;o por que utilizar uma classe ao inv&#xE9;s de usar o expl&#xED;cito? Porque n&#xE3;o diretamente <code>if ($user-&gt;status)</code>? Porque utilizar dessa forma que demonstrei, deixa o c&#xF3;digo mais claro, diminui a chance de erro e facilita a manuten&#xE7;&#xE3;o.</p>
<!--kg-card-end: markdown--><p>Imagine que voc&#xEA; est&#xE1; implementando um sistema que possui pagamento com diversos status, como:</p><pre><code class="language-php">&lt;?php

abstract class PaymentStatus
{
    const PENDING = 0;
    const PROCESSING = 1;
    const PAID = 2;
    const CANCELED = 3;
    const RETURNED = 4;
}</code></pre><!--kg-card-begin: markdown--><p>Agora fica bem mais claro usar <code>if ($payment-&gt;status === PaymentStatus::PAID)</code> ao inv&#xE9;s de <code>if ($payment-&gt;status === 2)</code>. Mas voc&#xEA; deve estar pensando &quot;por que n&#xE3;o usar string?&quot;, tipo <code>if ($payment-&gt;status === &apos;paid&apos;)</code>. O problema de utilizar string &#xE9; que pode conter erro de digita&#xE7;&#xE3;o, h&#xE1; um diferen&#xE7;a entre letras mai&#xFA;sculas e min&#xFA;sculas, caso queira trocar o valor, tem que fazer manuten&#xE7;&#xE3;o em todo o c&#xF3;digo.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Criar imagem com trecho de código]]></title><description><![CDATA[<p>As vezes queremos compartilhar um trecho de um c&#xF3;digo como imagem, seja no Facebook, no Twitter ou at&#xE9; mesmo no WhatsApp. Mas acontece que nem sempre o print fica legal e muito menos bonito.</p><figure class="kg-card kg-image-card"><img src="https://blog.vaneves.com/content/images/2020/05/carbon.sh-1.png" class="kg-image" alt loading="lazy"></figure><p>Para solucionar esse problema, tem uma ferramenta online chamada <a href="https://carbon.now.sh/">Carbon</a>, onde voc&#xEA;</p>]]></description><link>https://blog.vaneves.com/criar-imagem-com-trecho-de-codigo/</link><guid isPermaLink="false">5eb60a3b16e94252022174bd</guid><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Sat, 09 May 2020 01:52:12 GMT</pubDate><content:encoded><![CDATA[<p>As vezes queremos compartilhar um trecho de um c&#xF3;digo como imagem, seja no Facebook, no Twitter ou at&#xE9; mesmo no WhatsApp. Mas acontece que nem sempre o print fica legal e muito menos bonito.</p><figure class="kg-card kg-image-card"><img src="https://blog.vaneves.com/content/images/2020/05/carbon.sh-1.png" class="kg-image" alt loading="lazy"></figure><p>Para solucionar esse problema, tem uma ferramenta online chamada <a href="https://carbon.now.sh/">Carbon</a>, onde voc&#xEA; cola o c&#xF3;digo, informa a linguagem e escolhe o tema. &#xC9; tudo configur&#xE1;vel, padding, tamanho da fonte, cor de fundo... e ao final voc&#xEA; pode gerar um PNG ou SVG. </p><p>Tamb&#xE9;m &#xE9; poss&#xED;vel exportar as configura&#xE7;&#xF5;es para importar posteriormente, quando for gerar uma nova imagem.</p><p>Caso queira, &#xE9; poss&#xED;vel instalar o Carbon como <a href="https://github.com/carbon-app/carbon#editor-plugins">extens&#xE3;o para seu editor de c&#xF3;digo</a> favorito, como Visual Studio Code, Sublime Text 3, IntelliJ, Atom, Xcode e VIM.</p>]]></content:encoded></item><item><title><![CDATA[AdonisJS, o primo do Laravel]]></title><description><![CDATA[<p>H&#xE1; um tempo eu fiz uma aplica&#xE7;&#xE3;o com o backend todo em NodeJS, ent&#xE3;o utilizei o <em>framework</em> ExpressJS. Mas confesso, n&#xE3;o curti muito.</p><p>Esse ano, 2020, conheci o <a href="https://adonisjs.com/">AdonisJS</a>, um <em>framework</em> Javascript muito, muito, muito mesmo, parecido com o Laravel. De cara</p>]]></description><link>https://blog.vaneves.com/adonis-o-primo-do-laravel/</link><guid isPermaLink="false">5eb5c230fc45784f3ef2ae8f</guid><category><![CDATA[Javascript]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Sat, 09 May 2020 01:14:40 GMT</pubDate><content:encoded><![CDATA[<p>H&#xE1; um tempo eu fiz uma aplica&#xE7;&#xE3;o com o backend todo em NodeJS, ent&#xE3;o utilizei o <em>framework</em> ExpressJS. Mas confesso, n&#xE3;o curti muito.</p><p>Esse ano, 2020, conheci o <a href="https://adonisjs.com/">AdonisJS</a>, um <em>framework</em> Javascript muito, muito, muito mesmo, parecido com o Laravel. De cara j&#xE1; virou meu framework node favorito. ent&#xE3;o resolvi fazer essa publica&#xE7;&#xE3;o para apresent&#xE1;-lo &#xE0; voc&#xEA;s.</p><p>Atualmente o AdonisJS est&#xE1; na vers&#xE3;o 4 e se voc&#xEA; j&#xE1; conhece o Laravel, ficar&#xE1; bem a vontade em programar nesse <em>framework</em>.</p><p>Veja por exemplo como &#xE9; uma <em>migration</em>:</p><pre><code class="language-javascript">const Schema = use(&apos;Schema&apos;)

class ClientSchema extends Schema {
  up () {
    this.create(&apos;clients&apos;, (table) =&gt; {
      table.increments()
      table.string(&apos;name&apos;, 128).notNullable()
      table.string(&apos;cpf&apos;, 16).nullable().unique()
      table.string(&apos;phone&apos;, 32).nullable()
      table.timestamps()
    })
  }

  down () {
    this.drop(&apos;clients&apos;)
  }
}</code></pre><p>Agora repare como &#xE9; um <em>controller</em>:</p><pre><code class="language-javascript">const { validate } = use(&apos;Validator&apos;)
const Client = use(&apos;App/Models/Client&apos;)

class ClientController {
  async index ({ request }) {
    const { page } = request.get(&apos;page&apos;)
    const clients = await Client.query()
      .orderBy(&apos;name&apos;)
      .paginate(page, 10)
    return clients
  }
  async store ({ request, response }) {
    // 
  }
  async show ({ params }) {
    // 
  }
  async update ({ params, auth, request, response }) {
    //
  }
  async destroy ({ params, auth, response }) {
    //
  }
}</code></pre><p>Veja como &#xE9; a estrutura de pastas, veja a semelhan&#xE7;a:</p><pre><code>.
&#x251C;&#x2500;&#x2500; app/
  &#x251C;&#x2500;&#x2500; Controllers
  &#x251C;&#x2500;&#x2500; Middleware
&#x251C;&#x2500;&#x2500; config/
  &#x251C;&#x2500;&#x2500; app.js
  &#x251C;&#x2500;&#x2500; auth.js
  &#x2514;&#x2500;&#x2500; ...
&#x251C;&#x2500;&#x2500; database/
  &#x251C;&#x2500;&#x2500; migrations/
  &#x251C;&#x2500;&#x2500; seeds/
  &#x2514;&#x2500;&#x2500; factory.js
&#x251C;&#x2500;&#x2500; public/
&#x251C;&#x2500;&#x2500; resources/
  &#x251C;&#x2500;&#x2500; ...
  &#x2514;&#x2500;&#x2500; views/
&#x2514;&#x2500;&#x2500; storage/</code></pre><p>O mais legal disso &#xE9; reaproveitar o conhecimento. Para quem trabalha com o Laravel, poder mexer com NodeJS de forma bem confort&#xE1;vel &#xE9; bastante animador, principalmente para quem quer fazer uma aplica&#xE7;&#xE3;o desktop, com Electron.</p>]]></content:encoded></item><item><title><![CDATA[Como pegar o último dia do mês em PHP]]></title><description><![CDATA[<p>E ai, galera, beleza?</p><p>Todos n&#xF3;s sabemos que os meses do ano n&#xE3;o possuem o n&#xFA;mero fixo de dias, certo? Al&#xE9;m disso, o m&#xEA;s de fevereiro varia em anos bisextos (a cada quatro anos) e tem um dia a mais.</p>]]></description><link>https://blog.vaneves.com/como-pegar-o-ultimo-dia-do-mes-em-php/</link><guid isPermaLink="false">5d8e187efc45784f3ef2adf3</guid><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Fri, 27 Sep 2019 14:50:31 GMT</pubDate><content:encoded><![CDATA[<p>E ai, galera, beleza?</p><p>Todos n&#xF3;s sabemos que os meses do ano n&#xE3;o possuem o n&#xFA;mero fixo de dias, certo? Al&#xE9;m disso, o m&#xEA;s de fevereiro varia em anos bisextos (a cada quatro anos) e tem um dia a mais. Em algumas aplica&#xE7;&#xF5;es n&#xF3;s precisamos saber qual &#xE9; o &#xFA;ltimo dia de um determinado m&#xEA;s e ningu&#xE9;m que ficar perdendo tempo fazendo c&#xE1;lculos. Por isso irei apresenta 2 formas de n&#xF3;s sabermos isso.</p><h2 id="utilizando-php-puro">Utilizando PHP puro</h2><p>Se voc&#xEA; est&#xE1; utilizando o PHP para manipular datas, basta utilizar a classe DateTime:</p><pre><code class="language-php">&lt;?php

$data = &apos;2019-09-22&apos;;

$data = new \DateTime($data); 
$data-&gt;modify(&apos;last day of this month&apos;);

echo $data-&gt;format(&apos;Y-m-d&apos;);</code></pre><p>Veja como foi simples, utilizamos o m&#xE9;todo modify() e passamos &#xE0; ele o par&#xE2;metro &quot;last day of this month&quot; (&#xFA;ltimo dia desse m&#xEA;s). Depois &#xE9; pegar o formato que desejar.</p><h2 id="utilizando-carbon">Utilizando Carbon</h2><p>Caso voc&#xEA; utilize a biblioteca <a href="https://carbon.nesbot.com/">Carbo</a> (ela j&#xE1; vem instalada no Laravel) basta utilizar o seguinte c&#xF3;digo:</p><pre><code class="language-php">&lt;?php 

use Carbon\Carbon;

$data = &apos;2019-09-22&apos;;

$carbon = new Carbon($data);
$carbon-&gt;lastOfMonth();

echo $carbon-&gt;format(&apos;Y-m-d&apos;);</code></pre><p>Claramente podemos ver que utilizando a biblioteca Carbon o c&#xF3;digo fica mais limpo, usamos um m&#xE9;todo sem par&#xE2;metro, que diminui, inclusive, as changes de erro. No site da documenta&#xE7;&#xE3;o voc&#xEA; encontra bem mais detalhes sobre a biblioteca.</p>]]></content:encoded></item><item><title><![CDATA[Lendo e escrevendo arquivos CSV com PHP]]></title><description><![CDATA[As vezes precisamos ler ou escrever um arquivo em formato CSV. O que seria uma tarefa simples pode tomar boa parte do seu dia. Para solucionar esse problema de forma simples, eu recomendo utilizar a biblioteca League\Csv.]]></description><link>https://blog.vaneves.com/lendo-e-escrevendo-arquivos-csv-com-php/</link><guid isPermaLink="false">5d8d4f76fc45784f3ef2ad24</guid><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Fri, 27 Sep 2019 14:07:02 GMT</pubDate><content:encoded><![CDATA[<p>E ai, galera, beleza?</p><p>As vezes precisamos ler ou escrever um arquivo em formato CSV. O que seria uma tarefa simples pode tomar boa parte do seu dia. Para solucionar esse problema de forma simples, eu recomendo utilizar a biblioteca <a href="https://csv.thephpleague.com/">League\Csv</a>.</p><h2 id="instala-o">Instala&#xE7;&#xE3;o</h2><p>Sua instala&#xE7;&#xE3;o &#xE9; simples, basta executar o seguinte comando para baix&#xE1;-la usando o Composer:</p><pre><code>composer require league/csv</code></pre><p>Caso n&#xE3;o esteja utilizando algum framework que carregue automaticamente as classes, deve importar o arquivo autoload:</p><pre><code class="language-php">&lt;?php

require &apos;vendor/autoload.php&apos;;</code></pre><h2 id="ler-arquivo">Ler Arquivo</h2><p>Como exemplo, irei usar o seguinte conte&#xFA;do de uma arquivo CSV:</p><pre><code>Nome,Sobrenome,E-mail
van,neves,van@gmail.com
maria,souza,maria@gmail.com
paulo,silva,paulo@hotmail.com</code></pre><p>Agora vamos ler as linhas desse arquivo que coloquei como exemplo:</p><pre><code class="language-php">&lt;?php 

use League\Csv\Reader;

$leitor = Reader::createFromPath(&apos;/caminho/para/arquivo.csv&apos;, &apos;r&apos;);
$linhas = $leitor-&gt;getRecords();
foreach ($linhas as $numero =&gt; $linha) {
    echo $linha[0];
}</code></pre><p>No exemplo acima estamos pegando todas as linhas do arquivo, percorrendo-as e imprimindo o valor da primeira coluna, que no caso &#xE9; o &quot;Nome&quot;.</p><!--kg-card-begin: markdown--><p>Uma coisa que acho interessante, principalmente quando estamos trabalhando com muitas colunas, &#xE9; definir nomes para que a programa&#xE7;&#xE3;o fique mais clara. Ao inv&#xE9;s de usar <code>$linha[0]</code> ou <code>$linha[1]</code>, podemos definir um &#xED;ndice de texto. Para isso, bastaria substituir o c&#xF3;digo da linha 6 pelo seguinte c&#xF3;digo:</p>
<!--kg-card-end: markdown--><pre><code class="language-php">&lt;?php

$linhas = $leitor-&gt;getRecords([&apos;nome&apos;, &apos;sobrenome&apos;, &apos;email&apos;]);</code></pre><!--kg-card-begin: markdown--><p>Dessa maneira bastaria acessarmos as colunas pelos menos que definimos, como <code>$linha[&apos;nome&apos;]</code>. Mas com essa biblioteca podemos ir al&#xE9;m e fazer coisas mais interessantes. Imagine um arquivo CSV com mais de 100 e voc&#xEA; deseja filtra, ordenar ou retornar fazer uma pagina&#xE7;&#xE3;o. Ent&#xE3;o vamos l&#xE1;:</p>
<!--kg-card-end: markdown--><pre><code class="language-php">&lt;?php

use League\Csv\Reader;
use League\Csv\Statement;

function filtrarPorEmail(array $linha)
{
    // verifica se a coluna &#xE9; realmente um e-mail
    return (bool) filter_var($linha[2], FILTER_VALIDATE_EMAIL);
}

function ordernarPorSobrenome(array $linhaA, array $linhaB)
{
    // ordenando pela coluna 1 (sobrenome)
    return strcmp($linhaB[1], $linhaA[1]);
}

$leitor = Reader::createFromPath(&apos;/caminho/para/arquivo.csv&apos;, &apos;r&apos;);
$stmt = (new Statement())
    -&gt;where(&apos;filtrarPorEmail&apos;) // filtro
    -&gt;orderBy(&apos;ordernarPorSobrenome&apos;) // ordena&#xE7;&#xE3;o
    -&gt;offset(3) // pular os 3 primeiros resultados
    -&gt;limit(10) // retornar apenas 10 linhas
;

$linhas = $stmt-&gt;process($leitor);</code></pre><p>No exemplo acima o c&#xF3;digo est&#xE1; lendo um arquivo CSV, filtrando pela coluna 2 (verifica se &#xE9; um e-mail v&#xE1;lido), orderna pelo sobrenome, pula as 3 primeiras linhas e retorna as pr&#xF3;ximas 10 linhas.</p><h2 id="escrever-em-arquivo">Escrever em Arquivo</h2><p>Caso precise criar um arquivo em formato CSV, tamb&#xE9;m &#xE9; muito f&#xE1;cil. Veja o exemplo abaixo:</p><pre><code class="language-php">&lt;?php

use League\Csv\Writer;

$linhas = [
    [&apos;van&apos;,&apos;neves&apos;,&apos;van@gmail.com&apos;,&apos;+556392621234&apos;],
    [&apos;paulo&apos;,&apos;souza&apos;,&apos;paulo@hotmail.com&apos;,&apos;+556384082020&apos;],
    [&apos;fabio&apos;,&apos;maciel&apos;,&apos;fabio@gmail.com&apos;,&apos;+556399887766&apos;],
];

$escritor = Writer::createFromPath(&apos;/caminho/para/salvar/arquivo.csv&apos;, &apos;w+&apos;);
$escritor-&gt;insertAll($linhas);</code></pre><p>O c&#xF3;digo acima est&#xE1; pegando um array, com um array dentro, e inserindo no arquivo CSV. Voc&#xEA; pode inserir tamb&#xE9;m somente uma linha, para isso pode usar o seguinte m&#xE9;todo:</p><pre><code class="language-php">&lt;?php 

$escritor-&gt;insertOne([&apos;maria&apos;, &apos;nunes&apos;, &apos;maria@nunes.com.br&apos;, &apos;+556399876543&apos;]);</code></pre><p>O codigo recebe um array acima insere e uma linha no final do arquivo. A diferen&#xE7;a dele para o outro &#xE9; que n&#xE3;o precisa passar um array bidimensional para inserir apenas uma linha.</p><p>A biblioteca oferece bem mais recursos, como converter o array em arquivos XML e tabelas HTML. Al&#xE9;m disso voc&#xEA; pode ver mais detalhes e mais m&#xE9;todos das funcionalidades apresentadas aqui, basta acessar o <a href="https://csv.thephpleague.com/">site oficial</a> com a documenta&#xE7;&#xE3;o.</p>]]></content:encoded></item><item><title><![CDATA[Faker: criando dados de teste em PHP]]></title><description><![CDATA[<p>Sempre que criamos uma aplica&#xE7;&#xE3;o com banco de dados, precisamos preencher com alguns valores de testes. &#xC9; comum os desenvolvedores criarem a primeiro a funcionalidade de &quot;cadastrar&quot;, ent&#xE3;o fica preenchendo o formul&#xE1;rio com valores aleat&#xF3;rios. Isso se torna uma</p>]]></description><link>https://blog.vaneves.com/faker-criando-dados-de-teste-em-php/</link><guid isPermaLink="false">5d8a644ad7ca1013fce85456</guid><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Van Neves]]></dc:creator><pubDate>Tue, 24 Sep 2019 20:04:36 GMT</pubDate><content:encoded><![CDATA[<p>Sempre que criamos uma aplica&#xE7;&#xE3;o com banco de dados, precisamos preencher com alguns valores de testes. &#xC9; comum os desenvolvedores criarem a primeiro a funcionalidade de &quot;cadastrar&quot;, ent&#xE3;o fica preenchendo o formul&#xE1;rio com valores aleat&#xF3;rios. Isso se torna uma tarefa muito cansativa.</p><p>Para solucionar esse problema existem os Mocks, que permitem voc&#xEA; criar objetos com dados falsos. Para isso iremos utilizar a biblioteca para PHP chamada <a href="https://github.com/fzaninotto/Faker">Faker</a>.</p><h2 id="instalar-a-biblioteca">Instalar a biblioteca</h2><p>A instala&#xE7;&#xE3;o &#xE9; simples via Composer:</p><pre><code>composer require fzaninotto/faker</code></pre><h2 id="m-os-obra">M&#xE3;os &#xE0; obra</h2><p>Primeiro vamos importar a biblioteca via autoload (caso n&#xE3;o esteja usando um framework que fa&#xE7;a isso), depois vamos criar uma inst&#xE2;ncia da classe <em>Faker</em>:</p><pre><code class="language-php">&lt;?php 

require_once &apos;vendor/autoload.php&apos;;

$faker = Faker\Factory::create(&apos;pt_BR&apos;);</code></pre><p>Agora &#xE9; s&#xF3; &quot;chamar&quot; as propriedades ou m&#xE9;todos que retornar&#xE1; os dados que desejamos. Por exemplo, para criar um nome falso, basta usar:</p><pre><code class="language-php">&lt;?php

echo $faker-&gt;name;</code></pre><!--kg-card-begin: markdown--><p>Toda vez que usar a propriedade <code>name</code>, ele ir&#xE1; retornar um nome diferente. Como estamos usando o &quot;pt_BR&quot; na inst&#xE2;ncia, ir&#xE1; retornar nomes brasileiros. Os nomes retornados s&#xE3;o masculinos ou femininos, mas voc&#xEA; especificar qual deseja retorna:</p>
<!--kg-card-end: markdown--><pre><code class="language-php">&lt;?php

echo $faker-&gt;name(&apos;male&apos;);
echo $faker-&gt;name(&apos;female&apos;);</code></pre><p>Voc&#xEA; pode retornar o nome e sobrenome separadamente:</p><pre><code class="language-php">&lt;?php

echo $faker-&gt;firstName;
echo $faker-&gt;firstNameMale;
echo $faker-&gt;firstNameFemale;</code></pre><!--kg-card-begin: markdown--><p>Ao usar o m&#xE9;todo <code>firstName()</code> ir&#xE1; retornar somente o primeiro nome, mas de forma aleat&#xF3;ria (masculino ou feminino). Podemos novamente passar o par&#xE2;metro &quot;male&quot; ou &quot;female&quot;. Outra forma &#xE9; chamar diretamente a propriedade <code>firstNameMale</code> ou <code>firstNameFemale</code>.</p>
<!--kg-card-end: markdown--><p>Para gerar um RG, CPF ou CNPJ:</p><pre><code>&lt;?php

echo $faker-&gt;cpf;         // &apos;145.343.345-76&apos;
echo $faker-&gt;cpf(false);  // &apos;45623467866&apos;
echo $faker-&gt;cnpj;        // &apos;23.663.478/0001-24&apos;
echo $faker-&gt;cnpj(false); // &apos;23663478000124&apos;
echo $faker-&gt;rg;          // &apos;84.405.736-3&apos;
echo $faker-&gt;rg(false);   // &apos;844057363&apos;</code></pre><p>Agora vamos criar um exemplo preenchendo um array com 2 mil dados de exemplo de clientes. Cada cliente vai ter uma informa&#xE7;&#xE3;o diferente.</p><pre><code>&lt;?php

$clientes = [];
for ($i = 0; $i &lt; 2000; $i++) {
    array_push($clientes, [
    	&apos;nome&apos; =&gt; $faker-&gt;name,
        &apos;email&apos; =&gt; $faker-&gt;email,
        &apos;endereco&apos; =&gt; $faker-&gt;address,
        &apos;telefone&apos; =&gt; $faker-&gt;phoneNumber,
        &apos;foto&apos; =&gt; $faker-&gt;imageUrl(100, 100),
        &apos;cor_favorita&apos; =&gt; $faker-&gt;hexcolor,
        &apos;funcao&apos; =&gt; $faker-&gt;jobTitle,
        &apos;biografia&apos; =&gt; $faker-&gt;text(200)
    ]);
}</code></pre><p>Esses exemplos foi apenas uma pequena parte do que o Faker pode fazer. Para saber todas as funcionalidades ou as formas de usar as apresentadas aqui, basta acessar a documenta&#xE7;&#xE3;o oficial no <a href="https://github.com/fzaninotto/Faker#table-of-contents">GitHub</a>.</p>]]></content:encoded></item></channel></rss>