How to check if a PHP stream resource is readable or writable?

jnrbsn picture jnrbsn · Mar 14, 2011 · Viewed 16.6k times · Source

In PHP, how do I check if a stream resource (or file pointer, handle, or whatever you want to call them) is either readable or writable? For example, if you're faced with a situation where you know nothing about how the resource was opened or created, how do you check if it's readable? And how do you check if it's writable?

Based on the testing that I've done (just with regular text files using PHP 5.3.3), fread() does not throw any errors at any level when the resource is not readable. It just returns an empty string, but it also does that for an empty file. And ideally, it would be better to have a check that doesn't modify the resource itself. Testing if a resource is readable by trying to read from it will change the position of the pointer.

Conversely, fwrite() does not throw any errors at any level when the resource is not writable. It just returns zero. This is slightly more useful, because if you were trying to write a certain number of bytes to a file and fwrite() returns zero, you know something went wrong. But still, this is not an ideal method, because it would be much better to know if it's writable before I need to write to it rather than trying to write to it and see if it fails.

Also, ideally, the check should work on any sort of stream resource, not just files.

Is this possible? Does anything like this exist? I have been unable to find anything useful. Thanks in advance for your answers.

Answer

ircmaxell picture ircmaxell · Mar 14, 2011

Quite simple. Just call stream_get_meta_data($resource) from your script, then check the mode array element of the return value:

$f = fopen($file, 'r');
$meta = stream_get_meta_data($f);
var_dump($meta['mode']); // r

And if you want to know if the underlying data is writable:

var_dump(is_writable($meta['uri'])); // true if the file/uri is writable