Community discussions

MikroTik App
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

API PHP class

Fri Jul 18, 2008 1:44 pm

Take it, edit it and use it as you need.
No support.

CLASS
<?php

//
// RouterOS API class
// Author: Denis Basta
//

class routeros_api {

	var $debug = false;			// Show debug information
	var $error_no;				// Variable for storing connection error number, if any
	var $error_str;				// Variable for storing connection error text, if any

	var $attempts = 5;			// Connection attempt count
	var $connected = false;		// Connection state
	var $delay = 3;				// Delay between connection attempts in seconds
	var $port = 8728;			// Port to connect to
	var $timeout = 3;			// Connection attempt timeout and data read timeout

	var $socket;				// Variable for storing socket resource

	/**************************************************
	 *
	 *************************************************/

	function debug($text) {

		if ($this->debug)
			echo $text . "\n";

	}

	/**************************************************
	 *
	 *************************************************/

	function encode_length($length) {

		if ($length < 0x80) {

			$length = chr($length);

		}
		else
		if ($length < 0x4000) {

			$length |= 0x8000;

			$length = chr( ($length >> 8) & 0xFF) . chr($length & 0xFF);

		}
		else
		if ($length < 0x200000) {

			$length |= 0xC00000;

			$length = chr( ($length >> 8) & 0xFF) . chr( ($length >> 8) & 0xFF) . chr($length & 0xFF);

		}
		else
		if ($length < 0x10000000) {

			$length |= 0xE0000000;

			$length = chr( ($length >> 8) & 0xFF) . chr( ($length >> 8) & 0xFF) . chr( ($length >> 8) & 0xFF) . chr($length & 0xFF);

		}
		else
		if ($length >= 0x10000000)
			$length = chr(0xF0) . chr( ($length >> 8) & 0xFF) . chr( ($length >> 8) & 0xFF) . chr( ($length >> 8) & 0xFF) . chr($length & 0xFF);

		return $length;

	}

	/**************************************************
	 *
	 *************************************************/

	function connect($ip, $login, $password) {

		for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) {

			$this->connected = false;

			$this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $ip . ':' . $this->port . '...');

			if ($this->socket = @fsockopen($ip, $this->port, $this->error_no, $this->error_str, $this->timeout) ) {

				socket_set_timeout($this->socket, $this->timeout);

				$this->write('/login');

				$RESPONSE = $this->read(false);

				if ($RESPONSE[0] == '!done') {

					if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES) ) {

						if ($MATCHES[0][0] == 'ret' && strlen($MATCHES[0][1]) == 32) {

							$this->write('/login', false);
							$this->write('=name=' . $login, false);
							$this->write('=response=00' . md5(chr(0) . $password . pack('H*', $MATCHES[0][1]) ) );

							$RESPONSE = $this->read(false);

							if ($RESPONSE[0] == '!done') {

								$this->connected = true;

								break;

							}

						}

					}

				}

				fclose($this->socket);

			}

			sleep($this->delay);

		}

		if ($this->connected)
			$this->debug('Connected...');
		else
			$this->debug('Error...');

		return $this->connected;

	}

	/**************************************************
	 *
	 *************************************************/

	function disconnect() {

		fclose($this->socket);

		$this->connected = false;

		$this->debug('Disconnected...');

	}

	/**************************************************
	 *
	 *************************************************/

	function parse_response($response) {

		if (is_array($response) ) {

			$PARSED = array();
			$CURRENT = null;

			for ($i = 0, $imax = count($response); $i < $imax; $i++) {

				if (in_array($response[$i], array('!fatal', '!re', '!trap') ) ) {

					if ($response[$i] == '!re')
						$CURRENT = &$PARSED[];
					else
						$CURRENT = &$PARSED[$response[$i]][];

				}
				else
				if ($response[$i] != '!done') {

					if (preg_match_all('/[^=]+/i', $response[$i], $MATCHES) )
						$CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');

				}

			}

			return $PARSED;

		}
		else
			return array();

	}

	/**************************************************
	 *
	 *************************************************/

	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']) || ($this->connected && $_ == '!done' && !$STATUS['unread_bytes']) )
				break;

		}

		if ($parse)
			$RESPONSE = $this->parse_response($RESPONSE);

		return $RESPONSE;

	}

	/**************************************************
	 *
	 *************************************************/

	function write($command, $param2 = true) {

		if ($command) {

			fwrite($this->socket, $this->encode_length(strlen($command) ) . $command);

			$this->debug('<<< [' . strlen($command) . '] ' . $command);

			if (gettype($param2) == 'integer') {

				fwrite($this->socket, $this->encode_length(strlen('.tag=' . $param2) ) . '.tag=' . $param2 . chr(0) );

				$this->debug('<<< [' . strlen('.tag=' . $param2) . '] .tag=' . $param2);

			}
			else
			if (gettype($param2) == 'boolean')
				fwrite($this->socket, ($param2 ? chr(0) : '') );

			return true;

		}
		else
			return false;

	}

}

