父变量上的 array_push 在每次调用时都会被清除

问题描述 投票:0回答:1

这是我的代码:

<?php 
require('vendor/autoload.php');
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;

$temperature = array();

$server   = '<address>';
$port     = 1883;
$clientId = 'id';

$connectionSettings = (new ConnectionSettings)
  ->setKeepAliveInterval(60)
  ->setLastWillQualityOfService(1);

  $mqtt = new MqttClient($server, $port, $clientId, MqttClient::MQTT_3_1);
  $mqtt->connect($connectionSettings, true);

$mqtt->subscribe('foo', function ($topic, $message) use ($temperature) {
    printf("Received message on topic [%s]: %s\n", $topic, $message);
    $obj = json_decode($message);

    array_push($temperature, floatval($obj->temp));
    echo count($temperature);
}, 0);

$mqtt->loop(true);

我运行这个片段:

php mqtt_recv.php

然后我向上面的主题发送几条消息,输出是:

Received message on topic [foo]: {"temp":"20.0"}
1
Received message on topic [foo]: {"temp":"20.2"}
1
Received message on topic [foo]: {"temp":"20.4"}
1
Received message on topic [foo]: {"temp":"20.6"}
1

为什么每次调用时父变量

$temperature
都会被清除?

我很确定这取决于

use
的使用,因为在根级别执行相同的操作会导致预期的行为。阅读docs我理解“继承变量的值来自定义函数时,而不是调用时”,但是在第一次调用之后,变量不应该保留新值吗?

php anonymous-function
1个回答
0
投票

默认情况下,PHP 中的匿名函数通过值继承,而不是通过引用继承。因此,当您修改

$temperature
变量时,您只是更改了本地值。要通过引用传递值,您需要在其前面加上 & 符号 (
&
)。下面的示例演示了这种行为,取自您链接的文档页面中的示例 #3。

// Inherit by-reference
$message = 'hello';
$example = function () use (&$message) {
    var_dump($message);
};
$example(); // 'hello'

// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
$example(); // 'world'
© www.soinside.com 2019 - 2024. All rights reserved.