In-depth understanding of the Runtime Context of PHP anonymous function keyword use

When defining anonymous functions in PHP, you can use the use keyword to introduce external variables, and also support scalar value transfer/reference transfer

<?php
$msg = "hello world";

$foo = function () use ($msg) {
    echo $msg . PHP_EOL
};

$bar = function () use (&$msg) {
    echo $msg . PHP_EOL
};

But the use keyword has a small gotcha when using it:

In pass-by-value mode, the value of the variable in the current runtime context is introduced, and it does not dynamically obtain the latest value of the variable in the runtime context when you call this function later.

Code example:

<?php

$msg = "hello world";

$foo = function() use (&$msg)
{
    $msg = "modified by foo";
    echo $msg . PHP_EOL;
};

// 定义时就已经获取了当前上下文中 $msg 的值
// 后续 $msg 的变动并不能影响到这里定义时 use 的 $msg
$bar = function () use ($msg)
{
    echo $msg . PHP_EOL;
};

// 获取的为 $msg 的引用
$zoo = function () use (&$msg)
{
    echo $msg . PHP_EOL;
};

$foo();

// foo 虽然修改了 $msg
// 但 bar 使用的 msg 在定义时就已经被值传递了
// 很多人会误以为此时 bar 才被调用,此时 bar 才会去获取 $msg 的值然后 used
// 其实不然 bar 在定义是就已经 used 了上下文中的 $msg
// 所以这里输出的为 hello world 而非期望的 modified by foo
$bar();

// zoo 传入的为 msg 的引用 故可以获取 msg 当前运行时的值
$zoo();

// 此时上下文中的 $msg 已被 foo 更新
$bar_delay = function () use ($msg)
{
    echo $msg . PHP_EOL;
};

$bar_delay();

Although foo changes the value of $msg in memory, the $msg used by bar when running is copied by the value in the definition of bar, so bar will not be affected by foo, and zoo introduces a reference to $msg, Therefore, the latest value of $msg can be obtained in real time

At this point, the redefined bar_delay and the introduced $msg have been modified by foo in the Runtime Context.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325048033&siteId=291194637