hotspot management from PHP API

The code:

require('routeros_api.class.php');

function recorro($matriz)
{
            foreach($matriz as $key=>$value)
            {
               if (is_array($value))
				{
				        //echo $value["name"].'<br>';
					//si es un array busco dentro
					if ($value["name"] == $mac) 
					{
						//si coincide con el valor deseado, lo devuelvo para usarlo
					  return $value['.id'];
					  break;
					}
					recorro($value);
					}else{  
					   //si es un elemento continuo
					  continue;
					}
				}
	} 

	if ($API->connect('IP', 'USER', 'PASSWORD')) 
	{      
		
		echo '<br><br>';
		echo 'Conecatado Ok';
		echo '<br><br>';
		
		$API->write('/ip/hotspot/user/print',true);
		$READ = $API->read(true);

		$id = recorro($READ);
		$API->write('/ip/hotspot/user/disable',false);
		$API->write('=.id=' . $id);		
		
		echo 'Buscado: '.$id;
		echo '<br><br>';
		//print_r($READ);
		echo '<br><br>';
			
		$API->write('/ip/hotspot/active/print',true);
		$READ2 = $API->read(true);	
		
		foreach ($READ2 as $value2) {
		
		//echo $value2['mac-address'].'<br>';

			if ($value2['mac-address'] == $mac) 
			{
			  $API->write('/ip/hotspot/active/remove',false);
			  $API->write('=.id=' . $value2['.id']);
			  $KILL = $API->read();
			  
			  echo 'Encontrado ';
			  echo $value2['.id'];
			}
		}
		//print_r($READ2);
		$API->disconnect();
}

The problem:

if i send the $mac value from other web, or form, ($_GET) the api seems dont get this value,
if i use $value[“name”] == “MAC ADDRESS”, the api works fine.

any idea why the api dont read the value of the var?

thanks

In PHP, there’s just the global scope, and the function’s scope. The function scope does NOT inherit the global scope.

If you want to import a global variable, you must either pass it at call time, e.g.

<?php

function recorro($matriz, $mac) {
//...
}

$id = recorro($READ, $mac);
 

or use the “global” keyword at the start of the function declaration, e.g.

<?php

function recorro($matriz) {
global $mac;
//...
}

$id = recorro($READ);
 

P.S. That’s one unnecessarily complicated code.

Lol, i fell stupid :confused:


thx man i dont see this noob problem :S

all works fine now :slight_smile:

New problem, becouse the long arrays coming from mk, we need use 2 calls to api, but now, nothing wokrs…

<?php
require('routeros_api.class.php');

include('../../incluits/config.php');
include('../../incluits/functions.php');

if(!isset($_SESSION["admin"]) )

{
redirigir_a("../index.php?stat=nouser");
}else{

$mac = $_GET["mac"];
echo '<b>Todas las memorias estan expresadas en Bytes </b><br><br><br>';
echo 'Memoria antes de nada ' . memory_get_usage();
echo '<br>';


$API = new routeros_api();
$API->debug = true;


	function recorro($matriz)
	{
		global $mac;
		foreach($matriz as $key=>$value)
		{
	 
			if (is_array($value))
				{
					   //si es un array busco dentro
					if ($value['name'] == $mac) 
					{
						//si coincide con el valor deseado, lo devuelvo para usarlo
					  return $value['.id'];
					  break;
					}
					recorro($value);
					}else{  
					   //si es un elemento continuo
					  continue;
					}
				}
	} 

echo 'Memoria antes de conectar ' . memory_get_usage();
echo '<br>';

	if ($API->connect(xxx)) 
	{      
	
		$API->write('/ip/hotspot/user/print',true);
		$READ = $API->read(true);

		$id = recorro($READ);
		$API->write('/ip/hotspot/user/disable',false);
		$API->write('=.id=' . $id);		
		
		echo '<br>';
		echo 'Encontrado user: ' .$id;
		//print_r($READ);
		echo '<br><br>'; 
		echo "El Array tiene " . sizeof($READ) . " elementos";
		echo '<br><br>';
		
		$API->disconnect();
	
	}
	
echo 'Memoria al terminar el user print / disable ' . memory_get_usage();
echo '<br>';			
unset($READ); //Vacio la array y la memoria que use.
echo 'Memoria al vaciar el user print / disable ' . memory_get_usage();
echo '<br>';	

		unset($READ); //Vacio la array y la memoria que use.
	
	echo '<br><br><br><br><br><br>';
	
	$API2 = new routeros_api();
	$API2->debug = true;
	
	if ($API2->connect(xxx)) 
	{ 
	
		$API2->write('/ip/hotspot/host/print',true);
		$READ2 = $API2->read(true);	
		
		foreach ($READ2 as $value2) {

			if ($value2['mac-address'] == $mac) 
			{
			  $API2->write('/ip/hotspot/host/remove',false);
			  $API2->write('=.id=' . $value2['.id']);
			  
			  echo 'Encontrado user: ' . $value2['.id'];
			}
		
		}
		
		echo '<br><br>';
		echo "El Array tiene " . sizeof($READ2) . " elementos";
		echo '<br><br>';
		//print_r($READ2);
		
echo 'Memoria al terminar el host print / remove ' . memory_get_usage();
echo '<br>';
	
unset($READ2);  //Vacio la array y la memoria que use.

echo 'Memoria al vaciar el user print / disable ' . memory_get_usage();
echo '<br>';	

		$API2->disconnect();
	}
	
echo '<br> Pico de Memoria ' . memory_get_peak_usage();
	
}
?>

