代码之家  ›  专栏  ›  技术社区  ›  Mark

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

  •  0
  • Mark  · 技术社区  · 2 年前

    这里是我的代码:

    <?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 我理解“继承变量的值来自定义函数时,而不是调用时”,但在第一次调用后,变量不应该保留新值吗?

    2 回复  |  直到 2 年前
        1
  •  3
  •   CerebralFart    2 年前

    默认情况下,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'
    
        2
  •  2
  •   Vikas Biradargoudar    2 年前

    使用是早期绑定。这意味着变量值在定义闭包时被复制。所以修改 温度 闭包内部没有外部效果,除非它是一个指针,就像对象一样。 要修复它,你需要通过 温度 变量作为参考( &温度 ).

    $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);
    
    推荐文章