Node.js vs. PHP

php_vs_node

By Azat Mardanov

PHP is not going to disappear soon, but its position is being undermined even further by the nascent Node.js. When the Internet exploded in the 2000′s, PHP was the thing ”all the cool kids” did. PHP caught on because:

  • It was an interpreted language, unlike C++ or Java which require the source code compilation;
  • It had the ability to be used directly within HTML in its template files;
  • It had cheap, shared hosting providers on Apache servers with a Linux, Apache, MySQL and PHP (LAMP) stack;
  • It had a functional nature, which is easier to learn than the object-oriented programming.

Over the years, PHP and its apps became vulnerable to security threats (e.g., SQL injections), lacked a centralized packaging registry (was Composer inspired by Node Package Manager?), had an inconsistent API and suffered from subpar performance. It’s easy to argue that there are better alternatives to PHP, for example Ruby on Rails and Django, however nothing is as approachable as Node.js.

For those of you who aren’t familiar with Node.js, or who have heard of it but can’t quite grasp the concept, I like to say that it is functionally similar to the PHP + Apache or ASP + IIS stacks. Nowadays, it is also gaining momentum.

The platform uses JavaScript and its non-blocking I/O mechanism allows for a excellent performance. Node.js also comes with a robust package manager solution npm (which stands for Node Package Manager). However, because Node.js is a lower-level technology, it is not comparable to complex frameworks like Struts, Rails or Django directly.

Many people, whether software engineers or entrepreneurs, are often faced with the decision: “What tech stack should I use?” In this article, I’ll try to compare PHP and Node.js using an apples-to-apples approach, looking at the question from different angles including:

  • Syntax
  • Context switch
  • Modules
  • Ecosystem
  • Frameworks
  • Real-time apps
  • Database apps
  • Third-party services apps
  • Web servers
  • Hosting
  • Performance

Disclaimer

As this article reflects my own opinion, I wanted to start by clarifying my background as it might be reflected within my point of view.

I’ve worked with many technologies including Ruby on Rails, Python, Java/J2EE, VB, ASP, Perl and, of course, PHP. One of my most complex PHP projects was openList.co which involved the use of the MVC pattern with template engines, classes, a database abstraction layer and .htaccess re-routing.

However, during the past couple of years, my focus has been dedicated solely to Node.js and front-end JavaScript frameworks like Backbone.js. So my opinion might be biased. Please feel free to comment based upon your own experience with real projects in both PHP and Node.js. If you want to learn more about Node.js take a look at my book Rapid Prototyping with JS or the coding intensive full-time course at HackReactor.

Syntax

This section looks at some simple code examples so that you can compare the syntax of PHP and JavaScript (which, as we mentioned, is what Node.js is based upon). Both platforms can be accessed to the command line interface via $ php -i and $ node.

For example, this snippet prints “Hello World” in PHP:

echo 'Hello World';

This will output the same in Node.js:

console.log('Hello World');

Note: In JavaScript semi-colons are optional except when inside of the for loops and before immediately-invoked function expressions (IIFE).

The following is the sleep function in PHP:

echo "a"."\n";
sleep(2);
echo "b"."\n";
echo "c"."\n";

The above code will output:

a

…and then after a 2 second delay:

b  c

If we try to re-write this code in Node.js:

console.log('a')
setTimeout(function() {
  console.log('b')
 },2000)
console.log('c')

…this snippet will print:

a  c

…and, after a 2 second delay, it will print:

b

Why the difference in output? The setTimeout() function is asynchronous, meaning that the remaining code does not stop executing while that function is processed.

Note: In JavaScript, console.log() automatically adds the end of line symbol.

The for loop in PHP might look like this:

for ($i = 1; $i <= 10; $i++) { 
  echo $i;
} 

It’s strikingly similar in Node.js:

for (var i = 0; i <= 10; i++) { 
  console.log(i);
}

Create an array in PHP:

$users = array( 
  array('name' => 'John', 'id' => 3940), 
  array('name' => 'Peter', 'id' => 8904) 
); 

To create an array in Node.js:

