作者:人心城府深我如z何故做清纯 | 来源:互联网 | 2023-05-31 18:21
我有一个功能:$querySELECT*fromlol;database_query($query);考虑到$query永远不会在database_query函数内部进行更改,
我有一个功能:
$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的链接让我开始).
要回答你的问题,是的 – 当你调用一个函数时,最好使用类似的引用.通过使用引用,您将使用更少的资源 – 参考变量没有“写入时复制”.这是一些证明:
function noref_nowrite($var_a){
echo 'NOT Using a Reference/Not Changing Data
';
echo ''. xdebug_debug_zval('var_a') .'
';
echo ''. debug_zval_dump($var_a) .'
';
echo '$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'
';
}
function noref_write($var_a){
$var_a++;
echo 'NOT Using a Reference/Changing Data
';
echo ''. xdebug_debug_zval('var_a') .'
';
echo ''. debug_zval_dump($var_a) .'
';
echo '$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'
';
}
function ref_nowrite(&$var_a){
echo 'Using a Reference/Not Changing Data
';
echo ''. xdebug_debug_zval('var_a') .'
';
echo ''. debug_zval_dump($var_a) .'
';
echo '$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'
';
}
function ref_write(&$var_a){
$var_a++;
echo 'Using a Reference/Changing Data
';
echo ''. xdebug_debug_zval('var_a') .'
';
echo ''. debug_zval_dump($var_a) .'
';
echo '$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'
';
}
$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