12

我今天发现除了对象和原语,PHP 还有资源。文档指出,默认情况下php 按值传递名称。但是我们知道,在 PHP 5 中,对象是由句柄引用的,因此当句柄是按值传递时,您可以将句柄本身视为引用,巧妙地避免了这个问题。

但是资源呢?它们是像对象一样只是句柄本身被视为引用,还是它们实际上是在传递时被复制的值?

例如:

/**
 * 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);
    }
}
4

3 回答 3

7

不,默认情况下它们不是通过引用传递的,在这种情况下它们被当作任何其他 PHP 变量处理。检查这个例子:

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

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

...但根据资源的性质,它们指向单个外部资源。这可以是一个文件、一个数据库连接或类似的东西。因此,对资源(或其副本)的任何操作都会对该单个外部资源产生直接影响。

检查这个例子:

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

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

在上面的示例中,PHP 引擎在文件关闭后重置所有范围内对 $fd的所有引用。这意味着从这种副作用的角度来看,它们可能与其他变量并不完全相同。

于 2013-05-01T15:00:12.523 回答
6

资源不是实际的连接。资源只不过是指向连接的指针。因此,当您关闭属于此资源的连接时,无论是原始连接还是复制连接,行为都没有区别。

于 2013-05-01T14:59:53.867 回答
1

资源既不是对象也不是变量。它只是一种资源。基本上,这意味着您并没有真正与资源进行交互,例如一个对象。PHP 文档本身说:

“由于资源变量对打开的文件、数据库连接、图像画布区域等拥有特殊的处理程序,因此转换为资源没有任何意义。”

基本上,除非说您正在开发核心 Zend 引擎或为 PHP 创建扩展(如 PECL),否则您真的会非常担心资源问题。从 PHP 编码戳点开始,我们对资源做的唯一事情就是检查是否返回了数据库连接尝试NULL or a resource

你有一个调用的函数get_resource_type(),它返回type资源,比如说“文件”来返回一个fopen()函数,但它只是一个命名标识符,没什么可解决的。

于 2013-05-01T14:58:21.113 回答