?>
EXAMPLE
<?php

require('routeros_api.class.php');

$API = new routeros_api();

$API->debug = true;

if ($API->connect('111.111.111.111', 'LOGIN', 'PASSWORD')) {

   $API->write('/interface/getall');

   $READ = $API->read();
   $ARRAY = $API->parse_response($READ);

   print_r($ARRAY);

   $API->disconnect();

}

?>
OUTPUT
Array
(
	[0] => Array
		(
			[.id] => *1
			[name] => ether1
			[mtu] => 1500
			[type] => ether
			[running] => yes
			[dynamic] => no
			[slave] => no
			[comment] => 
			[disabled] => no
		)

	[1] => Array
		(
			[.id] => *2
			[name] => ether2
			[mtu] => 1500
			[type] => ether
			[running] => yes
			[dynamic] => no
			[slave] => no
			[comment] => 
			[disabled] => no
		)

	[2] => Array
		(
			[.id] => *3
			[name] => ether3
			[mtu] => 1500
			[type] => ether
			[running] => yes
			[dynamic] => no
			[slave] => no
			[comment] => ether3
			[disabled] => no
		)
)
You do not have the required permissions to view the files attached to this post.
Last edited by Denis Basta on Fri Sep 26, 2008 6:07 pm, edited 7 times in total.
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26368
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia

Re: API PHP class

Fri Jul 18, 2008 1:47 pm

cool! post it in the wiki and you will get a license :)
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

Re: API PHP class

Fri Jul 18, 2008 2:01 pm

I've never done this before...
Could you please help me with it?
Where and how to make a post?
Link to a help also would be great...

P.S. Already logged in wiki...
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26368
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia

Re: API PHP class

Fri Jul 18, 2008 2:12 pm

just think of an article name, and add it to the link in your address bar, it will make a new article, for example:

http://wiki.mikrotik.com/wiki/API_PHP_class

then hit the EDIT button and paste your text. to make text appear as CODE enclose it in <code> text </code>

more help:

http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

Re: API PHP class

Fri Jul 18, 2008 3:37 pm

 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26368
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia

Re: API PHP class

Fri Jul 18, 2008 3:40 pm

what are these things?
Picture 1.png
You do not have the required permissions to view the files attached to this post.
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

Re: API PHP class

Fri Jul 18, 2008 3:46 pm

Well, can't say.

I've copy/pasted everything from the forum...

While posting article in WIKI, there is a problem, if several "(" or ")" symbols is used one just right after another...
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26368
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia

Re: API PHP class

Fri Jul 18, 2008 3:54 pm

I think I fixed it, I used <nowiki> to stop interpreting anything in your code. Just add the same tag to other sections too and check if all is correct
 
jalokim
Frequent Visitor
Frequent Visitor
Posts: 76
Joined: Thu Dec 07, 2006 1:39 pm
Location: PL, Tychy
Contact:

Re: API PHP class

Sun Aug 17, 2008 9:52 pm

