fgetcsv()
A função fgetcsv() em PHP lê uma linha de um arquivo e a analisa como dados CSV. Saiba como usar, parâmetros e exemplos práticos.
Introdução à Função fgetcsv() do PHP
A função fgetcsv() em PHP lê uma única linha de um arquivo aberto e a analisa como CSV (Comma-Separated Values), retornando os campos como um array. É a ferramenta padrão para importar exportações de planilhas, feeds de dados e arquivos de texto tabulares para o PHP.
O motivo para usar fgetcsv() em vez de fgets() mais explode(',', ...) é que CSV é mais sutil do que simplesmente dividir por vírgulas. Um campo pode conter uma vírgula se estiver entre aspas ("Doe, John"), um campo pode abranger múltiplas linhas, e aspas dentro de um campo entre aspas são duplicadas (""). fgetcsv() cuida de todas essas regras por você, para que você obtenha campos limpos sem precisar escrever um parser.
Esta página cobre a assinatura e os parâmetros, os valores de retorno, e exemplos completos e executáveis — lendo um arquivo inteiro, usando um delimitador personalizado, e mapeando uma linha de cabeçalho para linhas associativas.
Sintaxe
A sintaxe da função fgetcsv() é a seguinte:
A Sintaxe do fgetcsv() do PHP
array fgetcsv ( resource $stream [, int $length = 0 [, string $delimiter = ',' [, string $enclosure = '"' [, string $escape = '\\' ]]]] )stream: o ponteiro de arquivo para lerlength: o comprimento máximo da linha a ser lidadelimiter: o caractere delimitador para dados CSVenclosure: o caractere de enclosure para dados CSVescape: o caractere de escape para dados CSV
Parâmetros
A função fgetcsv() recebe um parâmetro obrigatório e quatro parâmetros opcionais:
$stream: O ponteiro de arquivo do qual você deseja ler. Este parâmetro pode ser um resource criado usando a funçãofopen()ou uma função semelhante.$length: O comprimento máximo da linha a ser lida. Este parâmetro é opcional e tem valor padrão 0, o que significa que a linha inteira será lida.$delimiter: O caractere delimitador para dados CSV. Este parâmetro é opcional e tem valor padrão ','.$enclosure: O caractere de enclosure para dados CSV. Este parâmetro é opcional e tem valor padrão '"'.$escape: O caractere de escape para dados CSV. Este parâmetro é opcional e tem valor padrão '\'. Nota: Este parâmetro está obsoleto a partir do PHP 8.1.
Valores de Retorno
Em caso de sucesso, fgetcsv() retorna um array indexado contendo os campos lidos da linha. Uma linha em branco retorna um array com um único campo null. No final do arquivo retorna false, que é como você sabe quando parar de ler. Se o stream não for válido, também retorna false.
Como tanto "fim do arquivo" quanto "erro" retornam false, a forma idiomática de fazer um loop é continuar chamando fgetcsv() até que retorne false — geralmente dentro de uma condição while.
Exemplos
Exemplo 1: Ler uma única linha de dados CSV
O exemplo a seguir abre um arquivo, lê uma linha de dados CSV e fecha corretamente o identificador de arquivo. Sempre verifique se fopen() foi bem-sucedido antes de ler:
Ler uma única linha de dados CSV
$fileHandle = fopen('data.csv', 'r');
if ($fileHandle !== false) {
$row = fgetcsv($fileHandle);
print_r($row);
fclose($fileHandle);
}Para um arquivo cuja primeira linha é John,Doe,42, isso imprime:
Array
(
[0] => John
[1] => Doe
[2] => 42
)Exemplo 2: Iterar sobre todas as linhas de um arquivo
No código real você raramente lê apenas uma linha. Chame fgetcsv() em um loop while até que retorne false para processar o arquivo inteiro:
Ler todas as linhas de um arquivo CSV
$fileHandle = fopen('data.csv', 'r');
if ($fileHandle !== false) {
while (($row = fgetcsv($fileHandle)) !== false) {
echo implode(' | ', $row), PHP_EOL;
}
fclose($fileHandle);
}A comparação estrita !== false é importante: uma linha válida como ["0"] é "falsy" em PHP, então um while ($row = fgetcsv(...)) solto pararia prematuramente em dados legítimos.
Exemplo 3: Usar um delimitador personalizado
Muitos arquivos "CSV" são na verdade separados por ponto e vírgula ou tabulação. Passe o delimitador como terceiro argumento (o segundo argumento, $length, pode ficar em 0 para sem limite):
Ler dados CSV com um delimitador personalizado
// Semicolon-separated values
$row = fgetcsv($fileHandle, 0, ';');
// Tab-separated values
$row = fgetcsv($fileHandle, 0, "\t");Exemplo 4: Mapear uma linha de cabeçalho para arrays associativos
Arquivos CSV geralmente têm uma linha de cabeçalho. Leia-a uma vez, depois combine-a com cada linha de dados usando array_combine() para que você possa acessar os campos pelo nome em vez de pelo índice numérico:
Transformar um arquivo CSV em linhas associativas
$fileHandle = fopen('users.csv', 'r');
if ($fileHandle !== false) {
$header = fgetcsv($fileHandle); // e.g. ['id', 'name', 'email']
while (($data = fgetcsv($fileHandle)) !== false) {
$row = array_combine($header, $data);
echo $row['name'], ' <', $row['email'], '>', PHP_EOL;
}
fclose($fileHandle);
}Armadilhas Comuns
- O parâmetro
$escapeestá obsoleto. A partir do PHP 8.1, passar um$escapenão vazio aciona um aviso de obsolescência, e o PHP 9 mudará o padrão para"". Para CSV compatível com padrões (onde as aspas são escapadas por duplicação,""), passeescape: ""explicitamente. - UTF-8 BOM no primeiro campo. Arquivos exportados do Excel podem começar com uma marca de ordem de bytes, então o primeiro campo do cabeçalho pode parecer
"\u{FEFF}id". Remova-o comltrim($header[0], "\u{FEFF}")se as comparações falharem. auto_detect_line_endings. Terminações de linha Mac antigas (\r) podiam confundir o parser em versões mais antigas do PHP; essa configuraçãoinifoi removida no PHP 8.1 porque o parser agora as gerencia nativamente.
Funções Relacionadas
fopen()— abrir o arquivo antes de ler.fgets()— ler uma linha bruta sem análise CSV.fputcsv()— o inverso: escrever um array como uma linha CSV.fclose()— fechar o identificador quando terminar.- Manipulação de Arquivos PHP — o panorama geral de como trabalhar com arquivos.
Conclusão
fgetcsv() lê uma linha de um arquivo aberto e a analisa como CSV, retornando um array indexado de campos e false no fim do arquivo. Faça o loop com uma verificação estrita !== false, use array_combine() para mapear uma linha de cabeçalho para campos nomeados, e lembre-se de que o parâmetro $escape está obsoleto — passe escape: "" para uma análise moderna e compatível com padrões.