thephpleague/csv

Preformatting data before conversion

nyamsprod opened this issue · 3 comments

          Hi, sorry if this is not the right place to ask my question, but it seems that the issue title fits with my case.

I must read a CSV exported from MySQL and it seems that there are strange "\N" string values in some columns that I suspect that are representing null reference values.

My problem is that when I try to use the CastToInt isn't working because I don't know how to pre-transform this "\N" into a nullable integer.

// my DTO class
#[MapCell(column: 1, cast: CastToInt::class)]
private ?int $museumLegacyId;

[ERROR] Unable to cast the given data \N to a int.

Originally posted by @davidromani in #237 (comment)

@davidromani a Reader::addFormatter method was introduced in a recent minor version. You can use that function to formatter your records before accessing. Which gives you the opportunity to convert your \N in a proper null value.

Hi @nyamsprod 👋

I've tried a diffent approach, and now I'm using a custom CastType (extended). It would be possible for you to show me how can I use a Reader::addFormatter approach? This method aplies to the full columns (row array) readed?

I've show this documentation, but it's not clear to me how can I implement in my case to avoid \N strings (only in some columns)...

$formatter = fn (array $row): array => array_map(strtoupper(...), $row);
$reader = Reader::createFromString($csv)
    ->setHeaderOffset(0)
    ->addFormatter($formatter);
[...$reader]; 

Thanks for your answer.

There are many ways to make it more simple but I wanted to make it readable.

$formatNull = function (array $record) : array {
   $res = [];
   foreach ($records as $offset => $value) {
       if ($value === "\N" {
            $value = null;
       }
       $res[$offset] = $value;
   }

   return $res;
};

$reader->addFormatter($formatNull);

Then you can continue whatever you were doing.