normis, You did mistake by pasting, for ex. line if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES� {�� - there is something like new line on the end, but wrong interpretated under firefox@windows.
 
glaubergabriel
just joined
Posts: 3
Joined: Thu Aug 28, 2008 12:58 am

Re: API PHP class

Thu Aug 28, 2008 1:15 am

Expensive Friends of the FORUM,
Already I tried you vary mareiras more I am not obtaining to execute the commands for alterations of the functions of the MIKROTIK type.

system identity set name=test - in the terminal or ssh

in api
/system/identity/set =name=teste, does not function,

if I place

/system/identity/get functions there results giving it of the name.

As I will be able to decide this problem.
 
tweetylbc
just joined
Posts: 1
Joined: Sun Oct 19, 2008 11:49 am

Re: API PHP class

Sun Oct 19, 2008 11:53 am

Expensive Friends of the FORUM,
Already I tried you vary mareiras more I am not obtaining to execute the commands for alterations of the functions of the MIKROTIK type.

system identity set name=test - in the terminal or ssh

in api
/system/identity/set =name=teste, does not function,

if I place

/system/identity/get functions there results giving it of the name.

As I will be able to decide this problem.
$API->write('/system/identity/set',false);
$API->write('=name=teste');
 
fosben
Frequent Visitor
Frequent Visitor
Posts: 81
Joined: Thu Dec 14, 2006 4:50 pm

Re: API PHP class

Mon Oct 20, 2008 10:29 pm

I dont get anything from print_r($ARRAY); Its only showing the login process and the interface data when I run the example.. then I get several of the following error :
Warning: preg_match_all() expects parameter 2 to be string, array given in routeros_api.class.php on line 177
the line in the code is the following :
if (preg_match_all('/[^=]+/i', $response[$i], $MATCHES) )
						$CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');

When I echoed the $response[$i] on screen I get 'Array' as output when it fails with error message.
if (gettype($response[$i])!='array')
made it run without errors, but the print_r($ARRAY) still doesnt print out anything on screen.. Anyone have an idea where the real bug is ?
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

Re: API PHP class

Tue Oct 21, 2008 9:00 am

Post your full code...
 
fosben
Frequent Visitor
Frequent Visitor
Posts: 81
Joined: Thu Dec 14, 2006 4:50 pm

Re: API PHP class

Tue Oct 21, 2008 6:55 pm

Post your full code...
I just copied and pasted your 1st post here into 2 different php files..
 
User avatar
S1ghup
just joined
Posts: 7
Joined: Mon Oct 27, 2008 7:41 pm
Location: Joplin, MO. USA

Re: API PHP class

Mon Oct 27, 2008 11:54 pm

Hello All,

Fist of all I want to thank all of the users of this board for all of the information that has gotten me to this point in my project. I am designing a web interface for a client and have ran into this particular problem. Just so that everyone is on the same page I am using the PHP API class found above. When I send the following command to the Mikrotik via SSH or terminal it works without any problems.
  /ip hotspot user set mv99 password=newpassword
However when I submit this command via the API class the router replies with a !done command but does not change the password.
* Change user password via web interface */
   
   $API->write('/ip/hotspot/user/set', false);
   $API->write('=name=mv99',false);
   $API->write('=password=phptest');
Here is a an output/debug log for the code listed above showing the full transaction.
Connection attempt #1 to xxx.xxx.xxx.xxx:8728...

Router <<< Client: [6] /login
    Router >>> Client: [5, 39] !done
    Router >>> Client: [37, 1] =ret=00a61be5f4c5f0bdb48e3d710f2ce732
Router <<< Client: [6] /login
Router <<< Client: [14] =name=mvoffice
Router <<< Client: [44] =response=00aa6135b90a91bf4166629a3195a858b2
    Router >>> Client: [5, 1] !done
    
Connected...
Router <<< Client: [20] /ip/hotspot/user/set
Router <<< Client: [10] =name=mv99
Router <<< Client: [17] =password=phptest
    Router >>> Client: [5, 1] !done
Disconnected...


As best that I can tell my syntax is correct or mostly correct. If anyone out there has any suggestions as to what I may be doing wrong or some pointers feel free to let me know. I have used this API implementation to change things like the system identity, get interface lists, and to print the firewall entries. To date this is the only part of the API that I have not been able to get the desired data from.

Thank you in advance,
John Annis
The Wireless Web
 
fosben
Frequent Visitor
Frequent Visitor
Posts: 81
Joined: Thu Dec 14, 2006 4:50 pm

Re: API PHP class

Tue Oct 28, 2008 10:10 pm

in terminal you dont use the name=mv99 value on username, Have you tried it without that =name= in your code ?
 
User avatar
S1ghup
just joined
Posts: 7
Joined: Mon Oct 27, 2008 7:41 pm
Location: Joplin, MO. USA

Re: API PHP class

Wed Oct 29, 2008 3:16 am

in terminal you dont use the name=mv99 value on username, Have you tried it without that =name= in your code ?
fosben:

Thank you for the reply, I am aware that using the terminal you use the following syntax.
/ip hotspot user set mv99 password=newpassword
According to the Mikrotik API command sentences are to be formatted in the following format. I admit I most certainly could be using the wrong command arguments the API documentation lacks quite badly in this department. When looking at the available choices in the console for actions that can be preformed on hotspot users =name=mv99 is the closest option that makes sense to me. Also I have tried submitting the just the user name mv99 without the =name=, the code executed without any errors and completed with !done but it also did not change the password.
Command argument should begin with '=' followed by name of argument, followed by another '=', followed by value of argument.
Command Argument Examples
=address=10.0.0.1
=name=iu=c3Eeg
=disable-running-check=yes
 
User avatar
Denis Basta
newbie
Topic Author
Posts: 48
Joined: Wed Dec 07, 2005 12:11 am
Location: Latvia, Riga

Re: API PHP class

Sat Nov 01, 2008 4:31 am

Try this one:

1. Receive list of all users:
$API->write(/ip/hotspot/user/getall');
2. In PHP iterate through resulted array comparing user name, whose password should be changed, with current iteration's [name] property.
3. In the resulting array get [.id] property.
4.
$API->write('/ip/hotspot/user/set', false);
$API->write('=password=phptest',false);
$API->write('=.id=' . [.id]);
This might work.
 
lyma
just joined
Posts: 24
Joined: Tue Sep 09, 2008 4:00 am
Contact:

Re: API PHP class

Sat Nov 01, 2008 6:10 pm

With your Excellent class and a bit of ajax, we can have a "webWinbox" or phpbox or so. :D

Thanks!
 
norg
just joined
Posts: 6
Joined: Sat Jan 17, 2009 2:16 pm

Re: API PHP class

Sat Jan 17, 2009 2:39 pm

Hi
I have a problem with this API class, after checking I know it is in read function.
There is problem when I send command throught API which is correctly done by mikrotik, webbrowser get halted because of cycle.
this problem I solved by adding this line of code into the read function
if (!$LENGTH) break;
BUT when this line is added I got just first part of the outputs, especialy from command getall.
So I added second variable to function read
   function read($parse = true, $zerolength = false)
and by this second variable I chose to add that line or not
$API->read(true, true)
BUT this is just workaround and I got in situation when is very difficult to prepare all possible situations and decide if there would be that line or not.

Rewriting function read is far beyond my abilities so I would very appreciate if someone have allready solved this problem, to share the solution.

Thanks Norg
 
norg
just joined
Posts: 6
Joined: Sat Jan 17, 2009 2:16 pm

Re: API PHP class

Mon Jan 19, 2009 5:09 pm

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
 
mblanco
just joined
Posts: 21
Joined: Thu Apr 27, 2006 10:56 pm

Re: API PHP class

Tue Jan 27, 2009 12:02 am

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
 
mblanco
just joined
Posts: 21
Joined: Thu Apr 27, 2006 10:56 pm

Re: API PHP class

Tue Jan 27, 2009 2:34 am

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
 
michalk66
just joined
Posts: 3
Joined: Thu Mar 11, 2010 11:44 pm

Re: API PHP class

Mon Mar 15, 2010 11:59 am

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?
 
Christiano
Frequent Visitor
Frequent Visitor
Posts: 52
Joined: Fri Aug 13, 2010 8:53 pm

Re: API PHP class

Sat Sep 04, 2010 12:03 am

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?
 
Christiano
Frequent Visitor
Frequent Visitor
Posts: 52
Joined: Fri Aug 13, 2010 8:53 pm

Re: API PHP class

Mon Sep 13, 2010 5:34 pm

Well i see this http://forum.mikrotik.com/viewtopic.php ... HP#p147918

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.

:)
 
User avatar
tgrand
Long time Member
Long time Member
Posts: 667
Joined: Mon Aug 21, 2006 2:57 am
Location: Winnipeg, Manitoba, Canada

Re: API PHP class

Sat Jan 15, 2011 12:40 am

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);
 
