kojiro
kojiro

Reputation: 77137

Are php resources passed by reference?

I discovered today that in addition to objects and primitives, PHP has resources. The documentation states that by default php passes names by value. But we know that in PHP 5, objects are referenced by handle, and so while the handle is passed by value, you can treat the handles as references themselves, neatly avoiding the question.

But what about resources? Are they, like objects, just handles to be treated as references themselves, or are they actually values that get copied when they're passed?

For example:

/**
 * Close the ftp connection and throw an exception.
 *
 * @hack Because php doesn't have a `finally` statement,
 *       we workaround it to make sure the ftp connection is closed.
 * @param resource $conn FTP Buffer
 * @param Exception $e
 */
function ftpCloseWithException($conn, $e) {
    ftp_close($conn); // <-- Is this the same FTP Buffer resource or a new one?
    throw $e;
}
/**
 * Copy the README file from ftp.mozilla.org or do something equally arbitrary using ftp.
 */
function getMozReadme() {
    try {
        $conn = ftp_connect('ftp.mozilla.org');
        …
    } catch (Exception $e) {
        ftpCloseWithException($conn, $e);
    }
}

Upvotes: 12

Views: 3098

Answers (3)

nvanesch
nvanesch

Reputation: 2600

A resource is not the actual connection. A resource is nothing more than a pointer to a connection. So when you close the connection belonging to this resource, there is no difference in behavior if it was original or a copied one.

Upvotes: 6

hek2mgl
hek2mgl

Reputation: 158070

No they are not passed by reference by default, they are handled as any other PHP variable in this case. Check this example:

function test($fd) {
    $fd = NULL;
}

$fd = fopen('/tmp/test', 'w+');
test($fd);
var_dump(is_resource($fd)); // bool(true);

... but it's by the nature of resources they point to a single outer resource. This can be a file, a database connection or something like this. So any operations on a resource (or a copy of it) would have direct effect on that single outer resource.

Check this example:

function close($fd) {
    fclose($fd);
}

$fd = fopen('/tmp/test', 'w+');
close($fd);
var_dump(is_resource($fd)); // bool(false);

In the above example, the PHP engine resets the all references to $fd in all scopes after the files has been closed. This means from the sight of this side effect they may not being exactly the same as other variables.

Upvotes: 8

raidenace
raidenace

Reputation: 12836

A resource is neither an object nor a variable. It is just a resource. Basically what this means is that you do not really interact with resources the way you could do with, say an object. The PHP documentation itself says:

"As resource variables hold special handlers to opened files, database connections, image canvas areas and the like, converting to a resource makes no sense."

Basically unless say you are working on the core Zend Engine or creating extensions for PHP like PECL, you would really worry much about resource. From a PHP coding stamp point the only time we do stuff on resources is say to check if a database connection attempt returned NULL or a resource

You have a function called get_resource_type() which returns the type of resource like say "file" for the return of an fopen() function but it is just a named identifier and nothing much to work out off..

Upvotes: 1

Related Questions