var users = [ 
  { name: 'John', id: 3940 }, 
  { name: 'Peter', id: 8904 } 
]

To iterate through an array in PHP:

for($i = 0; $i < count($users); ++$i) { 
  $users[$i]['id'] = mt_rand(000000, 999999); 
}

To iterate through an array in Node.js:

for (var i; i < arr.length; i++) {
    users[i] = Math.floor(Math.random()*1000000);
}

Or in a functional manner:

users.forEach(function(user, i){ 
  users[i] = Math.floor(Math.random()*1000000); 
})

To declare a function in PHP:

function hello($name) {
  echo "Hi ".$name;
}
hello("Peter"); //outputs Hi Peter

To declare a function in Node.js:

function hello(name) {
  console.log('Hi' + name);
}
hello('Peter'); //outputs Hi Peter

To declare a new object in PHP:

class foo {
    function do_foo()  {
        echo "Doing foo."; 
    }
}

$bar = new foo;
$bar->do_foo();

To declare a new object in Node.js:

var foo = function () {
  return { 
    do_foo: function () {console.log('Doing foo');}
  };
};

var bar = foo();
bar.do_foo();

Note: there are no classes in Node.js/JavaScript, because objects inherit directly from other objects (prototypal inheritance). There are many instantiating patterns such as pseudo-classical, functional (as above) and classical.

A database snippet with the PDO database connection library in PHP:

$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); //execute();

A Node.js database script with the Mongoskin MongoDB library:

//assuming we use Connect/Express middleware for req.query
var db = require('mongoskin').db('localhost:27017/db'); 
db.collection('users').find({_id: req.query.id}).toArray(function(err, results) {
    if (err) throw err;
    console.log(results);
});

Context Switch

The switch between different environments and languages is attributed to a drop of efficiency when writing software code. Research and personal anecdotal observations show that interruption negatively impacts programmers’ performance. With less languages to learn and remember, the flow is smoother and the code is better. For a deeper articles on this subject you might want to take a look at Human Task Switches Considered Harmful and The Multi-Tasking Myth.

PHP

With the LAMP stack (i.e, Linux, Apache, MySQL and PHP), developers must master at least two more languages which are PHP and SQL in addition to the mandatory and omnipresent HTML, CSS and JavaScript.

Node.js

Node.js is brilliant at having less context switches, because together with MongoDB, this stack can operate only in one language: JavaScript.

Here’s an example of MongoDB shell commands (called by $ mongo):

> db.users.find({});
> db.users.insert({name: 'Azat', email: 'azat@rpjs.co'})
> db.users.update({name:'Azat'},{$set:{email:'hi@rpjs.co'}})

Modules

PHP

There is PEAR, a veteran system which installs packages on a server globally, and a better alternative, Composer.

In other cases, developers have to seek out modules – or components as they call them - on various websites, and to administer them manually by placing *.php files into sub-folders of their projects. Unfortunately, all this is not very kosher.

Node.js

Node.js comes with a superior and dependable package management system called npm and its registry (npmjs.org) which is easy to use and publish. Everything is administered via the package.json file and versioned locally, unless we’re installing a CLI tool with the -g option.

Ecosystem

PHP

This is probably one of the most important areas where PHP still beats Node.js. There are amazing open-source applications like WordPress, tons of free scripts, quality tools and books.

Node.js

Node.js is growing faster than any other platform/language. This is mostly due to the philosophy of keeping modules minimal and performing only a small set of tasks. Other factors might include such things as:

  • The popularity of front-end JavaScript among web developers
  • Existence of specs and an abundance of JavaScript resources and gurus amassed during the language’s many years of existence
  • A collaborative open-source community, mostly on GitHub
  • Ease of npm use (to publish an NPM module run $ npm publish).

As a result, some people predict that Node.js will surpass other languages in the absolute number of contributions.

Frameworks

It’s important to have rich tools and proven libraries at our disposal.

PHP

CakePHP and Zend come to mind first, but for more choices there is an extensive list.

Node.js

Playing field is relatively level, with Express.js being the most popular choice and full-stack MVC frameworks like Meteor and Derby growing quickly.