The id’s are found ok, but the write with the command fails.

Any idea ?
Thanks.

Do another read() after the remove, and that will fix it.


But seriously, you’re having some unecesarily complicated code.

Using the client from my signature, you can simplify that down to:

<?php
namespace PEAR2\Net\RouterOS;

include('PEAR2_Net_RouterOS-1.0.0b3.phar');
include('../../incluits/config.php');
include('../../incluits/functions.php');

if(!isset($_SESSION["admin"])) {
    redirigir_a("../index.php?stat=nouser");
} else {
    $client = new Client(...);

    $id = $client->sendSync(
        new Request('/ip hotspot user print .proplist=.id', Query::where('name', $_GET['mac']))
    )->getArgument('.id');

    $removeRequest = new Request('/ip hotspot user remove');
    $removeRequest->setArgument('numbers', $id);
    $client->sendSync($removeRequest);

    $id = $client->sendSync(
        new Request('/ip hotspot host print .proplist=.id', Query::where('mac-address', $_GET['mac']))
    )->getArgument('.id');

    $removeRequest = new Request('/ip hotspot host remove');
    $removeRequest->setArgument('numbers', $id);
    $client->sendSync($removeRequest);
} 

And that’s the verbose version. You can take it a step further, and compress that to:

<?php
namespace PEAR2\Net\RouterOS;

include('PEAR2_Net_RouterOS-1.0.0b3.phar');
include('../../incluits/config.php');
include('../../incluits/functions.php');

if(!isset($_SESSION["admin"])) {
    redirigir_a("../index.php?stat=nouser");
} else {
    $client = new Client(...);

    $removeRequest = new Request('/ip hotspot user remove');
    $client->sendSync($removeRequest
        ->setArgument(
            'numbers',
            $client->sendSync(
                new Request('/ip hotspot user print .proplist=.id', Query::where('name', $_GET['mac']))
            )->getArgument('.id')
        )
    );

    
    $client->sendSync($removeRequest
        ->setCommand('/ip hotspot host remove')
        ->setArgument(
            'numbers',
            $client->sendSync(
                new Request('/ip hotspot host print .proplist=.id', Query::where('mac-address', $_GET['mac']))
            )->getArgument('.id')
        )
    );
} 

(I realize that’s actually a few more lines… but it’s a few statements less)

i tried with a read() after each remove, and only works the disable part. the remove one fails.

Anyway i will study ur api for the next projects, but for now i dont understand fully this api so.. i go slowly :stuck_out_tongue:

Thanks for the tips

Are you sure that your usernames are the mac addresses? Perhaps you need to instead target the mac-address property in the user section too. It would be normal for the remove to fail if there’s no ID from the print being matched, which would happen if that’s the case.

BTW, I’m not even sure the removal in the “host” is necesary. It should be deleted automatically as a consequence of the user deletion.

Going slowly by starting with the more cumbersome and unintuitive API, towards the cleaner and easier one… fair enough… I think.

Should… but not…

$API2->write('/ip/hotspot/host/print',true);
      $READ2 = $API2->read(true);   
      
      foreach ($READ2 as $value2) {

         if ($value2['mac-address'] == $mac) 
         {
           $API2->write('/ip/hotspot/host/remove',false);
           $API2->write('=.id=' . $value2['.id']);
           
           echo 'Encontrado user: ' . $value2['.id'];
         }

The Echo shows the id, so the user with this mac address was found, but just don kick him from host list…

I don’t see a read() there. Make that:

           $API2->write('/ip/hotspot/host/remove',false);
           $API2->write('=.id=' . $value2['.id']);
           $API2->read(); 

i dont edit the first code with the read() :stuck_out_tongue:

i revised all code again, and now works fine.

Lot of thanks for ur help and ur tips.

Does not have any available stencil ·
Difficult to use!

I agree.

Try the other PHP client - the one from my signature. See how you like it. I’d love to hear your feedback on it.

how to run this code from api

/tool user-manager user> remove [/tool user-manager user find username=101]

With my API client:

<?php
use PEAR2\Net\RouterOS;

require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

$util = new RouterOS\Util($client = new RouterOS\Client('192.168.88.1', 'admin', 'password'));


$util->setMenu('/tool user-manager user')->remove(RouterOS\Query::where('username', '101')); 

Hi again, my script was working fine till now (some years working perfect), something more that i saw change with any of last routerOS updates, and now i have a problem with the remove part from hotpost, the enable/disable part works fine, looks like the problem is in the read return from the router, apears to come back empty.

Any ideas?