chapeupreto
just joined
Posts: 6
Joined: Wed Jul 21, 2010 5:49 pm

Re: API PHP class

Wed Mar 23, 2011 4:35 pm

Hello folks.
I've downloaded the php class mikrotik api posted here
http://forum.mikrotik.com/viewtopic.php?f=9&t=50176
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~
 
ITU
just joined
Posts: 4
Joined: Wed Jun 15, 2011 5:45 pm

Re: API PHP class

Wed Jun 15, 2011 5:52 pm

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 :)
Last edited by ITU on Thu Jun 16, 2011 9:05 am, edited 1 time in total.
 
ITU
just joined
Posts: 4
Joined: Wed Jun 15, 2011 5:45 pm

Re: API PHP class

Wed Jun 15, 2011 6:03 pm

Hi I'm trying to run a script via MT API but without success :( 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 :)
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API PHP class

Thu Jun 16, 2011 2:07 pm

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.
 
ITU
just joined
Posts: 4
Joined: Wed Jun 15, 2011 5:45 pm

Re: API PHP class

Thu Jun 16, 2011 5:35 pm

change to:
$API->write('=.proplist=.id',false);
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);
 
reverged
Member Candidate
Member Candidate
Posts: 270
Joined: Thu Nov 12, 2009 8:30 am

