Aussicht auf eine unbefahrene Straße

Can we do better than php?


Introduction

Writing php in a web environment has one incredibly advantage over ruby python and nodejs when it comes to simple web development. Its serverless by design. Get yourself a minute to understand what this means. The webserver can execute the php in a given file which often results in good-enough code. While everyones TODO: find a good word for estatics for code is different, the requirements are very relaxing, there is no compilation needed and routes are mapped automatically.

To better understand what this means, compare these 3 scripts, which are handling a form submission and write the result to disk.

POST www/subscriptions/index.php

<?php
if (!$_POST) {
    return header('Location: /');
}

if(!isset($_POST['email']) || !isset($_POST['name']) || !isset($_POST['content'])) {
    return header('Location: /');
}

$email = $_POST['email'];
$name = $_POST['name'];
$content = $_POST['content'];

file_put_contents($email.".txt", $email.";".$name.";".$content);

header('Location: /' . $success_variables);

In ruby (sinatra):

POST www/subscriptions/index.rb


return redirect "/" unless request.method == 'POST'
return redirect "/" unless params[:email] || unless params[:name] || unless params[:content]

email = params[:email]
name = params[:name]
content = params[:content]

File.write "#{email}.txt", "#{email};#{name};#{content}"

redirect "/"

In nodejs (expressjs):

POST www/subscriptions/index.js

const fs = require('fs');

if (request.method !== 'POST') {
    return request.redirect("/")
}

if (!request.body.name || !request.body.email || !request.body.content) {
    return request.redirect("/")
}

const email = request.body.email
const name = request.body.name
const content = request.body.content

fs.writeFileSync(email+'.txt', email+';'+name+';'+content)

return request.redirect("/")

This code is not optimal for sure , feel free to suggest me better versions of it. ;)

Both nodejs and ruby are not able to execute this code, because "request" and "params" will be undefined/nil. More, the whole http abstraction is missing. In ruby you would install sinatra, in nodejs you would install expressjs.

So depending on what language you actually like, you probably would also like to write your webscripts in this language, right?

Sadly, there is only php, atm.

This brings me to the gist of this article. By asking Can we do better than php? i am not asking to write better php, or bash php in any way. I am asking for more diversity and how to translate the cool parts of php into other languages.

I just want use ruby in a www folder. I want a "ruby-fpm" or a "nodejs-fpm" or a "python-fpm" and configure my nginx to route these scripts to its processor.

A polyglot world

In a polyglot world, there would be one process manager that can execute scripts no matter if its php, nodejs, ruby or python. This processor provides simple but convenient http abstractions like request and or response objects for the http context It handles session and cookies.

Going even further the process manager could be able to handle security and resource management of these scripts. Let me illustrate what i mean.

Lets call our process manager ppm polyglot process manager. With ppm you can run scripts like foreman or docker or pm2

Running a script or configure nginx:

ppm run script.rb or ppm run script.js

location ~ \.js$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/ppm.sock;
    fastcgi_index index.js;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Getting a list of actually running processes:

ppm ps

SCRIPT_ID       SCRIPT                                  CPU(%)  RAM(MB) NET(kB/s)   LANGUAGE    CONTEXT     TIME(s)     RESOURCES
cfa4a788c55d    /home/nhh/ruby/script.rb                14,3    148     599         ruby        script      30          allowCreateThread,allowIO,allowNet
1b6f963a1bb7    /home/nhh/script.js                     14,3    148     599         node        script      643         allowIO,allowNet
0fc412853c8d    /home/nhh/script.py                     14,3    148     599         python      script      48          allowNet
cfa4a788c55d    /home/nhh/bash/script.sh                14,3    148     599         bash        script      12          -
cfa4a788c55d    /var/www/html/subscriptions/index.js    2,4     148     599         bash        web         0,4         allowCreateThread,allowIO,allowNet
cfa4a788c55d    /var/www/html/users/index.rb            6,9     148     599         bash        web         1,5         allowCreateThread,allowIO,allowNet