SlideShare a Scribd company logo
Node.js for PHP developers 
for CampJS IV 
by Andrew Eddie
@AndrewEddie 
• Civil Engineer (1990) turned Software Engineer (2000) 
• Discovered Basic early 80's - nerd ever since 
• Cut teeth on C and C++ (late 90's vintage) 
• PHP Open Source contributor 
• Node acolyte
Node.js for PHP developers
JavaScript 
• Was born in 1995 (same as PHP) 
• Is ECMAScript 
• Shares a mostly familiar C-style syntax 
• Is not Java 
• Is not CoffeeScript et al
Node.js 
• It's just server-side JavaScript (it is the server) 
• V8 - very light core 
• Single thread event loop 
• Package management via NPM 
• No real equivalent to things like SPL or PHP-FIG
Documentation 
• https://developer.mozilla.org/en- 
US/docs/Web/JavaScript 
• http://nodejs.org/documentation/ 
• Individual modules/packages 
• http://kapeli.com/dash
Interactive command line / REPL 
$ php -a 
php > echo "Hello World!n";; 
Hello World! 
php > 
$ node 
> console.log('Hello World'); 
Hello World 
undefined 
>
Primitive value differences 
// PHP 
// * booleans 
// * integers 
// * floating point numbers 
// * strings 
// * arrays 
// * objects 
// * resources 
// * null 
// * callbacks 
// JavaScript 
// * boolean 
// (number) 
// * number 
// * string 
// (object) 
// * object 
// 
// * null 
// (function, which is an object)
Variable differences 
<?php 
// PHP 
$minecraft = '1.8.1-pre3'; 
$spawnX = -77; 
$spawnY = 63; 
$spawnZ = 241; 
// JavaScript 
seed = -6623756275123996544; 
var spawnX = -77; 
var spawnY = 63, 
spawnZ = 241; 
var $biome = 'Savanah';
Operator differences 
// PHP 
$number = 1 + 2; 
$string = 'mega' . 'taiga'; 
$string .= ' biome'; 
1 && 2 && 3; // true 
1 && 3 && 0; // false 
$perPage || 10; // true 
// JavaScript 
var number = 1 + 2; 
var string = 'extreme' + ' hills'; 
string += ' biome'; 
1 && 3 && 2; // 2 
1 && 3 && 0; // 0 
perPage || 10; // 10
Falsy differences 
// PHP 
false; 
0; 
""; 
"0" 
null; 
$x is undefined 
// NAN is truthy (double), need is_nan() 
array(); // Empty array 
// JavaScript 
false; 
0; 
""; 
// "0" is truthy! 
null; 
undefined; 
NaN; 
// [] is truthy!
Array differences 
// PHP 5.4+ 
$recipe = ['water', 'nether wart']; 
$recipe[] = 'glass bottle'; 
// array_push($recipe, 'another one'); 
$array = new ArrayObject($recipe); 
$array.count(); // 3 
array_keys($array); 
foreach ($array as $index => $value) { 
echo "narray[$index] = $value"; 
} 
// Note PHP < 5.4 
$recipe = array('water', 'nether wart'); 
// JavaScript 
var recipe = ['x', 'y', 'z']; 
recipe.push('4th dimension'); 
recipe.length; // 3 (are you sure?) 
recipe.keys(); 
recipe.forEach(function (value, index) { 
console.log(index + '=' + value); 
});
Associative arrays 
// PHP 
$inventory = [ 
'pick' => 'stone', 
'sword' => 'diamond', 
'axe' => 'iron' 
]; 
// JavaScript 
var inventory = { 
pick: 'stone', 
sword: 'diamond', 
axe: 'iron' 
};
Object differences 
// PHP 
$inventory = new stdClass; 
$inventory->pick = 'stone'; 
$inventory->sword = 'diamond'; 
$inventory->axe = 'iron'; 
// Alternatively 
$inventory = (object)[ 
'pick' => 'stone', 
'sword' => 'diamond', 
'axe' => 'iron' 
]; 
echo $inventory->pick; 
$axe = 'axe'; 
echo $inventory->$axe; 
// JavaScript 
var inventory = { 
pick: 'stone', 
sword: 'diamond', 
axe: 'iron' 
}; 
console.log(inventory.pick); 
console.log(inventory['axe']);
The same 
• if 
• while 
• do-while 
• for 
• function (or closure) declaration
Switch 
// PHP 
switch ("") { 
case false: 
echo 'It is false'; 
break; 
case "": 
echo 'Empty string'; 
break; 
default: 
echo 'Did not match'; 
} 
// It is false 
// Loose == comparison! 
// JavaScript 
switch ("") { 
case false: 
console.log('It is false'); 
break; 
case "": 
console.log('Empty string'); 
break; 
default: 
console.log('Did not match'); 
} 
// Empty string 
// Strict === comparison
Synchronous try-catch 
// PHP 
try { 
throw new Exception('Bad req', 400); 
} 
catch (Exception $e) { 
echo $e->getMessage(); 
echo $e->getCode(); 
echo $e->getTraceAsString(); 
} 
// JavaScript 
try { 
throw new Error('Bad req'); 
} 
catch (err) { 
console.log(err.message); 
// No native 'code' support. 
console.log(err.stack); 
}
foreach / for-in 
// PHP 
foreach ($objOrArr as $k => $v) { 
echo "Key is $kn"; 
echo "- value is $vn"; 
} 
// JavaScript 
for (k in object) { 
console.log("Key is %s", k); 
console.log("- value is %s", 
object[k]); 
}
Function defaults 
// PHP 
function fetch($page, $perPage = 10) { 
// ... 
return $page * perPage; 
} 
php > fetch(); 
Warning: Missing argument 1 for fetch(), called in php 
shell code on line 1 and defined in php shell code on 
line 1 
// JavaScript 
function fetch(page, perPage) { 
perPage = perPage || 10; 
return page * perPage; 
} 
> fetch(); 
NaN 
> 
// Workaround? 
function fetch(page, perPage) { 
if (page === undefined) { 
throw Error('Page missing'); 
} 
perPage = perPage || 10; 
return page * perPage; 
}
Invoking functions 
// PHP 
function getDamage($weapon, $level) { 
// ... 
return $damage; 
} 
$damage = getDamage('axe', 1); 
call_user_func('getDamage', 'axe', 1); 
call_user_func_array( 
'getDamage', 
['axe', 1] 
); 
// JavaScript 
function getDamage(weapon, level) { 
// ... 
return damage; 
} 
var damage = getDamage('axe', 1); 
getDamage.call(null, 'axe', 1); 
getDamage.apply(null, ['axe', 1]);
Closures 
// PHP 
$mineBlock = function ($block) { 
// ... 
return $item; 
}; 
$item = $mineBlock('diamond ore'); 
// JavaScript 
var mineBlock = function (block) { 
// ... 
return item; 
}; 
var item = mineBlock('diamond ore');
Function Scope 
// PHP 
// Global if in the main file. 
$sky = 'blue'; 
function night() { 
$sky = 'black'; 
} 
night(); 
echo $sky; // blue 
// JavaScript 
// Always global. 
sky = 'blue'; 
function night() { 
sky = 'black'; 
} 
night(); 
console.log(sky); // black
Function Scope - PHP equivalent to JavaScript 
// PHP 
// Global if in the main file. 
$sky = 'blue'; 
function night() { 
global $sky; 
$sky = 'black'; 
} 
night(); 
echo $sky; // black 
// JavaScript 
// Always global. 
sky = 'blue'; 
function night() { 
sky = 'black'; 
} 
night(); 
console.log(sky); // black
Function Scope - JavaScript equivalent to PHP 
// PHP 
// Global if in the main file. 
$sky = 'blue'; 
function night() { 
$sky = 'black'; 
} 
night(); 
echo $sky; // blue 
// JavaScript 
// Always local. 
var sky = 'blue'; 
function night() { 
var sky = 'black'; 
} 
night(); 
console.log(sky); // blue
Classes? 
// PHP 
class Block { 
public $type; 
public function __construct($type) { 
$this->type = $type; 
} 
public function getType() { 
return $this->type; 
} 
} 
$sand = new Block('sand'); 
// JavaScript 
function Block(type) { 
this.type = type; 
} 
Block.prototype.getType = function () { 
return this.type; 
} 
var dirt = new Block('dirt');
"Classes" in JavaScript 
• Constructors are just named functions 
• Functions called with `new` return `this` 
• `new` allows prototyping to work 
• Upper CamelCase function names by convention 
• No native equivalent to `protected` 
• True `private` is possible but awkward
Inheritance - JavaScript 
// PHP 
class DiamondOre extends Block { 
function __construct() { 
this.type = 'DiamondOre'; 
} 
} 
// JavaScript 
function DiamondOre() { 
// Remember the original constructor 
// back a slide or two took a type. 
Block.call(this, 'DiamondOre'); 
} 
DiamondOre.prototype = 
Object.create(Block.prototype); 
DiamondOre.prototype.constructor = 
Block;
Inheritance - Node 
// PHP 
class IronOre extends Block { 
function __construct() { 
parent::__construct('IronOre'); 
} 
function getType() { 
return 'Unsmelted' 
. parent::getType(); 
} 
} 
// JavaScript 
var util = require('util'); 
function IronOre() { 
Block.call(this, 'IronOre'); 
} 
util.inherits(IronOre, Block); 
IronOre.prototype.getType = function (){ 
return 'Unsmelted' 
+ super_.getType(); 
}
Class closure scope - public example 
// PHP 
class Tool { 
public $max = 5; 
function register($container) { 
// Pre PHP 5.4 
$self = $this; 
$f = function($bag) use ($self){ 
return count($bag) 
< $self->max); 
}; 
$container->register($f); 
} 
} 
// JavaScript 
function Tool() { 
this.max = 5; 
} 
Tool.prototype.register = function($c){ 
var self = this; 
var f = function (bag) { 
return bag.length < self.max; 
} 
c.register(f); 
}
Class closure scope - private example 
// PHP 
class Tool { 
private $max = 5; 
function register($container) { 
// Pre PHP 5.4 
$self = $this; 
$f = function($bag) use ($self){ 
return count($bag) 
< $self->max); 
}; 
$container->register($f); 
} 
} 
// Node module 
// "max" is now private to Tool. 
var max = 5; 
Tool.prototype.register = function($c){ 
var self = this; 
var f = function (bag) { 
return bag.length < max; 
} 
c.register(f); 
}
Modules 
• Modules sort of equate to "class" 
• Sand-boxed scope 
• Returns module.exports
Modules - conceptual equivalence 
// PHP 
root 
|- Game 
| `- Block.php 
|- vendor 
| |- composer 
| |- monolog 
| `- autoload.php 
|- index.php 
`- package.json 
---------- 
<?php 
require './vendor/autoload.php'; 
use MonologLogger; 
use GameBlock; 
$log = new Logger('name'); 
// JavaScript 
root 
|- lib 
| `- game 
| `- index.js 
|- node_modules 
| `- winston 
|- app.js 
`- package.json 
---------- 
// Conceptual equivalent 
var winston = require('winston'); 
var Game = require('./lib/game'); 
var Block = Game.Block; 
var block = new Block('DiamondOre');
Some popular modules 
• Logging - Winston 
• Promises - Bluebird, Q 
• Utility classes - Lodash 
• Web serving - Express 
• ORM - Waterline, JugglingDB 
• MVC/ADR - Build your own
Documentation, Testing and Build Tools 
• npm (vs Composer or <cough>PEAR</cough>) 
• JSDoc (vs phpDocumentor) 
• Mocha (vs PHPUnit) { ui: 'exports' } 
• Sinon (object mocking) 
• Nock (request mocking) 
• Frisby/Supertest (request functional testing) 
• Istanbul (code coverage) 
• Grunt (vs Phing)
What do to with non-public scope? 
• True private - hard to test 
• Could use the old PEAR underscore prefix 
• Could reference them via a faux value 
• Could use @private in the DocBlock
Thank you - Questions? 
eddify.me 
twitter.com/AndrewEddie 
slideshare.net/AndrewEddie 
delicious.com/eddieajau/node.js

More Related Content

KEY
A tour on ruby and friends
PPTX
Speed up your developments with Symfony2
PDF
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
PDF
Rich Model And Layered Architecture in SF2 Application
KEY
KEY
Keeping it small: Getting to know the Slim micro framework
PPT
Symfony2 Service Container: Inject me, my friend
PDF
Introducing ruby on rails
A tour on ruby and friends
Speed up your developments with Symfony2
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Rich Model And Layered Architecture in SF2 Application
Keeping it small: Getting to know the Slim micro framework
Symfony2 Service Container: Inject me, my friend
Introducing ruby on rails

What's hot (20)

PDF
Forget about Index.php and build you applications around HTTP - PHPers Cracow
PDF
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
PDF
PHPSpec - the only Design Tool you need - 4Developers
KEY
(Parameterized) Roles
PDF
Javascript - The Good, the Bad and the Ugly
PDF
The Beauty of Java Script
PDF
P6 OO vs Moose (&Moo)
PPTX
Java script for web developer
PDF
The Beauty Of Java Script V5a
PDF
How DRY impacts JavaScript performance // Faster JavaScript execution for the...
PPT
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
PDF
Perl web frameworks
PDF
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
ZIP
Web Apps in Perl - HTTP 101
PPTX
5 Tips for Better JavaScript
PPTX
Zephir - A Wind of Change for writing PHP extensions
PDF
Interceptors: Into the Core of Pedestal
PDF
Rails on Oracle 2011
PDF
JavaScript and the AST
PDF
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
PHPSpec - the only Design Tool you need - 4Developers
(Parameterized) Roles
Javascript - The Good, the Bad and the Ugly
The Beauty of Java Script
P6 OO vs Moose (&Moo)
Java script for web developer
The Beauty Of Java Script V5a
How DRY impacts JavaScript performance // Faster JavaScript execution for the...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
Perl web frameworks
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Web Apps in Perl - HTTP 101
5 Tips for Better JavaScript
Zephir - A Wind of Change for writing PHP extensions
Interceptors: Into the Core of Pedestal
Rails on Oracle 2011
JavaScript and the AST
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Ad

Similar to Node.js for PHP developers (20)

DOC
Jsphp 110312161301-phpapp02
PDF
JavaScript for PHP developers
KEY
Future of PHP
PDF
The Future of JavaScript (Ajax Exp '07)
PDF
Nodejs For Php Developers Porting Php To Nodejs 1st Edition Daniel Howard
PDF
JavaScript 1.5 to 2.0 (TomTom)
KEY
Server side scripting smack down - Node.js vs PHP
PDF
HHVM and Hack: A quick introduction
KEY
JavaScript Neednt Hurt - JavaBin talk
PDF
Php Crash Course - Macq Electronique 2010
PDF
Decoupling Content Management
PPTX
Awesomeness of JavaScript…almost
KEY
JavaScript Growing Up
PDF
Decoupling Content Management with Create.js and PHPCR
PDF
"Building Modern PHP Applications" - Jackson Murtha, South Dakota Code Camp 2012
KEY
Async. and Realtime Geo Applications with Node.js
PDF
Tamarin and ECMAScript 4
PDF
Living With Legacy Code
PPTX
Introducing PHP Latest Updates
PPTX
All of javascript
Jsphp 110312161301-phpapp02
JavaScript for PHP developers
Future of PHP
The Future of JavaScript (Ajax Exp '07)
Nodejs For Php Developers Porting Php To Nodejs 1st Edition Daniel Howard
JavaScript 1.5 to 2.0 (TomTom)
Server side scripting smack down - Node.js vs PHP
HHVM and Hack: A quick introduction
JavaScript Neednt Hurt - JavaBin talk
Php Crash Course - Macq Electronique 2010
Decoupling Content Management
Awesomeness of JavaScript…almost
JavaScript Growing Up
Decoupling Content Management with Create.js and PHPCR
"Building Modern PHP Applications" - Jackson Murtha, South Dakota Code Camp 2012
Async. and Realtime Geo Applications with Node.js
Tamarin and ECMAScript 4
Living With Legacy Code
Introducing PHP Latest Updates
All of javascript
Ad

Recently uploaded (20)

PDF
AI in Product Development-omnex systems
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
PDF
Build Multi-agent using Agent Development Kit
PDF
System and Network Administraation Chapter 3
PPTX
Materi-Enum-and-Record-Data-Type (1).pptx
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
System and Network Administration Chapter 2
PDF
medical staffing services at VALiNTRY
PDF
How to Confidently Manage Project Budgets
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
AIRLINE PRICE API | FLIGHT API COST |
PDF
Become an Agentblazer Champion Challenge Kickoff
PPTX
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
A REACT POMODORO TIMER WEB APPLICATION.pdf
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
AI in Product Development-omnex systems
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Build Multi-agent using Agent Development Kit
System and Network Administraation Chapter 3
Materi-Enum-and-Record-Data-Type (1).pptx
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
PTS Company Brochure 2025 (1).pdf.......
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
System and Network Administration Chapter 2
medical staffing services at VALiNTRY
How to Confidently Manage Project Budgets
How to Migrate SBCGlobal Email to Yahoo Easily
AIRLINE PRICE API | FLIGHT API COST |
Become an Agentblazer Champion Challenge Kickoff
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
Softaken Excel to vCard Converter Software.pdf
A REACT POMODORO TIMER WEB APPLICATION.pdf
ISO 45001 Occupational Health and Safety Management System
Upgrade and Innovation Strategies for SAP ERP Customers

Node.js for PHP developers

  • 1. Node.js for PHP developers for CampJS IV by Andrew Eddie
  • 2. @AndrewEddie • Civil Engineer (1990) turned Software Engineer (2000) • Discovered Basic early 80's - nerd ever since • Cut teeth on C and C++ (late 90's vintage) • PHP Open Source contributor • Node acolyte
  • 4. JavaScript • Was born in 1995 (same as PHP) • Is ECMAScript • Shares a mostly familiar C-style syntax • Is not Java • Is not CoffeeScript et al
  • 5. Node.js • It's just server-side JavaScript (it is the server) • V8 - very light core • Single thread event loop • Package management via NPM • No real equivalent to things like SPL or PHP-FIG
  • 6. Documentation • https://developer.mozilla.org/en- US/docs/Web/JavaScript • http://nodejs.org/documentation/ • Individual modules/packages • http://kapeli.com/dash
  • 7. Interactive command line / REPL $ php -a php > echo "Hello World!n";; Hello World! php > $ node > console.log('Hello World'); Hello World undefined >
  • 8. Primitive value differences // PHP // * booleans // * integers // * floating point numbers // * strings // * arrays // * objects // * resources // * null // * callbacks // JavaScript // * boolean // (number) // * number // * string // (object) // * object // // * null // (function, which is an object)
  • 9. Variable differences <?php // PHP $minecraft = '1.8.1-pre3'; $spawnX = -77; $spawnY = 63; $spawnZ = 241; // JavaScript seed = -6623756275123996544; var spawnX = -77; var spawnY = 63, spawnZ = 241; var $biome = 'Savanah';
  • 10. Operator differences // PHP $number = 1 + 2; $string = 'mega' . 'taiga'; $string .= ' biome'; 1 && 2 && 3; // true 1 && 3 && 0; // false $perPage || 10; // true // JavaScript var number = 1 + 2; var string = 'extreme' + ' hills'; string += ' biome'; 1 && 3 && 2; // 2 1 && 3 && 0; // 0 perPage || 10; // 10
  • 11. Falsy differences // PHP false; 0; ""; "0" null; $x is undefined // NAN is truthy (double), need is_nan() array(); // Empty array // JavaScript false; 0; ""; // "0" is truthy! null; undefined; NaN; // [] is truthy!
  • 12. Array differences // PHP 5.4+ $recipe = ['water', 'nether wart']; $recipe[] = 'glass bottle'; // array_push($recipe, 'another one'); $array = new ArrayObject($recipe); $array.count(); // 3 array_keys($array); foreach ($array as $index => $value) { echo "narray[$index] = $value"; } // Note PHP < 5.4 $recipe = array('water', 'nether wart'); // JavaScript var recipe = ['x', 'y', 'z']; recipe.push('4th dimension'); recipe.length; // 3 (are you sure?) recipe.keys(); recipe.forEach(function (value, index) { console.log(index + '=' + value); });
  • 13. Associative arrays // PHP $inventory = [ 'pick' => 'stone', 'sword' => 'diamond', 'axe' => 'iron' ]; // JavaScript var inventory = { pick: 'stone', sword: 'diamond', axe: 'iron' };
  • 14. Object differences // PHP $inventory = new stdClass; $inventory->pick = 'stone'; $inventory->sword = 'diamond'; $inventory->axe = 'iron'; // Alternatively $inventory = (object)[ 'pick' => 'stone', 'sword' => 'diamond', 'axe' => 'iron' ]; echo $inventory->pick; $axe = 'axe'; echo $inventory->$axe; // JavaScript var inventory = { pick: 'stone', sword: 'diamond', axe: 'iron' }; console.log(inventory.pick); console.log(inventory['axe']);
  • 15. The same • if • while • do-while • for • function (or closure) declaration
  • 16. Switch // PHP switch ("") { case false: echo 'It is false'; break; case "": echo 'Empty string'; break; default: echo 'Did not match'; } // It is false // Loose == comparison! // JavaScript switch ("") { case false: console.log('It is false'); break; case "": console.log('Empty string'); break; default: console.log('Did not match'); } // Empty string // Strict === comparison
  • 17. Synchronous try-catch // PHP try { throw new Exception('Bad req', 400); } catch (Exception $e) { echo $e->getMessage(); echo $e->getCode(); echo $e->getTraceAsString(); } // JavaScript try { throw new Error('Bad req'); } catch (err) { console.log(err.message); // No native 'code' support. console.log(err.stack); }
  • 18. foreach / for-in // PHP foreach ($objOrArr as $k => $v) { echo "Key is $kn"; echo "- value is $vn"; } // JavaScript for (k in object) { console.log("Key is %s", k); console.log("- value is %s", object[k]); }
  • 19. Function defaults // PHP function fetch($page, $perPage = 10) { // ... return $page * perPage; } php > fetch(); Warning: Missing argument 1 for fetch(), called in php shell code on line 1 and defined in php shell code on line 1 // JavaScript function fetch(page, perPage) { perPage = perPage || 10; return page * perPage; } > fetch(); NaN > // Workaround? function fetch(page, perPage) { if (page === undefined) { throw Error('Page missing'); } perPage = perPage || 10; return page * perPage; }
  • 20. Invoking functions // PHP function getDamage($weapon, $level) { // ... return $damage; } $damage = getDamage('axe', 1); call_user_func('getDamage', 'axe', 1); call_user_func_array( 'getDamage', ['axe', 1] ); // JavaScript function getDamage(weapon, level) { // ... return damage; } var damage = getDamage('axe', 1); getDamage.call(null, 'axe', 1); getDamage.apply(null, ['axe', 1]);
  • 21. Closures // PHP $mineBlock = function ($block) { // ... return $item; }; $item = $mineBlock('diamond ore'); // JavaScript var mineBlock = function (block) { // ... return item; }; var item = mineBlock('diamond ore');
  • 22. Function Scope // PHP // Global if in the main file. $sky = 'blue'; function night() { $sky = 'black'; } night(); echo $sky; // blue // JavaScript // Always global. sky = 'blue'; function night() { sky = 'black'; } night(); console.log(sky); // black
  • 23. Function Scope - PHP equivalent to JavaScript // PHP // Global if in the main file. $sky = 'blue'; function night() { global $sky; $sky = 'black'; } night(); echo $sky; // black // JavaScript // Always global. sky = 'blue'; function night() { sky = 'black'; } night(); console.log(sky); // black
  • 24. Function Scope - JavaScript equivalent to PHP // PHP // Global if in the main file. $sky = 'blue'; function night() { $sky = 'black'; } night(); echo $sky; // blue // JavaScript // Always local. var sky = 'blue'; function night() { var sky = 'black'; } night(); console.log(sky); // blue
  • 25. Classes? // PHP class Block { public $type; public function __construct($type) { $this->type = $type; } public function getType() { return $this->type; } } $sand = new Block('sand'); // JavaScript function Block(type) { this.type = type; } Block.prototype.getType = function () { return this.type; } var dirt = new Block('dirt');
  • 26. "Classes" in JavaScript • Constructors are just named functions • Functions called with `new` return `this` • `new` allows prototyping to work • Upper CamelCase function names by convention • No native equivalent to `protected` • True `private` is possible but awkward
  • 27. Inheritance - JavaScript // PHP class DiamondOre extends Block { function __construct() { this.type = 'DiamondOre'; } } // JavaScript function DiamondOre() { // Remember the original constructor // back a slide or two took a type. Block.call(this, 'DiamondOre'); } DiamondOre.prototype = Object.create(Block.prototype); DiamondOre.prototype.constructor = Block;
  • 28. Inheritance - Node // PHP class IronOre extends Block { function __construct() { parent::__construct('IronOre'); } function getType() { return 'Unsmelted' . parent::getType(); } } // JavaScript var util = require('util'); function IronOre() { Block.call(this, 'IronOre'); } util.inherits(IronOre, Block); IronOre.prototype.getType = function (){ return 'Unsmelted' + super_.getType(); }
  • 29. Class closure scope - public example // PHP class Tool { public $max = 5; function register($container) { // Pre PHP 5.4 $self = $this; $f = function($bag) use ($self){ return count($bag) < $self->max); }; $container->register($f); } } // JavaScript function Tool() { this.max = 5; } Tool.prototype.register = function($c){ var self = this; var f = function (bag) { return bag.length < self.max; } c.register(f); }
  • 30. Class closure scope - private example // PHP class Tool { private $max = 5; function register($container) { // Pre PHP 5.4 $self = $this; $f = function($bag) use ($self){ return count($bag) < $self->max); }; $container->register($f); } } // Node module // "max" is now private to Tool. var max = 5; Tool.prototype.register = function($c){ var self = this; var f = function (bag) { return bag.length < max; } c.register(f); }
  • 31. Modules • Modules sort of equate to "class" • Sand-boxed scope • Returns module.exports
  • 32. Modules - conceptual equivalence // PHP root |- Game | `- Block.php |- vendor | |- composer | |- monolog | `- autoload.php |- index.php `- package.json ---------- <?php require './vendor/autoload.php'; use MonologLogger; use GameBlock; $log = new Logger('name'); // JavaScript root |- lib | `- game | `- index.js |- node_modules | `- winston |- app.js `- package.json ---------- // Conceptual equivalent var winston = require('winston'); var Game = require('./lib/game'); var Block = Game.Block; var block = new Block('DiamondOre');
  • 33. Some popular modules • Logging - Winston • Promises - Bluebird, Q • Utility classes - Lodash • Web serving - Express • ORM - Waterline, JugglingDB • MVC/ADR - Build your own
  • 34. Documentation, Testing and Build Tools • npm (vs Composer or <cough>PEAR</cough>) • JSDoc (vs phpDocumentor) • Mocha (vs PHPUnit) { ui: 'exports' } • Sinon (object mocking) • Nock (request mocking) • Frisby/Supertest (request functional testing) • Istanbul (code coverage) • Grunt (vs Phing)
  • 35. What do to with non-public scope? • True private - hard to test • Could use the old PEAR underscore prefix • Could reference them via a faux value • Could use @private in the DocBlock
  • 36. Thank you - Questions? eddify.me twitter.com/AndrewEddie slideshare.net/AndrewEddie delicious.com/eddieajau/node.js

