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.
This commit is contained in:
parent
8258919d72
commit
f575d2b8b2
|
|
@ -544,6 +544,25 @@ $reader->setSheetIndex(5);
|
||||||
$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
|
$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Line endings
|
||||||
|
|
||||||
|
Line endings for Unix (`\n`) and Windows (`\r\n`) are supported.
|
||||||
|
|
||||||
|
Mac line endings (`\r`) are supported as long as PHP itself
|
||||||
|
supports them, which it does through release 8.0.
|
||||||
|
Support for Mac line endings is deprecated for 8.1,
|
||||||
|
and is scheduled to remain deprecated for all later PHP8 releases;
|
||||||
|
PhpSpreadsheet will continue to support them for 8.*.
|
||||||
|
Support is scheduled to be dropped with release 9;
|
||||||
|
PhpSpreadsheet will then no longer handle CSV files
|
||||||
|
with Mac line endings correctly.
|
||||||
|
|
||||||
|
You can suppress testing for Mac line endings as follows:
|
||||||
|
```php
|
||||||
|
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
|
||||||
|
$reader->setTestAutoDetect(false);
|
||||||
|
```
|
||||||
|
|
||||||
### \PhpOffice\PhpSpreadsheet\Writer\Csv
|
### \PhpOffice\PhpSpreadsheet\Writer\Csv
|
||||||
|
|
||||||
#### Writing a CSV file
|
#### Writing a CSV file
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,13 @@ class Csv extends BaseReader
|
||||||
*/
|
*/
|
||||||
private static $constructorCallback;
|
private static $constructorCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt autodetect line endings (deprecated after PHP8.1)?
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $testAutodetect = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new CSV Reader instance.
|
* Create a new CSV Reader instance.
|
||||||
*/
|
*/
|
||||||
|
|
@ -269,10 +276,15 @@ class Csv extends BaseReader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function setAutoDetect(?string $value): ?string
|
public function setTestAutoDetect(bool $value): void
|
||||||
|
{
|
||||||
|
$this->testAutodetect = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setAutoDetect(?string $value): ?string
|
||||||
{
|
{
|
||||||
$retVal = null;
|
$retVal = null;
|
||||||
if ($value !== null) {
|
if ($value !== null && $this->testAutodetect) {
|
||||||
$retVal2 = @ini_set('auto_detect_line_endings', $value);
|
$retVal2 = @ini_set('auto_detect_line_endings', $value);
|
||||||
if (is_string($retVal2)) {
|
if (is_string($retVal2)) {
|
||||||
$retVal = $retVal2;
|
$retVal = $retVal2;
|
||||||
|
|
@ -288,7 +300,7 @@ class Csv extends BaseReader
|
||||||
public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet
|
public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet
|
||||||
{
|
{
|
||||||
// Deprecated in Php8.1
|
// Deprecated in Php8.1
|
||||||
$iniset = self::setAutoDetect('1');
|
$iniset = $this->setAutoDetect('1');
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
$this->openFileOrMemory($filename);
|
$this->openFileOrMemory($filename);
|
||||||
|
|
@ -339,7 +351,7 @@ class Csv extends BaseReader
|
||||||
// Close file
|
// Close file
|
||||||
fclose($fileHandle);
|
fclose($fileHandle);
|
||||||
|
|
||||||
self::setAutoDetect($iniset);
|
$this->setAutoDetect($iniset);
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return $spreadsheet;
|
return $spreadsheet;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,31 @@ class CsvLineEndingTest extends TestCase
|
||||||
$spreadsheet->disconnectWorksheets();
|
$spreadsheet->disconnectWorksheets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerEndings
|
||||||
|
*/
|
||||||
|
public function testEndingsNoDetect(string $ending): void
|
||||||
|
{
|
||||||
|
$this->tempFile = $filename = File::temporaryFilename();
|
||||||
|
$data = ['123', '456', '789'];
|
||||||
|
file_put_contents($filename, implode($ending, $data));
|
||||||
|
$reader = new Csv();
|
||||||
|
$reader->setTestAutoDetect(false);
|
||||||
|
$spreadsheet = $reader->load($filename);
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
if ($ending === "\r") {
|
||||||
|
// Can't handle Mac line endings without autoDetect
|
||||||
|
self::assertEquals(implode("\n", $data), $sheet->getCell('A1')->getValue());
|
||||||
|
self::assertNull($sheet->getCell('A2')->getValue());
|
||||||
|
self::assertNull($sheet->getCell('A3')->getValue());
|
||||||
|
} else {
|
||||||
|
self::assertEquals($data[0], $sheet->getCell('A1')->getValue());
|
||||||
|
self::assertEquals($data[1], $sheet->getCell('A2')->getValue());
|
||||||
|
self::assertEquals($data[2], $sheet->getCell('A3')->getValue());
|
||||||
|
}
|
||||||
|
$spreadsheet->disconnectWorksheets();
|
||||||
|
}
|
||||||
|
|
||||||
public function providerEndings(): array
|
public function providerEndings(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue