Here my code:
<?php
require('vendor/autoload.php');
use PhpMqttClientMqttClient;
use PhpMqttClientConnectionSettings;
$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]: %sn", $topic, $message);
$obj = json_decode($message);
array_push($temperature, floatval($obj->temp));
echo count($temperature);
}, 0);
$mqtt->loop(true);
I run this snipped with:
php mqtt_recv.php
then I send several message to the above topic, and the output is:
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
why on each call the parent variable $temperature
is cleared?
I’m pretty sure it depends from the use of use
because doing the same at root level leads to the expected behavior. Reading the docs I understand the "Inherited variable’s value is from when the function is defined, not when called" but after the first call, should not the variable keep the new values?
2
Answers
By default, anonymous functions in PHP inherit by value, not by reference. So when you’re modifying the
$temperature
-variable, you’re only changing the local value. To pass a value by reference, you need to prefix it with an ampersand (&
). The example below demonstrates this behavior and is taken from example #3 in the documentation page you linked.use is early binding. That means the variable values are COPIED upon DEFINING the closure. So modifying $temperature inside the closure has no external effect, unless it is a pointer, like an object is.
To fix it, you need to pass $temperature variable as reference(&$temperature).