is_readable() does not distinguish whether a file doesn’t exist or simply lacks permissions. For example:
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-string">'/path/to/nonexistent.txt'</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)); </span><span><span class="hljs-comment">// Outputs false</span></span><span>
</span></span>
In this case, if you simply rely on the false result, you might mistakenly assume it’s a permission issue, when in fact the file doesn’t exist at all.
Solution: First use file_exists() to check whether the file exists, then verify readability.
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">file_exists</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>) && </span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"File exists and is readable"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"File does not exist or is not readable"</span></span><span>;
}
</span></span>
is_readable() works relative to PHP’s current working directory. If the path is unclear, the check may fail. For example:
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-string">'data/file.txt'</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>));
</span></span>
If your PHP script’s working directory is different from what you expect, it may return false. This is a common mistake beginners overlook.
Solution: Use absolute paths, or obtain the current script directory with __DIR__:
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-keyword">__DIR__</span></span><span> . </span><span><span class="hljs-string">'/data/file.txt'</span></span><span>;
</span></span>
is_readable() checks the readability of the target file of a symbolic link, not the link itself. This means that even if the link has accessible permissions, if the target file is restricted, it will still be unreadable.
<span><span><span class="hljs-comment">// Assume link.txt is a symbolic link to secret.txt</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-string">'link.txt'</span></span><span>)); </span><span><span class="hljs-comment">// Depends on secret.txt permissions</span></span><span>
</span></span>
Note: When dealing with symbolic links, always verify the target file’s permissions to avoid unexpected access failures.
On Windows, is_readable() checks file attributes, while on Unix/Linux, it considers both user permissions (UID/GID) and file permission bits. In some cases, identical code may return different results on different platforms.
is_readable() only checks file system permissions and does not account for file locks by other processes. If a file is in use (e.g., exclusively written by another program), is_readable() may still return true, but actual reading may fail.
On systems using advanced security mechanisms, file access may be restricted by ACLs or SELinux. is_readable() may still return true, but read attempts can be denied.