@@ -62,8 +62,19 @@ class Csv extends BaseReader
62
62
63
63
/**
64
64
* The character that can escape the enclosure.
65
+ * This will probably become unsupported in Php 9.
66
+ * Not yet ready to mark deprecated in order to give users
67
+ * a migration path.
65
68
*/
66
- private string $ escapeCharacter = '\\' ;
69
+ private ?string $ escapeCharacter = null ;
70
+
71
+ /**
72
+ * The character that will be supplied to fgetcsv
73
+ * when escapeCharacter is null.
74
+ * It is anticipated that it will conditionally be set
75
+ * to null-string for Php9 and above.
76
+ */
77
+ private static string $ defaultEscapeCharacter = '\\' ;
67
78
68
79
/**
69
80
* Callback for setting defaults in construction.
@@ -185,7 +196,7 @@ protected function inferSeparator(): void
185
196
return ;
186
197
}
187
198
188
- $ inferenceEngine = new Delimiter ($ this ->fileHandle , $ this ->escapeCharacter , $ this ->enclosure );
199
+ $ inferenceEngine = new Delimiter ($ this ->fileHandle , $ this ->escapeCharacter ?? self :: $ defaultEscapeCharacter , $ this ->enclosure );
189
200
190
201
// If number of lines is 0, nothing to infer : fall back to the default
191
202
if ($ inferenceEngine ->linesCounted () === 0 ) {
@@ -228,11 +239,11 @@ public function listWorksheetInfo(string $filename): array
228
239
$ delimiter = $ this ->delimiter ?? '' ;
229
240
230
241
// Loop through each line of the file in turn
231
- $ rowData = fgetcsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
242
+ $ rowData = self :: getCsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
232
243
while (is_array ($ rowData )) {
233
244
++$ worksheetInfo [0 ]['totalRows ' ];
234
245
$ worksheetInfo [0 ]['lastColumnIndex ' ] = max ($ worksheetInfo [0 ]['lastColumnIndex ' ], count ($ rowData ) - 1 );
235
- $ rowData = fgetcsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
246
+ $ rowData = self :: getCsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
236
247
}
237
248
238
249
$ worksheetInfo [0 ]['lastColumnLetter ' ] = Coordinate::stringFromColumnIndex ($ worksheetInfo [0 ]['lastColumnIndex ' ] + 1 );
@@ -379,7 +390,7 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
379
390
380
391
// Loop through each line of the file in turn
381
392
$ delimiter = $ this ->delimiter ?? '' ;
382
- $ rowData = fgetcsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
393
+ $ rowData = self :: getCsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
383
394
$ valueBinder = Cell::getValueBinder ();
384
395
$ preserveBooleanString = method_exists ($ valueBinder , 'getBooleanConversion ' ) && $ valueBinder ->getBooleanConversion ();
385
396
$ this ->getTrue = Calculation::getTRUE ();
@@ -416,7 +427,7 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
416
427
}
417
428
++$ columnLetter ;
418
429
}
419
- $ rowData = fgetcsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
430
+ $ rowData = self :: getCsv ($ fileHandle , 0 , $ delimiter , $ this ->enclosure , $ this ->escapeCharacter );
420
431
++$ currentRow ;
421
432
}
422
433
@@ -527,6 +538,11 @@ public function getContiguous(): bool
527
538
return $ this ->contiguous ;
528
539
}
529
540
541
+ /**
542
+ * Php9 intends to drop support for this parameter in fgetcsv.
543
+ * Not yet ready to mark deprecated in order to give users
544
+ * a migration path.
545
+ */
530
546
public function setEscapeCharacter (string $ escapeCharacter ): self
531
547
{
532
548
$ this ->escapeCharacter = $ escapeCharacter ;
@@ -536,7 +552,7 @@ public function setEscapeCharacter(string $escapeCharacter): self
536
552
537
553
public function getEscapeCharacter (): string
538
554
{
539
- return $ this ->escapeCharacter ;
555
+ return $ this ->escapeCharacter ?? self :: $ defaultEscapeCharacter ;
540
556
}
541
557
542
558
/**
@@ -649,4 +665,28 @@ public function setSheetNameIsFileName(bool $sheetNameIsFileName): self
649
665
650
666
return $ this ;
651
667
}
668
+
669
+ /**
670
+ * Php8.4 deprecates use of anything other than null string
671
+ * as escape Character.
672
+ *
673
+ * @param resource $stream
674
+ * @param null|int<0, max> $length
675
+ *
676
+ * @return array<int,?string>|false
677
+ */
678
+ private static function getCsv (
679
+ $ stream ,
680
+ ?int $ length = null ,
681
+ string $ separator = ', ' ,
682
+ string $ enclosure = '" ' ,
683
+ ?string $ escape = null
684
+ ): array |false {
685
+ $ escape = $ escape ?? self ::$ defaultEscapeCharacter ;
686
+ if (PHP_VERSION_ID >= 80400 && $ escape !== '' ) {
687
+ return @fgetcsv ($ stream , $ length , $ separator , $ enclosure , $ escape );
688
+ }
689
+
690
+ return fgetcsv ($ stream , $ length , $ separator , $ enclosure , $ escape );
691
+ }
652
692
}
0 commit comments