Real-time apps

PHP

For PHP, there is the Node.js-dependent Elephant.io and some other approaches. The problem with native PHP and websockets is that Apache and IIS — where PHP is usually run as a module — weren’t really built with a persistent connection in mind. Therefore, developers have to use the standalone processes like Apache WebSocket or Ratchet.

Node.js

Building real-time apps is just a breeze with the Node.js stack using Socket.IO library with the Express.js framework and the Handlebars reactive template engine. In the Meteor and Derby projects, building real-time apps is taken one step further by combining front and back end code bases with a persistence layer, which reduces the complexity and speeds up the development dramatically.

Database apps

PHP

PHP has a long and fruitful history with traditional, relational databases like MySQL, hence the name of the stack LAMP — Linux, Apache, MySQL and PHP.

Node.js

Node.js is natural with NoSQL databases like MongoDB.

The database performance is somewhat comparable to MySQL depending on the use case (for reference, see MySql vs MongoDB performance benchmark (MySQL), Simple Test : MongoDB vs MySQL (MongoDB) and MongoDb vs MySql – Fight!!! (MongoDB) articles). However, MongoDB is superior for distributed databases and is highly scalable. The added bonus is that without a fixed schema, NoSQL databases are perfect for cloud computing, prototyping and agile projects.

Third-party services apps

PHP

As is the case with many traditional languages, PHP’s flow is blocked until the remote server has responded, hence the need for multi-threading.

Note: Some languages provide this feature when special libraries/frameworks such as EventMachine for Ruby or Twisted for Python are used. However, they’re very complex and weren’t built from the ground up with the platform.

Node.js

On the contrary, due to its non-blocking I/O, Node.js can handle multiple requests and make multiple requests as a client to third-party services (e.g., Twitter, Amazon) with just one thread of execution.

Web Servers

PHP

Since PHP 5.4 and higher, there is a built-in development server that we can be started with:

$ php -S localhost:8000

Assuming we have an index.php in that folder:

<?php echo 'Hello World';  ?>

For versions prior to 5.4, there are “all-in-one” tools like MAMP and XAMPP.

As for the production environment, PHP can’t be run on its own. One of the most popular technologies used with PHP is Apache and nginx, where PHP is just a module of Apache web server. My personal experience with Apache is that it has a steep learning curve and while being very configurable, by default those configurations are prone to security leaks.

Node.js

Node.js was created from the ground up for the network applications and there is a set of core modules to write web servers.

We can start a Node.js server with:

$ node .

…assuming our index.js file in this folder has the code to create a new server such as:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

In production, Node.js can be run on SmartOS or Linux (like Ubuntu) as a service.

Note: Multi-threading is absolutely possible in Node.js with clusters and/or external modules.

Hosting

PHP

PHP owes its popularity in large part to the ease and cheapness of shared hosting solutions. True, it’s hard to find one without the LAMP stack on it. This commoditization sometimes leads to security holes and less than acceptable downtime due to hosting providers overselling and other consumers using malicious code.

Platform as a Service is a better alternative, being somewhere in between a full-fledged, dedicated server and shared hosting. Most of PaaS providers support PHP right of the gate.

Node.js

Node.js works nicely on PaaS’s, with Heroku and Nodjitsu leading the list. Also, the cloud infrastructure company Joyent (the maintainer of Node.js), developed a powerful operation system SmartOS that allows for performance bursts, painless deployment and DTrace debugging.

Performance

It’s needless to say that performance is important. This resource shows different benchmark tests: Which programs are fastest?.

PHP

PHP is relatively fast but due to its bottleneck in the file system, database and third-party requests, it fails miserably in comparison with Node.js and its super fast V8 engine.

For example, when Facebook reached its scalability limits with PHP, they wrote an extremely fast C++ library and virtual machine which they called HipHop VM, but kept the PHP API.

Node.js

Node.js is extremely fast due to its non-blocking I/O mechanism and V8 engine technology. I have even heard that Joyent started re-writing some of their C++ modules in Node.js.