Editor's Notes

  • #2: References: http://www.slideshare.net/stoyan/javascript-for-php-developers-7245314 http://radar.oreilly.com/2013/06/5-surprises-for-php-developers-coming-to-javascript.html https://medium.com/grand-things/migrating-from-php-to-node-js-522768ac482a http://technosophos.com/2011/10/26/nodejs-five-things-every-php-developer-should-know.html
  • #3: Who am I? Civil engineering prepared me well for a move into software engineering. I'm mostly known for my contributions to the Joomla CMS.
  • #4: Photo: NASA ASTP image gallery. The cognitive process for context switching between languages is not always easy.
  • #5: Javascript is defined by the ECMAScript standard, the name being a compromise between Microsoft and Netscape as two of the main stakeholders surrounding the inclusion of JavaScript in browsers. PHP, incidentally was also born in 1995. Node was born in 2009 a month before the release of PHP 5.3 (ironically introducing closures). JavaScript also has a family of derived languages, such as CoffeeScript, that have custom syntax that compile down to JavaScript. This can be a little confusing to the Node beginner because there are times you are searching for JavaScript/Node solutions and you either get people writing snippets in CoffeeScript, or, you find the source for an npm package is written in CoffeeScript, not pure JavaScript.
  • #6: It's the same Javascript that runs in your browser, BUT fully compliant with the ECMAScript standard so you don't have to contend with browser differences where some features are supported and others aren't (that said, operating systems present the usual challenges for installation). But it's important to note that Node is the server - you don't need to run it under Apache or IIS to get web support, Node supports the basics itself (much like PHP 5.4's built in web server). It's built on Chrome's V8 engine (so we are somewhat beholden to what Chrome wants to do with that) and the core library support is much, much lighter than PHP. Node expects you to extend functionality by adding modules and packages written in JavaScript (it's still all Vanilla JavaScript). While this is an over-simplification, Node includes enough for you to write a web server, at least enough for you to start handling requests and responses. When you start a Node application, it's running in a single thread in an event loop. The equivalent of both Composer, Packagist and PEAR in Node is NPM - the Node Package Manager.
  • #7: Node documentation is divided into two zones. Node is JavaScript so the Mozilla resources are still the standard for vanilla Javascript. Node has documentation for the modules it provides (like "fs" and others). Individual modules have their own documentation with varying degrees of depth and quality. Dash is a great tool to collect documentation offline (for Mac only) and it's worthwhile purchasing a license to get rid of the ads.
  • #8: Both Node and PHP have command line interpreters. References: http://php.net/manual/en/features.commandline.interactive.php http://nodejs.org/api/repl.html
  • #9: JavaScript has similar but fewer primitives. References http://php.net/manual/en/language.types.php https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
  • #10: Node doesn't require a tag (like <?php) to designate that you are in the language. PHP and JavaScript variables are both loosely typed. In JavaScript, the "$" identifier is not necessary, but could be included if it makes you feel better. However, the "var" keyword is used to define local scope and should always be used to prevent polluting of the global scope.
  • #11: Most operators share the same roll in both languages. In JavaScript, "+" is both a string and number operator. The "&&" and "||" operators behave a little differently in JavaScript because they resolve to a value, not a boolean (this makes the "||" operator particularly useful for assigning default values).
  • #12: There are some slight differences regarding truthiness and falsiness.
  • #13: References http://php.net/manual/en/language.types.array.php | http://php.net/manual/en/class.arrayobject.php https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array Note that Array.length in JavaScript is mutable. http://php.net/manual/en/control-structures.foreach.php
  • #14: JavaScript does not have the notion of a native associative array like PHP does.
  • #15: Object support in JavaScript is similar to PHP, just using the "." operator instead of "->".
  • #17: Switch statements should always be used sparingly, but in JavaScript you need to remember that the comparison for cases is strict.
  • #18: JavaScript's Error object is like a PHP exception, but without an error code. It is, however, a quirky object to extend. JavaScript also has a few native error types, but not nearly as rich as SPL. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
  • #19: Be careful of "hasOwnProperty". See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
  • #20: Function declarations are similar. However, in JavaScript all arguments are optional (and forget about type hinting).
  • #21: Because functions in JavaScript are objects, they contain a method to call themselves either with a list of arguments or an array of arguments.
  • #22: Closures (anonymous functions) are provided in both languages. Note that both have their respective "this" issues.
  • #23: Function scope is handled a little differently in JavaScript. Functions always have access to the global scope.
  • #24: To achieve the same result in PHP you'd have to resort to the evil "global" keyword.
  • #25: Or, in JavaScript land, you need to explicitly declare the variable in the local scope.
  • #26: JavaScript doesn't have classes (ES6 aside), but it does have the concept of constructor functions. You can achieve constructs like class methods in JavaScript by operating on a function's prototype object (and that's another story that's beyond the scope of this talk).
  • #28: Inheritance is certainly possible in JavaScript, but it's not as elegant.
  • #29: Node helps us by providing an "inherits" method in a module called "util" that eliminates the repetition. Note that it also implements (manually) a "super_" object to track the parent object.
  • #30: The best way to get your head around object closure scope is to imagine you are using closures in PHP 5.3, just without the "use" keyword (JavaScript automatically handles that sort of scope).
  • #31: Private class variables can be handled easily in Node modules.
  • #32: It's best to think of a Node module in the same way as you'd think about a PHP class. It's
  • #33: Good references: http://bites.goodeggs.com/posts/export-this/
  • #35: Note that npm is little different from Composer because Node can sandbox different versions of the same library. The "export" ui setting in Mocha gives you the closest feel for how testing is done with PHP Unit. I particularly dislike the BDD format.
  • #36: In PHP, I liked being pedantic about class property and method scope. But JavaScript doesn't have the idea of protected scope, and most private things are completely inaccessible (reflection is not an option). I've begrudgingly taken to using @private notation (yes, going back to the PHP 4 days) because it makes it easier to test the inner workings of a class (methods I would normally make protected).