PHP return empty array

Hello,
I would like to enable or disable interface through API. I have created PHP code which should do it, but U have a porblem when I enable one interface and try to get information about another interface, API returns empty array. I tried to put sleep() function, but I is not working.

Do you see somethnig wrong?

$dilna is variable which has Groupx.

$apMap["Group1"][0] = "AP1";
$apMap["Group2"][0] = "AP2";
$apMap["Group3"][0] = "AP3";
$apMap["Group4"][0] = "AP4";

$API = new RouterosAPI();
    $API->debug = true;
    if ($API->connect('192.168.103.86', 'API', 'YN@tpmjm7.p98th@')) {
        for ($i = 0; $i < sizeof($apMap[$dilna]); $i++) {
            $API->write('/caps-man/interface/print', false);
            $API->write('?name=' . $apMap[$dilna][$i]);

            $READ = $API->read(false);
            $ARRAY = $API->parseResponse($READ);

            if (isset($ARRAY[0]['disabled'])) {
                if ($ARRAY[0]['disabled'] == "true" && $run) {
                    $API->write("/caps-man/interface/enable", FALSE);
                    $API->write("=.id=" . $apMap[$dilna][$i]);
                    echo "Zapinam -> ".  $apMap[$dilna][$i]. "<br />";
                    sleep(30);
                } else if (!$run) {
                    $API->write("/caps-man/interface/disable", FALSE);
                    $API->write("=.id=" . $apMap[$dilna][$i]);
                    sleep(30);
                }
            } else {
                echo  $dilna . "  " . $apMap[$dilna][$i] . "  " . sizeof($apMap[$dilna]). "<br />";
                print_r($ARRAY);
            }
        }
        $API->disconnect();
    }

You must either read() before very write (even if you don’t care about the reply’s contents) or you must add a “.tag” when writing, and when reading, loop through the replies until you find the tag you had set when writing.

Or at least, that is what must happen on a protocol level. With the API client from my signature, this is taken care of in the background.

But… in all honesty, I think your algorithm is very much suboptimal… You don’t need the IDs of interfaces - you can use the names with “enable” and “disable”. Furthermore, you can separate multiple names with a comma. The only reason you may want to use an ID instead is if the name contains a comma.

With all of that in mind, here’s an optimized version with the API client from my signature:

<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

//Init $apMap here or in an external file that includes this one, or is included here; also $dilna and $run
$apMap["Group1"][0] = "AP1";
$apMap["Group2"][0] = "AP2";
$apMap["Group3"][0] = "AP3";
$apMap["Group4"][0] = "AP4";

$util = new RouterOS\Util($client = new RouterOS\Client('192.168.103.86', 'API', 'YN@tpmjm7.p98th@'));

$util->setMenu('/caps-man/interface');
if ($run) {
    $util->enable(implode(',', $apMap[$dilna]));
} else {
    $util->disable(implode(',', $apMap[$dilna]));
} 

or if you prefer to be name agnostic (i.e. support interface names with a comma) at a slight performance penalty (but still more efficient than your original code):

<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

//Init $apMap here or in an external file that includes this one, or is included here; also $dilna and $run
$apMap["Group1"][0] = "AP1";
$apMap["Group2"][0] = "AP2";
$apMap["Group3"][0] = "AP3";
$apMap["Group4"][0] = "AP4";

$util = new RouterOS\Util($client = new RouterOS\Client('192.168.103.86', 'API', 'YN@tpmjm7.p98th@'));

$query = RouterOS\Query::where('name', $apMap[$dilna][0]);
for ($i = 1, $l = count($apMap[$dilna]); $i < $l; ++$i) {
    $query->orWhere('name', $apMap[$dilna][$i]);
}

$util->setMenu('/caps-man/interface');
if ($run) {
    $util->enable($query);
} else {
    $util->disable($query);
} 

Thanks for response boen_robot. But when I reenable AP it will kick of all users which are connected to AP. This is reason why I read if the AP is active or not.

Sounds like a bug worthy to be reported to support@mikrotik.com.

But OK… As a workaround (I mean, even if they fix this in the next version, I’m sure you’ll want to keep supporting older ones for a while):

<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

//Init $apMap here or in an external file that includes this one, or is included here; also $dilna and $run
$apMap["Group1"][0] = "AP1";
$apMap["Group2"][0] = "AP2";
$apMap["Group3"][0] = "AP3";
$apMap["Group4"][0] = "AP4";

$util = new RouterOS\Util($client = new RouterOS\Client('192.168.103.86', 'API', 'YN@tpmjm7.p98th@'));

$query = RouterOS\Query::where('name', $apMap[$dilna][0]);
for ($i = 1, $l = count($apMap[$dilna]); $i < $l; ++$i) {
    $query->orWhere('name', $apMap[$dilna][$i]);
}
$query->andWhere('disabled', ($run ? 'true' : 'false'));

$util->setMenu('/caps-man/interface');
if ($run) {
    $util->enable($query);
} else {
    $util->disable($query);
}

When enabling, this will match only disabled interfaces, and when disabling, it would match only enabled interfaces.

Thanks boen_robot!!