Re: API PHP class

Thu Jun 16, 2011 6:25 pm

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.....)
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API PHP class

Fri Jun 17, 2011 8:53 am

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
 
reverged
Member Candidate
Member Candidate
Posts: 270
Joined: Thu Nov 12, 2009 8:30 am

Re: API PHP class

Fri Jun 17, 2011 9:27 am

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.
 
ITU
just joined
Posts: 4
Joined: Wed Jun 15, 2011 5:45 pm

Re: API PHP class

Fri Jun 17, 2011 9:57 am

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

Hope this helps.
Yes it does. Works now. Thank You! I must be more carefull checking my scripts syntax.
 
yogii
Member Candidate
Member Candidate
Posts: 148
Joined: Wed Jun 16, 2010 5:38 am
Location: Batam, Indonesia

Re: API PHP class

Thu Jun 30, 2011 4:05 pm

hello, please help.

why this parameter not work?
$API->write('/log',false);
$API->write('=info=success');
see at the /log, no result.
 
Beccara
Long time Member
Long time Member
Posts: 606
Joined: Fri Apr 08, 2005 3:13 am

Re: API PHP class

Fri Jul 01, 2011 1:59 am

You need a ", TRUE" on the log= success line I think
 
kobuss
just joined
Posts: 2
Joined: Thu Mar 11, 2010 3:04 pm

Re: API PHP class

Fri Jul 01, 2011 12:06 pm

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 "<strong>tx: </strong>" . $first['tx-total-average'];
echo "<strong>rx: </strong>" . $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
 
reverged
Member Candidate
Member Candidate
Posts: 270
Joined: Thu Nov 12, 2009 8:30 am

Re: API PHP class

Fri Jul 01, 2011 11:20 pm

.... [23, 146] =status=can not connect >>> .....
This implies bw-test could not connect from the client to the server.
 
alphahawk
Member Candidate
Member Candidate
Posts: 101
Joined: Fri Mar 28, 2008 6:40 pm

Re: API PHP class

Wed Oct 12, 2011 8:05 pm

Found a weird issue with php api. If you are doing a file fetch you get stuck in a infinate check loop for end of file transfer since you never recieve a !done. I had to edit the php api code on lines 313 to this to handle it.
         if ($_ == "!done" || $_ == "=status=finished" )
            $receiveddone=true;
This fixed it but if there is a cleaner way to handle this I would like to know
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: API PHP class

Wed Oct 12, 2011 9:34 pm

This fixed it but if there is a cleaner way to handle this I would like to know
Shameless plug incoming...

See my signature. I have an option to let PHP gather responses for a few seconds (after which you can get all responses for a tag, and do the status=finished check on the last one) or you could simply execute a function for each response (in which you can perform the status=finished check). If that doesn't seem clean enough, do tell.

BTW, what file fetch? What command are you performing?
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API PHP class

Thu Oct 13, 2011 12:24 pm

/tool fetch
looking into the problem why exactly it stays lingering with status=finished and never stops
 
