aldas / modbus-tcp-client

PHP client for Modbus TCP and Modbus RTU over TCP (can be used for serial)
Apache License 2.0
191 stars 55 forks source link

Exception array_merge(): Argument #1 must be of type array in NonBlockingClient.php:183 #137

Closed niniob closed 1 year ago

niniob commented 1 year ago

Using WriteRegistersBuilder to write registers leads to following exception: _Fatal error: Uncaught TypeError: arraymerge(): Argument #1 must be of type array, ModbusTcpClient\Packet\ModbusFunction\WriteMultipleRegistersResponse given in /php/modbus-test-01/vendor/aldas/modbus-tcp-client/src/Network/NonBlockingClient.php:183

Issue seems to be line 183 in NonBlockingClient.php: $data = array_merge(...$data);

I'm not sure why array_merge and the spread operator are used together. I assume it should be just $data = array_merge($data);

At least this fixes the issue for me.

Example to reproduce the issue:

<?php
require __DIR__ . '/vendor/autoload.php';
use ModbusTcpClient\Composer\Write\WriteRegistersBuilder;
use ModbusTcpClient\Network\NonBlockingClient;

$request = WriteRegistersBuilder::newWriteMultipleRegisters()
                ->allFromArray([['uri' => 'tcp://192.168.100.10:5555', 'type' => 'uint16', 'value' => 123, 'address' => 1024, 'unitId' => 1]])
                ->build();

$response = (new NonBlockingClient())->sendRequests($request);
?>

Environment:

aldas commented 1 year ago

This is a bug with Write requests. Basically Composer Requests should extract values as array. Like ReadRegisterRequest does it here https://github.com/aldas/modbus-tcp-client/blob/3d6af61c15de90aa3655b6883b42f5c30e7d7ece/src/Composer/Read/Register/ReadRegisterRequest.php#L73

but WriteRegisterRequest https://github.com/aldas/modbus-tcp-client/blob/3d6af61c15de90aa3655b6883b42f5c30e7d7ece/src/Composer/Write/Register/WriteRegisterRequest.php#L70 just returns own instance instead of array - this is a bug / something that I forgot.

I will fix it.

aldas commented 1 year ago

I have released version 3.2.0 that contains fix for this problem.

niniob commented 1 year ago

Excellent, the fix works fine with PHP 8, many thanks for the quick response. But have in addition an environment still running PHP 7.4.28 which cannot be upgraded to PHP 8. Therefore I need to use version 2.4.0 of modbus-tcp-client. Any chance to get the fix also downported to 2.4.0?

aldas commented 1 year ago

@niniob I think you could create custom patch for PHP 7 and let composer to apply it.

See

  1. https://www.howtogeek.com/devops/how-to-apply-your-own-patches-to-composer-packages/
  2. https://scandiweb.com/blog/php-series-using-a-composer-patch/
niniob commented 1 year ago

@niniob I think you could create custom patch for PHP 7 and let composer to apply it.

Thanks, custom patch might be an option, but I found another workaround: Create NonBlockingClient with option 'flatRequestResponse' => false. This avoids $data = array_merge(...$data) being called.

$response = (new NonBlockingClient([ 'flatRequestResponse' => false ]))->sendRequests($request);

aldas commented 1 year ago

aa yeah, this is also an option as write requests do not need responses.