Conclusion

PHP was an outstanding technology in its day. Its success and popularity came from:

  • Its ease of learning and use;
  • Availability of cheap and straightforward hosting mostly using shared LAMP servers;
  • Abundance of open-source scripts, apps and libraries.

At the same time, it is my opinion that these same things now lead to its dusk. The contributions to the core from beginner programmers modified the API inconsistently while the lack of OOP/classes and module management systems inhibited open-source community growth. Absence of a leading framework (Ruby on Rails comes to mind as an example of a single dominant framework for a language) or programming paradigm also helped to produce a lot of bad code that relied heavily on mixing PHP and HTML code without any separation of concerns. On the other hand, there are a lot of good products and infrastructure built on PHP that are here to stay for the time being.

Node.js is relatively young, with only three years since its first commit, but it’s already the fastest growing platform by the pace of contributions (and the absolute number will surpass other languages in a few years). The fact that the JavaScript language is the most popular language in the world and has the biggest attributed to that. Many tools are ported to Node.js with little or no modification from the browser environment. Also, great books on JavaScript fundamentals (for example, JavaScript: The Good Parts and Eloquent JavaScript) have experienced a surge in the popularity again. Most importantly perhaps, Node.js is very efficient and great for building real-time, NoSQL-oriented, scalable systems.

This article was originally published at http://webapplog.com/php-vs-node-js/