joelp
just joined
Posts: 1
Joined: Wed Jan 23, 2013 4:13 am

Re: API PHP class

Wed Jan 23, 2013 4:49 am

hi I trying do this, but without positive result.
Try this one:

1. Receive list of all users:
$API->write(/ip/hotspot/user/getall');
2. In PHP iterate through resulted array comparing user name, whose password should be changed, with current iteration's [name] property.
3. In the resulting array get [.id] property.
4.
$API->write('/ip/hotspot/user/set', false);
$API->write('=password=phptest',false);
$API->write('=.id=' . [.id]);
This might work.




I trying disable one que with this code:

returns me right que
  $RB->write('/queue/simple/print',false);
  $RB->write('?target-addresses='.$IP_to_disable);
  $queues = $RB->read(true);
trying to disable que
  foreach($queues as $queue) {
      if ($queue['target-addresses']==$IP_to_disable) {
        echo "queue with IP ".$IP_to_disable." is: ".$queue['.id'];
        
        //debug
        $RB->debug = true;
	
        $RB->write('/queue/simple/set',false);
        $RB->write('=disabled=yes',false);
        $RB->write('=.id='.$queue['.id']);
      }     
  }
But it disable nothing. Any idea whats wrong with my code?
 
ryvan
just joined
Posts: 3
Joined: Thu Jul 04, 2013 9:28 am

Re: API PHP class

Tue Jul 09, 2013 6:10 am

jpelp

when i run your code
  $RB->write('/queue/simple/print',false);
  $RB->write('?target-addresses='.$IP_to_disable);
  $queues = $RB->read(true);
am receiving this error after the "?target-addresses="

=message=no such command prefix when

and i am using versionMikroTik RouterOS 5.2 on rb750up....tanx..really lost.
 
penwelldlamini
just joined
Posts: 7
Joined: Thu Jan 22, 2015 4:08 pm

Re: API PHP class

Tue Jan 10, 2017 3:50 pm

How can I echo out only interface names and also how can I echo out total traffic used on a single specified interface
 
tayroborges
just joined
Posts: 3
Joined: Tue Jan 08, 2019 2:23 am
Location: Brazil

Re: API PHP class

Thu Feb 27, 2020 9:55 pm

Hello friends,
I would like to know how to transform the command
/interface ethernet poe set poe-out=off numbers=0
command line telnet.
to be used in the API, as it is unable to enable and disable poe out via API.
I need to activate and deactivate the POE output via API, I use the routeros_api.class.php
THANKFUL
 
vm2ns
just joined
Posts: 1
Joined: Tue Jun 30, 2020 2:16 pm

Re: API PHP class

Tue Jun 30, 2020 2:26 pm

hi, i don't know if this will be useful for anyone but...

Its a version of the connection function for the API post-v6.43 for ssl connections. not perfect but is a base for anyone trying to explore it..

AND
Take it, edit it and use it as you need.
No support...
<?php
function connect($ip, $login, $password) {

	for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) {

			$this->connected = false;

			$this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $ip . ':' . $this->port . '...');

			/*SEE MORE IN: https://www.php.net/manual/en/context.ssl.php*/
			$stream_context = stream_context_create( array( 'ssl' => array(
			'verify_peer'       => false,
			'verify_peer_name'  => false,
			'capath' => '/etc/ssl/certs' )));

			if ($this->socket = @stream_socket_client($ip.':'.$this->port, $this->error_no, $this->error_str, $this->timeout, STREAM_CLIENT_CONNECT, $stream_context) ) {
					stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
					socket_set_timeout($this->socket, $this->timeout);

					#Login method post-v6.43
					$this->write('/login', false);
					$this->write('=name=' . $login, false);
					$this->write('=password=' . $password);

					$RESPONSE = $this->read(false);

					if ($RESPONSE[0] == '!done') {

						$this->connected = true;

						break;

					}

					fclose($this->socket);

			}
			$this->debug('Connetion attempt #' . $ATTEMPT . ' failed - (' . $this->error_no .') ' . $this->error_str);
			sleep($this->delay);

	}
All credit to the original poster just changed some lines... didn't even put it flexible to general usage... since with my modification it only works with ssl.

Who is online

Users browsing this forum: No registered users and 16 guests