Aqui meu código:
<?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);
Eu executo este recorte com:
php mqtt_recv.php
então envio várias mensagens para o tópico acima e o resultado é:
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
por que em cada chamada a variável pai $temperature
é limpa?
Tenho certeza de que depende do uso, use
porque fazer o mesmo no nível raiz leva ao comportamento esperado. Lendo a documentação entendi que "O valor da variável herdada é de quando a função é definida, não quando chamada", mas após a primeira chamada, a variável não deveria manter os novos valores?
Por padrão, funções anônimas em PHP herdam a maioria dos argumentos por valor, não por referência. (Apenas objetos são passados por referência.) Portanto, quando você modifica a
$temperature
variável -, está alterando apenas o valor local. Para passar um valor por referência, você precisa prefixá-lo com um e comercial (&
). O exemplo abaixo demonstra esse comportamento e foi retirado do exemplo nº 3 na página de documentação que você vinculou.o uso é vinculativo antecipado. Isso significa que os valores das variáveis são COPIADOS ao DEFINIR o fechamento. Portanto, modificar $temperature dentro do fechamento não tem efeito externo, a menos que seja um ponteiro, como um objeto. Para consertar, você precisa passar a variável $temperature como referência( &$temperature ).