get_resource_id

Returns the unique integer identifier of a resource handle.

Signature
get_resource_id(resource $resource): int
  • Added in PHP 8.0

Parameters

ParameterTypeDescription
$resourceresourceThe 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.