php API connection problem?

I use php API and I get this error:
http://wiki.mikrotik.com/wiki/API_PHP_class
Connection attempt #5 to IP:8728… Error…

What is my problem?
Should I enable any function?

Do you have API enabled under /ip services ? It is disabled by default.

Do you have a firewall rule blocking input on tcp 8728?

I enable API services and add rule in firewall.
Chain:Input
Protocol: tcp or 6(tcp)
Port:8728
Interface:Ether1
Action:Accept

Yet it doesn’t work for me!

Do the counters increment on that firewall rule?

Is your version of php compiled with sockets enabled?

I have used this and had no trouble.

If the firewall counters increment then the server has sockets enabled.

There is also API Studio that I have used. This will tell you if the problem is with the RB or something else.
This is a great tool to debug commands as you can quickly test api functions without coding them in php.
As you will soon find out, API has quirks and not all the commands work the same as they do from the cli.

http://wiki.mikrotik.com/wiki/API_Delphi#The_API_STUDIO_application

When I use API API Studio
I get:
15/04/2011 10.40.39 - info 103 - connected to MikroTik
and some more message!
this means socket function doesn’t work in my website!

if you find quirks that are not documented please write to support.

Now I get this error:
Warning: preg_match_all() expects parameter 2 to be string, array given in C:\xampp\htdocs\routeros_api.class.php on line 171

What should I do with this?

when in run the php script from the cli, everything is working

sudo -u apache php script.php

Connection attempt #1 to mikrotik_ip:8728...
<<< [6] /login

[5/5] bytes read.
[5, 39]!done
[37/37] bytes read.
[37, 1]=ret=d2b0464485a7688758f2503d7346a2a5
<<< [6] /login
<<< [9] =name=api
<<< [44] =response=007d865b5e7ad498684367513f8707e9f9
[5/5] bytes read.
[5, 1]!done
Connected...
<<< [18] /system/script/run
<<< [12] =.id=script_name
[5/5] bytes read.
[5, 1]!done
Disconnected...

when i run the same script in chrome i receive "Connection attempt #1 to mikrotik_ip:8728... Connection attempt #2 to mikrotik_ip:8728... Connection attempt #3 to mikrotik_ip:8728... Connection attempt #4 to mikrotik_ip:8728... Connection attempt #5 to mikrotik_ip:8728... Error..."


the script i use is,

<?php require('routeros_api.class.php'); $API = new routeros_api(); $API->debug = true; if ($API->connect('mikrotik_ip','user','password')) { $API->write('/system/script/run',false); $API->write("=.id=script_name"); $API->read(false); $API->disconnect(); } ?>

permissions and ownership
-rwxrwxrwx. 1 apache apache script.php

@c1audiu
@UGP2

Try out the PHAR from my signature. In particular, first try to run it from the command line, like:

php PEAR2_Net_RouterOS-1.0.0b5.phar mikrotik_ip user password

and see what errors, if any, it gives. If you can start typing no problem, the connection is fine, and the problem is definitely not on the side of the router. You can exit gracefully with “/quit” and pressing enter twice.

Now… If that part works, try to run a test piece of PHP code, like:

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

try {
    $client = new RouterOS\Client('mikrotik_ip', 'user', 'password');
    echo 'OK';
} catch (Exception $e) {
    die($e);
}

And see if that outputs “OK”.

If it doesn’t, and yet the above commands worked, then chances are the problem is in the web server’s firewall - Depending on what SAPI the PHP installation is using, Apache’s executable (“httpd” I think), or PHP’s “php-cgi” executable must be allowed to make outgoing connections. Or alternatively, you could allow ANY application to make outgoing connections to port 8728.

@boen_robot

Thank you for the response.

Downloading PEAR2_Net_RouterOS-1.0.0b5.phar and running #php script.php

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

try {
    $client = new RouterOS\Client('mikrotik_ip', 'user', 'password');
    echo 'OK';
} catch (Exception $e) {
    die($e);
}

I get “Ok” response in CLI.

I dont think i have a connection problem. As i mentioned in my first post, running the php script from CLI the script on mikrotik is executed. I cannot run the script from within a web browser.

I tried even with chown -R 777 permisions on the public_folder. And running the script with apache user from cli is working…

But if you run the script from a web browser, do you get “OK”? That was the key point there. PHP uses a different executable when running from a web server after all.

If you don’t get OK from a web browser, then you should instead see an error message indicating where the problem might be. If you do have an error message, please post it.

When the script is executed in chrome,

