Локально запускать PHP-программу из браузера с помощью Node.js

Node.js - это звено, позволяющее подключить браузер к исполняемым файлам на локальном компьютере.

На следующей диаграмме показана работа системы:

  1. Запускаем Node со сценарием сервера:
    node runphp.js
  2. В
  3. браузере вводится локальный URL-адрес сценария:
    localhost:1000/dirlist.php
  4. Узел запускает выполнение сценария.
  5. Сценарий отображает результат с помощью команды echo.
  6. Результат отправляется Node на новую HTML-страницу.

PHP HTML et Node.js

Для запуска программы в URL-строке вводится имя программы:

localhost:1000/dirlist.php

И можно также перейти от переменных к программе, которую нужно выполнить в таком виде:

localhost:1000/dirlist.php?x=test 

Код JavaScript сервера происходит от кода, который уже использовался для создания HTML-файлового сервера с Node.js. Но на этот раз вместо отображения контента для запуска программы используется модуль child_process, тогда будут отображаться именно результаты программы.
Это работает как на местном посту, так и на удаленном хостинге.

1) Как всегда начинаешь с создания сервера

var server = http.createServer(php);
server.listen(1000);
console.log("PHP ready to run script given on port 1000.");

И мы назначаем порт связи.

2) Проверяется наличие сценария в файловой системе

function php(request, response)
{
  var urlpath = url.parse(request.url).pathname;
  var param = url.parse(request.url).query;
  var localpath = path.join(process.cwd(), urlpath);
  fs.exists(localpath, function(result) { runScript(result, localpath, param, response)});
}

Имя файла извлекается из URL с помощью метода parse модуля url.
И дополнительно извлекаем строку параметров методом query. Она передается как есть на PHP-скрипт.

3) Запускаем выполнение сценария

function runScript(exists, file, param, response)
{
  if(!exists) return sendError(404, 'File not found', response);
  runner.exec("php " + file + " " + param,
   function(err, stdout, stderr) { sendData(err, stdout, stderr, response); });
}

Метод exec от child_process до первого параметра, что вводится в командной строке, поэтому имя интерпретатора PHP, имя сценария и список параметров.

4) Все, что отображает скрипт, будет отображаться в браузере

function sendData(err, stdout, stderr, response)
{
  if (err) return sendError(500, stderr, response);
  response.writeHead(200,{"Content-Type": "text/plain;charset=utf-8"});
  response.write(stdout);
  response.end();
}

Это роль функции sendData, вызванной в качестве обратного вызова методом exec.

5) Пример PHP-скрипта

Этот демонстрационный PHP-скрипт считывает файлы из каталога и отображает их список. Все, что он отображает, появится в браузере.

<?php
echo "Parameter:".$argv[1]."\n";
echo "Directory content...\n\n";

$output="";
if ($hnd = opendir('.'))
{
  while($file = readdir($hnd))
  {
    if ($file == "." || $file == "..") continue;
    $output .= "$file\n";
  }
  closedir($hnd);
}
echo $output;
?>

Параметры находятся в таблице $ argv. Первый параметр (единственный в примере) в $ argv [1]. Программист должен вырезать строку и использовать ее содержимое.

6) Полный исходный код JavaScript

var http = require("http"),
path = require("path"),
fs = require("fs"),
url = require("url"),
runner = require("child_process");

function sendError(errCode, errString, response)
{
  response.writeHead(errCode, {"Content-Type": "text/plain;charset=utf-8"});
  response.write(errString + "\n");
  response.end();
  return false;
}

function sendData(err, stdout, stderr, response)
{
  if (err) return sendError(500, stderr, response);
  response.writeHead(200,{"Content-Type": "text/plain;charset=utf-8"});
  response.write(stdout);
  response.end();
}

function runScript(exists, file, param, response)
{
  if(!exists) return sendError(404, 'File not found', response);
  runner.exec("php " + file + " " + param,
   function(err, stdout, stderr) { sendData(err, stdout, stderr, response); });
}

function php(request, response)
{
  var urlpath = url.parse(request.url).pathname;
  var param = url.parse(request.url).query;
  var localpath = path.join(process.cwd(), urlpath);
  fs.exists(localpath, function(result) { runScript(result, localpath, param, response)});
}

var server = http.createServer(php);
server.listen(1000);
console.log("PHP ready to run script given on port 1000.");

Локальный сервер

На самом деле у нас с этой программой есть база локального сервера приложений: изменив имя сценария в URL-строке, можно запускать разные инструменты.
Чтобы автоматизировать запуск, можно поставить каждый в bookmark, а возможно, использовать bookmarklets для передачи настроек.
Этот локальный сервер также может быть запущен сам, поместив приведенную выше команду в пакетный файл, который будет выполняться при запуске сеанса.