Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Csv Laravel Package

league/csv

View on GitHub
Deep Wiki
Context7

layout: default title: Converting a collection into a JSON description: The JsonConverter class converts and store CSV records collection into a JSON or a JSON-Lines structure in a memory efficient way

JSON conversion

The JsonConverter converts or store a collection into a JSON structure.

To reduce memory usage, the converter transforms one collection element at a time. This means that the class settings are geared toward a single element and not the whole collection. The only pre-requisite is that each element of your collection must either be an object implementing the JsonSerializable interface or a PHP structure that can be encoded via json_encode.

Instantiation

To create a new JsonConverter instance you can call its constructor or the create named constructor. The latter is deprecated since version 9.22.0 and will be removed whenever the next major version is released.

- JsonConverter::create()->download($record);
+ (new JsonConverter())->download($record);

With the release of PHP8.4, the parenthesis around the constructor are no longer needed.

(new JsonConverter())->download($record); //old usage (deprecated in PHP8.4+)
new JsonConverter()->download($record); //new and fast-forward method usage

Settings

Prior to converting your collection into a JSON structure, you may wish to configure it.

Encoding Flags

public JsonConverter::addFlags(int ...$flag): self
public JsonConverter::removeFlags(int ...$flag): self
public JsonConverter::useFlags(int ...$flag): bool

These methods set the JSON flags to be used during conversion. The method handles all the flags supported by PHP json_encode function.

If you prefer a more expressive way for setting the flags you can use the with* and without* methods whose name are derived from PHP JSON constants.

$converter = (new JsonConverter())
    ->addFlags(JSON_PRETTY_PRINT, JSON_HEX_QUOT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT)
    ->removeFlags(JSON_HEX_QUOT);

//is equivalent to

$converter = (new JsonConverter())
    ->withPrettyPrint()
    ->withHexQuot()
    ->withUnescapedSlashes()
    ->withForceObject()
    ->withoutHexQuot();

To quickly check which flags is being used, calle the JsonConverter::useFlags method. As for the other methods a more expressive way exists.

$converter = (new JsonConverter())
    ->addFlags(JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT)
    ->removeFlags(JSON_HEX_QUOT);
    
$converter->useFlags(JSON_PRETTY_PRINT, JSON_FORCE_OBJECT); //returns true both flags are used
$converter->useFlags(JSON_PRETTY_PRINT, JSON_HEX_QUOT); //returns false at least one of the flag is not set
$converter->usePrettyPrint();  // returns true the flag is used
$converter->useThrowOnError(); // returns true the flag is always used
$converter->useHexQuot();      // returns false the flag is not used
$converter->flags;             //returns the actual flags value (as used by json_encode)
$converter = (new JsonConverter())->withPrettyPrint(2);

will produce a JSON with an indentation size of 2.

Encoding Depth

public JsonConverter::depth(int $depth): self

This method sets the JSON depth value during conversion. The method is a proxy to using the json_encode depth parameter.

$converter = (new JsonConverter())->depth(2);
$converter->depth; //returns the actual depth value (as used by json_encode) 

Encode Indentation

public JsonConverter::indentSize(int $indentSize): self

This method sets the JSON indentation size value if you use the JSON_PRETTY_PRINT flag. In all other situation this value stored via this method is never used. By default, the indentation size is the same as in PHP (ie : 4 characters long).

- $converter = (new JsonConverter())->indentSize(2);
+ $converter = (new JsonConverter())->withPrettyPrint(2);
$converter->indentSize; //returns the value used

Encoding Formatter

public JsonConverter::formatter(?callable $formatter): self

This method allow to apply a callback prior to json_encode your collection individual item. Since the encoder does not rely on PHP's JsonSerializable interface but on PHP's iterable structure. The resulting conversion may differ to what you expect. This callback allows you to specify how each item will be converted. The formatter should return a type that can be handled by PHP json_encode function.

Chunk Size

public JsonConverter::chunkSize(int $chunkSize): self

This method sets the number of rows to buffer before convert into JSON string. This allow for faster conversion while retaining the low memory usage. Of course, the default chunk size can vary for one scenario to another. The correct size is therefore left to the user discretion. By default, the value is 500. The value can not be lower than one otherwise a exception will be thrown.

$converter = (new JsonConverter())->chunkSize(1_000);
$converter->chunkSize; //returns the value used

Conditional Settings

This method allows to conditionally create your converter depending on the success or failure of a condition.

use League\Csv\JsonConverter;

$converter = (new JsonConverter());
if ($condition) {
    $converter = $converter->chunkSize(1_000);
} else {
    $converter = $converter->chunkSize(200);
}

becomes

$stmt = (new JsonConverter())
    ->when(
        $condition,
        fn (JsonConverter $c) => $c->chunkSize(1_000),
        fn (JsonConverter $c) => $c->chunkSize(200),
    );
)

