Parsing csv files the right way in php 8

Dev Diary

Our new library fusonic/csv-reader helps you to parse CSV files using a strongly typed data model in PHP 8 and above.

Matthias Burtscher
April 7, 2021
Reading time
2 Minutes

How many times have you looked up the documentation for fopen() and fgetcsv() to parse a single CSV file? How many times have you been disappointed by the libraries out there which are all super performant but do not do a good job in keeping your codebase clean? Well, at least I was struggling every time I was supposed to parse a CSV. No longer.

With the option to strictly type properties and methods and with the latest addition of attributes to PHP 8, we were given mighty tools which we can use to build a clean codebase. Based on these features we created fusonic/csv-reader, which allows you to convert data from CSV files to strictly typed data models.

The old way of parsing CSV

This is how most of us parsed CSV files in the past:

$file = fopen('file.csv', 'r'); while ($row = fgetcsv($file)) { echo $row[7]; // 27.05.2020 13:37:00 }

You probably want to load the parsed data into your object-oriented model. You would then write a function for the mapping. That kinda works, but it has a few drawbacks:

  • Reads all data from all columns for every row, which you might not need.
  • Uses numeric indices for accessing data which you have to look up every time.
  • Data is always given as strings. You need to convert it manually.
  • In addition to your data model, you need to maintain the mapping code.
  • Read how our CSV library solves these drawbacks below.

The shiny new way

First, create your data model. Strongly type your properties or setters and use attributes to specify the mapping:

class Foo { // You may use TitleMapping if your CSV file contains a header row. This way // you don't have to count indices. #[TitleMapping('Price')] public float $price; // You may use IndexMapping if there is no header row or if you don't like // to use it. #[IndexMapping(1)] public function setPrice(float $value): void { // Not implemented } }

As you can see, the library supports both public properties and setter methods. Just use what you prefer.

For type hints you may use any of the scalars available (string, bool, int and float) or one of the datetime derivatives (DateTimeInterface, DateTime, DateTimeImmutable). You may prefix them with a ? to unserialize empty values as null.

You can now easily read from a CSV file:

$reader = new CsvReader('myfile.csv'); foreach ($reader->readObjects(Foo::class) as $item) { var_dump($item); }

$reader->readObjects() will give you an iterator allowing you to process data from large CSV files as well.

It’s as simple as that.

Getting started

Head over to GitHub, get comfy with the README and start using the library by installing fusonic/csv-reader today.

More of that?

Contact form

*Required field
*Required field
*Required field
*Required field
We protect your privacy

We keep your personal data safe and do not share it with third parties. You can find out more about this in our privacy policy.