php资源是通过引用传递的吗?
Posted
技术标签:
【中文标题】php资源是通过引用传递的吗?【英文标题】:Are php resources passed by reference? 【发布时间】:2013-04-25 14:08:42 【问题描述】:我今天发现,除了对象和原语,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);
【问题讨论】:
资源总是通过引用传递 资源是参考 【参考方案1】:不,默认情况下,它们不是通过引用传递,在这种情况下,它们将作为任何其他 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 引擎在文件关闭后将所有范围内的 all 引用重置为 $fd。这意味着从这种副作用的角度来看,它们可能与其他变量不完全相同。
【讨论】:
准确地说,在 PHP 中默认情况下不会通过引用传递任何内容。 @PEMapModder 不正确,对象通过引用传递。 @NinoŠkopac 您根本无法在 PHP 中传递对象。您只能传递对象引用。默认情况下,对象引用不会通过引用传递。比较function f(&$o) $o=new stdclass;
和function f($o) $o = new stdclass;
@NinoŠkopac 从这个意义上说,您实际上是在传递对象引用,这类似于资源引用。您仍在处理相同的最终基础数据,但传递 &$object
就像通过引用传递某物的引用。同时,PHP中不能对变量进行双重引用,即function f(&$a) $a = "b"; $b =& $c; f($b);
仍然会修改$c
,但如果$b = $object;
,则不会修改真正的$object。【参考方案2】:
资源不是实际的连接。资源只不过是指向连接的指针。因此,当您关闭属于该资源的连接时,无论是原始连接还是复制连接,行为都没有区别。
【讨论】:
说“没关系”并不能回答问题或指定行为。 在这种情况下,说没关系并不意味着“我不在乎”。这意味着他们之间的行为没有区别。我将编辑文本【参考方案3】:资源既不是对象也不是变量。它只是一个资源。基本上,这意味着您并没有真正与资源进行交互,例如一个对象。 PHP 文档本身说:
“由于资源变量包含打开文件、数据库连接、图像画布区域等的特殊处理程序,因此转换为资源没有任何意义。”
基本上,除非说您正在开发核心 Zend 引擎或为 PHP 创建扩展(如 PECL),否则您真的会非常担心资源问题。从 PHP 编码戳点来看,我们对资源做的唯一事情就是检查数据库连接尝试是否返回 NULL or a resource
您有一个名为get_resource_type()
的函数,它返回资源的type
,例如说“文件”以返回fopen()
函数,但它只是一个命名标识符,没有什么可解决的..
【讨论】:
@raidenance:“我们唯一一次在资源上做事”这部分没有多大意义。文件操作、外部连接等都使用资源。 @nvanesch:我的意思是当我们直接对资源进行操作时,比如if($myResource=="<something>")...
好吧,现在我明白了。我以为你的意思是像 fopen($fileResource, "Foo");
这样的东西几乎没有被使用过以上是关于php资源是通过引用传递的吗?的主要内容,如果未能解决你的问题,请参考以下文章