API PHP class

after 2 days and levelup in php skills problem solved
new php api function is

	function read($parse = true) {
		$RESPONSE = array();
		while (true) {
			$LENGTH = ord(fread($this->socket, 1) );
			if ($LENGTH > 0) {
				$_ = fread($this->socket, $LENGTH);
				$RESPONSE[] = $_;
			}
			$STATUS = socket_get_status($this->socket);
			if ($LENGTH > 0)
				$this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . '] ' . $_);
      if (!$this->connected && !$STATUS['unread_bytes']) break;
         if ($this->connected && $_ == '!done') {
            if ($STATUS['unread_bytes'] > 1) {
                $LENGTH = ord(fread($this->socket, 1) );
                if ($LENGTH > 0) {
                    $_ = fread($this->socket, $LENGTH);
                    if (preg_match_all('/[^=]+/i', $_, $MATCHES)){ 
                        if ($MATCHES[0][0] == 'ret') {
                            $RESPONSE[] = $MATCHES[0][1];
                        }                             
                    }                       
                }else {
                  continue;
                }    
         }
         break;
      }     
	  }
		if ($parse)
			$RESPONSE = $this->parse_response($RESPONSE);
		return $RESPONSE;
	}

it still have small glitch after succesfull proceded command from parser comes out empty array
at the moment I am not going to solve it
it does what I need no cykle, error mesages come out correctly

I have a problem, when I use this

$API->write(‘/interface/wireless/monitor’,false);
$API->write(‘=.id=’.$Id,false);
$API->write(‘=once’);

works fine just for band=2.4ghz-b
this is the error

<<< [27] /interface/wireless/monitor
<<< [7] =.id=*B
<<< [5] =once

[3, 420] !re
[7, 412] =.id=*B
[18, 393] =status=running-ap
[14, 378] =band=2.4ghz-g
[15, 362] =frequency=2484
[16, 345] =noise-floor=-91
[18, 326] =overall-tx-ccq=52
[22, 303] =registered-clients=49
[25, 277] =authenticated-clients=49
[24, 252] =current-ack-timeout=246
[14, 237] =nstreme=false
[17, 219] =wmm-enabled=true
[128, 90] �=current-tx-powers=1Mbps:20(20),2Mbps:20(20),5.5Mbps:20(20),11Mbps:20(20),6Mbps:20(20),9Mbps:20(20),12Mbps:20(20),18Mbps:20(20)
[44, 45] 24Mbps:20(20),36Mbps:18(18),48Mbps:17(17),54
[77, 0] bps:16(16)=notify-external-fdb=true!done

from this part is doesn’t work

Thanks

P.S. in python works fine, in php and perl don’t

I include this part in the read function after the while for resolve my problem, I’m testing now, is’t work for now
function …
while (true) {
$LENGTH = ord(fread($this->socket, 1));
if (($LENGTH & 0x80) == 0x00) {
} elseif (($LENGTH & 0xC0) == 0x80) {
$LENGTH = ($LENGTH &= ~0xC0) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1)));
} elseif (($LENGTH & 0xE0) == 0xC0) {
$LENGTH = ($LENGTH &= ~0xE0) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1)));
} elseif (($LENGTH & 0xF0) == 0xE0) {
$LENGTH = ($LENGTH &= ~0xF0) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1)));
} elseif (($LENGTH & 0xF8) == 0xF0) {
$LENGTH = ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1))) . ($LENGTH <<= 8) . ($LENGTH += ord(fread($this->socket, 1)));
}
if ($LENGTH > 0) {
… }

you can try for test

There’s sonething wrong with php api class and ROS 3.30 on RB433. Until i add any simple queue in system, I can’t connect to its through API interface. I recieve an error:

Connection attempt #1 to 172.16.7.20:8728... <<< [6] /login >>> [5, 0] Connection attempt #2 to 172.16.7.20:8728... <<< [6] /login >>> [5, 0] Connection attempt #3 to 172.16.7.20:8728... <<< [6] /login >>> [5, 0] Connection attempt #4 to 172.16.7.20:8728... <<< [6] /login >>> [5, 0] Connection attempt #5 to 172.16.7.20:8728... <<< [6] /login >>> [5, 0] Error...

