Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 860
jnrbsn Avatar asked Mar 14 '11 03:03

jnrbsn


2 Answers

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
like image 149
ircmaxell Avatar answered Sep 30 '22 20:09

ircmaxell


Okay, so this may not be the best solution, but I think it suffices, given that there's nothing in PHP to do this automagically.

For the first step, you'll get the inode of the resource from the file, and then read the filename:

$stat = fstat($fp);
$inode = $stat['ino'];
system("find -inum $inode", $result);

Taken directly from this question about finding the filename from a filehandle.

Now that you have the filename (in $result) you can do a fileperms($result) on it to get the permissions out.

Note that fileperms() returns an int, and the documentation does the magic (actually just treating the int as an octal) of retaining that leading 0 (e.g. 0755).

Also note that the documentation does the magic of converting that int into a nice string like -rw-r--r--

like image 25
rockerest Avatar answered Sep 30 '22 18:09

rockerest