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) => FALSE
Note 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.