is_resource()
(PHP 4, PHP 5, PHP 7)
检测变量是否为资源类型
描述
is_resource(mixed $var): bool
如果给出的参数$var是resource类型,is_resource()返回TRUE,否则返回FALSE。
查看resource类型文档获取更多的信息。
I was recently trying to loop through some objects and convert them to arrays so that I could encode them to json strings.
I was running into issues when an element of one of my objects was a SoapClient. As it turns out, json_encode() doesn't like any resources to be passed to it. My simple fix was to use is_resource() to determine whether or not the variable I was looking at was a resource.
I quickly realized that is_resource() returns false for two out of the 3 resources that are typically in a SoapClient object. If the resource type is 'Unknown' according to var_dump() and get_resource_type(), is_resource() doesn't think that the variable is a resource!
My work around for this was to use get_resource_type() instead of is_resource(), but that function throws an error if the variable you're checking isn't a resource.
So how are you supposed to know when a variable is a resource if is_resource() is unreliable, and get_resource_type() gives errors if you don't pass it a resource?
I ended up doing something like this:
<?php
function isResource ($possibleResource) { return !is_null(@get_resource_type($possibleResource)); }
?>
The @ operator suppresses the errors thrown by get_resource_type() so it returns null if $possibleResource isn't a resource.
I spent way too long trying to figure this stuff out, so I hope this comment helps someone out if they run into the same problem I did.Try this to know behavior:
<?php
function resource_test($resource, $name) {
  echo 
    '[' . $name. ']',
    PHP_EOL,
    '(bool)$resource => ',
    $resource ? 'TRUE' : 'FALSE',
    PHP_EOL,
    'get_resource_type($resource) => ',
    get_resource_type($resource) ?: 'FALSE',
    PHP_EOL,
    'is_resoruce($resource) => ',
    is_resource($resource) ? 'TRUE' : 'FALSE',
    PHP_EOL,
    PHP_EOL
  ;
}
 
$resource = tmpfile();
resource_test($resource, 'Check Valid Resource');
 
fclose($resource);
resource_test($resource, 'Check Released Resource');
 
$resource = null;
resource_test($resource, 'Check NULL');
?>
It will be shown as...
[Check Valid Resource]
(bool)$resource => TRUE
get_resource_type($resource) => stream
is_resoruce($resource) => TRUE
[Check Released Resource]
(bool)$resource => TRUE
get_resource_type($resource) => Unknown
is_resoruce($resource) => FALSE
[Check NULL]
(bool)$resource => FALSE
get_resource_type($resource) => FALSE
Warning: get_resource_type() expects parameter 1 to be resource, null given in ... on line 10
is_resoruce($resource) => FALSENote that is_resource() is unreliable. It considers closed resources as false:
<?php
$a = fopen('http://www.google.com', 'r');
var_dump(is_resource($a)); var_dump(is_scalar($a));
//bool(true)
//bool(false)
fclose($a);
var_dump(is_resource($a)); var_dump(is_scalar($a));
//bool(false)
//bool(false)
?>
That's the reason why some other people here have been confused and devised some complex (bad) "solutions" to detect resources...
There's a much better solution... In fact, I just showed it above, but here it is again with a more complete example:
<?php
$a = fopen('http://www.google.com', 'r');
var_dump(is_resource($a)); var_dump(is_scalar($a)); var_dump(is_object($a)); var_dump(is_array($a)); var_dump(is_null($a));
//bool(true)
//bool(false)
//bool(false)
//bool(false)
//bool(false)
?>
So how do you check if something is a resource?
Like this!
<?php
$a = fopen('http://www.google.com', 'r');
$isResource = is_resource($a) || ($a !== null && !is_scalar($a) && !is_array($a) && !is_object($a));
var_dump($isResource);
//bool(true)
fclose($a);
var_dump(is_resource($a));
//bool(false)
$isResource = is_resource($a) || ($a !== null && !is_scalar($a) && !is_array($a) && !is_object($a));
var_dump($isResource);
//bool(true)
?>
How it works:
- An active resource is a resource, so check that first for efficiency.
- Then branch to check what the variable is NOT:
- A resource is never NULL. (We do that check via `!== null` for efficiency).
- A resource is never Scalar (int, float, string, bool).
- A resource is never an array.
- A resource is never an object.
- Only one variable type remains if all of the above checks succeeded: IF it's NOT any of the above, then it's a closed resource!
Just surfed by and saw the bad and hacky methods other people had left, and wanted to help out with this proper technique. Good luck, everyone!
PS: The core problem is that is_resource() does a "loose" check for "living resource". I wish that it had a $strict parameter for "any resource" instead of these user-workarounds being necessary.