There isn’t that problem in ROS 3.25 with the same PHP Api class and ROS v3.30 on RB1000 also with the same PHP Api class.

In python Api client (with both ROS 3.25 and 3.30 on RB433) everythings work ok (so it must be BUG in php api class).

Do anybody know where could be the BUG?

Hi community mikrotik, i´m from Brazil.

I use API PHP but, on line, sometimes connect, sometimes not!!! In localhost everything is all right. I´m a newbe and look for any help.

My code:

<?php
function gravarequipamento() 
{
	if($this->data['Equipamento']['form'] == 'gravarequipamento')
	{
		$this->data = Sanitize::clean($this->data, array('encode' => false));
		
		$this->Equipamento->set($this->data);
		
		if ($this->Equipamento->validates()) 
		{   
			// SYSTEN SETS
			define('USER_PADRAO', 'manut'); // System User
			define('GRUPO_PADRAO', 'write'); // Group System User
			define('ADMIN_SISTEMA', 'zuca'); // System Admin test
			define('SENHA_SISTEMA', '123456'); // Password test
			$ip = $this->data['Equipamento']['ip']; // IP of MIKROTIK
			
			
			$new_password = 654321 // Encryption omitted; 
			
			$this->data['Equipamento']['senha'] = $new_password;

			// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ACTION IN MIKROTIK
			require('routeros_api.class.php'); 
			$API = new routeros_api();
			$API->debug = false; 
			
			if ($API->connect($ip, ADMIN_SISTEMA, SENHA_SISTEMA)) 
			{
					$this->Equipamento->save($this->data); // If connect fail, this data save fail to.
				
					$API->write('/user/add', false);
					$API->write('=group='.GRUPO_PADRAO, false);
					$API->write('=name='.USER_PADRAO, false);
					$API->write('=password='.$new_password);
					
					$ARRAY = $API->read();
					$API->disconnect();
					$mensagem = 'SAVE SUCESS!
					<br/> USUÁRIO PADRÃO: '.USER_PADRAO.'
					<br/>SENHA: '.$new_password;
					$this->Session->setFlash($mensagem);
					$this->redirect(array('action' => 'gravarequipamento'));
			}
			else 
			{
					$mensagem = 'FAIL CONECTION WITH MIKROTIK ('.$ip.')';
					$this->Session->setFlash($mensagem);
					$this->redirect(array('action' => 'gravarequipamento'));
			}
			// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ACTION IN MIKROTIK
		} 
		else 
		{
			// Tratando as mensagens de erro
			$mensagem = $this->Equipamento->invalidFields();
			if(isset($mensagem['ip'])){$ip = ">> ".$mensagem['ip']." <<";} else {$ip = '';}
			if(isset($mensagem['nome'])){$nome = ">> ".$mensagem['nome']." <<";} else {$nome = '';}
			$this->Session->setFlash("Please, read the instructions here:<br/>".$ip."<br/>".$nome);

			//if(!empty($mensagem)){$this->Session->setFlash($mensagem);}
			$this->redirect(array('action' => 'gravarequipamento'));
		}

		
		
	} 
} 
?>

When i use a webpage (debug=false) i see the message “'FAIL CONECTION WITH MIKROTIK” after ‘else’ into MIKROTIK ACTION.

When i use API´s debug i received:


Connection attempt #1 to xxx.xxx.xxx.xxx:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !trap
Connection attempt #2 to xxx.xxx.xxx.xxx:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !trap
Connection attempt #3 to xxx.xxx.xxx.xxx:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !trap
Connection attempt #4 to xxx.xxx.xxx.xxx:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !trap
Connection attempt #5 to xxx.xxx.xxx.xxx:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !trap
Error...

But this is a random situation. Some rarely works. Does anyone have any idea what could be?

Well i see this http://forum.mikrotik.com/t/api-login-problem-on-rb133/27084/3

and for me it´s work very well.

I do not declare to say that this is the problem or the solution, just it worked for me.

:slight_smile:

instead of the following:

   $API->write('/ip/hotspot/user/set', false);
   $API->write('=name=mv99', false);
   $API->write('=password=phptest');

Do the following:

   $API->write('/tool/user-manager/user/print', false);
   $API->write('?name=mv99');

