微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 使用引用布置简单函数是一种好习惯

我有一个功能

$query = "SELECT * from lol";
database_query( $query );

考虑到$query永远不会在database_query函数内部进行更改,使用指向$query的指针是不错的做法,这样函数不需要为传入的值的新迭代分配更多内存?

function database_query( &$query ){
    //do stuff that does not affect $query
}

解决方法:

这是一个非常有趣的问题,我花了最后一个半小时阅读PHP以及它如何处理引用(感谢Tim Cooper的链接让我开始).

要回答你的问题,是的 – 当你调用一个函数时,最好使用类似的引用.通过使用引用,您将使用更少的资源 – 参考变量没有“写入时复制”.这是一些证明:

<?PHP
function noref_Nowrite($var_a){
    echo '<h3>NOT Using a Reference/Not Changing Data</h3>';
    echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
    echo '<p>'. debug_zval_dump($var_a) .'</p>';
    echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
function noref_write($var_a){
    $var_a++;
    echo '<h3>NOT Using a Reference/Changing Data</h3>';
    echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
    echo '<p>'. debug_zval_dump($var_a) .'</p>';
    echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}

function ref_Nowrite(&$var_a){
    echo '<h3>Using a Reference/Not Changing Data</h3>';
    echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
    echo '<p>'. debug_zval_dump($var_a) .'</p>';
    echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
function ref_write(&$var_a){
    $var_a++;
    echo '<h3>Using a Reference/Changing Data</h3>';
    echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
    echo '<p>'. debug_zval_dump($var_a) .'</p>';
    echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}

$a = 5;
noref_Nowrite($a);
noref_write($a);
ref_Nowrite($a);
ref_write($a);
?>

如果您将上述代码复制/粘贴到PHP页面并执行它,您将看到:

NOT Using a Reference/Not Changing Data
var_a: (refcount=3, is_ref=0)=5
long(5) refcount(4)

$var_a = 5 and $GLOBALS[a] = 5


NOT Using a Reference/Changing Data
var_a: (refcount=1, is_ref=0)=6
long(6) refcount(2)
$var_a = 6 and $GLOBALS[a] = 5

Using a Reference/Not Changing Data
var_a: (refcount=3, is_ref=1)=5
long(5) refcount(1)
$var_a = 5 and $GLOBALS[a] = 5

Using a Reference/Changing Data
var_a: (refcount=3, is_ref=1)=6
long(6) refcount(1)
$var_a = 6 and $GLOBALS[a] = 6

所以我们这里有四个基本测试.我创建一个全局变量($a)并为其赋值5.

当我调用noref_Nowrite函数时,我们看到XDebug计算3个引用,而PHP的内置函数计数为4.有趣的是,PHP在内部优化它就像调用ref_Nowrite函数一样,因为PHP使$var_a引用$GLOBALS [‘a’] .

当我调用noref_write函数时,我们看到refcount降为1(如果你看看PHP的内置函数,则为2).为什么?因为这是发生“写入时复制”问题的地方.直到我们增加$var_a PHP在内部使用$var_a作为对$a的引用但是当我们更改了值时,我们强制PHP生成变量的副本,以便它可以递增.所以在这一点上,$var_a不再是对$a的引用,而是改为引用它自己的数据.

ref_Nowrite函数显示不明确的结果.单单看它我们无法证明什么.然而,ref_write函数告诉我们XDebug说我们正在处理一个引用变量(is_ref = 1),最重要的是我们看到在我们增加$var_a后,我们的全局变量$a的值也发生了变化 – 这意味着$var_a和$GLOBALS [‘a’]肯定指向内存中的同一个地方.这意味着更改$var_a不会触发“写入时复制”的情况 – 而且它不应该因为我们正在处理引用.

玩这个来说服自己,这里有更多的阅读:

Detecting whether a PHP variable is a reference / referenced(我认为ircmaxell有一个深思熟虑的答案)

http://us2.php.net/debug-zval-dump

XDebug文档:http://xdebug.org/docs/display

PHP参考文献的内容http://us3.php.net/manual/en/language.references.whatdo.php

PHP参考计数基础:http://us3.php.net/manual/en/features.gc.refcounting-basics.php

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