exception 'PEAR2\Net\Transmitter\SocketException' with message 'stream_socket_client(): unable to connect to tcp://mikrotik_ip:8728/user%2Fpassword (Permission denied)' in phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/Transmitter/TcpClient.php:205 Stack trace: #0 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/Transmitter/Stream.php(130): PEAR2\Net\Transmitter\TcpClient->createException('stream_socket_c...', 0) #1 [internal function]: PEAR2\Net\Transmitter\Stream->handleError(2, 'stream_socket_c...', 'phar:///var/www...', 147, Array) #2 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/Transmitter/TcpClient.php(147): stream_socket_client('tcp://10.11.12....', 13, 'Permission deni...', '60', 4, Resource id #15) #3 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Communicator.php(148): PEAR2\Net\Transmitter\TcpClient->__construct('mikrotik_ip', 8728, false, NULL, 'user/04J650ej1y2...', '', NULL) #4 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Client.php(146): PEAR2\Net\RouterOS\Communicator->__construct('mikrotik_ip', 8728, false, NULL, 'user/04J650ej1y2...', '', NULL) #5 /var/www/public_html/script.php(6): PEAR2\Net\RouterOS\Client->__construct('mikrotik_ip', 'user', 'password') #6 {main} Next exception 'PEAR2\Net\Transmitter\SocketException' with message 'Failed to connect with socket.' in phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/Transmitter/TcpClient.php:205 Stack trace: #0 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/Transmitter/TcpClient.php(163): PEAR2\Net\Transmitter\TcpClient->createException('Failed to conne...', 8, Object(PEAR2\Net\Transmitter\SocketException)) #1 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Communicator.php(148): PEAR2\Net\Transmitter\TcpClient->__construct('mikrotik_ip', 8728, false, NULL, 'user/04J650ej1y2...', '', NULL) #2 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Client.php(146): PEAR2\Net\RouterOS\Communicator->__construct('mikrotik_ip', 8728, false, NULL, 'user/04J650ej1y2...', '', NULL) #3 /var/www/public_html/script.php(6): PEAR2\Net\RouterOS\Client->__construct('mikrotik_ip', 'user', 'password') #4 {main} Next exception 'PEAR2\Net\RouterOS\SocketException' with message 'Error connecting to RouterOS' in phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Communicator.php:150 Stack trace: #0 phar:///var/www/public_html/PEAR2_Net_RouterOS-1.0.0b5.phar/PEAR2_Net_RouterOS-1.0.0b5/src/PEAR2/Net/RouterOS/Client.php(146): PEAR2\Net\RouterOS\Communicator->__construct('mikrotik_ip', 8728, false, NULL, 'user/04J650ej1y2...', '', NULL) #1 /var/www/public_html/script.php(6): PEAR2\Net\RouterOS\Client->__construct('mikrotik_ip', 'user', 'password') #2 {main}

OK… The part

stream_socket_client('tcp://10.11.12....', 13, 'Permission deni...', '60', 4, Resource id #15)

Seems to indicate the problem is exactly what I said previously about the web server’s firewall.

The message stream_socket_client() gives you is “Permission denied”, meaning that the OS ultimately prevents it from making a connection. There is a firewall, which allows the executable “php” to make outgoing connections… But apparently doesn’t allow Apache’s executable or the “php-cgi” executable to make such connections.

Trying to Google the error message points me also to this StackOverflow exchange where they suggest that running SELinux could also be an issue - by default, it prevents Apache from making any outgoing connections, since Apache doesn’t “normally” do that. If PHP is running as an Apache module though, any connection you make from PHP is executed inside the Apache process. So to solve the problem, you need to either disable SELinux or configure it to allow outgoing connections, as shown in the link above.

@boen_robot

It seems selinux was the problem.
Thank you very much for the help.

Hi, got this error :
Parsing is OK if you are seeing this…File included!..Connection FAIL! Details:exception ‘PEAR2\Net\Transmitter\SocketException’ with message ‘stream_socket_client(): unable to connect to tcp://10.0.34.53:8728 (Permission denied)’ in /var/www/html/PEAR2_Net_RouterOS-1.0.0b6/src/PEAR2/Net/Transmitter/TcpClient.php:225

I am using CentOS7, how do you fix this ?

Try the answers in the StackOverflow exchange linked above.

Thanks, I read it more carefully and disabled SELinux, it works fine now, let’s start with more API/PHP examples

Hi, I am using this code and works well with CCR1009 6.44.3 (stable) RB3011 6.44.5 (long term) and RB941
my problem is when i use it on Hex RB750 Gr3 6.44.5 it doesn’t work.
on logfile says: system,error,critical login failure from user from ip via api
kindly help. thanks in advance.

<?php require('routeros_api.class.php'); $API = new RouterosAPI(); $API->debug = false; if ($API->connect('routerip','user',password')) { $API->write('/ip/hotspot/ip-binding/print', false); $API->write('=count-only=', false); $API->write('~active-address~"1.1."'); $ARRAY = $API->read(); $API->disconnect(); } ?>