我今天发现,除了对象和原语之外,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);
}
}
答案 0 :(得分: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的所有引用。这意味着从这种副作用来看,它们可能与其他变量不完全相同。
答案 1 :(得分:5)
资源不是实际连接。资源只不过是指向连接的指针。因此,当您关闭属于此资源的连接时,无论它是原始连接还是复制的连接都无关紧要。
答案 2 :(得分:1)
资源既不是对象也不是变量。它只是一个资源。基本上,这意味着你不会像对象那样真正地与资源进行交互。 PHP文档本身说:
“由于资源变量拥有打开的文件,数据库连接,图像画布区域等的特殊处理程序,转换为资源是没有意义的。”
除非你说你正在研究核心Zend引擎或者像PECL那样为PHP创建扩展,否则你真的会担心资源问题。从PHP编码标记点开始,我们对资源执行操作的唯一时间就是检查是否返回了数据库连接尝试NULL or a resource
你有一个名为get_resource_type()
的函数,它返回type
这样的资源,比如说“file”,用于返回fopen()
函数,但它只是一个命名的标识符,并没有什么解决..