【问题标题】:When is it good to use pass by reference in PHP?什么时候在 PHP 中使用传递引用比较好?
【发布时间】:2019-06-06 12:25:46
【问题描述】:

在 C++ 中如果你将一个大数组传递给一个函数,你需要通过引用来传递它,这样它就不会被复制到新的函数中浪费内存。如果您不想修改它,请通过 const 引用传递它。

任何人都可以验证通过引用传递也可以节省我在 PHP 中的内存。我知道 PHP 不使用 C++ 之类的引用地址,这就是为什么我有点不确定。这就是问题。

【问题讨论】:

  • 只是一个与 C++ 相关的注释:传递给函数的数组实际上是指针,因此传递对它们的引用是不必要的,并且实际上并没有像您认为的那样做。不过完全同意 const!

标签: php


【解决方案1】:

在 PHP 中:

  • 对象通过引用传递1 -- 总是
  • 数组和标量默认按值传递;并且可以传递by reference,在函数声明中使用&


对于您问题的性能部分,PHP 的处理方式与 C/C++ 不同;您应该阅读以下文章:Do not use PHP references


1. 或者这就是我们通常所说的——即使它不是“完全正确”——见Objects and references

【讨论】:

  • 我有点困惑..这是否意味着我可以创建一个单例类并将引用传递给站点的每个访问者,而不是为每个访问者查询数据库? (所有访问者都在请求相同的数据)
  • 在 PHP 中,您不会有一个单例“每个服务器”——而是一个单例“每次执行脚本”。每个用户都有自己独特的、独立的脚本执行——这意味着每个用户都有自己的内存空间;您的单例将是脚本执行一次的单例;并且脚本的每次执行都会有自己的单例实例。
  • 那太可悲了.. 在 php 中有这样的功能会很棒。谢谢。
  • 除非您将数据序列化到数据库或磁盘中。
  • 您可以使用缓存模块以您描述的方式缓存数据。
【解决方案2】:

以下内容不适用于对象,因为已在此处说明。如果您打算修改传递的值,则通过引用传递数组和标量值只会为您节省内存,因为 PHP 使用更改时复制(也称为写时复制)策略。例如:

# $array will not be copied, because it is not modified.
function foo($array) {
    echo $array[0];
}

# $array will be copied, because it is modified.
function bar($array) {
    $array[0] += 1;
    echo $array[0] + $array[1];
}

# This is how bar shoudl've been implemented in the first place.
function baz($array) {
    $temp = $array[0] + 1;
    echo $temp + $array[1];
}


# This would also work (passing the array by reference), but has a serious 
#side-effect which you may not want, but $array is not copied here.
function foobar(&$array) {
    $array[0] += 1;
    echo $array[0] + $array[1];
}

总结一下:

  • 如果您正在处理一个非常大的数组并计划在函数内修改它,您实际上应该使用引用来防止它被复制,这会严重降低性能甚至耗尽您的内存限制。

  • 1234563确定在函数调用之后传递的变量可能包含什么,这有时会导致令人讨厌且难以发现的错误。
  • 恕我直言,标量值永远不应通过引用传递,因为性能影响不能大到足以证明代码中失去透明度是合理的。

【讨论】:

【解决方案3】:

简短的回答是在您需要它们提供的功能 时使用参考。不要从内存使用或速度方面考虑它们。如果变量是只读的,通过引用传递总是会变慢。

一切都是按值传递的,包括对象。但是,传递的是对象的句柄,所以人们经常错误地将其称为引用,因为它看起来像那样。

那么它提供了哪些功能呢?它使您能够在调用范围内修改变量:

class Bar {}
$bar = new Bar();

function by_val($o) { $o = null; }
function by_ref(&$o) { $o = null; }

by_val($bar); // $bar is still non null
by_ref($bar); // $bar is now null

因此,如果您需要此类功能(通常不需要),请使用参考。否则,只传值。

如下所示的函数:

$foo = modify_me($foo);

有时是传递引用的好选择,但应该绝对清楚该函数修改了传入的变量。 (如果这样的函数有用,通常是因为它真的应该只是某个修改自己私有数据的类的一部分。)

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 1970-01-01
    • 2013-11-08
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    相关资源
    最近更新 更多