is_resource()
Функция is_resource() в PHP проверяет, является ли переменная ресурсом — дескриптором файла, соединения с БД и т.д.
Введение
is_resource() — встроенная функция PHP, которая проверяет, содержит ли переменная ресурс. Ресурс — это особый тип PHP, который выступает в роли дескриптора чего-то, живущего за пределами самого PHP: открытого файла, соединения с базой данных, сетевого сокета или изображения, создаваемого в памяти. Значение ресурса нельзя напрямую проинспектировать так, как строку или массив; его можно только передавать функциям, которые умеют с ним работать (fread(), fclose() и другим).
is_resource() возвращает true, если переменная является открытым ресурсом, и false для любого другого типа, включая уже закрытый ресурс. На этой странице рассматриваются синтаксис, поведение во время выполнения, важное изменение в PHP 8, которое нужно знать, а также связь с другими функциями проверки типов.
Синтаксис
is_resource(mixed $value): boolФункция принимает один аргумент — переменную, которую нужно проверить, — и возвращает boolean. Она никогда не выбрасывает исключений и не изменяет свой аргумент, поэтому её безопасно вызывать с любым значением.
Пример использования
Дескриптор файла, возвращаемый fopen(), — наиболее распространённый ресурс, с которым вы столкнётесь:
<?php
$handle = fopen("php://temp", "r"); // a real, open resource
$text = "hello"; // a plain string
var_dump(is_resource($handle)); // bool(true)
var_dump(is_resource($text)); // bool(false)
fclose($handle);
?>Используйте var_dump() вместо echo: true выводится как 1, а false — как пустая строка, что легко ввести в заблуждение. var_dump() печатает тип и значение без двусмысленности.
Закрытый ресурс больше не является ресурсом
Это ловушка, в которую попадают многие. Как только вы закрываете дескриптор, is_resource() возвращает для него false — он не остаётся true. Это делает функцию удобным защитным условием против повторного использования дескриптора:
<?php
$handle = fopen("php://temp", "w");
var_dump(is_resource($handle)); // bool(true)
fclose($handle);
var_dump(is_resource($handle)); // bool(false) — already closed
?>Проверка через is_resource() перед fwrite() или повторным fclose() предотвращает предупреждения «supplied resource is not a valid stream resource».
Изменение в PHP 8: многие ресурсы теперь являются объектами
В PHP 8.0 большое количество встроенных расширений было переведено с ресурсов на непрозрачные объекты. Дескрипторы Curl, изображения GD и ряд других бывших ресурсов теперь являются объектами, поэтому is_resource() возвращает для них false, даже если концептуально они ведут себя так же:
<?php
$ch = curl_init(); // PHP 7: a resource — PHP 8: a CurlHandle object
var_dump(is_resource($ch)); // bool(false) on PHP 8+
var_dump(is_object($ch)); // bool(true) on PHP 8+
?>Если вы поддерживаете код, работающий на PHP 7 и PHP 8 одновременно, не предполагайте, что дескриптор curl или GD является ресурсом. Проверяйте конкретный ожидаемый тип или принимайте оба варианта через is_resource($x) || is_object($x).
Определение типа ресурса
Когда is_resource() возвращает true, get_resource_type() сообщает, какого рода этот ресурс — "stream" для файлов, "curl" в PHP 7, "gd" для изображений и т.д.:
<?php
$handle = fopen("php://temp", "r");
echo get_resource_type($handle), "\n"; // stream
fclose($handle);
?>Когда это использовать?
- Защитные проверки. Перед вызовом
fread(),fwrite()илиfclose()для значения, которое вы не создавали сами, убедитесь, что ресурс всё ещё открыт. - Функции, принимающие «дескриптор или путь». Вспомогательная функция может принимать как строку с именем файла, так и уже открытый дескриптор;
is_resource()позволяет разветвить логику в зависимости от того, что было передано. - Логика очистки. В блоке
finallyили деструкторе конструкцияif (is_resource($h)) fclose($h);предотвращает двойное закрытие дескриптора.
Связанные функции
is_resource() — одна из функций-предикатов проверки типов в PHP. Для других типов используйте is_object(), is_array() или is_string(). Если вам нужно имя типа в виде строки, а не булевая проверка, используйте gettype(), которая возвращает "resource" (или "resource (closed)") для дескрипторов.
Заключение
is_resource() подтверждает, что переменная является открытым дескриптором внешнего ресурса, возвращая false для закрытых дескрипторов и для любого другого типа. Главное, что нужно помнить в современном PHP: начиная с PHP 8, многие бывшие ресурсы — дескрипторы curl и GD в их числе — стали объектами, поэтому при разработке под PHP 8+ проверяйте их через is_object() (или оба варианта сразу).