get_resource_id
Returns the unique integer identifier of a resource handle.
get_resource_id(resource $resource): int- Added in PHP 8.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$resource | resource | The evaluated resource handle. |
Return value
intThe integer identifier for the given resource.
Errors
Throws TypeError if $resource is not a resource.
A typed replacement for (int) $resource
Casting a resource to int has always yielded its internal handle number, but the cast is untyped: pass it a string, an object or false and you get 0, 1 or a warning instead of an error. get_resource_id(), added in PHP 8.0, does exactly the same conversion but declares resource as its parameter type, so anything else throws a TypeError at the call site. That is the entire reason it exists — use it wherever old code did an int cast on a handle.
What the id is good for
The id is a stable, unique integer for as long as the resource is open, which makes it a usable array key. Registries that need to attach metadata to a handle — a per-stream buffer, a timing record, a name for logging — key on it. It is the resource-world counterpart of spl_object_id() for objects.
The reuse trap
Ids are only unique among currently open resources. Once a handle is closed, PHP is free to hand its number to the next resource you open. A long-lived registry keyed by resource id must delete its entry at close time, or a new stream will inherit stale metadata belonging to a handle that no longer exists.
Example
When to use it
- Key a per-stream metadata array (buffer, filename, open timestamp) so helper functions can look up context from a bare handle.
- Include a stable handle number in debug log lines to trace which of several open streams a write went to.
- Replace legacy (int) $handle casts during a PHP 8 upgrade so bad arguments fail loudly instead of becoming 0.
Frequently asked questions
What is the difference between get_resource_id and casting a resource to int?
They return the same integer. get_resource_id() declares a resource parameter type, so passing anything else throws a TypeError instead of quietly producing 0 or 1 the way the cast does.
Are resource ids unique across a script run?
No, only among resources open at the same moment. PHP reuses the id of a closed resource for the next one you open, so remove any registry entry keyed by an id before closing its handle.
Is there an equivalent for objects?
Yes, spl_object_id() returns an integer handle for an object, and it has the same reuse caveat once the object is garbage collected. Use spl_object_hash() only if you need a string form.
More examples
Why it beats an int cast
The cast turns a failed fopen() into the integer 0 with no complaint, so a broken handle flows on into your registry as a valid-looking key. get_resource_id() throws a TypeError naming the argument, which is why it is the safer form in new code.
<?php
try {
get_resource_id('not a handle');
} catch (TypeError $e) {
echo 'TypeError: ', $e->getMessage(), "\n";
}
$bad = false; // what a failed fopen() returns
var_dump((int) $bad); // silently 0 - no error at all
$fh = fopen('php://memory', 'r+');
echo 'id = ', get_resource_id($fh), "\n";
fclose($fh);A registry keyed by resource id
Two open streams get distinct ids, so the registry looks each one up correctly. Note the unset() immediately before fclose(): dropping the entry at close time is what prevents a recycled id from resolving to the wrong label later.
<?php
$registry = [];
function track(array &$reg, $handle, string $label): void {
$reg[get_resource_id($handle)] = $label;
}
$log = fopen('php://memory', 'r+');
$cache = fopen('php://memory', 'r+');
track($registry, $log, 'log');
track($registry, $cache, 'cache');
echo $registry[get_resource_id($cache)], "\n";
unset($registry[get_resource_id($log)]);
fclose($log);
print_r($registry);The id survives closing, the resource does not
get_resource_id() still reports the same number for a closed handle, because the id lives in the resource wrapper rather than the underlying stream. is_resource() has already gone false and get_resource_type() reports "Unknown" — so never treat a non-zero id as proof the handle is usable.
<?php
$fh = fopen('php://memory', 'r+');
$id = get_resource_id($fh);
echo "while open: $id\n";
fclose($fh);
echo 'after close: ', get_resource_id($fh), "\n";
var_dump(is_resource($fh));
echo get_resource_type($fh), "\n";
Discussion