如何检查PHP流资源是可读还是可写?

时间:2022-10-17 17:10:02

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?

在PHP中,如何检查流资源(或文件指针,句柄或任何您想要调用它们)是可读还是可写?例如,如果您遇到的情况是您对资源的打开或创建方式一无所知,那么如何检查它是否可读?你怎么检查它是否可写?

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.

根据我所做的测试(只使用PHP 5.3.3的常规文本文件),当资源不可读时,fread()不会在任何级别抛出任何错误。它只返回一个空字符串,但它也为空文件执行此操作。理想情况下,最好使用不会修改资源本身的检查。通过尝试从中读取资源来测试资源是否可读将改变指针的位置。

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.

相反,当资源不可写时,fwrite()不会在任何级别抛出任何错误。它只返回零。这稍微有用,因为如果你试图将一定数量的字节写入文件并且fwrite()返回零,那么你就知道出了问题。但是,这仍然不是一种理想的方法,因为在我需要写入它之前知道它是否可写会更好,而不是试图写入它并查看它是否失败。

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.

这可能吗?有这样的事吗?我一直找不到任何有用的东西。提前感谢您的回答。

2 个解决方案

#1


25  

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

非常简单。只需从脚本中调用stream_get_meta_data($ resource),然后检查返回值的mode数组元素:

$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

#2


1  

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.

好的,所以这可能不是最好的解决方案,但我认为这已经足够了,因为PHP中没有任何东西可以自动完成。

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

对于第一步,您将从文件中获取资源的inode,然后读取文件名:

$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.

现在你有了文件名(在$ result中),你可以在其上执行一个fileperms($ result)来获取权限。

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).

请注意,fileperms()返回一个int,并且文档执行保留前导0(例如0755)的魔法(实际上只是将int视为八进制)。

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

另请注意,文档将将int转换为像-rw-r这样的好字符串的魔力 - r--

#1


25  

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

非常简单。只需从脚本中调用stream_get_meta_data($ resource),然后检查返回值的mode数组元素:

$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

#2


1  

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.

好的,所以这可能不是最好的解决方案,但我认为这已经足够了,因为PHP中没有任何东西可以自动完成。

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

对于第一步,您将从文件中获取资源的inode,然后读取文件名:

$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.

现在你有了文件名(在$ result中),你可以在其上执行一个fileperms($ result)来获取权限。

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).

请注意,fileperms()返回一个int,并且文档执行保留前导0(例如0755)的魔法(实际上只是将int视为八进制)。

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

另请注意,文档将将int转换为像-rw-r这样的好字符串的魔力 - r--