那么 php 中的引用传递究竟是如何工作的呢?

发布于 2024-10-09 13:04:28 字数 129 浏览 6 评论 0原文

非常简单的问题,但我不想寻求学术解释,而是希望尽可能保持务实:PHP何时创建我传递给函数的庞大类的副本,何时简单地创建指向相关数据的指针?如果它一直创建指针,那么指定 & 有什么用? (显然除了关闭之外)?我想我对翻译的胆量还不够了解。

Really simple question but rather than asking for an academic explanation I want to keep it as pragmatic as possible: when will PHP create a copy of my huge class I'm passing into a function and when will it simply create a pointer to the relevant data? And if it creates pointers all the time, what's the use of specifying & (aside from closures, obviously)? I guess I don't know enough about the guts of the interpreter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

翻了热茶 2024-10-16 13:04:28

在 PHP 5 中,所有对象都通过其句柄传递。是否通过引用传递与性能无关。 (事实上​​,手册中警告通过引用传递速度较慢。)您在函数内部处理的对象与函数外部指向的对象相同。

当您通过引用传递对象(句柄)时,您可以更改外部变量指向的内容。这几乎总是不必要的。

In PHP 5, all objects are passed by their handle. Whether you pass by reference or not is irrelevant in terms of performance. (In fact, passing by reference is warned to be slower in the manual.) The object you are working on inside the function is the same object as pointed to outside the function.

When you pass an object (handle) by reference, then you can alter what the outer variable points to. This is almost always unnecessary.

旧时浪漫 2024-10-16 13:04:28

& 运算符表示变量通过引用传递。

$x = 'Hello World';
echo($x);

function asdf(&$var){
  $var = 'Test';
}

asdf($x);
echo($x);

赋值和几乎任何其他语句也是如此。如果它不是通过引用传递或分配的,则假设它是通过值传递或分配的。

The & operator denotes a variable as being passed by reference.

$x = 'Hello World';
echo($x);

function asdf(&$var){
  $var = 'Test';
}

asdf($x);
echo($x);

Same goes for assignment and pretty much any other statement. If it isn't passed or assigned by reference, assume it is passed or assigned by value instead.

终止放荡 2024-10-16 13:04:28

为什么要为 & 烦恼,即使你可以随意这样做。这就是我的做法:

假设我有一个“Book”类,其中包含一些公共方法和属性,例如标题、作者、年份
然后简单地创建它的一个对象:

$book = new Book()
// then I can use all public methods and properties

$book->title;

$book->author;

$book->year;

如果我愿意,那么我可以创建一个子类,

class Novel extends Books{

  function buildIt(Book $bk){

      $bk->title;

      // so on 

  }

}

在函数 buildIt 中,我故意有一个 Book 'parameter' 的类对象,其中
我可以传递“Book”类的整个对象。

我希望这有帮助。

Why bother with &, even though you can do so as please. This is how I do:

Assume I have a class 'Book' with some public methods and properties like title, author, year
then to make an object of it simply:

$book = new Book()
// then I can use all public methods and properties

$book->title;

$book->author;

$book->year;

If I like to then I can make a subclass say

class Novel extends Books{

  function buildIt(Book $bk){

      $bk->title;

      // so on 

  }

}

In the function buildIt, I purposedly have an class object of Book 'parameter' in which
I can pass the whole object of class 'Book'.

I hope this help.

玩物 2024-10-16 13:04:28

您可以在 PHP 手册中找到很多通过引用传递变量的用法。最好的例子之一是 preg_match

preg_match 将返回输入字符串中模式匹配的出现次数。然后,如果提供的话,它将填充包含匹配项的引用 $matches 数组。

它可以被视为返回多个值的一种方式,尽管您应该小心这一点。每个示例:

class Server {

    protected $_clientId = 0;

    protected $_clients = array();

    /**
     * Get a pending connection.
     *
     * @param &$connection_id int The connection identifier.
     * @return resource The socket resource.
     */
    public function getNextClient(&$connection_id) {
        $clientSocket = socket_accept($this->_server);     
        $connection_id = $this->_clientId++; 
        $this->_clients[$connection_id] = $clientSocket;
        return $clientSocket;
    }

}

$server = new Server;
$socket1 = $server->getNextClient($id);
echo $id; // 0
$socket2 = $server->getNextClient($id);
echo $id; // 1

重要说明。默认情况下,对象是按引用传递的。 它们不会被克隆。即使没有在函数参数中指定 &,修改传递的对象也会导致原始对象也被修改。防止这种情况的唯一方法是在函数/方法中克隆对象。

You can find a lot of uses of passing a variable by reference in the PHP manual. One of the best examples is preg_match.

preg_match will return the number of occurrences a pattern has been matched in the input string. It will then populate, if provided, a referenced $matches array containing the matches.

It can be seen as a way to return more than one value, although you ought to be careful with that. Per example:

class Server {

    protected $_clientId = 0;

    protected $_clients = array();

    /**
     * Get a pending connection.
     *
     * @param &$connection_id int The connection identifier.
     * @return resource The socket resource.
     */
    public function getNextClient(&$connection_id) {
        $clientSocket = socket_accept($this->_server);     
        $connection_id = $this->_clientId++; 
        $this->_clients[$connection_id] = $clientSocket;
        return $clientSocket;
    }

}

$server = new Server;
$socket1 = $server->getNextClient($id);
echo $id; // 0
$socket2 = $server->getNextClient($id);
echo $id; // 1

Important note. Objects are passed-by-reference by default. They will not be cloned. Even without specifying the & in the function argument, modifying the passed object will result in the original object being modified as well. The only way to prevent this is to clone the object in the function/method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文