PHP CSV
last modified January 10, 2023
PHP CSV tutorial shows how to work with CSV data in PHP.
$ php -v php -v PHP 8.1.2 (cli) (built: Aug 8 2022 07:28:23) (NTS) ...
We use PHP version 8.1.2.
CSV
CSV (Comma Separated Values) is a very popular import and export data format used in spreadsheets and databases. Each line in a CSV file is a data record. Each record consists of one or more fields, separated by commas. While CSV is a very simple data format, there can be many differences, such as different delimiters, new lines, or quoting characters.
The fgetcsv
reads a line from the provided file pointer and parses
for CSV fields. It returns an array containing the fields read. The
fputcsv
takes an array of data and writes it as a CSV line to the
specified file handle.
The league/csv
is a simple PHP library to ease CSV documents
loading as well as writing, selecting and converting CSV records.
PHP read CSV with fgetcsv
The following example uses the build-in fgetcsv
function to read
CSV data.
John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
This is the users.csv
file.
<?php $f = fopen('users.csv', 'r'); while(!feof($f)) { $row = fgetcsv($f); if (!empty($row)) { echo "$row[0] $row[1] is a(n) $row[2]\n"; } } fclose($f);
We read data from users.csv
file.
$f = fopen('users.csv', 'r');
With fopen
, we open a file handle to the users.csv
file.
while(!feof($f)) {
In a while loop, we read all lines until the end of the file. The
feof
function checks for end-of-file on the file handle.
$row = fgetcsv($f);
We read a line with fgetcsv
; the function returns an array of
fields read.
if (!empty($row)) { echo "$row[0] $row[1] is a(n) $row[2]\n"; }
If the row is not empty, we output the fields in a message.
fclose($f);
The fclose
function closes an open file pointer.
$ php read_data.php John Doe is a(n) gardener Lucy Smith is a(n) teacher Brian Bethamy is a(n) programmer
PHP write CSV with fputcsv
The following example writes CSV data into a file.
<?php $users = [ ['John', 'Doe', 'gardener' ], ['Lucy', 'Smith', 'teacher'], ['Brian', 'Bethamy', 'programmer'] ]; $fp = fopen('users.csv', 'w'); foreach ($users as $user) { fputcsv($fp, $user); } fclose($fp);
We have an array of users. We write the users into a CSV file with
fputcsv
.
PHP CSV different separator
The fgetcsv
function allows to read data with a different separator.
John|Doe|gardener Lucy|Smith|teacher Brian|Bethamy|programmer
We have data separated with the |
character.
<?php $f = fopen('users2.csv', 'r'); while(!feof($f)) { $row = fgetcsv($f, 0, '|'); if (!empty($row)) { echo "$row[0] $row[1] is a(n) $row[2]\n"; } } fclose($f);
The third parameter of the fgetcsv
function is the optional
delimiter, which sets the field delimiter (one character only). It is comma by
default.
PHP send CSV data
The following example sends CSV data as an attachment to the user.
<?php header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=users.csv'); $output = fopen('php://output', 'w'); fputcsv($output, ['First name', 'Last name', 'Occupation']); $f = fopen('users.csv', 'r'); while (!feof($f)) { $rows[] = fgetcsv($f); } foreach ($rows as $row) { fputcsv($output, $row); } fclose($f);
The example reads CSV from a file and returns it to the user; the user receives the file as an attachment.
header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=users.csv');
These headers specify the content type and the disposition as attachment.
$output = fopen('php://output', 'w');
We create a file pointer connected to the output stream.
fputcsv($output, ['First name', 'Last name', 'Occupation']);
We send the header fields to the output stream.
$f = fopen('users.csv', 'r'); while (!feof($f)) { $rows[] = fgetcsv($f); }
We read the CSV data into an array.
foreach ($rows as $row) { fputcsv($output, $row); }
The array is written to the output stream.
PHP league\csv
The league\csv
is a PHP library for processing CSV data.
$ composer require league/csv
The library is installed with the above command.
First, we parse CSV data with League\Csv\Reader
for reading.
The League\Csv\Statement
class is a constraint builder for
selecting records from a CSV document created by League\Csv\Reader
.
The Statement::process
method processes the reader object and
returns the found records as a ResultSet
object. We can perform
filtering, interval, or sorting operations on the result set, as in SQL.
We use League\Csv\Writer
for writing.
'First name','Last name','Occupation' John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer Lucy,Black,musician Pau,Novak,teacher
We have this data.
PHP league\csv count rows
In the first example, we count available rows in the CSV file.
<?php require __DIR__ . '/vendor/autoload.php'; use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::createFromPath('users.csv', 'r'); $rows = Statement::create()->process($reader); echo count($rows);
We create a reader object with Reader::createFromPath
. Then
we create a statement and process the reader object with the
process
method. Applying the count
function on the
returned result set returns the number of rows.
$ php count_rows.php 6
There are six rows in the file, including the header.
If we do not want to header line, we can use the setHeaderOffset
.
<?php require __DIR__ . '/vendor/autoload.php'; use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::createFromPath('users.csv', 'r'); $reader->setHeaderOffset(0); $rows = Statement::create()->process($reader); echo count($rows);
We count the number of lines in the CSV file, excluding the header line.
PHP league\csv read data
In the following example, we read CSV data with league\csv
.
<?php require __DIR__ . '/vendor/autoload.php'; use League\Csv\Reader; $csv = Reader::createFromPath('users.csv', 'r'); $csv->setHeaderOffset(0); $header = $csv->getHeader(); print_r($header); $records = $csv->getRecords(); print_r(iterator_to_array($records)); echo $csv->getContent();
We read the header and the data from the users.csv
file.
$csv = Reader::createFromPath('users.csv', 'r'); $csv->setHeaderOffset(0);
We create the reader object and set the header position.
$header = $csv->getHeader(); print_r($header);
We get the header line.
$records = $csv->getRecords(); print_r(iterator_to_array($records));
The getRecords
method returns all the CSV records as an
Iterator
object.
echo $csv->getContent();
The getContent
method returns the CSV document as a string.
$ php read_data2.php Array ( [0] => 'First name' [1] => 'Last name' [2] => 'Occupation' ) Array ( [1] => Array ( ['First name'] => John ['Last name'] => Doe ['Occupation'] => gardener ) [2] => Array ( ['First name'] => Lucy ['Last name'] => Smith ['Occupation'] => teacher ) [3] => Array ( ['First name'] => Brian ['Last name'] => Bethamy ['Occupation'] => programmer ) [4] => Array ( ['First name'] => Lucy ['Last name'] => Black ['Occupation'] => musician ) [5] => Array ( ['First name'] => Pau ['Last name'] => Novak ['Occupation'] => teacher ) ) 'First name','Last name','Occupation' John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer Lucy,Black,musician Pau,Novak,teacher
PHP league/csv fetchColumn
A specific column of data can be selected with fetchColumn
.
<?php require __DIR__ . '/vendor/autoload.php'; use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::createFromPath('users.csv', 'r'); $reader->setHeaderOffset(0); $records = Statement::create()->process($reader); foreach ($records->fetchColumn(2) as $value) { echo $value . "\n"; }
In the example, we fetch the third column from the data.
$ php fetch_column.php gardener teacher programmer musician teacher
PHP CSV in Slim
In the following example, we return CSV data from a Slim application.
$ composer req slim/slim $ composer req slim/psr7 $ composer req slim/http
We install slim/slim
, slim/psr7
, and slim/http
packages.
<?php use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; use Slim\Psr7\Stream; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); $app->get('/users', function (Request $request, Response $response): Response { $csv_file = '../users.csv'; $fp = fopen($csv_file); $stream = new Stream(fopen($csv_file, 'rb')); return $response->withHeader('Content-Type', 'application/octet-stream') ->withHeader('Content-Disposition', 'attachment; filename=users.csv') ->withHeader('Pragma', 'no-cache') ->withBody($stream); }); $app->run();
We read the data from the file and send it in the body of the response.
$ php -S localhost:8000 -t public
We start the built-in server.
$ curl localhost:8000/users "First name","Last name",Occupation John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
A GET request is created with curl
.
PHP CSV in Symfony
In the following example, we send a CSV response from a Symfony application.
$ symfony new symcsv $ cd symcsv
A new project is created.
$ composer req maker --dev $ composer req annot
We install the maker
and annot
dependencies.
$ php bin/console make:controller UserController
We create the UserController
.
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use App\Service\ContainerParametersHelper; class UserController extends AbstractController { /** * @Route("/users", name="user") */ public function index(): Response { $rootDir = $this->getParameter('kernel.project_dir'); $fp = fopen("$rootDir/var/users.csv", 'r'); $response = new Response(stream_get_contents($fp)); fclose($fp); $response->headers->set('Content-Type', 'text/csv'); $response->headers->set('Pragma', 'no-cache'); $response->headers->set('Content-Disposition', 'attachment; filename="users.csv"'); return $response; } }
The users.csv
file is located in the var
directory.
We read the contents of the file and send it in the response object as an
attachment.
$ symfony serve
We start the web server.
$ curl localhost:8000/users "First name","Last name",Occupation John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
We send a GET request with curl
.
PHP CSV in Laravel
In the following example, we send a CSV response from a Laravel application.
$ laravel new laracsv $ cd laracsv
A new project is created.
<?php use Illuminate\Support\Facades\Route; use Symfony\Component\HttpFoundation\StreamedResponse; Route::get('/users', function() : StreamedResponse { $headers = [ "Content-type" => "text/csv", "Content-Disposition" => "attachment; filename=users.csv", "Pragma" => "no-cache", ]; $columns = ['First name', 'Last name', 'Occupation']; $fileName = storage_path('users.csv'); $f = fopen($fileName, 'r'); while (!feof($f)) { $rows[] = fgetcsv($f); } fclose($f); return new StreamedResponse( function() use ($rows) { $handle = fopen('php://output', 'w'); foreach ($rows as $row) { if (!empty($row)) { fputcsv($handle, $row); } } fclose($handle); }, 200, [ 'Content-type' => 'text/csv', 'Content-Disposition' => 'attachment; filename=members.csv' ] ); });
The users.csv
file is located in the storage
directory. We read the contents of the file and send it in the
response object as an attachment.
$ php artisan serve
We start the web server and locate to localhost:8000/users
.
In this article we have worked with CSV data in plain PHP, Symfony, Slim, and Laravel.
Author
List all PHP tutorials.