{"record":{"id":"500365ec9fa51d92","repo":"PHPOffice/PhpSpreadsheet","slug":"could-not-open-file-filename-for-reading-500365","errorCode":null,"errorMessage":"Could not open file $filename for reading.","messagePattern":"Could not open file \\$filename for reading\\.","errorType":"exception","errorClass":"ReaderException","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Csv.php","lineNumber":361,"sourceCode":"    }\n\n    public function castFormattedNumberToNumeric(\n        bool $castFormattedNumberToNumeric,\n        bool $preserveNumericFormatting = false\n    ): void {\n        $this->castFormattedNumberToNumeric = $castFormattedNumberToNumeric;\n        $this->preserveNumericFormatting = $preserveNumericFormatting;\n    }\n\n    /**\n     * Open data uri for reading.\n     */\n    private function openDataUri(string $filename): void\n    {\n        $fileHandle = fopen($filename, 'rb');\n        if ($fileHandle === false) {\n            // @codeCoverageIgnoreStart\n            throw new ReaderException('Could not open file ' . $filename . ' for reading.');\n            // @codeCoverageIgnoreEnd\n        }\n\n        $this->fileHandle = $fileHandle;\n    }\n\n    /**\n     * Loads PhpSpreadsheet from file into PhpSpreadsheet instance.\n     */\n    public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet\n    {\n        return $this->loadStringOrFile($filename, $spreadsheet, false);\n    }\n\n    /**\n     * Loads PhpSpreadsheet from file into PhpSpreadsheet instance.\n     */\n    private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bool $dataUri): Spreadsheet","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Csv.php#L343-L379","documentation":"Csv::loadSpreadsheetFromString() funnels the string into a data://text/plain URI and fopen()s it. If fopen of the data:// wrapper fails, the reader throws this. The dominant cause is allow_url_fopen=Off (a common hardening setting), which disables the URL-style stream wrappers including data://.","triggerScenarios":"Calling $reader->loadSpreadsheetFromString($csv) on any server where allow_url_fopen is disabled (php.ini hardening, managed hosting, strict container defaults); the string API works locally but explodes only in production.","commonSituations":"Code that loads CSV/HTML from strings (API payloads, DB blobs, scraped content) moving from a dev machine to a hardened production host.","solutions":["Enable allow_url_fopen (php.ini, or ini_set('allow_url_fopen', '1') at runtime where the host permits it)","If you cannot change ini settings, bypass the string API: write the content to a temporary file and call load() instead","Check the setting in deployment smoke tests wherever string loading is used"],"exampleFix":"// before\n$spreadsheet = (new Csv())->loadSpreadsheetFromString($csvText); // allow_url_fopen=Off -> throws\n\n// after\nif (filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOL)) {\n    $spreadsheet = (new Csv())->loadSpreadsheetFromString($csvText);\n} else {\n    $tmp = tempnam(sys_get_temp_dir(), 'csv');\n    file_put_contents($tmp, $csvText);\n    $spreadsheet = (new Csv())->load($tmp);\n    unlink($tmp);\n}","handlingStrategy":"fallback","validationCode":"if (!filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOL)) {\n    // string API unavailable — use the temp-file route below instead of calling it\n}","typeGuard":null,"tryCatchPattern":"try {\n    $spreadsheet = (new Csv())->loadSpreadsheetFromString($text);\n} catch (ReaderException $e) {\n    $tmp = tempnam(sys_get_temp_dir(), 'csv');\n    file_put_contents($tmp, $text);\n    $spreadsheet = (new Csv())->load($tmp); // fallback path\n    unlink($tmp);\n}","preventionTips":["Assert allow_url_fopen in deployment checks wherever string loading is used","Default to the temp-file pattern for string content in hardened environments","Document the ini requirement next to any loadSpreadsheetFromString call"],"tags":["csv","stream-wrapper","allow-url-fopen","php-ini"],"backgroundTag":"allow-url-fopen-disabled","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}