{"record":{"id":"87172ef78436372b","repo":"PHPOffice/PHPWord","slug":"could-not-open-sfilename-for-reading-file-does-not-exist-or","errorCode":null,"errorMessage":"Could not open ' . $sFileName . ' for reading! File does not exist, or it is not readable.","messagePattern":"Could not open ' \\. \\$sFileName \\. ' for reading! File does not exist, or it is not readable\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/PhpWord/Shared/OLERead.php","lineNumber":87,"sourceCode":"    public $bigBlockChain = null;\n    public $smallBlockChain = null;\t\n    public $entry = null;\t\n    public $rootentry = null;\n    public $wrkObjectPoolelseif = null;\n    public $props = array();\t\n\n    /**\n     * Read the file\n     *\n     * @param $sFileName string Filename\n     *\n     * @throws Exception\n     */\n    public function read($sFileName)\n    {\n        // Check if file exists and is readable\n        if (!is_readable($sFileName)) {\n            throw new Exception('Could not open ' . $sFileName . ' for reading! File does not exist, or it is not readable.');\n        }\n\n        // Get the file identifier\n        // Don't bother reading the whole file until we know it's a valid OLE file\n        $this->data = file_get_contents($sFileName, false, null, 0, 8);\n\n        // Check OLE identifier\n        if ($this->data != self::IDENTIFIER_OLE) {\n            throw new Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');\n        }\n\n        // Get the file data\n        $this->data = file_get_contents($sFileName);\n\n        // Total number of sectors used for the SAT\n        $this->numBigBlockDepotBlocks = self::getInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);\n\n        // SecID of the first sector of the directory stream","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/PHPOffice/PHPWord/blob/aef95c04151b5633cc505f672ddd6a71da900ee1/src/PhpWord/Shared/OLERead.php#L69-L105","documentation":"OLERead::read() is the low-level reader for OLE compound documents (legacy .doc, .xls). Before parsing, it checks is_readable($sFileName) and throws if the path cannot be read — covering nonexistent files, unreadable permissions, and directories. Called from loadOLE when loading legacy binary documents.","triggerScenarios":"Passing a path to loadOLE/read where the file does not exist, lacks read permission for the PHP user, is a directory, or is a stream/URL wrapper that is_readable() cannot validate (e.g. some remote wrappers).","commonSituations":"Opening legacy .doc files after moving uploads to another storage directory; web-server user lacking permission on the upload folder; passing a URL or in-memory content instead of a local filesystem path; open_basedir restrictions.","solutions":["Confirm the file exists at the exact path with file_exists()/is_readable() before calling loadOLE.","Copy remote/uploaded content to a local temp file first, then load that path.","Fix filesystem permissions (chown/chmod) so the PHP process user can read the file.","Check open_basedir and safe paths in php.ini if the path is outside allowed roots."],"exampleFix":"// before\n$phpWord = IOFactory::load('/uploads/report.doc'); // file was moved\n// after\n$path = '/var/www/uploads/report.doc';\nif (!is_readable($path)) {\n    throw new RuntimeException(\"OLE document not readable: $path\");\n}\n$phpWord = IOFactory::load($path);","handlingStrategy":"validation","validationCode":"if (!is_file($path)) {\n    throw new InvalidArgumentException(\"File not found: $path\");\n}\nif (!is_readable($path)) {\n    throw new RuntimeException(\"File not readable (check permissions/open_basedir): $path\");\n}","typeGuard":"function isReadableFile(string $path): bool\n{\n    return is_string($path) && is_file($path) && is_readable($path);\n}","tryCatchPattern":"try {\n    $phpWord = IOFactory::load($path);\n} catch (\\PhpOffice\\PhpWord\\Exception\\Exception $e) {\n    if (str_contains($e->getMessage(), 'for reading')) {\n        throw new RuntimeException(\"Cannot read OLE document at $path\", 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Use absolute paths resolved with realpath()","Check is_readable() immediately before loading legacy documents","Ensure upload directories are readable by the PHP process user","Copy remote/stream sources to a local temp file first"],"tags":["phpword","ole","file-not-found","permissions"],"backgroundTag":"file-not-found","analyzedSha":"aef95c04151b5633cc505f672ddd6a71da900ee1","analyzedAt":"2026-09-14T10:53:58.933Z","contentChangedAt":"2026-09-14T10:53:58.933Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}