Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScripting for the PHP Developer in 2012

JavaScripting for the PHP Developer in 2012

The modern day web developer is presented with possibilities the developers of 2005 would salivate over. In this session we'll look at some JavaScript tools that will simplify your web development life by reducing the complexity of your PHP backend, increasing the rich user interface presented in the browser, as well as redundancy in your frontend and backend code.

Jeff Carouth

October 24, 2012
Tweet

More Decks by Jeff Carouth

Other Decks in Programming

Transcript

  1. JavaScripting for the PHP Developer in 2012 this is not

    the JavaScript from 1999 Jeff Carouth ZendCon 2012
  2. Arrays array(); []; //PHP 5.4+ array(1, 2, 3, 4); array(1,

    "foo", new stdClass()); array("foo" => "bar", "fizz" => "buzz");
  3. Arrays array(); []; //PHP 5.4+ array(1, 2, 3, 4); array(1,

    "foo", new stdClass()); array("foo" => "bar", "fizz" => "buzz"); []; // new Array(); [1, 2, 3, 4]; [1, "foo", {}]; ["foo": "bar", "fizz": "buzz"]; //ERROR
  4. Arrays array(); []; //PHP 5.4+ array(1, 2, 3, 4); array(1,

    "foo", new stdClass()); array("foo" => "bar", "fizz" => "buzz"); []; // new Array(); [1, 2, 3, 4]; [1, "foo", {}]; ["foo": "bar", "fizz": "buzz"]; //ERROR {"foo": "bar", "fizz": "buzz"}; //NOT an array
  5. Arrays typeof []; // 'object' typeof new Array(); // 'object'

    [3]; // arr.length = 1 new Array(3); // arr.length = 3
  6. class Car { private $make; private $model; private $year; public

    function __construct($make, $model, $year) { $this->make = $make; $this->model = $model; $this->year = $year; } // could use __toString() public function toString() { return $this->year." ".$this->make." ".$this->model; } } $myFirstCar = new Car('Acura', 'Integra', 1990); print $myFirstCar->toString(); // Result: ‘1990 Acura Integra’
  7. function Car(make, model, year) { this.make = make; this.model =

    model; this.year = year; this.toString = function() { return this.year + " " + this.make + " " + this.model; } } var myFirstCar = new Car('Acura', 'Integra', 1990); var myNewCar = new Car('Dodge', 'Charger', 2009); myFirstCar.toString(); // Result: ‘1990 Acura Integra’ myNewCar.toString(); // Result: ‘2009 Dodge Charger’
  8. Checking Type gettype($myFirstCar); // object $myFirstCar instanceof Car; // true

    get_class($myFirstCar); // Car typeof myFirstCar; // 'object' myFirstCar instanceof Car; // true myFirstCar.constuctor; // Car php JavaScript
  9. Object Methods Via the Prototype function Car(make, model, year) {

    this.make = make; this.model = model; this.year = year; this.toString = function() { return this.year + " " + this.make + " " + this.model; } }
  10. Object Methods Via the Prototype function Car(make, model, year) {

    this.make = make; this.model = model; this.year = year; this.toString = function() { return this.year + " " + this.make + " " + this.model; } } function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } Car.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; }
  11. function Car(make, model, year) { this.make = make; this.model =

    model; this.year = year; this.toString = function() { return this.year + " " + this.make + " " + this.model; } } var aCar = new Car('Saturn', 'Vue', 2007); var anotherCar = new Car('Ford', 'F150', '2003'); aCar.toString(); // '2007 Saturn Vue' anotherCar.toString(); // '2003 Ford F150' aCar.toString = function() { return '2013 BMW 335is Convertible'; }; aCar.toString(); // '2013 BMW 335is Convertible' anotherCar.toString(); // '2003 Ford F150'
  12. function Car(make, model, year) { this.make = make; this.model =

    model; this.year = year; } Car.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } var aCar = new Car('Saturn', 'Vue', 2007); var anotherCar = new Car('Ford', 'F150', '2003'); aCar.toString(); // '2007 Saturn Vue' anotherCar.toString(); // '2003 Ford F150' Car.prototype.toString = function() { return '2013 BMW 335is Convertible'; }; aCar.toString(); // '2013 BMW 335is Convertible' anotherCar.toString(); // '2013 BMW 335is Convertible'
  13. class Dad extends Person { public function __construct($firstName) { $this->familyName

    = 'Carouth'; parent::__construct($firstName); } } class Son extends Dad { } $son = new Son('Jeff'); print $son->familyName; // 'Carouth'
  14. var Dad = function() { this.familyName = 'Carouth'; }; var

    Son = function(firstName) { this.firstName = firstName; }; Son.prototype = new Dad(); Son.prototype.constructor = Son; var jeff = new Son('Jeff'); jeff.familyName; // 'Carouth' jeff instanceof Son; // true jeff instanceof Dad; // true
  15. <?php namespace Foo; class Car { public function __construct($make, $model,

    $year) { // ...snip... } // ...snip... } //someotherfile.php $myCar = new Foo\Car('Toyota', 'Prius', '2011');
  16. var Foo = Foo || {}; Foo.Car = function(make, model,

    year) { // ...snip.. }; var myCar = new Foo.Car('Toyota', 'Prius', '2011');
  17. var Car = (function() { var Constructor; Constructor = function(make,

    model, year) { this.make = make; this.model = model; this.year = year; } Constructor.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } return Constructor; }());
  18. var Car = (function() { var Constructor; Constructor = function(make,

    model, year) { this.make = make; this.model = model; this.year = year; } Constructor.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } return Constructor; }()); (function() { }());
  19. var Car = (function() { var Constructor; Constructor = function(make,

    model, year) { this.make = make; this.model = model; this.year = year; } Constructor.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } return Constructor; }()); var Car = var Constructor; return Constructor;
  20. var Car = (function($) { var Constructor; Constructor = function(make,

    model, year) { this.make = make; this.model = model; this.year = year; } Constructor.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } return Constructor; }(jQuery)); Dependencies
  21. Extension myCar.beep(); //undefined Car = (function(Car) { Car.prototype.beep = function()

    { return 'Beep'; }; return Car; }(Car)); myCar.beep(); // 'Beep'
  22. var Car = (function() { var started = false; var

    Constructor; Constructor = function(make, model, year) { /* snip */ }; Constructor.prototype = { constructor: Constructor, toString: function() { /* snip */ }, start: function() { if (!started) { started = true; } }, isRunning: function() { return started === true; } }; return Constructor; })();
  23. var myCar = new Car('BMW', '335is Convertible', 2013); myCar.isRunning(); //

    false myCar.started; // undefined myCar.start(); myCar.isRunning(); // true
  24. require(["jquery", "Car"], function($, Car) { var myCar = new Car('BMW',

    '335is Convertible', 2013); $("#output").html(myCar.toString()); }); scripts/main.js
  25. scripts/Car.js define(function () { var Constructor; Constructor = function(make, model,

    year) { this.make = make; this.model = model; this.year = year; }; Constructor.prototype.toString = function() { return this.year + " " + this.make + " " + this.model; } return Constructor; });
  26. Backbone.Router MyRouter = Backbone.Router.extend({ routes: { "": "index", "cars": "cars",

    "cars/:id": "car" }, index: function() { /* show homepage */ }, cars: function() { /* list of cars */ }, car: function(id) { /* show car */ } });
  27. Backbone.View View takes data and transform it into HTML via

    templates and a reference to a DOM element. The view also listens to events and triggers action based those events.
  28. Backbone.View var CarView = Backbone.View.extend({ tagName: "li", className: "car", events:

    { 'click .start': 'start' }, render: function() { this.$el.html( this.name() + ' <span class="start">[start]</span>' ); return this; }, start: function() { alert('car started'); }, name: function() { return this.model.toString(); } });
  29. Backbone.Model The model syncs with a server. If the backend

    is RESTful the “out of the box” sync will just work. A model holds information about a single record from the backend. Model update triggers and event which will update the view for that specific model.
  30. Backbone.Model var Car = Backbone.Model.extend({ urlRoot: '/cars', toString: function() {

    return this.get('year') + " " + this.get('make') + " " + this.get('model'); } }); var CarView = Backbone.View.extend({ initialize: function() { this.model.on('change', this.render, this); } /* ...snip... */ });
  31. Backbone.Collection var Cars = Backbone.Collection.extend({ url: '/cars', model: Car });

    var CarsView = Backbone.View.extend({ initialize: function() { this.collection = new Cars(); this.collection.fetch({ success: _.bind(function(resp, status, xhr) { this.render(); }, this) }); }, render: function() { this.collection.each(this.renderCar, this); }, renderCar: function(model) { var carView = new CarView({model: model}); this.$el.append(carView.el); } });
  32. Templates in Backbone There is no default. You can use

    Underscore.js templates since it is a dependency. You are able to use whatever JavaScript templating such as Handlebars.
  33. <!doctype html> <html> <head> <title>Example Test Runner</title> <link rel="stylesheet" href="vendor/qunit.css"

    /> <script src="vendor/qunit.js"></script> <script src="../src/vendor/require.js" data-main="tests.js"></script> </head> <body> <div id="qunit"></div> </body> </html>
  34. (function() { QUnit.config.autostart = false; require.config({ baseUrl: "../src" }); var

    testModules = [ "model/CarTests.js" ]; require(testModules, QUnit.start); }());
  35. define(function(require) { var Car = require("./Car"); QUnit.module("model/Car", { setup: function()

    {}, teardown: function() {} }); QUnit.test("Car should not be running when first created", function() { var mycar = new Car('BMW', '335is', 2013); ok(!mycar.isRunning()); } ); QUnit.test("Car should be running after it is started", function() { var mycar = new Car("BMW", "335is", 2013); mycar.start(); ok(mycar.isRunning()); } ); });
  36. module.exports = function(grunt) { grunt.initConfig({ lint: { src: ['src/model/**/*.js'], tests:

    ['tests/model/**/*.js'] }, qunit: { files: ['tests/tests.html'] }, uglify: {} }); grunt.registerTask('default', 'lint qunit'); };
  37. $ grunt Running "lint:src" (lint) task Lint free. Running "lint:tests"

    (lint) task Lint free. Running "qunit:files" (qunit) task Testing tests.htmlOK >> 2 assertions passed (15ms) Done, without errors.