|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2018-01-24 14:31 UTC] bobonov at gmail dot com
Description: ------------ Checking the closed resource with: gettype() return resource (closed) get_resources() list it as resource is_resource() return false. There is an ancient Bug #42797 (php 4.3.6) that is relevant to this bug Test script: --------------- <?php $a = fopen('http://www.google.com', 'r'); echo "$a : the type is " . gettype($a)."\n"; // resource var_dump(is_resource($a)); // true print_r(get_resources()); fclose($a); echo "$a : the type is " . gettype($a)."\n"; // resource closed var_dump(is_resource($a)); // false print_r(get_resources()); Expected result: ---------------- I expect is_resource() to return true since get_resources() and gettype() see the var as resource Actual result: -------------- Resource id #6 : the type is resource bool(true) Array ( [1] => Resource id #1 [2] => Resource id #2 [3] => Resource id #3 [4] => Resource id #4 [6] => Resource id #6 ) Resource id #6 : the type is resource (closed) bool(false) Array ( [1] => Resource id #1 [2] => Resource id #2 [3] => Resource id #3 [4] => Resource id #4 [6] => Resource id #6 ) PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 16:00:02 2025 UTC |
In the title I reported it as "inconsistent result on closed resource". I know that is the intend behavior, as clearly reported in the documentation, but anyway it is a bug. While 2 function report it as still a resource, is_resource() say is not a resource. Yes gettype() report it as "resource (closed)" which in my opinion is a strange type since closed denote a status not a variable type, or at least resource type We have 3 different result checking the same variable is_resource() say is a resource gettype() report "resource (closed)" (which in php does not exist) get_resources() which still list it as resource To make more clear the inconsistent type checking by different function for a resource I made a bit more complete script (in which you can see that var_dump() get_resource_type() still see closed one as resource). In particular get_resource_type() give a warning when used to test a non resource type. "PHP Warning: get_resource_type() expects parameter 1 to be resource, string given" So if even the runtime see closed resource as resource... it is a resource <?php function testResource($a) { echo "$a\n"; echo "gettype(): " . gettype($a)."\n"; echo "is_resource():"; var_dump(is_resource($a)); echo "get_resource_type(): " . get_resource_type ( $a )."\n"; echo "get_resources():"; print_r(get_resources()); echo "var_dump():"; var_dump($a); } $a = fopen('http://www.google.com', 'r'); echo "OPEN resource\n"; testResource($a); fclose($a); echo "\n\n\nCLOSED resource\n"; testResource($a); ?> this script will produce the following result: OPEN resource Resource id #6 gettype(): resource is_resource():bool(true) get_resource_type(): stream get_resources():Array ( [1] => Resource id #1 [2] => Resource id #2 [3] => Resource id #3 [4] => Resource id #4 [6] => Resource id #6 ) var_dump():resource(6) of type (stream) CLOSED resource Resource id #6 gettype(): resource (closed) is_resource():bool(false) get_resource_type(): Unknown get_resources():Array ( [1] => Resource id #1 [2] => Resource id #2 [3] => Resource id #3 [4] => Resource id #4 [6] => Resource id #6 ) var_dump():resource(6) of type (Unknown) Probably the correct output (to make everything consistent and logic) for a closed resource should be: gettype(): resource is_resource():bool(true) get_resource_type(): closed var_dump():resource(6) of type (closed) All "resource provider" should change a resource type to closed when *close() is called.For the record, closed resources are "unknown type"s (or "resource (closed)" since PHP 7.2.0) according to gettype() and are not resources at all according to is_resource(), but these values are still reported as resource in the stack trace, for example: <?php // Set a safe environment: error_reporting(-1); // Maps errors to ErrorException. function my_error_handler($errno, $message) { throw new ErrorException($message); } set_error_handler("my_error_handler"); $f = fopen(__FILE__, "r"); fclose($f); fclose($f); # double close -- here fails, as expected ?> displays: PHP Fatal error: Uncaught exception 'ErrorException' with message 'fclose(): 5 is not a valid stream resource' in C:\Users\UmbertoSalsi\Desktop\php\resource.php:7 Stack trace: #0 [internal function]: my_error_handler(2, 'fclose(): 5 is ...', 'C:\\Users\\Umbert...', 13, Array) #1 C:\Users\UmbertoSalsi\Desktop\php\resource.php(13): fclose(Resource id #5) #2 {main} thrown in C:\Users\UmbertoSalsi\Desktop\php\resource.php on line 7 Fatal error: Uncaught exception 'ErrorException' with message 'fclose(): 5 is not a valid stream resource' in C:\Users\UmbertoSalsi\Desktop\php\resource.php:7 Stack trace: #0 [internal function]: my_error_handler(2, 'fclose(): 5 is ...', 'C:\\Users\\Umbert...', 13, Array) #1 C:\Users\UmbertoSalsi\Desktop\php\resource.php(13): fclose(Resource id #5) #2 {main} thrown in C:\Users\UmbertoSalsi\Desktop\php\resource.php on line 7 Note the "fclose(): 5 is not a valid stream resource" and then the following "fclose(Resource id #5)" above: it's all a bit confusing. I still do not understand what a program should do to safely detect the type of a value at runtime.Okay, were are we? We cannot change the behavior of is_resource() for stated reasons; we will not change the behavior of gettype() for BC reasons; we should document that get_resources() also includes closed resources in its return value ("all currently active resources" is indeed confusing). We should also document the concept of "closed resources" on the resources page. Other than that, we should convert all resources to objects; this work has already begun[1], but is still work in progress for time and BC reasons. [1] <https://www.php.net/manual/en/migration80.incompatible.php#migration80.incompatible.resource2object>