Как проверить, доступен ли ресурс потока PHP для чтения или записи?

В PHP, как проверить, является ли ресурс потока (или указателем на файл, дескриптором или тем, что вы хотите назвать), является либо читаемым, либо доступным для записи? Например, если вы столкнулись с ситуацией, когда вы ничего не знаете о том, как был открыт или создан ресурс, как вы проверяете, является ли он доступным для чтения? И как вы проверяете, доступна ли запись?

Основываясь на тестировании, которое я сделал (только с обычными текстовыми файлами с использованием PHP 5.3.3), fread() не бросает никаких ошибок на любом уровне, когда ресурс не читается. Он просто возвращает пустую строку, но также делает это для пустого файла. И в идеале было бы лучше иметь чек, который не будет изменять сам ресурс. Тестирование, если ресурс читается, пытаясь прочитать его, изменит положение указателя.

И наоборот, fwrite() не создает ошибок на любом уровне, когда ресурс недоступен для записи. Он просто возвращает ноль. Это немного более полезно, потому что если вы пытались записать определенное количество байтов в файл, а fwrite() возвращает ноль, вы знаете, что что-то пошло не так. Но тем не менее, это не идеальный метод, потому что было бы намного лучше знать, если он доступен для записи, прежде чем мне нужно будет написать ему, а не пытаться написать ему и посмотреть, не сработает ли он.

Кроме того, в идеале проверка должна работать на любом ресурсе потока, а не только на файлах.

Это возможно? Есть ли что-нибудь подобное? Я не смог найти ничего полезного. Заранее благодарю за ваши ответы.

Довольно просто. Просто вызовите stream_get_meta_data($resource) из вашего скрипта, затем проверьте элемент массива mode возвращаемого значения:

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

И если вы хотите узнать, доступны ли базовые данные:

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

Хорошо, так что это может быть не лучшее решение, но я думаю, этого достаточно, учитывая, что в PHP нет ничего, что можно было бы сделать это автоматически.

На первом этапе вы получите inode ресурса из файла, а затем прочитайте имя файла:

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

Возникает непосредственно из этого вопроса об обнаружении имени файла из дескриптора файла .

Теперь, когда у вас есть имя файла (в $result ), вы можете сделать fileperms($result) на нем, чтобы получить разрешения.

Обратите внимание, что fileperms () возвращает int, и в документации делается волшебство (на самом деле просто обрабатывается int как восьмеричное) для сохранения ведущего 0 (например, 0755).

Также обратите внимание, что в документации делается магия преобразования этого int в красивую строку, такую ​​как -rw-r--r--