34 Comments

  1. Mike Keesey said:

    Nice overview. Note that if you do want to use classes, you can use TypeScript instead of JavaScript (or along with it, since it’s a superset of JavaScript). (It all transpiles to prototype inheritance, but the code’s a lot nicer to work with.)

    • Jonathan Fielding said:

      I work so much in PHP and javascript the similarity has in the past lead to me trying to use . to join strings in JS and + to join strings in PHP in the past. Not done that for a while now though.

  2. EllisGL said:

    I use both PHP and Node and want to point out the following issues:
    “for($i = 0; $i < count($users); ++$i) {"
    is bad, you should count before looping.
    "$cnt = count($users);

    for($i = 0; $i < $cnt; ++$i) {"

    Node JS does have MySQL drivers and PHP does have drivers for all types of databases.

    "Node.js can be run on SmartOS". SmartOS is a hyper-visor. Unless you have a trick up your sleeve running Node JS with out an OS, I would love to see it.

    • Logan Murray said:

      I don’t think that’s true. Accessing the count of the array is little different than reading a local variable. It’s not like PHP is actually iterating over the array to count its items. It surely maintains the count as a private variable internal to its structure and so any performance gains by capturing the count initially would be negligible at best and not worth the effort, imo.

      • Chong said:

        I’d agreed with EllisGL on using a variable to hold the array count. “for” loop calls “count” function in each loop which could slowdown the execution quite a bit if you’re looping over a big array.

  3. Raymond Camden said:

    I’m not sure your database section is fair. I’m not a PHP user (I do ColdFusion and Node), but PHP has a module for Mongo, and Node has a module for MySQL. You can use both in both platforms.

    • Azat Mardanov said:

      Yes, that’s true. But majority of apps use Node + MongoDB and PHP + MySQL combinations. I really don’t know why.. Oh, maybe because MongoDB uses BSON which is basically JSON and also MongoDB has JavaScript interface virtually identical to native MongoDB Node.js driver (and it’s wrappers like Mongoskin, Monk, and Mongoose)? ;-)

      In addition to that MongoDB is more scalable and faster.

  4. Justin Noel said:

    Did you mean : users.forEach(function(user, i){ users[i]['id'] = Math.floor(Math.random()*1000000); })
    Otherwise, you’re replacing the existing user properties with some integers.

  5. Ben said:

    Chalk & cheese.

    I had to build an identical app in both PHP and Node.js as part of a technical feasibility study. PHP won outright due to the brevity of the code written and its ability to be scaled cheaply and easily (a large amount of data had to be bootstrapped to each client, rendering Node.js’s non-blocking API fairly useless given the circumstance), and its excellent support of PDO.

    I understand that this is a blow-for-blow commentary but the conclusion I would draw from personal experience is that PHP and Node.js are entirely discrete in principle and should be used accordingly.

  6. Tim Anderson said:

    Nice comparison. I would add that you can also use couchdb in lieu of mongodb, and still use just javascript.

  7. Joe Mamma said:

    I just started playing with Node.js last night and ended up staying awake until 3a. I’m pretty excited! I enjoyed my read on CouchDB a few months ago and couldn’t think of a way to really make it fit with any projects I had in mind. Now with Node I’ll be pushing some ideas further.

  8. Corey Ballou said:

    This was a naive comparison IMO as several of your points are incorrect or out of context.

    1. Security threats: SQL injection is a moot point. You’re comparing MySQL to MongoDB. That’s apples to oranges. For those using the mysql extension in node, it’s just as applicable. Likewise, if you use PHP’s Mongo library, that disappears. The true difference is in the quality of blog posts and articles demonstrating proper usage of PDO or mysqli with prepared statements. Both languages are subject to XSS attacks, CSRF, etc. It’s up to your application or framework to handle these attack vectors.

    2. PHP has Packagist which maintains Composer repositories. It’s not the prettiest solution, but it’s well known.

    3. My own personal preference is that I prefer classes over prototypal inheritance. There’s so many caveats to prototypal inheritance that entire chapters of books have been written on writing wrapper code to fix or hack it’s quirks. That’s really just boiling down to user preference. CoffeeScript goes as far as to mimic this functionality, so there’s definitely interest in JS having it.

    4. I think your “Context Switching” argument regarding MongoDB is a bit of a misnomer. There’s still a learning curve. You need to learn about indexing and collections. You have to separate the concept of database relations in favor of nested objects and duplication of data. There’s still syntax involved. It’s just not SQL.

    5. Your section on realtime apps is mostly correct, however I would give Ratchet and React a bit more credit. PHP offers event-driven, non-blocking I/O with React. Using Ratchet and supervisord to monitor the PHP processes and restart if necessary, you have yourself a fully functional Websocket server that auto-restarts itself. PHP garbage collection has drastically improved, so there aren’t any concerns for memory leaks unless the application has been poorly coded.

    6. In conclusion, PHP is still growing and adding new features with every release. It’s battle tested and hardened. The community isn’t nitpicking other languages or writing direct comparisons; there’s no need for justifications. Write with whatever tools you know best to get the job done right. Be platform agnostic.

    • me said:

      Bravo! Couldn’t have said it better. I do my work in php, and really I just can’t find any reason to switch. It everywhere, support is great from communauty and formost it does the job and my customer are happy. Who cares about the rest.

    • Michael Lesher said:

      Agreed. I keep kicking tires on Node and from what I have seen, I really like it, but as you point out, the “comparisons” do not really hold enough water for me to invest billable time into switching. Additionally, I don’t have many enterprise level clients who are willing to risk their projects on Node just yet, but they are willing to work with many PHP frameworks, etc.

    • Azat Mardanov said:

      Hi Corey,

      Let’s see point by point who’s right or wrong:
      1) If SQL injections were a moot point why they would be such a wide spread thread and one of the most popular vulnerabilities? If someone builds real-production apps, he/she knows that implementing of CSRF, sanitations, etc. (freaking magic quotes in PHP?!) could make a night and day difference.
      2) I mentioned Packagist and Composer, did you read the article? :-)
      3) CoffeeScript is awesome, but for the native JS, the functional inheritance patterns is the way to go, because that’s the nature of the language (object inherit from objects).
      4) What are you talking about? The MongoDB syntax is BSON which is binary JSON (JavaScript Object Notation). There’s ZERO learning curve! Try it yourself. There’re no relationships in the database, hence no complexity of SQL.
      5) Again, I mentioned those PHP libraries. Please, read articles before commenting. :-)
      6) Maybe PHP is growing, but at a fraction of the speed at which Node.js expands. You’re welcome to stick to old legacy technologies. The world always needs experts on them up to the point of migrations to newer stacks (think COBOL, DB2 — VISA still uses them).

      • Kevin said:

        The only advantage with node.js is “you can write front end and backend code in javascript”
        Enterprise wont go for node.js at any point, Node.js will end up like rails [DEAD]

        Most of the corporations who used node [ebay,walmart] responded like they could do their work(problemset) in java, but they just want to try some thing new.

        and “PHP is growing, but at a fraction of the speed at which Node.js expands” !! really??

      • Kevin said:

        “As is the case with many traditional languages, PHP’s flow is blocked until the remote server has responded, hence the need for multi-threading.”

        Just for the record php do have threading support(@pthreads) unlike python/ruby (which uses GIL to emulate)

  9. Michiel van Eerd said:

    Nice comparison. I agree Node.js will become a dominant factor for web applications, but I do think Apache + PHP holds it’s place for websites. The Apache + PHP stack is suitable for serving webpages, while Node.js is more suitable for real time communication and serving data to applications.

  10. Dan Sutton said:

    I just love that there’s competition among bad programming languages to see who can be convinced to program badly in them…

    • Azat Mardanov said:

      Hi Dan,

      JavaScript is only bad in the hands of programmers who didn’t bother to learn it. If you ask any great JavaScript/Node.js developers they’ll tell you 100 and 1 things why JS is awesome over all other languages (not perfect of course because nothing is perfect).

  11. Logan Murray said:

    Just to offer a slight correction, PHP has a procedural nature, not functional. Functional languages (like scheme and lisp) are arguably much harder to learn than object-oriented programming. :)

    Thanks for the article!

    • Azat Mardanov said:

      Hi Logan,

      Yes, now I remember that PHP is procedural but hardly can point the difference between functional and procedural. Also since PHP 5 or 6 it’s OOP, however not many people use it this way.

  12. Paul said:

    I stopped reading when you said PHP has the requirement to learn at least 2 languages, counting MySQL, and then HTML + CSS are on top.

    Apparetnyl Node.js figures out your HTML + CSS too? Cool story bro.

    Just because you’re using Mongo here instead of MySQL, it’s stupid to say theres no learning curve for it.

    This isn’t a PHP vs Node.js – it’s a “Hey I like Node.js so Im gonna to tell you how to PHP stuff in Node.js and say its better with nothing to back it up”

    • Azat Mardanov said:

      Hi Paul,

      Too bad you stopped reading… HTML+CSS is in every stack so just disregard that. PHP+MySQL/Ruby on Rails + Postgress/Python + MySQL require at least 2 language SQL and app language while Node.js + MongoDB just one. Got it? :-)
      MongoDB has really NO learning curve compare to MySQL/MSSQL/Postrgress/Oracle, believe my 10+ years experience with traditional SQL RDBMSs.

  13. Richard said:

    I think the comparison is fair – apart from where you dismiss PHP as that it has passed its time. I think it’s always not fair to compare 2 languages generally rather than by task. Some jobs require small tools, others require big ones :)

    • Azat Mardanov said:

      Hi Richard, thank you. The question most people face is “What technology to choose?”. In the end, they’ll end up most likely with ONLY one stack (PHP, Python, Ruby or Node.js). So, it’s very important for them to compare and make the right choice. In big companies, situation is different (more resources) and it’s possible to cherry pick techs for special tasks.

  14. Pingback: Node.js and Mobile News Round-up – September 10, 2013 | StrongLoop

  15. Pingback: Ekhtarna Lak – September 12 | ThePlanet Blogs

  16. Sohail said:

    I decided to avoid judgments based on comparison when I was in my mid 30s.
    It might help to create a heated discussion but it doesn’t cover the whole facts and features about a programming/scripting language.
    (Taking one or two frame from a language and comparing it to a few frames of another one is not a good idea I believe and it does not cover the full story)

    In my humble opinion, demand and supply dictates the current state of success for each programming language.
    Simply have a look at following link to see what I mean:
    http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

    P.S.
    The title of this article is Node.js vs PHP
    Node.js is not a programming/scripting language. That’s why I believe it is not a good comparison in nature.

*

*

Top