Then parse out from the return data the field .id and use the value as follows:

   $API->write('/tool/user-manager/user/set', false);
   $API->write('=password=' . $newpassword, false);
   $API->write('=.id=' . $retid);

Hello folks.
I’ve downloaded the php class mikrotik api posted here

http://forum.mikrotik.com/t/mikrotik-php-api/45595/1

by sw0rdf1sh and I’m using it in some of my projects.
After executing a script that uses that routeros_api.class.php class, I got this message:

Notice: Undefined variable: _ in ... on line 313

Then, I would like to ask you guys a question:
First, consider the following piece of code which exists in that php class (lines 300 up to 320)

// If we have got more characters to read, read them in.
         if ($LENGTH > 0) {
            $_ = "";
            $retlen=0;
            while ($retlen < $LENGTH) {
               $toread = $LENGTH - $retlen ;
               $_ .= fread($this->socket, $toread);
               $retlen = strlen($_);
            }
            $RESPONSE[] = $_ ;
            $this->debug('>>> [' . $retlen . '/' . $LENGTH . ' bytes read.');
         }

         // If we get a !done, make a note of it.
         if ($_ == "!done")
            $receiveddone=true;

         $STATUS = socket_get_status($this->socket);

         
         if ($LENGTH > 0)
            $this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . '] ' . $_);

So, there is this PHP variable $_ on it.
Besides the code above, I’ve glanced the entire class and saw no other mentions for that $_
I suppose my script don’t execute those instructions inside that first conditional, i.e., if ($LENGTH > 0) …
Therefore, when the script reachs that second conditional, i.e., if ($_ == “!done”), the PHP produces the notice message

undefined variable: _

, just because the $_ variable had never been initialized.
Although it’s just a simple notice message, is that code right? I mean, don’t you guys think the $_ variable should be initialized somewhere before the execution of those IF’s?
That’s it.
Thanks for any reply and suggestions.

rod~

Hi my question is when I’m trying to do export, the result is that the export file is incomplete. PHP code is :

$API->write(‘/export’, false); $API->write(‘=file=’.$MT_NAME);
$A = $API->read(); $A = $A[0];

there is no PPP and Wireless part in the file, but if I do that from MT’s terminal by /export file=name I’ve got export file with all data. What is the problem?

Thank You for all answers :slight_smile:

Hi I’m trying to run a script via MT API but without success :frowning: My PHP code is :

$API->write(‘/system/script/print’,false);
$API->write(‘.proplist=.id’,false);
$API->write(‘?name=bak’);
$A = $API->read(); $A = $A[0];

$API->write(‘system/script/run’, false); $API->write(‘=.id=’.$A[‘.id’]);
$A = $API->read(); $A = $A[0];

Everytime I’ve got !trap message.

