• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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.

    上篇:is_real()

    下篇:is_scalar()