array_push on an parent variable is cleared on each call

Advertisements

Here my code:

<?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);

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?

>Solution :

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.

// 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'

Leave a ReplyCancel reply