The else expression is not required but if present in MUST BE a callable which only accepts the JsonConverter instance and returns null or a JsonConverter instance.

The only requirements are:

  • that the condition is a boolean or a callable that returns a boolean.
  • the callback returns a JsonConverter instance or null.

Conversion

public JsonConverter::convert(iterable $records): iterable<string>
public JsonConverter::encode(iterable $records): string
public JsonConverter::save(iterable $records, mixed $destination, $context = null): int

The JsonConverter::convert accepts an iterable which represents the records collection and returns a iterable structure lazily converted to JSON one item at a time to avoid high memory usage. The class is built to handle large collection but can be used with small ones if needed.

The JsonConverter::encode and JsonConverter::save methods are sugar syntactic methods to ease storing the JSON in a file or displaying it in its full JSON string representation.

Here's a conversion example:

$document = Reader::from(__DIR__.'/test_files/prenoms.csv');
$document->setDelimiter(';');
$document->setHeaderOffset(0);

CharsetConverter::addTo($document, 'iso-8859-15', 'utf-8');
$converter = (new JsonConverter())
    ->withPrettyPrint(2)
    ->withUnescapedSlashes()
    ->depth(2)
    ->formatter(function (array $row) {
        $row['nombre'] = (int) $row['nombre'];
        $row['annee'] = (int) $row['annee'];
        $row['sexe']  = $row['sexe'] === 'M' ? 'male' : 'female';

        //other attributes of $row are not affected
        //and will be rendered as they are.

        return $row;
    });

echo $converter->encode($document->slice(3, 2)), PHP_EOL;

This will produce the following response:

[
  {
    "prenoms": "Abdoulaye",
    "nombre": 15,
    "sexe": "male",
    "annee": 2004
  },
  {
    "prenoms": "Abel",
    "nombre": 14,
    "sexe": "male",
    "annee": 2004
  }
]

Of note, if your data is not encoded in UTF-8 it will trigger a JSON exception. In our example, we first convert The document data to utf-8 using the CharsetConverter class to avoid the exception triggering.

If we wanted to store the data instead of displaying it we could do the following

- echo $converter->encode($document), PHP_EOL;
+ $converter->save($document, 'my/new/document.json');

the generated JSON will then be stored at the my/new/document.json path. The destination path can be specified using:

  • a SplFileObject instance;
  • a SplFileInfo instance;
  • a resource created by fopen;
  • a string;

If you provide a string or a SplFileInfo instance:

  • the file will be open using the w open mode.
  • You can provide an additional $context parameter, a la fopen, to fine tune where and how the JSON file will be stored.

JSON Format

When exporting a collection to JSON, you can choose between two output styles:

  • Standard JSON – the entire collection is represented as a single JSON array.
  • JSON Lines (NDJSON) – each record is written as a separate JSON object on its own line.

The JsonConverter::format method allows you to configure which style to use:

use League\Csv\JsonConverter;
use League\Csv\JsonFormat;

echo (new JsonConverter())
    ->format(JsonFormat::NdJson)
    ->encode([
        ['city' => 'Accra', 'country' => 'Ghana'],
        ['city' => 'Nouakchott', 'country' => 'Mauritania'],
        ['city' => 'Gaborone', 'country' => 'Botswana'],
    ]);
// returns
// {"city":"Accra","country":"Ghana"}
// {"city":"Nouakchott","country":"Mauritania"}
// {"city":"Gaborone","country":"Botswana"}

You can inspect the current format via the JsonConverter::format property. This property always contains one of the JsonFormat enum values:

  • JsonFormat::Standard— produces a single JSON array containing all records.
  • JsonFormat::NdJson — produces one JSON object per line.
  • JsonFormat::NdJsonHeader — produces one JSON list per line with the first line representing the file header
  • JsonFormat::NdJsonHeaderLess — produces one JSON list per line without any header

Download

To download the generated JSON you can use the JsonConverter::download method. The method returns the total number of bytes sent just like the JsonConverter::save method and enable downloading the JSON on the fly.

General purpose

use League\Csv\Reader;
use League\Csv\JsonConverter;

$reader = Reader::from('file.csv');
$reader->setHeaderOffset(0);

header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
header('Content-Type: application/json; charset=UTF-8');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="name-for-your-file.json"');

(new JsonConverter())->download($reader);
die;

In this scenario, you have to specify all the headers for the file to be downloaded.

Using a filename

If you want to reduce the number of headers to write you can specify the downloaded filename.

use League\Csv\Reader;
use League\Csv\JsonConverter;

$reader = Reader::from('file.csv');
$reader->setHeaderOffset(0);

header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
 //the filename will be the name of the downloaded json as shown by your HTTP client!
(new JsonConverter())->download($reader, 'generated_file.json');
die;
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport