PHP script used locally, with HTML 5 interface thanks to WebSocket

To give a native script a HTML 5 interface, we use Node.js, and WebSocket to make best use of data in the interface.

In a previous study we saw how to use locally HTML for interface of a PHP script, thanks to a Node.js server. However, this method is too simple since the results of the script are displayed as such in the browser. This may be suitable for some applications, but if you want a more interactive interface, it is necessary that we can process data sent from the script when they are received by the HTML page.
To do this we use two modules:

Net

This module is integrated by default in Node.js and it can connect via sockets to a program in the file system by creating a TCP server. One can of course connect also to a remote script, but this is beyond our purpose.
The server runs the PHP script with the given arguments. This can be done actually with a script in any programming language provided it supports TCP connections. The script performs the processing it is dedicated and sends the result to the server through the PHP socket_write function, or equivalent in another language.
To use TCP with PHP on Windows, you must enable two lines in php.ini (remove the semicolon):

extension_dir="ext"
extension=php_sockets.dll 

Socket.io

This module must be added with npm, if it is not already. It is used to exchange information between the HTML interface and Node.js. The interface sends the arguments from the interface and the script name to the server, by WebSocket.
When the server then receives the results of the script, it sends them to the interface always by WebSocket.

The flow diagram is as follows:

PHP et HTML par WebSocket et Node.js

The PHP script

The data from the interface being passed to the script as arguments, there is nothing to change if it designed to be used at command line.

To get the results, which were previously displayed in the console, we replace:

echo $data;

by a function:

function echoSocket($data)
{
  $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  if($socket==false) die("Not created");
  socket_connect($socket, '127.0.0.1', '1001')
    or die(socket_strerror(socket_last_error()));
  socket_write($socket, $data);
  socket_close($socket);
}

echoSocket("You choosen: <b><span style='color:$data'>$data</span></b>.");

The function creates a local TCP connection on port 1001, sends data and closes the connection.

The HTML interface

We create an instance of WebSocket with the socket.io the module in the HTML page:

<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect();
... 

The demo page asks the user to choose a color:

<select id="color">...</select>
<input type="button" value="Send color" onClick="callserver()">

When he clicks on the button, the information is sent to Node by this function:

function callserver()
{
  var mycolor = document.getElementById("color").value;
  socket.emit('interface', mycolor);
}

The interface expects the server's response:

socket.on('notification', function(x) { notification(x); });	

It deals with the content sent from the PHP script. It adds <br> and put the answer in an area of ​​the interface:

function notification(content)
{
  var x=document.getElementById("storage");
  x.innerHTML += content + '<br>';
}

The HTML interface therefore uses data provided by the native program as needed.

Limitations

If you want your HTML interface can load a CSS file or image, the ability to load these files must be added to the JavaScript server. This will be adressed in a later article. For now the CSS code should be integrated into the page.

The JavaScript server

An instance of WebSocket is created to communicate with the HTML page:

var websocket = require("socket.io");
var app = http.createServer(function(r, s){ handler(r,s); });
app.listen(1000);
var listener = websocket.listen(app);

And an instance of Net to receive data from the native script:

var net = net = require('net');
var nativeserver = net.createServer(function(native) { nativeComm(native);});
nativeserver.listen(1001, '127.0.0.1');

When the server receives data on port 1000 from the HTML interface, it launches the PHP script with the data as parameters.

websocket.on('interface', function (data) {
  fs.exists(localpath, function(result) { runScript(result, localpath, data)});
});

When the server receives data from the native script on port 1001, it sends them on port 1000 to the HTML interface:

native.on('data', function(data) {
  listener.sockets.emit('notification', data);
});

For the full source, download the demo ...

Download the PHP, JavaScript and HTML files

In the archive, the files used by this demonstration are:

To try the demo, run the server:

node php-socket.js

Then open the browser and type in the URL bar:

localhost:1000/php-socket.php

The server then displays the interface php-socket.html in the browser. Choose a color and click on the button to send the data to the PHP script.

These elements should be a sufficient starting point to create a local application with a complex interface in HTML 5 and CSS, in PHP, Python, Ruby or any language running on the command line. Such an application should be universally portable and even run natively on a mobile.

For a real application of this tool, see Link Checker with graphical user interface.