PHP - LENDO ARQUIVOS CSV COM A FUNÇÃO fgetcsv


O PHP possui muitas funções pouco conhecidas mas que quebram um galhão na hora de fazer algo rapidamente e com poucas linhas.

Ler e parsear um arquivo no formato CSV pode ser bem chato mas com a função fgetcsv se torna bem tranquilo.

Podemos dizer que utilizar funções nativas ao invés de cria-la no próprio script é muito mais eficiente e rápido, tanto na questão da velocidade de se programar quanto na execução. Procure sempre utilizar as funções nativas.

Vamos começar criando um script muito simples apenas para ilustrar como a função fgetcsv funciona e depois daremos uma solução completa para ler um arquivo e convertê-lo em array.

Vamos trabalhar com um arquivo chamado "test.csv" com a seguinte estrutura:

nome;idade
Joao;25
carlos;50

O script básico é o que segue abaixo:

<?php
$handle = fopen("test.csv", "r");
$linha = fgetcsv($handle, 1000, ";");

var_dump($linha);

O resultado será:

array(2) {
[0]=>
string(4) "nome"
[1]=>
string(5) "idade"
}

Ou seja, apenas a primeira linha foi lida
Segundo a documentação oficial
http://php.net/manual/en/function.fgetcsv.php

fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = ',' )

resource $handle é o ponteiro do arquivo "test.txt", $length é a quantidade de caratreres a serem lidas por linha. $delimiter é o marcador de limite entre os campos. Em nosso caso o ponto e virgula ";".

Vamos modificar um pouco o script para que possamos ler todas as linhas do arquivo:
<?php
$handle = fopen("test.csv", "r");

while  ($linha = fgetcsv($handle, 1000, ";"))  {

var_dump($linha);

}

O resultado será:

array(2) {
  [0]=>
  string(4) "nome"
  [1]=>
  string(5) "idade"
}
array(2) {
  [0]=>
  string(7) "Joao"
  [1]=>
  string(2) "25"
}
array(2) {
  [0]=>
  string(11) "Carlos"
  [1]=>
  string(2) "50"
}

O "while" move o ponteiro pelo handler do arquivo e lê cada uma das linhas e o fgetcsv parseia  esta linha.
Se quisermos inserir em uma única array o arquivo inteiro temos de fazer uma nova modificação:

<?php

$handle = fopen("test.csv", "r");
$arquivo = Array();

while  ($linha = fgetcsv($handle, 1000, ";"))  {

$arquivo[] = $linha;

}

var_dump($arquivo);

O resultado é:
array(3) {
  [0]=>
  array(2) {
    [0]=>
    string(4) "nome"
    [1]=>
    string(5) "idade"
  }
  [1]=>
  array(2) {
    [0]=>
    string(7) "Joao"
    [1]=>
    string(2) "25"
  }
  [2]=>
  array(2) {
    [0]=>
    string(11) "Carlos"
    [1]=>
    string(2) "50"
  }
}

Está bem mais interessante agora. Mas podemos melhorar ainda mais. Como podemos ver a primeira linha contém os nomes dos campos. O ideal é passar estes "titulos" mapeados dentro da array.

<?php

$handle = fopen("test.csv", "r");
$arquivo = Array();
$campo = Array();
$count = 1;

while  ($linha = fgetcsv($handle, 1000, ";"))  {

if  ($count == 1)  {

$campo = $linha;

}  else  {

$arquivo[] = array_combine($campo, $linha);

}

$count++;

}

var_dump($arquivo);

Lemos a primeira linha e a transformamos em array com os campos. As demais linhas são as informações. Utilizamos a função "array_combine" para ligar os campos com sua respectiva informação.

O resultado é:

array(2) {
  [0]=>
  array(2) {
    ["nome"]=>
    string(7) "Joao"
    ["idade"]=>
    string(2) "25"
  }
  [1]=>
  array(2) {
    ["nome"]=>
    string(11) "Carlos"
    ["idade"]=>
    string(2) "50"
  }
}

Então é isso pessoal.

Comentários

  1. Boa tarde estou tendo dificuldades para importar csv de 14MB o navegador trava, não teria uma função para deixar o navegador e o servidor das uma respirada, atualmente estou dividindo o arquivo em pequenos pedaços
    Obrigado

    ResponderExcluir
  2. Olá Geovan

    Vc pode tentar colocar no inicio de seu script:

    ini_set('memory_limit', '20000M');

    ou alterando o parametro memory_limit de seu arquivo php.ini

    Abraço

    ResponderExcluir
  3. Olá, Estou com dificuldade em relação ao uso de aspas duplas nos campos. Quando uso ocorre um erro na função array_combine() dizendo que os parâmetros devem ter o mesmo numero de elementos.
    Como proceder neste caso?
    Obrigado

    ResponderExcluir
    Respostas
    1. Olá Diogo
      Estes problemas de aspas geralmente é na tentativa e erro mesmo que se resolve. Tente escapar as aspas duplas - addslashes()

      Excluir
  4. Olá estou tentando ler um aquivo que possui 140 linhas, mas nao está dando certo, só consigo ler 15, será que vcs poderiam me ajudar?

    ResponderExcluir
  5. aqui está o meu codigo
    http://nopaste.info/8e18f976bb.html

    ResponderExcluir
  6. Tutorial passo a passo de como efetuar a leitura de arquivos CSV de foma fácil:
    http://www.mestredev.com.br/leitura-de-arquivos-csv-com-php/

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

MySQL - Completando quantidades fixas de caracteres com as funções LPAD() e RPAD()

MySQL - Clonando tabelas na linha de comando

PHP - Gerando arquivo em UTF-8 com fwrite() e utf8_encode()