pear2 / Net_RouterOS

This package allows you to read and write information from a RouterOS host using the MikroTik RouterOS API protocol.
http://pear2.php.net/PEAR2_Net_RouterOS
241 stars 116 forks source link

Response collection to plain array conversion method #40

Open aTanCS opened 6 years ago

aTanCS commented 6 years ago

Often I don't need to get a particular property using $response->getProperty('name'), but need all rows as a plain array. There is toArray() method, but it just returns array of Response objects, which has $apttributes property protected. For now I have to use this helper, but it is a quite dirty hack. Is there any better way to get a plain array of response data, or could you please add such method to a ResponseCollection (and also to a Response)?

    $plain = [];
    /** @var \PEAR2\Net\RouterOS\ResponseCollection $response */
    $props = array_keys($response->getPropertyMap());
    foreach ($response as $row)
    {
      $tmp = [];
      foreach ($props as $prop)
      {
        $tmp[$prop] = $row->getProperty($prop);
      }
      $plain[] = $tmp;
    }
boenrobot commented 6 years ago

The properties in each response are also traversable. i.e. you can do

$plain = [];
/**
 * @var \PEAR2\Net\RouterOS\ResponseCollection $response
 * @var \PEAR2\Net\RouterOS\Response $row
 */
foreach ($response as $i => $row) {
    $plain[$i] = [];
    foreach ($row as $name => $value) {
        $plain[$i][$name] = $value;
    }
}

And with that in mind, I'm not sure I see a good use case for when a plain array is required... In the rare case where it might be needed, you can extract it out of the traversable, e.g.

$plain = [];
/** @var \ArrayObject $iterator */
$iterator = $response[0]->getIterator();
$plain[0] = $iterator->getArrayCopy();

The typical cases where you may need an array, like indexing based on a property value or ordering based on one or more properties are possible with the methods in ResponseCollection.

aTanCS commented 6 years ago

I use plain arrays for saving a result as a json to a DB. And I use it a lot for debugging, when I just need to dump a result. With the current state I can't see a result in a readable format, when I use breakpoints. I have to convert it to an array.

boenrobot commented 6 years ago

Well, I've made 0a8e77c8386e4afb1d3851712e13349945a0656a in which I've added __debugInfo() support to answer this request, and also an option in ResponseCollection::toArray() to call it on all responses in the collection.

The JSON serialization is an interesting use case, and my first thought was to use the JsonSerializable interface, but that one would require that the minimum required PHP version is bumped to PHP 5.4. __debugInfo() on the other hand has an effect in PHP 5.6 and later, but can be called like a normal function in all earlier PHP versions.

The upcoming phar will include it, but in the meantime, if you want to try it out now, you can use composer, and specify the version you want as "dev-develop".

aTanCS commented 6 years ago

Thanks a lot!