diff --git a/composer.json b/composer.json index 79440a8e..9645d068 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ ], "require": { "php": "^8.1.2", + "ext-filter": "*", "ext-json": "*", "ext-mbstring": "*" }, diff --git a/src/AbstractCsv.php b/src/AbstractCsv.php index 2b4c8b64..237c59f1 100644 --- a/src/AbstractCsv.php +++ b/src/AbstractCsv.php @@ -51,7 +51,7 @@ abstract class AbstractCsv implements ByteSequence /** * @final This method should not be overwritten in child classes */ - protected function __construct(protected SplFileObject|Stream $document) + protected function __construct(protected readonly SplFileObject|Stream $document) { [$this->delimiter, $this->enclosure, $this->escape] = $this->document->getCsvControl(); $this->resetProperties(); @@ -64,11 +64,6 @@ protected function resetProperties(): void { } - public function __destruct() - { - unset($this->document); - } - /** * @throws UnavailableStream */ @@ -258,15 +253,25 @@ public function output(string $filename = null): int } $this->document->rewind(); - if (!$this->is_input_bom_included) { - if (-1 === $this->document->fseek(strlen($this->getInputBOM()))) { - throw new RuntimeException('Unable to seek the document.'); - } + $this->document->setFlags(0); + if (!$this->is_input_bom_included && -1 === $this->document->fseek(strlen($this->getInputBOM()))) { + throw new RuntimeException('Unable to seek the document.'); } - echo $this->output_bom; + $stream = Stream::createFromString($this->output_bom); + $stream->rewind(); + + $res1 = $stream->fpassthru(); + if (false === $res1) { + throw new RuntimeException('Unable to output the document.'); + } + + $res2 = $this->document->fpassthru(); + if (false === $res2) { + throw new RuntimeException('Unable to output the document.'); + } - return strlen($this->output_bom) + (int) $this->document->fpassthru(); + return $res1 + $res2; } /**