Connection attempt #1 to 10.10.35.34:8728… <<< [6] /login >>> [5/5 bytes read. >>> [5, 39] !done >>> [37/37 bytes read. >>> [37, 1] =ret=e6e75ac1bc1c73a5906ec78bb59e5da4 <<< [6] /login <<< [11] =name=admin <<< [44] =response=007b0c8bdc6b731a8cbe82933f0ddfd116 >>> [5/5 bytes read. >>> [5, 1] !done
Connected… <<< [20]
/system/script/print <<< [13] .proplist=.id <<< [9] ?name=bak >>> [3/3 bytes read. >>> [3, 203] !re >>> [7/7 bytes read. >>> [7, 195] =.id=*1 >>> [9/9 bytes read. >>> [9, 185] =name=bak >>> [26/26 bytes read. >>> [26, 158] =source=/export file=bakup >>> [12/12 bytes read. >>> [12, 145] =owner=admin >>> [73/73 bytes read. >>> [73, 71] =policy=ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive >>> [34/34 bytes read. >>> [34, 36] =last-started=jun/15/2011 10:54:31 >>> [12/12 bytes read. >>> [12, 23] =run-count=6 >>> [14/14 bytes read. >>> [14, 8] =invalid=false >>> [5/5 bytes read. >>> [5, 1] !done <<< [17]
system/script/run <<< [7] =.id=*1 >>> [5/5 bytes read. >>> [5, 40] !trap >>> [31/31 bytes read. >>> [31, 8] =message=no such command prefix >>> [5/5 bytes read. >>> [5, 1] !done Disconnected…

Thank You for all answers :slight_smile:

there is error in API syntax

$API->write('.proplist=.id',false);

change to:

$API->write('=.proplist=.id',false);

and there is a known problem that export does not include some parts of configuration. The problem is, if, for example, execute /interface/wireless/export, export actually has wireless configuration, while /export does not include that.

I’ve done that, but the result is still the same. I’ve got : [17] system/script/run <<< [7] =.id=*1 >>> [5/5 bytes read. >>> [5, 40] !trap >>> [31/31 bytes read. >>> [31, 8] =message=no such command prefix >>>

Any ideas why?

The code looks like that right now:

                   $API->write('/system/script/print',false);
                   $API->write('=.proplist=.id',false);
                   $API->write('?name=bak');
                   $A = $API->read(); $A=$A[0];
                   $API->write('system/script/run', false); $API->write("=.id=".$A['.id']);
                   $API->read(false);

Change ‘print’ to ‘getall’. ‘print’ doesn’t work in API; AFIAK.

$API->write('/system/script/getall',false);

(I think that is the first time I have used AFAIK, IMHO, LOL…)

this works for me on 5.5 test build, should work on any 5.x version. getall was changed to alias of print some time when 4.x reigned.

/system/script/print
=.proplist=.id,name
?name=morse

this works for me on 5.5 test build, should work on any 5.x version. getall was changed to alias of print some time when 4.x reigned.

It does work! Of course, it is right there in the release notes…

As for the problem above, it appears there is a leading “/” missing:

$API->write('system/script/run', false); $API->write("=.id=".$A['.id']);

Should be:

$API->write('/system/script/run', false); $API->write("=.id=".$A['.id']);

Hope this helps.

Yes it does. Works now. Thank You! I must be more carefull checking my scripts syntax.

hello, please help.

why this parameter not work?

$API->write('/log',false);
$API->write('=info=success');

see at the /log, no result.

You need a “, TRUE” on the log= success line I think

Hi I am trying to put together a simple bandwidth test thru the api, but it is giving me endless headaches.
Is there a problem doing a bandwidth test thru the api because all other stuff I did worked fine?
the php file looks like this:

<?php require('routeros_api.class.php'); $API = new routeros_api(); $API->debug = true; if ($API->connect('xx.xx.xx.xx', 'api', 'verysecure')){ $API->write('/tool/bandwidth-test',false); $API->write('=address=xx.xx.xx.xx',false); $API->write('=duration=10',false); $API->write('=protocal=udp',false); $API->write('=direction=both'); $ARRAY = $API->read(); $first = $ARRAY['0']; echo "tx: " . $first['tx-total-average']; echo "rx: " . $first['rx-total-average']; } ?>

and what i get is:

Connection attempt #1 to xx.xx.xx.xx:8728… <<< [6] /login >>> [5/5 bytes read. >>> [5, 39] !done >>> [37/37 bytes read. >>> [37, 1] =ret=df1dbc88a93306791152ceb5ffb1c34d <<< [6] /login <<< [11] =name=api <<< [44] =response=000b00d5ebd7494a0cd1ec08b1d6f391a8 >>> [5/5 bytes read. >>> [5, 1] !done Connected… <<< [20] /tool/bandwidth-test <<< [21] =address=xx.xx.xx.xx <<< [13] =duration=10 <<< [14] =protocal=udp <<< [16] =direction=both >>> [3/3 bytes read. >>> [3, 170] !re >>> [23/23 bytes read. >>> [23, 146] =status=can not connect >>> [18/18 bytes read. >>> [18, 127] =duration=00:00:00 >>> [13/13 bytes read. >>> [13, 113] =rx-current=0 >>> [23/23 bytes read. >>> [23, 89] =rx-10-second-average=0 >>> [19/19 bytes read. >>> [19, 69] =rx-total-average=0 >>> [15/15 bytes read. >>> [15, 53] =lost-packets=0 >>> [18/18 bytes read. >>> [18, 34] =random-data=false >>> [18/18 bytes read. >>> [18, 15] =direction=receive >>> [13/13 bytes read. >>> [13, 1] =rx-size=1500 >>> [3/3 bytes read. >>> [3, 170] !re >>>

any help would apreciated

This implies bw-test could not connect from the client to the server.