Skip to content

Commit f575d2b

Browse files
authored
Add Ability to Suppress Mac Line Ending Check for CSV Reader (#2623)
With the deprecation of `auto_detect_line_endings` in Php8.1, there have been some tickets (issue #2609 and PR #2438). Although the deprecation message is suppressed, users with a homegrown error handler may still see it. I am not very concerned about that symptom, but I imagine that there will be more similar tickets in future. This PR adds a new property/method to Reader/CSV to allow the user to avoid the deprecated code, at the negligible cost of being unable to read a CSV with Mac line endings even on a Php version that could support it.
1 parent 8258919 commit f575d2b

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

docs/topics/reading-and-writing-to-file.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,25 @@ $reader->setSheetIndex(5);
544544
$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
545545
```
546546

547+
#### Line endings
548+
549+
Line endings for Unix (`\n`) and Windows (`\r\n`) are supported.
550+
551+
Mac line endings (`\r`) are supported as long as PHP itself
552+
supports them, which it does through release 8.0.
553+
Support for Mac line endings is deprecated for 8.1,
554+
and is scheduled to remain deprecated for all later PHP8 releases;
555+
PhpSpreadsheet will continue to support them for 8.*.
556+
Support is scheduled to be dropped with release 9;
557+
PhpSpreadsheet will then no longer handle CSV files
558+
with Mac line endings correctly.
559+
560+
You can suppress testing for Mac line endings as follows:
561+
```php
562+
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
563+
$reader->setTestAutoDetect(false);
564+
```
565+
547566
### \PhpOffice\PhpSpreadsheet\Writer\Csv
548567

549568
#### Writing a CSV file

src/PhpSpreadsheet/Reader/Csv.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ class Csv extends BaseReader
8484
*/
8585
private static $constructorCallback;
8686

87+
/**
88+
* Attempt autodetect line endings (deprecated after PHP8.1)?
89+
*
90+
* @var bool
91+
*/
92+
private $testAutodetect = true;
93+
8794
/**
8895
* Create a new CSV Reader instance.
8996
*/
@@ -269,10 +276,15 @@ private function openFileOrMemory(string $filename): void
269276
}
270277
}
271278

272-
private static function setAutoDetect(?string $value): ?string
279+
public function setTestAutoDetect(bool $value): void
280+
{
281+
$this->testAutodetect = $value;
282+
}
283+
284+
private function setAutoDetect(?string $value): ?string
273285
{
274286
$retVal = null;
275-
if ($value !== null) {
287+
if ($value !== null && $this->testAutodetect) {
276288
$retVal2 = @ini_set('auto_detect_line_endings', $value);
277289
if (is_string($retVal2)) {
278290
$retVal = $retVal2;
@@ -288,7 +300,7 @@ private static function setAutoDetect(?string $value): ?string
288300
public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet
289301
{
290302
// Deprecated in Php8.1
291-
$iniset = self::setAutoDetect('1');
303+
$iniset = $this->setAutoDetect('1');
292304

293305
// Open file
294306
$this->openFileOrMemory($filename);
@@ -339,7 +351,7 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp
339351
// Close file
340352
fclose($fileHandle);
341353

342-
self::setAutoDetect($iniset);
354+
$this->setAutoDetect($iniset);
343355

344356
// Return
345357
return $spreadsheet;

tests/PhpSpreadsheetTests/Reader/Csv/CsvLineEndingTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ public function testEndings(string $ending): void
3636
$spreadsheet->disconnectWorksheets();
3737
}
3838

39+
/**
40+
* @dataProvider providerEndings
41+
*/
42+
public function testEndingsNoDetect(string $ending): void
43+
{
44+
$this->tempFile = $filename = File::temporaryFilename();
45+
$data = ['123', '456', '789'];
46+
file_put_contents($filename, implode($ending, $data));
47+
$reader = new Csv();
48+
$reader->setTestAutoDetect(false);
49+
$spreadsheet = $reader->load($filename);
50+
$sheet = $spreadsheet->getActiveSheet();
51+
if ($ending === "\r") {
52+
// Can't handle Mac line endings without autoDetect
53+
self::assertEquals(implode("\n", $data), $sheet->getCell('A1')->getValue());
54+
self::assertNull($sheet->getCell('A2')->getValue());
55+
self::assertNull($sheet->getCell('A3')->getValue());
56+
} else {
57+
self::assertEquals($data[0], $sheet->getCell('A1')->getValue());
58+
self::assertEquals($data[1], $sheet->getCell('A2')->getValue());
59+
self::assertEquals($data[2], $sheet->getCell('A3')->getValue());
60+
}
61+
$spreadsheet->disconnectWorksheets();
62+
}
63+
3964
public function providerEndings(): array
4065
{
4166
return [

0 commit comments

Comments
 (0)