我今天发现,除了对象和基元之外,PHP还具有resources。该文档指出默认情况下为php passes names by value。但是我们知道,在PHP 5中,objects are referenced by handle等按值传递句柄时,您可以将句柄本身视为引用,从而巧妙地避免了问题。
但是资源呢?它们是像对象一样,本身只是被视为引用的句柄,还是它们实际在传递时被复制的值?
例如:
/**
* 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);
}
}
资源不是实际的连接。资源不过是指向连接的指针。因此,当您关闭属于该资源的连接时,无论是原始连接还是复制连接,其行为都没有区别。
否它们是not通过引用传递,在这种情况下,它们将像其他任何PHP变量一样进行处理。检查此示例:
function test($fd) {
$fd = NULL;
}
$fd = fopen('/tmp/test', 'w+');
test($fd);
var_dump(is_resource($fd)); // bool(true);
...但是根据资源的性质,它们指向single外部资源。这可以是文件,数据库连接或类似的东西。因此,对资源(或其副本)的任何操作都将直接影响该single外部资源。
检查此示例:
function close($fd) {
fclose($fd);
}
$fd = fopen('/tmp/test', 'w+');
close($fd);
var_dump(is_resource($fd)); // bool(false);
在上面的示例中,在文件关闭之后,PHP引擎在所有范围中将all引用重置为$ fd。这意味着,从这种副作用的角度来看,它们可能与其他变量不完全是same。
资源既不是对象也不是变量。它只是一个resource。基本上,这意味着您实际上没有像使用对象那样与资源进行交互。 PHP文档本身说:
“由于资源变量对打开的文件,数据库连接,图像画布区域等具有特殊的处理程序,因此转换为资源没有任何意义。”
[基本上,除非说您正在使用核心Zend Engine或为PECL这样的PHP创建扩展,否则您确实会非常担心资源。从PHP编码标记的角度来看,我们唯一一次在资源上做的事情就是检查数据库连接尝试是否返回了NULL or a resource
[您有一个名为get_resource_type()
的函数,它为返回type
函数而返回资源的fopen()
,例如说“文件”,但这只是一个命名的标识符,没有什么可解决的。]]