Kenyanke Kenyanke - 4 months ago 18
Node.js Question

Allow Node.js webserver to handle PHP

I have a web server that I created using Node.js that supports multiple file types, I'd like to integrate PHP into Node.js, so if a user wishes to use a php script, my web server will know how to handle it.

I've read up about Nginx, php.js and several other guides, wondering if anyone has any other simpler method, or has a newer node framework been created for this?

Any help is appreciated, thanks

Answer

For the below code, you will need php installed on the host machine and added to $PATH. Don't try to re-invent the wheel, everything you need has already been made for you, all you have to do is connect the dots.

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

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

http.createServer(function(request, response) {

  var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

  var contentTypesByExtension = {
    '.html': "text/html",
    '.css':  "text/css",
    '.js':   "text/javascript",
    '.avi' : "video/x-msvideo",
    '.exe' : "application/octet-stream",
    '.gif' : "image/gif",
    '.htm' : "text/html",
    '.ico' : "image/x-icon",
    '.png' : "image/png",
    '.jpeg' : "image/jpeg",
    '.jpg' : "image/jpeg",
    '.mp3' : "audio/mpeg",
    '.mpeg' : "video/mpeg",
    '.pdf' : "application/pdf",
    '.sh' : "application/x-sh",
    '.snd' : "audio/basic",
    '.src' : "application/x-wais-source",
    '.svg' : "image/svg+xml",
    '.tar' : "application/x-tar",
    '.tgz' : "application/x-compressed",
    '.txt' : "text/plain",
    '.zip' : "application/zip",
    '.woff' : "application/font-woff",
    '.woff2' : "application/font-woff2"
  };

  var param = url.parse(request.url).query;

  fs.exists(filename, function(exists) {


    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';

    fs.readFile(filename, "binary", function(err, file) {
        if(err) {        
            response.writeHead(500, {"Content-Type": "text/plain"});
            response.write(err + "\n");
            response.end();
            return;
        }

        var headers = {};
        var contentType = contentTypesByExtension[path.extname(filename)];

        if (contentType) { 
            headers["Content-Type"] = contentType;
            response.writeHead(200 + " " + headers);
            response.write(file, "binary");
            response.end(); }
        else if(filename.indexOf(".php") >= 0) {
            var tmp = filename.replace(/ /g, '\\ ');
            runner.exec("php " + tmp + " " + param, function(err, phpResponse, stderr) {
            if(err) console.log(err); /* log error */
            response.writeHead(200, {"Content-Type": "text/plain"});
            response.write( phpResponse );
            response.end();
            }); }

    });
  });
}).listen(1000);

console.log("Server started on http://localhost:1000/");
console.log("Server supports HTML, CSS, JS and PHP!");
Comments