在PHP中使用引用
我问这个问题是因为我学到了在编程和设计中,你必须有一个很好的决策理由。我是php学习者,我正处在一个十字路口,我正在使用简单的增量来尝试理解我的要求。我当然不是在这里就引用的优缺点展开辩论,但说到php,哪一种编程实践更好:在PHP中使用引用,php,pass-by-reference,parameter-passing,pass-by-value,Php,Pass By Reference,Parameter Passing,Pass By Value,我问这个问题是因为我学到了在编程和设计中,你必须有一个很好的决策理由。我是php学习者,我正处在一个十字路口,我正在使用简单的增量来尝试理解我的要求。我当然不是在这里就引用的优缺点展开辩论,但说到php,哪一种编程实践更好: function increment(&$param) { ++$param; } vs 根据定义,增加变量的值(至少在PHP中)会使变量发生变异。它不接受值,将其增加1并返回;相反,它会更改保存该值的变量 因此,您的第一个示例将是更好的方法,因为它引
function increment(&$param) {
++$param;
}
vs
根据定义,增加变量的值(至少在PHP中)会使变量发生变异。它不接受值,将其增加1并返回;相反,它会更改保存该值的变量
因此,您的第一个示例将是更好的方法,因为它引用了
$param
的引用(PHP本身并不真正做指针)并对其进行后期递增
<?php
function increment(&$param){
$param++;
}
$param = 1;
$start = microtime();
for($i = 1; $i <= 1000000; $i++) {
increment($param);
}
$end = microtime();
echo $end - $start;
?>
这返回的值始终在.42到.43之间,其中如下代码返回的值约为.55到.59
<?php
function increment($param){
return $param++;
}
$param = 1;
$start = microtime();
for($i = 1; $i <= 1000000; $i++) {
$param = increment($param);
}
$end = microtime();
echo $end - $start;
?>
所以我想说,引用速度更快,但仅在极端情况下。我认为您的示例有点抽象
使用指针没有问题,但在大多数实际情况下,您可能是在修改对象而不是int,在这种情况下,您不需要引用(至少在PHP5中)。最好的做法是在表达式可用时不编写函数
$param++;
这就是你所需要的。我想这完全取决于你在做什么。如果您试图在不希望在内存中有额外副本的情况下对一大组数据进行交互,请按值传递(您的第二个示例)。如果要保存内存并直接与对象交互,请先通过引用传递(第一个示例) 我尝试了@John在回答中给出的代码,但得到了奇怪的结果。结果是
microtime()
返回一个字符串。算术是不可靠的,我甚至在一些测试中得到了否定的结果。应该使用microtime(true)
以浮点形式获取值
我添加了另一个没有函数调用的测试,只是增加了变量:
<?php
$param = 1;
$start = microtime(true);
for($i = 1; $i <= 1000000; $i++) {
$param++;
}
$end = microtime(true);
echo "increment: " . ($end - $start) . "\n";
这取决于函数的用途。如果其明确目的是修改输入,请使用引用。如果目的是基于输入计算某些数据,而不是改变输入,请务必使用常规的返回
例如:
此函数的明确目的是修改数组。您不太可能同时需要原始数组和包含推送值的数组副本
array_push($array, 42); // most likely use case
// if you really need both versions, just do:
$old = $array;
array_push($array, 42);
如果array\u push
没有引用,则需要执行以下操作:
// array_push($array, $var[, $...])
$array = array_push($array, 42); // quite a waste to do this every time
// pow(&$base, $exp)
$x = 123;
$y = $x; // nuisance
pow($y, 42);
另一方面,纯计算函数(如)不应修改原始值:
number pow(number $base, number $exp)
您可能更愿意在希望保持原始数字不变并基于其计算结果的上下文中使用此函数。在这种情况下,如果pow
修改了原始编号,则会造成麻烦
$x = 123;
$y = pow($x, 42); // most likely use case
如果pow
引用了引用,则需要执行以下操作:
// array_push($array, $var[, $...])
$array = array_push($array, 42); // quite a waste to do this every time
// pow(&$base, $exp)
$x = 123;
$y = $x; // nuisance
pow($y, 42);
第二个版本:
function increment($param){
return $param++;
}
$param = increment($param);
什么也不做。increment()返回$param。也许你的意思是++$param或$param+1
我提到这一点并不是为了显得迂腐,但如果你比较计时,你就是在比较同一个函数(PHP的优化器可能会完全删除该函数)。不错的测试,但在PHP5中,至少出于性能原因,你不应该使用指针。你应该使用microtime(true)
以浮点数而不是字符串形式返回时间。关于字符串值的算术是不可靠的。啊,很有道理。只需使用microtime(true)和1000000个测试(而不是100000个)重新运行测试。引用得到4.9-5.1,而返回函数得到5.5-5.7。您的函数什么都不做。它应该是return++$param代码>PHP的默认值是按值传递。因此,传递到函数中的值上的任何交互都保持在该范围内。IIRC PHP5的默认值是除对象外的所有对象上的按值传递,对象是按引用传递的。@jlindenbaum否,对象是按值传递的。实际上,通过值传递的是对象引用(或者在这种情况下,你可以称它们为“智能指针”;在本讨论的其余部分中,它们不是引用),对象从未被传递过,所以它似乎是通过引用传递的,但是它实际上是按值传递对象引用。顺便说一句,OP的第一个示例指定按引用传递$param。reference!=更好的建议:apple
或peach
?sof警察来了。为什么你必须尝试关闭每一个出于真正好奇的问题,因为你认为它不值得回答?似乎你在问,通过引用还是通过价值传递更好。这不是非此即彼。这类似于询问您是否应该使用include或require。这取决于你具体想完成什么。顺便说一句,我知道这只是一个例子,但第二个函数不会达到你的预期。您需要返回+++$param代码>:)我相信他只是举了个例子,他并不打算使用那个确切的函数。@John:这就是程序员和哲学家的主要区别:程序员解决特定的任务。没有澄清,这是对所问问题的最佳答案。@zerkms OP明确表示,他正在以它为例:我正在使用简单的递增法,试图让我所问的内容在
@zerkms中得到体现。问题的措辞可以大幅度改进,但我认为问题的重点显然是($param)
vs(&$param)
部分,$param++
只是一个占位符,也可以是/*做点什么*/
@deceze:答案应该取决于任务,而不是任何最佳实践。程序员应该根据“&”选择最合适的实现性质和基本任务:如果函数应该返回int,那么它应该是