Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Php 8.4 Will Deprecate fgetcsv Parameter #4162

Merged
merged 2 commits into from
Sep 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 47 additions & 7 deletions src/PhpSpreadsheet/Reader/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,19 @@ class Csv extends BaseReader

/**
* The character that can escape the enclosure.
* This will probably become unsupported in Php 9.
* Not yet ready to mark deprecated in order to give users
* a migration path.
*/
private string $escapeCharacter = '\\';
private ?string $escapeCharacter = null;

/**
* The character that will be supplied to fgetcsv
* when escapeCharacter is null.
* It is anticipated that it will conditionally be set
* to null-string for Php9 and above.
*/
private static string $defaultEscapeCharacter = '\\';

/**
* Callback for setting defaults in construction.
Expand Down Expand Up @@ -185,7 +196,7 @@ protected function inferSeparator(): void
return;
}

$inferenceEngine = new Delimiter($this->fileHandle, $this->escapeCharacter, $this->enclosure);
$inferenceEngine = new Delimiter($this->fileHandle, $this->escapeCharacter ?? self::$defaultEscapeCharacter, $this->enclosure);

// If number of lines is 0, nothing to infer : fall back to the default
if ($inferenceEngine->linesCounted() === 0) {
Expand Down Expand Up @@ -228,11 +239,11 @@ public function listWorksheetInfo(string $filename): array
$delimiter = $this->delimiter ?? '';

// Loop through each line of the file in turn
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
while (is_array($rowData)) {
++$worksheetInfo[0]['totalRows'];
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
}

$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
Expand Down Expand Up @@ -379,7 +390,7 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo

// Loop through each line of the file in turn
$delimiter = $this->delimiter ?? '';
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$valueBinder = Cell::getValueBinder();
$preserveBooleanString = method_exists($valueBinder, 'getBooleanConversion') && $valueBinder->getBooleanConversion();
$this->getTrue = Calculation::getTRUE();
Expand Down Expand Up @@ -416,7 +427,7 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
}
++$columnLetter;
}
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$rowData = self::getCsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
++$currentRow;
}

Expand Down Expand Up @@ -527,6 +538,11 @@ public function getContiguous(): bool
return $this->contiguous;
}

/**
* Php9 intends to drop support for this parameter in fgetcsv.
* Not yet ready to mark deprecated in order to give users
* a migration path.
*/
public function setEscapeCharacter(string $escapeCharacter): self
{
$this->escapeCharacter = $escapeCharacter;
Expand All @@ -536,7 +552,7 @@ public function setEscapeCharacter(string $escapeCharacter): self

public function getEscapeCharacter(): string
{
return $this->escapeCharacter;
return $this->escapeCharacter ?? self::$defaultEscapeCharacter;
}

/**
Expand Down Expand Up @@ -649,4 +665,28 @@ public function setSheetNameIsFileName(bool $sheetNameIsFileName): self

return $this;
}

/**
* Php8.4 deprecates use of anything other than null string
* as escape Character.
*
* @param resource $stream
* @param null|int<0, max> $length
*
* @return array<int,?string>|false
*/
private static function getCsv(
$stream,
?int $length = null,
string $separator = ',',
string $enclosure = '"',
?string $escape = null
): array|false {
$escape = $escape ?? self::$defaultEscapeCharacter;
if (PHP_VERSION_ID >= 80400 && $escape !== '') {
return @fgetcsv($stream, $length, $separator, $enclosure, $escape);
}

return fgetcsv($stream, $length, $separator, $enclosure, $escape);
}
}
Loading