From 137302bd540e023eca2585664c70cd5efb0dcf9f Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 11 Dec 2012 18:31:26 +0100 Subject: [PATCH 01/71] Publish slides --- index.html | 8956 +++++++++++++++++++++++++++++++++++++++++++++++++++ index2.html | 8249 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 17205 insertions(+) create mode 100644 index.html create mode 100644 index2.html diff --git a/index.html b/index.html new file mode 100644 index 0000000..a5e9218 --- /dev/null +++ b/index.html @@ -0,0 +1,8956 @@ + + + + + + + PHP + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ 00:00:00 +
+
+
+
+
+ + +
+
+
+ +

PHP

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Who Is Speaking?

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

William DURAND

+ + +

PhD student at Michelin / LIMOS

+

Graduated from IUT and ISIMA

+

Worked at:

+ +

Open-Source evangelist:

+
    +
  • Lead developer of the Propel ORM, +Geocoder, and several other projects;
  • +
  • (Inactive?) Contributor on Symfony2.
  • +
+

twitter.com/couac + | github.com/willdurand + | williamdurand.fr

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Julien MUETTON

+ + +

Software developer at IT Networks

+

Graduated from ESIGELEC (Rouen)

+

Co-founder of Carpe Hora (Clermont-Ferrand, France)

+

Worked at:

+ +

Passionate front end developer, believe in standards and open source.

+
+

Read the code, not the doc

+
+

twitter.com/themouette + | github.com/themouette

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Agenda

+ + +

Week #1

+

PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server

+

Week #2

+

Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View Controller

+

Week #3

+

Databases

+

Week #4

+

Writing Better Code, Testing, Embracing Open Source

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP: Hypertext Preprocessor

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

History & Numbers

+ + +
    +
  • Created by Rasmus Lerdorf
  • +
  • 5th language in the world (TIOBE November 2012)
  • +
  • 1st language for web development
  • +
  • Running on 75% of all web servers
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Getting Started

+ + +

Linux

+
$ sudo apt-get install php5-common libapache2-mod-php5 php5-cli
+
+ +
+

http://php.net/manual/en/install.unix.debian.php

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Getting Started

+ + +

Mac OS X

+
$ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.4
+
+ +
+

http://php-osx.liip.ch/

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Getting Started

+ + +

Windows

+

+
+

http://www.php.net/manual/en/install.windows.installer.msi.php

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

RTFM: http://www.php.net

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The PHP Syntax

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Primitive Types

+ + +

4 scalar types: boolean, integer, float, string;

+

2 compound types: array, object;

+

2 special types: resource, null;

+

And 3 pseudo types: mixed, number, callable.

+

Note: most of these types have aliases. E.g. double for float.

+
+

Read more about the PHP primitive types: +http://www.php.net/manual/en/language.types.intro.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Comparison Operators

+ + +
// so, this is a PHP variable
+$a = 5;
+
+// compare value; return true
+var_dump($a == 5);
+
+// compare value (ignore type); return true
+var_dump($a == '5');
+
+// compare type/value (integer vs. integer); return true
+var_dump($a === 5);
+
+// compare type/value (integer vs. string); return false
+var_dump($a === '5');
+
+ +
+

Read more about comparison operators: +http://php.net/manual/en/language.operators.comparison.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Operators

+ + +
$a++; // or: ++$a;
+
+$b--; // or: --$b;
+
+$a && $b;   // AND
+$a || $b;   // OR
+
+! $a;       // `true` if $a is not `true`
+
+$a . 'foo'; // concatenation
+
+ +

But also:

+
$a  = 'foo';
+$a .= 'bar';
+// $a => 'foobar'
+
+$b  = 0;
+$b += 1;    // $b = 1
+$b -= 1;    // $b = 0
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Classes (1/2)

+ + +

Simple class definition

+
class Foo
+{
+}
+
+ +

Important: No class-level visibility in PHP.

+

Abstract class definition

+
abstract class AbstractFoo
+{
+    abstract public function doSomething();
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Classes (2/2)

+ + +

Creating an instance:

+
$foo = new Foo();
+// $foo = new Foo;
+
+// can also be done with a variable
+$class = 'Foo';
+$foo   = new $class();
+
+ +

Getting the classname of an instance:

+
echo get_class($foo);
+=> Foo
+
+ +

Useful keyword: instanceof

+
if ($foo instanceof Foo) {
+    // do something
+}
+
+ +
+

http://www.php.net/manual/en/language.oop5.basic.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Visibility

+ + +

Keywords

+
    +
  • public
  • +
  • protected
  • +
  • private
  • +
+

The Rules

+

Attribute visibility MUST be set.

+

Method visibility SHOULD be set.

+

Methods without any explicit visibility keyword are defined as public.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Attributes

+ + +
class Foo
+{
+    /**
+     * @var int
+     */
+    public static $count = 0;
+
+    /**
+     * @var Iterator
+     */
+    public $iterator;
+
+    /**
+     * @var array
+     */
+    protected $values = array();
+
+    /**
+     * @var string|null
+     */
+    private $language = null;
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Methods (1/3)

+ + +
class Foo
+{
+    public function doSomething()
+    {
+    }
+}
+
+ +

Type Hinting

+

Works with objects, interfaces, arrays or callable. You can't use +scalar types such as int or string:

+
public function doSomething(Foo $foo);
+
+public function doSomething(Traversable $iterator);
+
+public function doSomething(array $values);
+
+public function doSomething(callable $callback);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Methods (2/3)

+ + +

The -> sign is used to call methods on objects.

+

Usage

+
$foo->doSomething();
+
+// >= PHP 5.4
+(new Foo())->doSomething();
+
+// can also be done with a variable
+$method = 'doSomething';
+$foo->$method();
+
+$foo->{$method . 'Else'}();
+// will call 'doSomethingElse()'
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Methods (3/3)

+ + +
public function doSomething()
+{
+    // method call
+    $this->doSomethingElse();
+
+    // parent method call (inheritance)
+    parent::doSomething();
+
+    // accessing a constant
+    self::VALUE;
+
+    // accessing a constant from another class
+    Bar::ANOTHER_VALUE;
+
+    // accessing an attribute
+    return $this->attribute;
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Static Keyword (1/2)

+ + +

Attributes/Methods can be defined as static:

+
class Foo
+{
+    public static $value;
+
+    public static function doThings()
+    {
+        // accessing a static attribute
+        // don't forget the dollar sign!
+        self::$value;
+    }
+}
+
+ +

Warning: the static keyword can also be used to +define static variables and for late static bindings. +This is different!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Static Keyword (2/2)

+ + +

Usage

+
$foo = new Foo();
+
+// accessing the attribute from an instance
+$foo::$value = 123;
+
+// accessing the attribute directly from the class
+echo Foo::value;
+=> 123
+
+ +
+

http://php.net/manual/en/language.oop5.static.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Interfaces

+ + +

Simple interface definition

+
interface Fooable
+{
+    const VALUE = 123;
+
+    // it's always public anyway
+    public function doSomething();
+}
+
+ +

Inheritance

+
interface MyTraversable extends Traversable
+{
+}
+
+ +

Usage

+
class Foo implements Fooable, MyTraversable {}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Namespaces

+ + +

Namespaces prevent naming collisions with identifiers such as function, class, +and interface names:

+
namespace Vendor\Model;
+// ...
+
+ +

Or:

+
namespace MyNamespace {
+    // ...
+}
+
+ +

PSR-0

+

PSR-0 +describes a set of rules related to namespaces for autoloader interoperability.

+
\ns\package\Class_Name      => vendor/ns/package/Class/Name.php
+\ns\package_name\Class_Name => vendor/ns/package_name/Class/Name.php
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Traits

+ + +

Horizontal Inheritance FTW!

+
trait Hello                         trait World
+{                                   {
+    public function sayHello()          public function sayWorld()
+    {                                    {
+        echo 'Hello ';                       echo 'World';
+    }                                    }
+}                                   }
+
+class MyHelloWorld
+{
+    use Hello, World;
+}
+
+$obj = new MyHelloWorld();
+$obj->sayHello();
+$obj->sayWorld();
+
+ +
+

Read more about traits: +http://www.php.net/manual/en/language.oop5.traits.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Anonymous Functions

+ + +
$greet = function ($name) {
+    printf("Hello %s\n", $name);
+};
+
+$greet('World');
+=> Hello World
+
+ +
+

Read more about anonymous functions: +http://www.php.net/manual/en/functions.anonymous.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Closures

+ + +
$fibonacci = function ($n) use (&$fibonacci) {
+    if (0 === $n || 1 === $n) {
+        return 1;
+    }
+
+    return $fibonacci($n - 1) + $fibonacci($n - 2);
+};
+
+echo (int) $fibonacci(6);
+=> 13
+
+ +
+

Read more about closures: +http://php.net/manual/en/class.closure.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Magic Methods

+ + +

Starts with __.

+

Two useful methods:

+
__construct() { /* ... */ }
+
+ +

and:

+
__toString() { /* ... */ }
+
+ +

Other methods are not really useful but it's worth knowing them (__get(), __set()).

+
+

Read more about magic methods: +http://php.net/manual/en/language.oop5.magic.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The PHP Command Line

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The PHP Command Line (1/2)

+ + +

PHP is an interpreted language, no need for a compiler.

+

You can try PHP using the command line:

+
$ php -r 'echo "Hello, World\n"'
+Hello, World
+
+ +
+

Help available by running: php -h.

+
+

PHP also provides an interactive shell:

+
$ php -a
+Interactive Shell
+
+php > echo "Hello, World\n";
+Hello, World
+
+ +
+

The command line is really useful, read more about command line options: +http://php.net/manual/en/features.commandline.options.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The PHP Command Line (2/2)

+ + +

Your new best friend is the linter:

+
$ php -l my/script.php
+No syntax errors detected in my/script.php
+
+ +
+

A linter is a program that looks for problems in your code (syntax +errors for instance).

+
+

Embedded web server:

+
$ php -S localhost:8000
+
+ +
+

Learn more about the built-in, command line web server: +http://www.php.net/manual/en/features.commandline.webserver.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Writing a CLI program

+ + +
#!/usr/bin/env php
+<?php
+
+if (2 !== $argc) {
+    echo "Usage: php $argv[0] [name]\n";
+    exit(1);
+}
+
+$name = $argv[1];
+echo "Hello, $name!\n";
+
+ +

Run the script:

+
$ ./hello.php
+Usage: ./hello.php [name]
+
+$ php hello.php
+Usage: php hello.php [name]
+
+$ php hello.php World
+Hello, World!
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Client/Server

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Client/Server Basics

+ + +

A typical client/server request follows this pattern:

+

+
    +
  • +

    Client: Hello server, give me the resource at URI.

    +
  • +
  • +

    Server: Here is the resource at URI:

    +

    > Content

    +
  • +
+

For HTTP, a typical client is a web browser, and a server is a web server.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Request

+ + +

Request is made of:

+
    +
  • A Unique Resource Identifier (URI);
  • +
  • An HTTP verb describing the action;
  • +
  • Some headers describing requirements;
  • +
  • A request body to send data.
  • +
+

Here is an example:

+
GET /my/simple/uri?with-query-string HTTP/1.1
+Host: example.org
+Content-Type: text/plain; charset=utf-8
+Content-Length: length
+
+This is a content
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Response

+ + +

Response is made of:

+
    +
  • Some headers to describe the content;
  • +
  • The response status;
  • +
  • The content of the request;
  • +
+

Here is an example:

+
HTTP/1.1 200 OK
+Content-Type: text/html; charset=utf-8
+Content-Length: length
+
+<!DOCTYPE HTML>
+<html>
+    <head>
+    </head>
+    <body>
+        <h1>Hello world !</h1>
+    </body>
+</html>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Verbs

+ + +

An HTTP verb is an action to perform on a resource located at a given +URI:

+
    +
  • GET: retrieve a resource or a collection of resources;
  • +
  • POST: create a new resource;
  • +
  • PUT: update an existing resource;
  • +
  • DELETE: delete a given resource;
  • +
  • PATCH: partial update of a given resource.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Parameters (1/2)

+ + +

There are two types of parameters, query string and request body.

+

If the request follows the URL Form Encoded format, you can access +parameters through global variables:

+
    +
  • query string: $_GET;
  • +
  • request body: $_POST;
  • +
  • All parameters are available in the $_REQUEST global variable.
  • +
+

You can always use the following, but you need to parse them by yourself:

+
    +
  • query string: $_SERVER['QUERY_STRING'];
  • +
  • request body: $HTTP_RAW_POST_DATA.
  • +
+

Note: Don't use $_REQUEST, as there is a collision risk!

+

Also, never trust user input, never!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Parameters (2/2)

+ + +
GET /my/simple/uri?a=1&id=2 HTTP/1.1
+Host: example.org
+Content-Type: text/plain; charset=utf-8
+Content-Length: length
+
+b=3&city=paris
+
+ +

Will result in:

+
$_GET = array("a" => 1, "id" => 2);
+
+$_POST = array("b" => 3, "city" => 'paris');
+
+$_REQUEST = array("a" => 1, "id" => 2, "b" => 3, "city" => 'paris');
+
+$_SERVER['QUERY_STRING'] = "a=1&id=2";
+
+$HTTP_RAW_POST_DATA = "b=3&city=paris";
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

REST (REpresentational State Transfer)

+ + +

Each URI represents a unique resource that can be formatted as requested in +json, xml, or html.

+
    +
  • /bananas/joe: URI for banana "Joe"
  • +
  • /bananas/henry: URI for banana "Henry"
  • +
+

Those resources are organized into collections:

+
    +
  • /bananas: collection of all available bananas.
  • +
+

So it makes sense to use HTTP verbs to execute an action:

+
+

GET /banana/joe will return banana "Joe".

+
+

And:

+
+

DELETE /bananas will delete all bananas in the collection!

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Autoloading

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Why Is It Necessary?

+ + +

PHP won't magically load your classes by itself.

+

You have to manually include the class declaration:

+
class Octopus
+{
+    public function scream()
+    {
+        echo "o o O O  ° °";
+    }
+}
+
+ +

If you want to create a new Octopus, you will write the following code:

+
$paul = new Octopus();
+$paul->scream();
+
+ +

As the class declaration isn't included, PHP raises a Fatal Error:

+
Fatal error: Class 'Octopus' not found in /path/to/file.php
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The require() Way

+ + +

Include the class definition before instantiating it:

+
require __DIR__ . '../Model/Octopus.php';
+
+$paul = new Octopus();
+$paul->scream();
+
+ +

It works!

+

But, what happens when the class is included again, somewhere else?

+
// somewhere further in your application
+require __DIR__ . '../Model/Octopus.php';
+
+class Squid extends Octopus
+{
+}
+
+ +

PHP raises a Fatal Error:

+
Fatal error: Cannot redeclare class Octopus in /path/to/file.php
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The require_once() Way

+ + +

The require_once() function is identical to require() except that PHP will +check whether the file has already been included:

+
require_once __DIR__ . '../Model/Octopus.php';
+
+$paul = new Octopus();
+$paul->scream();
+
+ +

And somewhere else:

+
// somewhere further in your application
+require_once __DIR__ . '../Model/Octopus.php';
+
+class Squid extends Octopus
+{
+}
+
+ +

It just works!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Working With Multiple Files

+ + +

Multiple require_once() can turn into a nightmare when you deal with more than +a few files:

+
<?php
+
+/**
+ * lib/Model/Location.php
+ */
+require_once __DIR__ . '/../../common.php';
+require_once DOCROOT . '/lib/Model/ModelInterface.php';
+require_once DOCROOT . '/lib/Model/User.php';
+require_once DOCROOT . '/lib/Validator/Email.php';
+require_once DOCROOT . '/lib/Validator/Username.php';
+require_once DOCROOT . '/lib/Validator/Url.php';
+
+class Location implements ModelInterface
+{
+    /* ... */
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Rethinking The Way We Load Classes

+ + +

PHP 5.2 and upper provides a usable autoloading API with performances close to +the use of require_once() thanks to the following functions:

+

__autoload()

+

Main autoload callback.

+

spl_autoload_register()

+

Register a new autoload callback.

+

spl_autoload_unregister()

+

Unregister an autoload callback.

+

spl_autoload_functions()

+

List all autoload methods.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Examples

+ + +

__autoload()

+
function __autoload($className)
+{
+    require_once __DIR__ . DIRECTORY_SEPARATOR . $className . '.php';
+}
+
+ +

spl_autoload_register()

+
function my_autoload($className)
+{
+    require_once __DIR__ . DIRECTORY_SEPARATOR . $className . '.php';
+}
+
+spl_autoload_register('my_autoload');
+
+ +

spl_autoload_unregister()

+
spl_autoload_unregister('my_autoload');
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Under The Hood

+ + +
new Foo();
+
+ +

The new algorithm in pseudo code:

+
1. Does the 'Foo' class exist?
+    => Yes
+        Go on
+
+    => No
+         Do we have registered autoload functions?
+            => Yes
+                Call each function with 'Foo' as parameter
+                until the class gets included
+
+            => No
+                Is there a `__autoload()` method?
+                    => Yes
+                        Call `__autoload('Foo')`
+
+2. Does the 'Foo' class exist?
+    => Yes
+        Continue
+    => No
+        Fatal Error
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Leveraging PHP APIs

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Built-in Interfaces

+ + +

ArrayAccess

+

Access properties as an array:

+
$tom = new MyObject();
+$tom['name'] = 'Tom';
+
+ +

Serializable

+

Allow the use of serialize() and unserialize().

+

Traversable

+

Allow the use of foreach.

+
+

Read more http://fr2.php.net/manual/en/reserved.interfaces.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Reflection API (1/2)

+ + +

Enable code introspection:

+
/** A comment */
+class MyClass
+{
+    public function hello() { printf("Hello %s", $this->getName()); }
+
+    protected function getName() { return 'foo'; }
+}
+
+$reflClass = new ReflectionClass('MyClass');
+
+// access comments
+var_dump($reflClass->getDocComment());
+// string(16) "/** A comment */"
+
+// get all methods
+$reflClass->getMethods();
+
+// get all public methods
+$reflClass->getMethods(ReflectionMethod::IS_PUBLIC);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Reflection API (2/2)

+ + +

It is even possible to invoke protected methods!

+
class MyClass
+{
+    public function hello() { printf("Hello %s", $this->getName()); }
+
+    private function getName() { return 'foo'; }
+}
+
+$reflClass = new ReflectionClass('MyClass');
+
+// access private method
+$method = $reflClass->getMethod('getName');
+$method->setAccessible(true);
+
+$method->invoke(new MyClass());
+// Hello
+
+ +
+

Read more http://www.php.net/manual/en/book.reflection.php +.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Standard PHP Library (SPL)

+ + +

Provides a collection of classes and interfaces:

+

Datastructures

+

SplStack, SplQueue, SplObjectStorage, etc.

+

Named Exceptions

+

LogicException, InvalidArgumentException, OutOfRangeException, etc.

+

SPL Functions

+

class_parents(), spl_autoload_register(), spl_autoload_unregister(), etc.

+
+

Read more about the SPL: +http://php.net/manual/en/book.spl.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Observer/Observable (1/2)

+ + +

The SplObserver interface is used alongside SplSubject to implement the +Observer Design Pattern.

+
class Subject implements SplSubject
+{
+    /* ... */
+}
+
+class Observer implements SplObserver
+{
+    /* ... */
+}
+
+$subject = new Subject();
+
+$observer1 = new Observer();
+
+$subject->attach($observer1);
+
+$subject->notify();
+
+ +
+

Read more: php.net/manual/en/class.splobserver.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Observer/Observable (2/2)

+ + +

Those interfaces are never used as default channel has to be specified for the +notify() method.

+

Symfony2 EventDispatcher +component to the rescue!

+
use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\EventDispatcher\Event;
+
+$dispatcher = new EventDispatcher();
+
+$dispatcher->addListener('event_name', function (Event $event) {
+    // ...
+});
+
+$dispatcher->dispatch('event_name');
+
+ +
+

Read more: http://symfony.com/doc/2.0/components/event_dispatcher/.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Exceptions

+ + +

try/catch block with multiple catch statements:

+
try {
+    // ...
+} catch (RuntimeException $e) {
+    // do something
+} catch (Exception $e) {
+    // do something else
+}
+
+ +

Create your own exceptions:

+
class MyException extends RuntimeException
+{
+}
+
+class MyException extends Exception implements ExceptionInterface
+{
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Archive (PHAR)

+ + +

The phar extension provides a way to put entire PHP applications into +a single file called a "phar" (PHP Archive) for easy distribution and +installation.

+

But, the API is hard to use.

+

Solution? Box, a command line for simplifying +the PHAR creation process.

+
+

Read more about PHAR:

+ +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Management in PHP

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Management

+ + +

There are a ton of PHP libraries, frameworks, and components to choose from. +Most of them have different versions, and don't always work well together.

+

Composer is a tool for dependency management in PHP. It allows you to declare +the dependent libraries your project needs and it will install them in your +project for you.

+

A lot of PHP libraries are compatible with Composer and listed on +Packagist, the official repository for Composer-compatible +PHP libraries.

+
$ curl -s https://getcomposer.org/installer | php
+
+ +

This will download composer.phar (a PHP binary archive).

+
+

Read more about Composer: +http://getcomposer.org/doc/00-intro.md.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Composer

+ + +

Create a composer.json file in your project's root directory:

+
{
+    "require": {
+        "willdurand/geocoder": "1.1.*"
+    }
+}
+
+ +

Run the following command to download and install the project dependencies into +a vendor directory:

+
$ php composer.phar install
+
+ +

Require the generated autoloader in your project:

+
<?php
+
+require 'vendor/autoload.php';
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Example

+ + +

Instead of writing a console application by hand, let's use an existing library: +the Symfony2 Console component:

+
{
+    "require": {
+        "symfony/console": "v2.1.5"
+    }
+}
+
+ +

The structure of your application should look like:

+
console-app
+├── app
+│   └── console
+├── composer.json
+├── src
+├── tests
+└── vendor
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Symfony2 Console Component

+ + +

The easiest way to write strong console applications:

+
    +
  • Create a set of commands;
  • +
  • Add them to a console application.
  • +
+

Your Commands should extend the Command class:

+
class GreetCommand extends Command
+{
+    protected function configure()
+    {
+        // configure the name, arguments, options, etc.
+    }
+
+    protected function execute(InputInterface $input,
+        OutputInterface $output)
+    {
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

A Basic Command (1/2)

+ + +

Configuration

+
$this
+    ->setName('demo:greet')
+    ->addArgument(
+        'name',
+        InputArgument::OPTIONAL,
+        'Who do you want to greet?'
+    );
+
+ +

Execution

+
if (null === $name = $input->getArgument('name')) {
+    $name = 'World';
+}
+
+$output->writeln('Hello, ' . $name);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

A Basic Command (2/2)

+ + +

The Console Application

+
#!/usr/bin/env php
+# app/console
+<?php
+
+// require the Composer autoloader
+require __DIR__ . '/../vendor/autoload.php';
+
+$application = new Application();
+$application->add(new GreetCommand());
+$application->run();
+
+ +

Usage

+
$ app/console demo:greet
+Hello, World
+$ app/console demo:greet William
+Hello, William
+
+
+

http://symfony.com/doc/master/components/console/introduction.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Model View Controller

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

MVC Overview

+ + +

Typical client request process in MVC architecture:

+

+
+ +
+
+

Notes

+
+ +
    +
  1. Client makes a request
  2. +
  3. Controller handles request:
      +
    • interactions with model
    • +
    • data preparation
    • +
    • send data to view
    • +
    +
  4. +
  5. View format data
  6. +
+ +
+
+ +
+
+ + +
+
+
+ +

The Model

+ + +

Model is the layer in charge of data interaction.

+

All data related business logic is embedded here. +Using it should not require to understand internals.

+

Examples:

+
    +
  • Manipulate database records;
  • +
  • Communicate with search engine;
  • +
  • API calls;
  • +
  • etc.
  • +
+
+

More on this next week!

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The View

+ + +

PHP is a templating language per se.

+

Never, ever, ever mix HTML and PHP codes or kittens +will die: you have to separate the presentation from the business logic. +But creating a template engine is ok!

+
class TemplateEngine
+{
+    private $templateDir;
+
+    public function __construct($templateDir)
+    {
+        $this->templateDir = $templateDir;
+    }
+
+    public function render($template, $parameters = array())
+    {
+        extract($parameters);
+
+        ob_start();
+        include $this->templateDir . DIRECTORY_SEPARATOR . $template;
+
+        return ob_get_clean();
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The View

+ + +

Template

+
<!-- my_template.html -->
+<p>Hello, <?php echo $name; ?>!</p>
+
+ +

Even better with PHP 5.4:

+
<p>Hello, <?= $name ?>!</p>
+
+ +

Usage

+
$engine = new TemplateEngine('/path/to/templates');
+
+echo $engine->render('my_template.html', array(
+    'name' => 'World',
+));
+=> <p>Hello, World!</p>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The View

+ + +

Twig is a modern template engine for PHP. It takes care of escaping for +you and much much more! Read more: +http://twig.sensiolabs.org/.

+

Template

+
{# my_template.html #}
+<p>Hello, {{ name }}!</p>
+
+ +

Usage

+
$loader = new Twig_Loader_Filesystem('/path/to/templates');
+$engine = new Twig_Environment($loader, array(
+    'cache' => '/path/to/compilation_cache',
+));
+
+echo $engine->render('my_template.html', array(
+    'name' => 'World',
+));
+=> <p>Hello, World!</p>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Controller

+ + +

Glue between the Model and the View layers.

+

It should not contain any logic.

+
class BananaController
+{
+    public function __construct(BananaMapper $mapper,
+            TemplateEngineInterface $engine)
+    {
+        $this->mapper = $mapper;
+        $this->engine = $engine;
+    }
+
+    public function listAction()
+    {
+        $bananas = $this->mapper->findAll();
+
+        return $this->engine->render('list.html', array(
+            'bananas' => $bananas,
+        ));
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Routing

+ + +

Routing is the process of binding URIs to controllers.

+

Folder organization

+

The simplest kind of routing, but also the hardest to maintain:

+
web/
+├ trees/
+│ ├ banana.php
+│ └ pineapple.php
+└ tree.php
+
+

Centralized declaration

+

Modern frameworks all provide a routing component such as Symfony2 Routing +component allowing to define all routes in a centralized place and easing +URI generation.

+

This require a single entry point: the Frontend Controller.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Front Controller Pattern

+ + +

A controller that handles all requests for a web application:

+

+

This controller dispatches the request to the specialized controllers.

+

It is usually tied to URL rewriting.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Interact With Multiple Services

+ + +

Web applications become more and more complex and interact with +multiple services such as:

+
    +
  • Relational database to store consistent data;
  • +
  • Search engine to index and retrieve documents;
  • +
  • Message queues to postpone executions or as event brokers;
  • +
  • External APIs (geocoding, payment, social, ...);
  • +
  • Mail server to send or receive emails;
  • +
  • Text message gateway;
  • +
  • HTTP cache server to reduce resources needs and speed up responses;
  • +
  • and much much more.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Databases

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Agenda

+ + +
    +
  • Database Design Patterns
  • +
  • Data Access Layer
  • +
  • Object Relational Mapping
  • +
  • Existing Components
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Quick note

+ + +

In our context, a database is seen as a server hosting:

+
    +
  • a set of records;
  • +
  • organised through tables or collections;
  • +
  • grouped by databases.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Database Design Patterns

+ + +
    +
  • Row Data Gateway
  • +
  • Table Data Gateway
  • +
  • Active Record
  • +
  • Data Mapper
  • +
  • Identity Map
  • +
  • etc.
  • +
+

Definitions and figures are part of the Catalog of Patterns of Enterprise +Application Architecture +created by Martin Fowler.

+

Don't forget his name! Read his books!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Row Data Gateway

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Row Data Gateway

+ + +

An object that acts as a Gateway to a single record (row) in a database. +There is one instance per row.

+
class Banana
+{
+    private $id;
+
+    private $name;
+
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Row Data Gateway

+ + +

Usage

+
$con = new Connection('...');
+
+$banana = new Banana();
+$banana->setName('Super Banana');
+
+// Save the banana
+$banana->insert($con);
+
+// Update it
+$banana->setName('New name for my banana');
+$banana->update($con);
+
+// Delete it
+$banana->delete($con);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Row Data Gateway

+ + +

Under the hood

+
public function insert(Connection $con)
+{
+    // Prepared statement
+    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
+
+    $stmt->bindValue(':name', $name);
+
+    $stmt->execute();
+
+    // Set the id for this banana
+    //
+    // It becomes easy to know whether the banana is new or not,
+    // you just need to check if id is defined.
+    $this->id = $this->con->lastInsertId();
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

An object that acts as a Gateway to a database table. +One instance handles all the rows in the table.

+

It's a Data Access Object.

+
$table = new BananaGateway(new Connection('...'));
+
+// Insert a new record
+$id = $table->insert('My favorite banana');
+
+// Update it
+$table->update($id, 'THE banana');
+
+// Delete it
+$table->delete($id);
+
+ +

CRUD

+

A DAO implements the well-known Create Read Update +Delete methods.

+

Read should not be a single method: Finders to the rescue!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

Implementation

+
class BananaGateway
+{
+    private $con;
+
+    public function __construct(Connection $con)
+    {
+        $this->con = $con;
+    }
+
+    public function insert($name) {}
+
+    public function update($id, $name) {}
+
+    public function delete($id);
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

The insert method

+
/**
+ * @param string $name The name of the banana you want to create
+ *
+ * @return int The id of the banana
+ */
+public function insert($name)
+{
+    // Prepared statement
+    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
+
+    $stmt->bindValue(':name', $name);
+
+    $stmt->execute();
+
+    return $this->con->lastInsertId();
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

The update method

+
/**
+ * @param int    $id   The id of the banana to update
+ * @param string $name The new name of the banana
+ *
+ * @return bool Returns `true` on success, `false` otherwise
+ */
+public function update($id, $name)
+{
+    $stmt = $this->con->prepare(<<<SQL
+UPDATE bananas
+SET name = :name
+WHERE id = :id
+SQL
+    );
+
+    $stmt->bindValue(':id', $id);
+    $stmt->bindValue(':name', $name);
+
+    return $stmt->execute();
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

The delete method

+
/**
+ * @param int $id The id of the banana to delete
+ *
+ * @return bool Returns `true` on success, `false` otherwise
+ */
+public function delete($id)
+{
+    $stmt = $this->con->prepare('DELETE FROM bananas WHERE id = :id');
+
+    $stmt->bindValue(':id', $id);
+
+    return $stmt->execute();
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Table Data Gateway

+ + +

Finders

+
// Retrieve all bananas
+$bananas = $table->findAll();
+
+// Find bananas by name matching 'THE %'
+$bananas = $table->findByName('THE %');
+
+// Retrieve a given banana using its id
+$banana = $table->find(123);
+
+// Find one banana by name matching 'THE %'
+$banana = $table->findOneByName('THE %');
+
+ +
+

Use the __call() magic method to create magic finders: +http://www.php.net/manual/en/language.oop5.overloading.php#object.call.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Active Record

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Active Record

+ + +

An object that wraps a row in a database table, encapsulates +the database access, and adds domain logic on that data.

+

Active Record = Row Data Gateway + Domain Logic

+
$con = new Connection('...');
+
+$banana = new Banana();
+$banana->setName('Another banana');
+$banana->save($con);
+
+// Call a method that is part of the domain logic
+// What can a banana do anyway?
+$banana->grow();
+
+// Smart `save()` method
+// use `isNew()` under the hood
+$banana->save($con);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Active Record

+ + +
class Banana
+{
+    private $height = 1;
+
+    public function grow()
+    {
+        $this->height++;
+    }
+
+    public function save(Connection $con)
+    {
+        if ($this->isNew()) {
+            // issue an INSERT query
+        } else {
+            // issue an UPDATE query
+        }
+    }
+
+    public function isNew()
+    {
+        // Yoda style
+        return null === $this->id;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Mapper

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Mapper

+ + +

A layer of Mappers that moves data between objects and a database +while keeping them independent of each other and the mapper itself.

+

Sort of "Man in the Middle".

+
class BananaMapper
+{
+    private $con;
+
+    public function __construct(Connection $con)
+    {
+        $this->con = $con;
+    }
+
+    public function persist(Banana $banana)
+    {
+        // code to save the banana
+    }
+
+    public function remove(Banana $banana)
+    {
+        // code to delete the banana
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Mapper

+ + +

Usage

+
$banana = new Banana();
+$banana->setName('Fantastic Banana');
+
+$con    = new Connection('...');
+$mapper = new BananaMapper($con);
+
+$mapper->persist($banana);
+
+$mapper->remove($banana);
+
+ +

But also:

+
// Retrieve a collection
+$bananas = $mapper->findAll();
+
+// or a single record
+$banana = $mapper->find(123);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Identity Map

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Identity Map

+ + +

Ensures that each object gets loaded only once by keeping every loaded object in +a map. Looks up objects using the map when referring to them.

+
class Finder
+{
+    private $identityMap = array();
+
+    public function findOneById($id)
+    {
+        if (!isset($this->identityMap[$id])) {
+            // fetch the object for the given id
+            $this->identityMap[$id] = ...;
+        }
+
+        return $this->identityMap[$id];
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Access Layer

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Access Layer

+ + +

A Data Access Layer (DAL) is a standard API to manipulate data, +no matter which database server is used.

+

The Data Source Name (DSN) can be used to determine which database +vendor you are using.

+

PHP Data Object (PDO)

+

A DSN in PHP looks like: <database>:host=<host>;dbname=<dbname> where:

+
    +
  • <database> can be: mysql, sqlite, pgsql, etc;
  • +
  • <host> is the IP address of the database server (most of the time localhost);
  • +
  • <dbname> is your database name.
  • +
+
+

http://www.php.net/manual/en/intro.pdo.php

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Access Layer

+ + +

PDO usage

+
$dsn = 'mysql:host=localhost;dbname=test';
+
+$con = new PDO($dsn, $user, $password);
+
+// Prepared statement
+$stmt = $con->prepare($query);
+$stmt->execute();
+
+ +

Looks like the Connection class we used before, right?

+
class Connection extends PDO
+{
+}
+
+ +

Usage

+
$con = new Connection($dsn, $user, $password);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Access Layer

+ + +

Refactoring

+

Refactoring is a disciplined technique for restructuring an existing +body of code, altering its internal structure without changing its +external behavior.

+
class Connection extends PDO
+{
+    /**
+     * @param string $query
+     * @param array  $parameters
+     *
+     * @return bool Returns `true` on success, `false` otherwise
+     */
+    public function executeQuery($query, $parameters = array())
+    {
+        $stmt = $this->prepare($query);
+
+        foreach ($parameters as $name => $value) {
+            $stmt->bindValue(':' . $name, $value);
+        }
+
+        return $stmt->execute();
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Data Access Layer

+ + +

Usage

+
/**
+ * @param int    $id   The id of the banana to update
+ * @param string $name The new name of the banana
+ *
+ * @return bool Returns `true` on success, `false` otherwise
+ */
+public function update($id, $name)
+{
+    $query = 'UPDATE bananas SET name = :name WHERE id = :id';
+
+    return $this->con->executeQuery($query, array(
+        'id'    => $id,
+        'name'  => $name,
+    ));
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Object Relational Mapping

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Object Relational Mapping (1/4)

+ + +

Introduces the notion of relations between objects:

+
    +
  • One-To-One;
  • +
  • One-To-Many;
  • +
  • Many-To-Many.
  • +
+

An ORM is often considered as a tool that implements some design patterns +seen above, and that eases relationships between objects.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Object Relational Mapping (2/4)

+ + +

One-To-One (1-1)

+

+

Example

+
$profile = $banana->getProfile();
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Object Relational Mapping (3/4)

+ + +

One-To-Many (1-N)

+

+

Example

+
$bananas = $bananaTree->getBananas();
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Object Relational Mapping (4/4)

+ + +

Many-To-Many (N-N)

+

+

Example

+
$roles = array();
+foreach ($banana->getBananaRoles() as $bananaRole) {
+    $roles[] = $bananaRole->getRole();
+}
+
+// Or, better:
+$roles = $banana->getRoles();
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Existing Components

+ + +

Propel ORM

+

An ORM that implements the Table Data Gateway and Row Data Gateway +patterns, often seen as an Active Record approach.

+
+

Documentation: propelorm.org.

+
+

Doctrine2 ORM

+

An ORM that implements the Data Mapper pattern.

+
+

Documentation: doctrine-project.org.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Your Turn!

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Sessions

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Overview

+ + +

A way to persist browsing data accross client calls:

+
    +
  • unique identifier;
  • +
  • stored server side;
  • +
  • easy to use;
  • +
  • built-in.
  • +
+

Some usecases:

+
    +
  • Keep user authentication and roles;
  • +
  • Store cart;
  • +
  • Store a flash message between redirections.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Code Please

+ + +
// initalize session
+session_start();
+
+// regenerate identifier
+session_regenerate_id();
+
+// affect "key"
+$_SESSION['key'] = $value;
+
+// retrieve key
+$_SESSION['key'];
+
+// terminate session
+session_destroy();
+
+ +
+

Session should be started before headers are sent! +http://php.net/manual/en/book.session.php.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Security Concerns

+ + +
    +
  • Cookie hijacking/XSS;
  • +
  • Man in the Middle;
  • +
  • Predicatable session token.
  • +
+

Workarounds

+
    +
  • Regenerate ids when authentication changes;
  • +
  • Validate client informations (user agent);
  • +
  • Maximum lifetime;
  • +
  • Use HTTPS.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Authentication

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

What You Have Right Now

+ + +

No Authentication/Security Layer, anyone can access everything:

+

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Big Picture

+ + +

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Interceptor Pattern

+ + +

The Security Layer, as seen before, has to intercept the process of +converting a request into a response in order to perform some checks.

+

We need a way to hook into this process before invoking the controller: +Interceptor Pattern to the rescue!

+

The Interceptor Pattern allows you to execute some code during the default +application's lifecyle.

+

A way to implement this pattern is to use events. It's more or less like +the Observer/Observable pattern.

+

Event Dispatcher

+

The application notifies a set of listeners to an event.

+

The listeners can register themselves to a particular event.

+

An Event Dispatcher manages both the listeners, and the events.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Introducing the Event Dispatcher

+ + +

Using a trait:

+
trait EventDispatcherTrait
+{
+    private $events = [];
+
+    public function addListener($name, $callable)
+    {
+        $this->events[$name][] = $callable;
+    }
+
+    public function dispatch($name, array $arguments = [])
+    {
+        foreach ($this->events[$name] as $callable) {
+            call_user_func_array($callable, $arguments);
+        }
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using the EventDispatcherTrait

+ + +

In order to intercept the process described before, we have to notify some +listeners once we enter in the process() method by dispatching the event:

+
class App
+{
+    use EventDispatcherTrait;
+
+    ...
+
+    private function process(Request $request, Route $route)
+    {
+        $this->dispatch('process.before', [ $request ]);
+
+        ...
+    }
+}
+
+ +

The listeners have to listen to this event:

+
$app->addListener('process.before', function (Request $request) {
+    // code to execute
+});
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Firewall

+ + +

Now that we can hook into the appplication's lifecycle, we need to write a +Firewall.

+

A Firewall needs a whitelist of unsecured routes (routes which don't +require the user to be authenticated):

+
$allowed = [
+    '/login'     => [ Request::GET, Request::POST ],
+    '/locations' => [ Request::GET ],
+];
+
+ +

The Firewall leverages the session to determine whether the user is +authenticated:

+
session_start();
+
+if (isset($_SESSION['is_authenticated'])
+    && true === $_SESSION['is_authenticated']) {
+    return;
+}
+
+ +

If authentication fails, the server should return a 401 status code.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Implementing The Firewall

+ + +
$app->addListener('process.before', function(Request $req) use ($app) {
+    session_start();
+
+    $allowed = [
+        '/login' => [ Request::GET, Request::POST ],
+    ];
+
+    if (isset($_SESSION['is_authenticated'])
+        && true === $_SESSION['is_authenticated']) {
+        return;
+    }
+
+    foreach ($allowed as $pattern => $methods) {
+        if (preg_match(sprintf('#^%s$#', $pattern), $req->getUri())
+            && in_array($req->getMethod(), $methods)) {
+            return;
+        }
+    }
+
+    switch ($req->guessBestFormat()) {
+        case 'json':
+            throw new HttpException(401);
+    }
+
+    return $app->redirect('/login');
+});
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Authentication Mechanism

+ + +

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Adding New Routes

+ + +
$app->get('/login', function () use ($app) {
+    return $app->render('login.php');
+});
+
+$app->post('/login', function (Request $request) use ($app) {
+    $user = $request->getParameter('user');
+    $pass = $request->getParameter('password');
+
+    if ('will' === $user && 'will' === $pass) {
+        $_SESSION['is_authenticated'] = true;
+
+        return $app->redirect('/');
+    }
+
+    return $app->render('login.php', [ 'user' => $user ]);
+});
+
+$app->get('/logout', function (Request $request) use ($app) {
+    session_destroy();
+
+    return $app->redirect('/');
+});
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Stateless Authentication

+ + +

Useful for API authentication.

+

OAuth

+

http://oauth.net/

+

Basic and Digest Access Authentication

+

http://pretty-rfc.herokuapp.com/RFC2617

+

WSSE Username Token

+

http://www.xml.com/pub/a/2003/12/17/dive.html

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Writing Better Code

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Agenda

+ + +
    +
  • Coding Standards
  • +
  • Programming To The Interface
  • +
  • Component Driven Development
  • +
  • Dependency Injection
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Coding Standards

+ + +
<?php
+
+namespace Vendor\Model;
+
+class Foo
+{
+    const VERSION   = '1.0';
+
+    public $bar     = null;
+
+    protected $opts = array();
+
+    private $var3   = 123;
+
+    public function __construct(BarInterface $bar, $opts = array())
+    {
+        $this->bar  = $bar;
+        $this->opts = $opts;
+    }
+}
+
+ +
+

Read more about coding standards with +PSR-1 +and +PSR-2.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Coding Standards Fixer

+ + +

The PHP Coding Standards Fixer tool fixes most issues in your code when +you want to follow the PHP coding standards as defined in the PSR-1 and +PSR-2 documents.

+

Installation:

+
$ wget http://cs.sensiolabs.org/get/php-cs-fixer.phar
+
+ +

Usage:

+
$ php php-cs-fixer.phar fix /path/to/dir/or/file
+
+ +
+

http://cs.sensiolabs.org/.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Programming To The Interface

+ + +

Reduces dependency on implementation specifics and makes code more reusable.

+

The BananaController can use either Twig or the raw PHP implementation +as template engine thanks to the TemplateEngineInterface:

+
interface TemplateEngineInterface
+{
+    /**
+     * @param string $template
+     * @param array  $parameters
+     *
+     * @return string
+     */
+    public function render($template, array $parameters = array());
+}
+
+ +

You should think about interfaces, not about internal implementation details.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Component Driven Development

+ + +

It’s all about Separation of Concerns (SoC).

+

You design components with their own logic, each component does one thing +well, and only one thing.

+

How to manage these components in your application?

+
+

Read Component Driven Development: it's like Lego!.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Injection

+ + +

Design Pattern that allows a choice of component to be made at runtime +rather than compile time.

+

Most of the time, you rely on configuration files to describe your classes +and their dependencies.

+

A class in this context is also known as a service, and all services live +in a service container or dependency injection container.

+

You ask this container to retrieve a service, and it is lazy loaded and dynamically +built:

+
// It's an instance of TemplateEngineInterface, but you don't know
+// anything about its internal implementation.
+// Is it the raw PHP implementation or Twig?
+$engine = $container->get('template_engine');
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Injection

+ + +

Constructor Injection

+

All dependencies are injected using a constructor:

+
class Foo
+{
+    private $bar;
+
+    public function __construct(BarInterface $bar)
+    {
+        $this->bar = $bar;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Injection

+ + +

Setter Injection

+

Dependencies are injected through setters:

+
class Foo
+{
+    private $bar;
+
+    public function setBar(BarInterface $bar)
+    {
+        $this->bar = $bar;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dependency Injection

+ + +

Interface Injection

+

An interface describes the injection:

+
interface BarAware
+{
+    public function setBar(BarInterface $bar);
+}
+
+ +

It needs to be implemented by the class that wants to use a BarInterface:

+
class Foo implements BarAware
+{
+    private $bar;
+
+    public function setBar(BarInterface $bar)
+    {
+        $this->bar = $bar;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Implementations

+ + +

Twittee

+

Twittee is the smallest Dependency Injection +Container written in PHP. +It fits in a tweet (less than 140 characters):

+
class Container
+{
+    protected $s = array();
+
+    function __set($k, $c)
+    {
+        $this->s[$k] = $c;
+    }
+
+    function __get($k)
+    {
+        return $this->s[$k]($this);
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Implementations

+ + +

Pimple

+

Pimple is a small Dependency Injection Container +for PHP 5.3 that consists of just one file and one class.

+

The Symfony2 DependencyInjection Component

+

The DependencyInjection component +allows you to standardize and centralize the way objects are constructed in your +application.

+
+

Read more:

+ +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Testing

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Agenda

+ + +
    +
  • Unit Testing
  • +
  • Functional Testing
  • +
  • Behavior Driven Development
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Unit Testing

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Unit Testing

+ + +

Unit testing is a Method by which individual units of source code are tested to +determine if they are fit for use.

+

PHPUnit is the de-facto standard for +unit testing in PHP projects.

+

Install it using Composer:

+
{
+    "require-dev": {
+        "phpunit/phpunit": "3.7.*"
+    }
+}
+
+ +

Or as a PHAR:

+
$ wget http://pear.phpunit.de/get/phpunit.phar
+$ chmod +x phpunit.phar
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using PHPUnit

+ + +

The Rules

+

The tests for a class Class go into a class ClassTest.

+

ClassTest inherits (most of the time) from PHPUnit_Framework_TestCase, but +a common practice is to create a TestCase class for a project, and to inherit +from it:

+
class TestCase extends PHPUnit_Framework_TestCase {}
+
+ +

The tests are public methods that are named test*. +You can also use the @test annotation:

+
class ClassTest extends TestCase
+{
+    public function testFoo()
+    {
+        $object = new MyClass();
+        $this->assertEquals('foo', $object->foo(), 'optional comment');
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHPUnit Assertions

+ + +
    +
  • assertEquals()
  • +
  • assertTrue()
  • +
  • assertFalse()
  • +
  • etc.
  • +
+

See all assertion methods: http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Running PHPUnit

+ + +

Running the test suite:

+
$ phpunit
+PHPUnit 3.7.0 by Sebastian Bergmann.
+
+.
+
+Time: 1 seconds, Memory: 5.25Mb
+
+OK (1 test, 1 assertion)
+
+ +

Getting the code coverage:

+
$ phpunit --coverage-text
+
+ +

See also:

+
$ phpunit --log-junit junit_output.xml
+
+$ phpunit --testdox
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Functional Testing

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Functional Testing

+ + +

Also known as acceptance testing.

+

Use tools to create automated tests that actually use your application instead +of just verifying that individual units of code are behaving correctly.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Behavior Driven Development

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Behavior Driven Development

+ + +

SpecBDD

+
    +
  • You write specifications that describe how your actual code should + behave;
  • +
  • Focused on technical behavior;
  • +
  • PHPSpec.
  • +
+

StoryBDD

+
    +
  • You write human-readable stories that describe the behavior of your + application;
  • +
  • Business oriented;
  • +
  • Behat.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Behat

+ + +

Install Behat via Composer:

+
{
+    "require-dev": {
+        "behat/behat": "2.4.*@stable"
+    },
+    "config": {
+        "bin-dir": "bin/"
+    }
+}
+
+ +

The bin/behat command is now installed!

+

Or as a PHAR:

+
$ wget https://github.com/downloads/Behat/Behat/behat.phar
+$ chmod +x behat.phar
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using Behat (1/2)

+ + +

Initialize your project:

+
$ bin/behat --init
+
+ +

Define a Feature:

+
# features/your_first_feature.feature
+Feature: Your first feature
+  In order to start using Behat
+  As a manager or developer
+  I need to try
+
+ +

Define a Scenario:

+
Scenario: Successfully describing scenario
+  Given there is something
+  When I do something
+  Then I should see something
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using Behat (2/2)

+ + +

Executing Behat:

+
$ behat
+
+ +

Writing your Step definitions:

+
/**
+ * @Given /^there is something$/
+ */
+ public function thereIsSomething()
+ {
+    throw new PendingException();
+ }
+
+ +

Must Read: +https://speakerdeck.com/everzet/behat-by-example.

+
+

Read more about Behat: +http://docs.behat.org/.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Embracing Open Source

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

GitHub

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Travis-CI

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Golden Rules

+ + +
    +
  • Read other people's code is the fastest way to learn
  • +
  • Think about what you have to do
  • +
  • Read the code, not the doc
  • +
  • Never trust the user
  • +
  • Think again
  • +
  • Simple is always better than complicated
  • +
  • Keep your code readable
  • +
  • Test your code, it eases refactoring
  • +
  • Keep HTTP protocol in mind
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The End

+ + +

Second part.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/index2.html b/index2.html new file mode 100644 index 0000000..7fafa7e --- /dev/null +++ b/index2.html @@ -0,0 +1,8249 @@ + + + + + + + PHP Extended + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ 00:00:00 +
+
+
+
+
+ + +
+
+
+ +

PHP Extended

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Let's Do Professional Development Now!

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

A Framework To Simplify Developments

+ + +

A framework helps you work better by structuring developments, +and faster by reusing generic modules.

+

A framework facilitates long-term maintenance and scalability by +complying with standard development rules.

+

Compliance with development standards also simplifies integrating and +interfacing the application with the rest of the information system.

+

In other words, it works as a tool to make the development process +easier and more productive.

+

Most of the time, a framework implements many kinds of design patterns.

+
+

Read more: Symfony explained to a +Developer.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

What Is Symfony2?

+ + +

First of all:

+
+

Symfony2 is a reusable set of standalone, decoupled, and cohesive PHP +components that solve common web development problems.

+
+

Then, based on these components:

+
+

Symfony2 is also a full-stack web framework.

+
+

Fabien Potencier, +http://fabien.potencier.org/article/49/what-is-symfony2.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Is Symfony2 A MVC Framework?

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

NO!

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Why You Should Use Symfony2

+ + +

Symfony2 is built on powerful concepts:

+
    +
  • Separation of Concerns;
  • +
  • Pragmatism;
  • +
  • Best Practices.
  • +
+

+

It has been written by ~700 developers.

+

Open Source, MIT licensed.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Symfony2 Components

+ + +

The Components implement common features needed to develop websites.

+

They are the foundation of the Symfony full-stack framework, but they can +also be used standalone even if you don't use the framework as they don't +have any mandatory dependencies.

+

There are more than 21 components, including:

+
BrowserKit             EventDispatcher    Routing
+ClassLoader            Finder             Security
+Config                 Form               Serializer
+Console                HttpFoundation     Templating
+CssSelector            HttpKernel         Translation
+DependencyInjection    Locale             Validator
+DomCrawler             Process            Yaml
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Getting Ready With Components

+ + +

Assuming you want to play with YAML files, start by requiring the symfony/yaml +component into your composer.json file:

+
{
+    "require": {
+        "symfony/yaml": "~2.1"
+    }
+}
+
+ +

Install it by running php composer.phar install, and use it:

+
require __DIR__ . '/vendor/autoload.php';
+
+use Symfony\Component\Yaml\Yaml;
+
+$yaml = Yaml::parse('/path/to/file.yml');
+
+ +
+

Read more: +http://symfony.com/doc/current/components/yaml/introduction.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Full-Stack Framework

+ + +

The Symfony2 Framework is a PHP library that accomplishes two distinct +tasks:

+
    +
  • Provides a selection of components;
  • +
  • Provides sensible configuration and a "glue" library that ties all of these + pieces together.
  • +
+

The goal of the framework is to integrate many independent tools in order to +provide a consistent experience for the developer. Even the framework itself is +a Symfony2 bundle (i.e. a plugin) that can be configured or replaced entirely.

+

Symfony2 provides a powerful set of tools for rapidly developing web +applications without imposing on your application.

+
+

Documentation available at: +http://symfony.com/doc/current/book/index.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Overall Architecture

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Symfony2 Request

+ + +
use Symfony\Component\HttpFoundation\Request;
+
+$request = Request::createFromGlobals();
+
+// the URI being requested (e.g. /about) minus any query parameters
+$request->getPathInfo();
+
+// the HTTP verb
+$request->getMethod();
+
+// GET variables
+$request->query->get('foo');
+
+// POST variables
+$request->request->get('bar');
+
+// SERVER variables
+$request->server->get('HTTP_HOST');
+
+// retrieve an HTTP request header, with normalized, lowercase keys
+$request->headers->get('host');
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Symfony2 Response

+ + +
use Symfony\Component\HttpFoundation\Response;
+
+$response = new Response();
+
+$response->setContent(<<<HTML
+<html>
+    <body>
+        <h1>Hello world!</h1>
+    </body>
+</html>
+HTML
+);
+
+$response->setStatusCode(200);
+
+$response->headers->set('Content-Type', 'text/html');
+
+// prints the HTTP headers followed by the content
+$response->send();
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Simplest Front Controller Ever

+ + +
// index.php
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+$request = Request::createFromGlobals();
+$path    = $request->getPathInfo();
+
+if (in_array($path, array('', '/'))) {
+    $response = new Response('Welcome to the homepage.');
+} elseif ($path == '/hello') {
+    $response = new Response('hello, World!');
+} else {
+    $response = new Response('Page not found.', 404);
+}
+
+$response->send();
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Symfony Application Flow

+ + +

It's all about transforming a Request into a Response: +

+

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Routing Definition

+ + +

The routing system determines which PHP function should be executed based on +information from the request and routing configuration you've created.

+
# app/config/routing.yml
+hello:
+    pattern:  /hello
+    defaults: { _controller: AcmeDemoBundle:Main:hello }
+
+ +

The AcmeDemoBundle:Main:hello string is a short syntax that points to a +specific PHP method named helloAction() inside a class called +MainController.

+
+

Note: this example uses YAML to define the routing configuration. +Routing configuration can also be written in other formats such as XML or +PHP.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Your First Controller

+ + +

In Symfony2, a method in a controller is called an action. The convention is +to suffix each method with Action.

+

Also, each controller should be suffixed with Controller.

+
// src/Acme/DemoBundle/Controller/MainController.php
+namespace Acme\DemoBundle\Controller;
+
+use Symfony\Component\HttpFoundation\Response;
+
+class MainController
+{
+    public function helloAction()
+    {
+        return new Response('<h1>Hello, World!</h1>');
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

A Symfony2 Project

+ + +

Recommended structure of a Symfony2 project:

+
path/to/project/
+    app/
+        cache/
+        config/
+        logs/
+    src/
+        ...
+    vendor/
+        ...
+    web/
+        app.php
+        ...
+
+
    +
  • app/ contains the application kernel, and the configuration;
  • +
  • src/ contains your bundles;
  • +
  • vendor/ contains your dependencies;
  • +
  • web/ contains your front controllers and your assets.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Application Kernel

+ + +

This is the central part of your application:

+
// app/AppKernel.php
+use Symfony\Component\HttpKernel\Kernel;
+
+class AppKernel extends Kernel
+{
+    public function registerBundles()
+    {
+        $bundles = array(
+            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
+            // ...
+        );
+
+        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
+            $bundles[] = // dev bundle;
+        }
+
+        return $bundles;
+    }
+
+    // ...
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Application Configuration

+ + +

An application consists of a collection of "bundles" representing all of the +features and capabilities of your application.

+

Each "bundle" can be customized via configuration files written in YAML, XML +or PHP.

+

By default, the main configuration file lives in the app/config/ +directory and is called either config.yml, config.xml or config.php +depending on which format you prefer.

+

Symfony2 is all about configuring everything, and you can do pretty much +everything you want. That's why people agreed on some conventions, but then +again, a convention is just A way to do things, not THE way to do them.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

YAML Configuration

+ + +

Example:

+
# app/config/config.yml
+imports:
+    - { resource: parameters.yml }
+    - { resource: security.yml }
+
+framework:
+    secret: "%secret%"
+    router: { resource: "%kernel.root_dir%/config/routing.yml" }
+    # ...
+
+# Twig Configuration
+twig:
+    debug:            "%kernel.debug%"
+    strict_variables: "%kernel.debug%"
+
+# ...
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

XML Configuration

+ + +

Example:

+
<!-- app/config/config.xml -->
+<imports>
+    <import resource="parameters.yml"/>
+    <import resource="security.yml"/>
+</imports>
+
+<framework:config secret="%secret%">
+    <framework:router resource="%kernel.root_dir%/config/routing.xml"/>
+    <!-- ... -->
+</framework:config>
+
+<!-- Twig Configuration -->
+<twig:config debug="%kernel.debug%" strict-variables="%kernel.debug%"/>
+
+<!-- ... -->
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

PHP Configuration

+ + +

Example:

+
$this->import('parameters.yml');
+$this->import('security.yml');
+
+$container->loadFromExtension('framework', array(
+    'secret' => '%secret%',
+    'router' => array(
+        'resource' => '%kernel.root_dir%/config/routing.php'
+    ),
+    // ...
+));
+
+// Twig Configuration
+$container->loadFromExtension('twig', array(
+    'debug'            => '%kernel.debug%',
+    'strict_variables' => '%kernel.debug%',
+));
+
+// ...
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Rules (Well... My Rules)

+ + +

The main configuration has to be written in YAML:

+
# app/config/config.yml
+# ...
+twig:
+    debug:            "%kernel.debug%"
+    strict_variables: "%kernel.debug%"
+
+ +

The routing definition has to be written in YAML:

+
# app/config/routing.yml
+hello:
+    pattern:  /hello
+    defaults: { _controller: AcmeDemoBundle:Main:hello }
+
+ +

The Dependency Injection Container configuration has to be written in XML.

+
<services>
+    <service id="acme_demo.controllers.main"
+        class="Acme\DemoBundle\MainController" />
+</services>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Environments

+ + +

An application can run in various environments. The different environments +share the same PHP code, but use different configuration.

+

A Symfony2 project generally uses three environments: dev, test and prod.

+
// web/app.php
+
+// ...
+$kernel = new AppKernel('prod', false);
+
+ +

The AppKernel class is responsible for actually loading the configuration file +of your choice:

+
// app/AppKernel.php
+public function registerContainerConfiguration(LoaderInterface $loader)
+{
+    $loader->load(
+        __DIR__ . '/config/config_' . $this->getEnvironment() . '.yml'
+    );
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

What Is A Bundle?

+ + +

A Bundle is a directory containing a set of files (PHP files, stylesheets, +JavaScripts, images, ...) that implement a single feature (a blog, a forum, +etc).

+

It should be reusable, so that you don't reinvent the wheel each time you +need a common feature. In Symfony2, (almost) everything lives inside a bundle.

+

In order to use a bundle in your application, you need to register it in the +AppKernel, using the registerBundles() method:

+
public function registerBundles()
+{
+    $bundles = array(
+        // ...
+
+        new My\AwesomeBundle\MyAwesomeBundle(),
+    );
+
+    // ...
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Bundle: Directory Structure

+ + +

Recommended structure for a bundle:

+
XXX/...
+    DemoBundle/
+        DemoBundle.php
+        Controller/
+        Resources/
+            meta/
+                LICENSE
+            config/
+            doc/
+                index.rst
+            translations/
+            views/
+            public/
+        Tests/
+
+

The DemoBundle class is mandatory, and both Resources/meta/LICENSE and +Resources/doc/index.rst files should be present.

+

The XXX directory(ies) reflects the namespace structure of the bundle.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Bundle: Where To Put Your Classes?

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDirectory
CommandsCommand/
ControllersController/
Service Container ExtensionsDependencyInjection/
Event ListenersEventListener/
ConfigurationResources/config/
Web ResourcesResources/public/
Translation filesResources/translations/
TemplatesResources/views/
Unit and Functional TestsTests/
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Creating a Bundle

+ + +

A bundle has to extend the Symfony\Component\HttpKernel\Bundle\Bundle +class:

+
// src/Acme/MyFirstBundle/AcmeMyFirstBundle.php
+namespace Acme\MyFirstBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class AcmeMyFirstBundle extends Bundle
+{
+}
+
+ +

You can register your bundle:

+
// app/AppKernel.php
+public function registerBundles()
+{
+    $bundles = array(
+        new Acme\MyFirstBundle\AcmeMyFirstBundle(),
+    );
+
+    return $bundles;
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Web Directory

+ + +

The web root directory is the home of all public and static files including +images, stylesheets, and JavaScript files. It is also where each front +controller lives:

+
// web/app.php
+require_once __DIR__.'/../app/bootstrap.php.cache';
+require_once __DIR__.'/../app/AppKernel.php';
+
+use Symfony\Component\HttpFoundation\Request;
+
+$kernel   = new AppKernel('prod', false);
+$request  = Request::createFromGlobals();
+$response = $kernel->handle($request);
+$response->send();
+
+ +

The front controller file (app.php in this example) is the actual PHP file +that's executed when using a Symfony2 application and its job is to use a +Kernel class, AppKernel, to bootstrap the application, for a given +environment.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Summary

+ + +

Creating a page is a three-step process involving a route, a controller, and +(optionally) a template.

+

Each project contains just a few main directories: web/ (web assets and the +front controllers), app/ (configuration), src/ (your bundles), and vendor/ +(third-party code).

+

Each feature in Symfony2 (including the Symfony2 framework core) is organized +into a bundle, which is a structured set of files for that feature.

+

The configuration for each bundle lives in the Resources/config directory of the +bundle and can be specified in YAML, XML or PHP.

+

The global application configuration lives in the app/config/ directory.

+

Each environment is accessible via a different front controller (e.g. app.php +and app_dev.php) and loads a different configuration file.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Controllers

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Request, Controller, Response

+ + +

A controller is a PHP function you create that takes information from the +HTTP request and constructs and returns an HTTP response.

+

Every request handled by a Symfony2 project goes through the same lifecycle:

+
    +
  1. Each request is handled by a single front controller file (e.g. app.php or +app_dev.php) that bootstraps the application;
  2. +
  3. The Router reads information from the request (e.g. the URI), finds a route +that matches that information, and reads the _controller parameter from the +route;
  4. +
  5. The controller from the matched route is executed and the code inside the +controller creates and returns a Response object;
  6. +
  7. The HTTP headers and content of the Response object are sent back to the +client.
  8. +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Simplest Page Ever

+ + +

Routing Definition

+
# app/config/routing.yml
+homepage:
+    pattern:  /
+    defaults: { _controller: AcmeDemoBundle:Hello:index }
+
+ +

Controller Implementation

+
// src/Acme/DemoBundle/Controller/HelloController.php
+namespace Acme\DemoBundle\Controller;
+
+use Symfony\Component\HttpFoundation\Response;
+
+class HelloController
+{
+    public function indexAction()
+    {
+        return new Response('Home, Sweet Home!');
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Controller Naming Pattern

+ + +

Every route must have a _controller parameter, which dictates which controller +should be executed when that route is matched.

+

This parameter uses a simple string pattern called the logical controller name.

+

The pattern has three parts, each separated by a colon:

+
bundle:controller:action
+
+

For example, a _controller value of AcmeBlogBundle:Blog:show means:

+
    +
  • Bundle: AcmeBlogBundle;
  • +
  • Controller Class: BlogController;
  • +
  • Method Name: showAction.
  • +
+

Notice that Symfony adds the string Controller to the class name (Blog => +BlogController) and Action to the method name (show => showAction).

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Route Params as Controller Arguments

+ + +

Routing Definition

+
# src/Acme/DemoBundle/Resources/config/routing.yml
+acme_demo.hello_hello:
+    pattern:  /hello/{name}
+    defaults: { _controller: AcmeDemoBundle:Hello:hello }
+    requirements:
+        _method: GET
+
+ +

Controller Implementation

+
// src/Acme/DemoBundle/Controller/HelloController.php
+
+class HelloController
+{
+    // ...
+
+    public function helloAction($name)
+    {
+        return new Response(sprintf('Home, Sweet %s!', $name));
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Request as a Controller Argument

+ + +

For convenience, you can also have Symfony pass you the Request object as an +argument to your controller:

+
use Symfony\Component\HttpFoundation\Request;
+
+class HelloController
+{
+    // ...
+
+    public function updateAction(Request $request)
+    {
+        // do something useful with $request
+    }
+}
+
+ +

This is useful when you are working with forms.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Base Controller Class

+ + +

Symfony2 comes with a base Controller class that assists with some of the most +common controller tasks and gives your controller class access to any resource +it might need:

+
use Symfony\Bundle\FrameworkBundle\Controller\Controller
+
+class HelloController extends Controller
+{
+    // ...
+}
+
+ +

Redirecting

+
$this->redirect($this->generateUrl('homepage'));
+
+ +

Rendering Templates

+
return $this->render(
+    'AcmeDemoBundle:Hello:hello.html.twig', array('name' => $name)
+);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Response

+ + +

The only requirement for a controller is to return a Response object.

+

Create a simple Response with a 200 status code:

+
use Symfony\Component\HttpFoundation\Response;
+
+$response = new Response('Hello, ' . $name, 200);
+
+ +

Create a JSON response with a 200 status code:

+
$response = new Response(json_encode(array('name' => $name)));
+$response->headers->set('Content-Type', 'application/json');
+
+ +

Or:

+
use Symfony\Component\HttpFoundation\JsonResponse;
+
+$response = new JsonResponse(array('name' => $name));
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Routing

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Basic Route Configuration

+ + +

The Symfony2 router lets you define URLs that you map to different areas of +your application.

+

A route is a map from a URL path to a controller. Each route is named, and +maps a pattern (or path as of Symfony2.2) to a _controller:

+
# app/config/routing.yml
+homepage:
+    pattern:  /
+    defaults: { _controller: AcmeDemoBundle:Hello:index }
+
+ +

This route matches the homepage (/) and maps it to the +AcmeDemoBundle:Hello:index controller.

+
+

Read more: +http://symfony.com/doc/master/book/routing.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Routing with Placeholders

+ + +

Required Placeholders

+
blog:
+    path:      /blog/{page}
+    defaults:  { _controller: AcmeBlogBundle:Blog:index }
+
+ +

The path will match anything that looks like /blog/*. Even better, the value +matching the {page} placeholder will be available inside your controller.

+

/blog will not match.

+

Optional Placeholders

+
blog:
+    path:      /blog/{page}
+    defaults:  { _controller: AcmeBlogBundle:Blog:index, page: 1 }
+
+ +

By adding page to the defaults key, {page} is no longer required.

+

/blog will match this route and the value of the page parameter will be +set to 1. /blog/2 will also match, giving the page parameter a value of 2.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Requirements

+ + +
blog:
+    path:      /blog/{page}
+    defaults:  { _controller: AcmeBlogBundle:Blog:index, page: 1 }
+    requirements:
+        page:  \d+
+
+ +

The \d+ requirement is a regular expression that says that the value of +the {page} parameter must be a digit (i.e. a number).

+

HTTP Method Requirements

+
# src/Acme/DemoBundle/Resources/config/routing.yml
+acme_demo.hello_hello:
+    pattern:  /hello/{name}
+    defaults: { _controller: AcmeDemoBundle:Hello:hello }
+    requirements:
+        _method: GET
+        # _methods: GET|POST
+
+    # New in Symfony2.2!
+    methods: [ GET ]
+    # methods: [ GET, POST ]
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Including External Routing Resources

+ + +

All routes are loaded via a single configuration file, most of the time it will +be app/config/routing.yml.

+

In order to respect the "bundle" principle, the routing configuration should be +located in the bundle itself, and you should just require it:

+
# app/config/routing.yml
+acme_demo:
+    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
+
+ +

Prefixing Imported Routes

+

You can eventually "prefix" all routes for a given routing configuration:

+
# app/config/routing.yml
+acme_demo:
+    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
+    prefix: /demo
+
+ +

The string /demo now be prepended to the path of each route loaded from +the new routing resource.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Generating URLs

+ + +

The Router is able to generate both relative and absolute URLs.

+
$router = $this->get('router');
+
+ +

Relative URLs

+
$router->generate('acme_demo.hello_hello', array('name' => 'will'));
+// /hello/will
+
+ +

Absolute URLs

+
$router->generate('acme_demo.hello_hello',
+    array('name' => 'will'), true);
+// http://example.com/hello/will
+
+ +

Query String

+
$router->generate('acme_demo.hello_hello',
+    array('name' => 'will', 'some' => 'thing'));
+// /hello/will?some=thing
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Templating

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Why Twig?

+ + +

Fast, Secure, Flexible.

+

Before

+
<ul id="navigation">
+    <?php foreach ($navigation as $item): ?>
+        <li>
+            <a href="<?php echo $item->getHref() ?>">
+                <?php echo $item->getCaption() ?>
+            </a>
+        </li>
+    <?php endforeach; ?>
+</ul>
+
+ +

After

+
<ul id="navigation">
+    {% for item in navigation %}
+        <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
+    {% endfor %}
+</ul>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Getting Familiar With Twig

+ + +

Delimiters

+
    +
  • {{ ... }}: prints a variable or the result of an expression;
  • +
  • {% ... %}: controls the logic of the template; it is used to execute for + loops and if statements, for example;
  • +
  • {# ... #}: comments.
  • +
+
+

Documentation: http://twig.sensiolabs.org/.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Accessing Variables

+ + +
{# array('name' => 'Fabien') #}
+{{ name }}
+
+{# array('user' => array('name' => 'Fabien')) #}
+{{ user.name }}
+
+{# force array lookup #}
+{{ user['name'] }}
+
+{# array('user' => new User('Fabien')) #}
+{{ user.name }}
+{{ user.getName }}
+
+{# force method name lookup #}
+{{ user.name() }}
+{{ user.getName() }}
+
+{# pass arguments to a method #}
+{{ user.date('Y-m-d') }}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Control Structure

+ + +

Conditions

+
{% if user.isSuperAdmin() %}
+    ...
+{% elseif user.isMember() %}
+    ...
+{% else %}
+    ...
+{% endif %}
+
+ +

Loops

+
<ul>
+    {% for user in users if user.active %}
+        <li>{{ user.username }}</li>
+    {% else %}
+        <li>No users found</li>
+    {% endfor %}
+</ul>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Filters

+ + +

Filters are used to modify Twig variables.

+

You can use inline filters by using the | symbol:

+
{{ 'hello'|upper }}
+
+ +

But you can also use the block syntax:

+
{% filter upper %}
+    hello
+{% endfilter %}
+
+ +

Filters can be parametrized:

+
{{ post.createdAt|date('Y-m-d') }}
+
+ +
+

Documentation for all filters is available at: +http://twig.sensiolabs.org/doc/filters/index.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Including Other Templates

+ + +

The include tag is useful to include a template and return the rendered +content of that template into the current one:

+
{% include 'sidebar.html' %}
+
+ +

Example

+

Given the following template:

+
{% for user in users %}
+    {% include "render_user.html" %}
+{% endfor %}
+
+ +

with render_user.html:

+
<p>{{ user.username }}</p>
+
+ +

The result with two users would be:

+
<p>William D.</p>
+<p>Julien M.</p>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Template Inheritance (1/2)

+ + +

Let's define a base template, base.html, which defines a simple HTML skeleton:

+
{# app/Resources/views/base.html.twig #}
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>{% block title %}Test Application{% endblock %}</title>
+    </head>
+    <body>
+        <div id="sidebar">
+            {% block sidebar %}
+            <ul>
+                <li><a href="/">Home</a></li>
+                <li><a href="/blog">Blog</a></li>
+            </ul>
+            {% endblock %}
+        </div>
+
+        <div id="content">
+            {% block body %}{% endblock %}
+        </div>
+    </body>
+</html>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Template Inheritance (2/2)

+ + +

The key to template inheritance is the {% extends %} tag.

+

A child template might look like this:

+
{# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
+{% extends '::base.html.twig' %}
+
+{% block title %}My cool blog posts{% endblock %}
+
+{% block body %}
+    {% for entry in blog_entries %}
+        <h2>{{ entry.title }}</h2>
+        <p>{{ entry.body }}</p>
+    {% endfor %}
+{% endblock %}
+
+ +

The parent template is identified by a special string syntax +(::base.html.twig) that indicates that the template lives in +app/Resources/views/.

+

If you need to get the content of a block from the parent template, you can +use the {{ parent() }} function.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Template Naming and Locations (1/2)

+ + +

By default, templates can live in two different locations:

+
    +
  • app/Resources/views/: The applications views directory can contain + application-wide base templates (i.e. your application's layouts) as well as + templates that override bundle templates;
  • +
  • path/to/bundle/Resources/views/: Each bundle houses its templates in its + Resources/views directory (and subdirectories).
  • +
+

Symfony2 uses a bundle:controller:template string syntax for templates.

+

You can skip the controller string: bundle::template. The template +file would live in Resources/views/.

+

You can also skip the bundle string. It refers to an application-wide base +template or layout. This means that the template is not located in any bundle, +but instead in the root app/Resources/views/ directory.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Template Naming and Locations (2/2)

+ + +

Example

+
AcmeBlogBundle:Blog:index.html.twig
+
+

AcmeBlogBundle: (bundle) the template lives inside the AcmeBlogBundle (e.g. +src/Acme/BlogBundle).

+

Blog: (controller) indicates that the template lives inside the Blog +subdirectory of Resources/views.

+

index.html.twig: (template) the actual name of the file is index.html.twig.

+

Assuming that the AcmeBlogBundle lives at src/Acme/BlogBundle, the final +path to the layout would be:

+
src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Overriding Bundle Templates

+ + +

Once you use a third-party bundle, you'll likely need to override and customize +one or more of its templates.

+

When the FooBarBundle:Bar:index.html.twig is rendered, Symfony2 actually +looks in two different locations for the template:

+
    +
  • app/Resources/FooBarBundle/views/Bar/index.html.twig;
  • +
  • src/Foo/BarBundle/Resources/views/Bar/index.html.twig.
  • +
+

To override the bundle template, copy the index.html.twig template from the +bundle to: app/Resources/FooBarBundle/views/Bar/index.html.twig.

+

Overriding Core Templates

+

The core TwigBundle contains a number of different templates that can be +overridden by copying each from the Resources/views/ directory of the +TwigBundle to the app/Resources/TwigBundle/views/ directory.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Three-Level Approach

+ + +
    +
  1. +

    Create a app/Resources/views/base.html.twig file that contains the main +layout for your application (like in the previous example). Internally, this +template is called ::base.html.twig.

    +
  2. +
  3. +

    Create a template for each section of your site. The AcmeBlogBundle +would have a template called AcmeBlogBundle::layout.html.twig that contains +only blog section-specific elements.

    +
  4. +
  5. +

    Create individual templates for each page and make each extend the +appropriate section template. For example, the "index" page would be called +something close to AcmeBlogBundle:Blog:index.html.twig and list the actual +blog posts.

    +
  6. +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Twig Into Symfony2

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Rendering A Template

+ + +

Using The Base Controller

+
public function listAction()
+{
+    // ...
+
+    return $this->render('AcmeBlogBundle:Blog:index.html.twig', array(
+        'posts' => $posts,
+    ));
+}
+
+ +

Using the Templating Service

+
$engine  = $this->container->get('templating');
+$content = $engine->render('AcmeBlogBundle:Blog:index.html.twig', array(
+    'posts' => $posts,
+));
+
+return new Response($content);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Linking to Pages

+ + +

Assuming the following routing definition:

+
homepage:
+    path:     /
+    defaults: { _controller: AcmeDemoBundle:Hello:index }
+
+acme_blog.post_show:
+    path:     /posts/{slug}
+    defaults: { _controller: AcmeBlogBundle:Post:show }
+
+ +

You can create a relative URL using path():

+
<a href="{{ path('homepage') }}">Home</a>
+
+ +

You can create an absolute URL using url():

+
<a href="{{ url('homepage') }}">Home</a>
+
+ +

The second argument is used to pass parameters:

+
<a href="{{ path('acme_blog.post_show', {'slug': 'my-super-slug'}) }}">
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Linking to Assets

+ + +
<script src={{ asset('js/script.js') }}></script>
+
+<link href="{{ asset('css/style.css') }}" rel="stylesheet">
+
+<img src="{{ asset('images/logo.png') }}" alt="Symfony!" />
+
+ +

Cache Busting

+

Cache busting is the process of forcing browsers or proxy servers to +update their cache, for instance, JavaScript and CSS files or images.

+
# app/config/config.yml
+framework:
+    # ...
+    templating: { engines: ['twig'], assets_version: v2 }
+
+ +

The asset_version parameter is used to bust the cache on assets by globally +adding a query parameter to all rendered asset paths:

+
/images/logo.png?v2
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Linking To Pages In JavaScript

+ + +

The FOSJsRoutingBundle +allows you to expose your routing in your JavaScript code. That means you'll +be able to generate URL with given parameters like you can do with the Router +component provided in Symfony2.

+
# app/config/routing.yml
+my_route_to_expose:
+    pattern:  /foo/{id}/bar
+    defaults: { _controller: FooBarBundle:Foo:bar }
+    options:
+        expose: true
+
+ +

According to the routing definition above, you can write the following +JavaScript code to generate URLs:

+
Routing.generate('my_route_to_expose', { id: 10 });
+// /foo/10/bar
+
+Routing.generate('my_route_to_expose', { id: 10 }, true);
+// http://example.org/foo/10/bar
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Global Template Variables

+ + +
    +
  • app.security: the security context;
  • +
  • app.user: the current user object;
  • +
  • app.request: the request object;
  • +
  • app.session: the session object;
  • +
  • app.environment: the current environment (dev, prod, etc);
  • +
  • app.debug: true if in debug mode. false otherwise.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Service Container

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Definitions

+ + +

What is a Service?

+

A Service is a generic term for any PHP object that performs a specific task.

+

A service is usually used globally, such as a database connection object or an +object that delivers email messages.

+

In Symfony2, services are often configured and retrieved from the service +container. An application that has many decoupled services is said to follow a +Service-Oriented Architecture (SOA).

+

What is a Service Container?

+

A Service Container, also known as a Dependency Injection Container +(DIC), is a special object that manages the instantiation of services inside +an application.

+

The service container takes care of lazily instantiating and injecting +dependent services.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Creating A Service

+ + +
class Foo
+{
+    private $bar;
+    private $debug;
+
+    public function __construct(Bar $bar = null, $debug = false)
+    {
+        $this->bar   = $bar;
+        $this->debug = $debug;
+    }
+}
+
+ +

The service definition for the class described above is:

+
<services>
+    <service id="foo" class="My\Bundle\Foo" />
+</services>
+
+ +

This service is now available in the container, and you can access it by +asking the service from the container:

+
$foo = $this->container->get('foo');
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Service Parameters

+ + +

The service definition described before is not flexible enough. For instance, +we never configure the $debug argument.

+

Parameters make defining services more organized and flexible:

+
<parameters>
+    <parameter key="my_bundle.foo.class">My\Bundle\Foo</parameter>
+</parameters>
+
+<services>
+    <service id="foo" class="%my_bundle.foo.class%">
+        <argument></argument> <!-- null -->
+        <argument>%kernel.debug%</argument>
+    </service>
+</services>
+
+ +

In the definition above, kernel.debug is a parameter defined by the framework +itself.

+

The class of the foo service is now parametrized. It becomes easy to +change the implementation of this service by simply overriding the +my_bundle.foo.class parameter.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Injecting Services

+ + +

As you may noticed, the Foo class takes an instance of Bar as first +argument. You can inject this instance in your foo service by +referencing the bar service:

+
<parameters>
+    <parameter key="my_bundle.foo.class">My\Bundle\Foo</parameter>
+    <parameter key="my_bundle.bar.class">My\Bundle\Bar</parameter>
+</parameters>
+
+<services>
+    <service id="bar" class="%my_bundle.bar.class%" />
+
+    <service id="foo" class="%my_bundle.foo.class%">
+        <argument type="service" id="bar" />
+        <argument>%kernel.debug%</argument>
+    </service>
+</services>
+
+ +

Optional Dependencies: Setter Injection

+
<call method="setBar">
+    <argument type="service" id="bar" />
+</call>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Importing Configuration Resources

+ + +

The imports Way

+
# app/config/config.yml
+imports:
+    - { resource: "@AcmeDemoBundle/Resources/config/services.xml" }
+
+ +

Container Extensions

+

A service container extension is a PHP class to accomplish two things:

+
    +
  • import all service container resources needed to configure the services for + the bundle;
  • +
  • provide semantic, straightforward configuration so that the bundle can + be configured without interacting with the flat parameters of the bundle's + service container configuration.
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Creating an Extension Class

+ + +

An extension class should live in the DependencyInjection directory of your +bundle and its name should be constructed by replacing the Bundle suffix of +the Bundle class name with Extension.

+
// Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php
+namespace Acme\DemoBundle\DependencyInjection;
+
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+class AcmeDemoExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+        $loader = new XmlFileLoader($container, new FileLocator(
+            __DIR__ . '/../Resources/config'
+        ));
+        $loader->load('services.xml');
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dealing With Configuration (1/2)

+ + +

The presence of the previous class means that you can now define an +acme_demo configuration namespace in any configuration file:

+
# app/config/config.yml
+acme_demo: ~
+
+ +

Take the following configuration:

+
acme_demo:
+    foo: fooValue
+    bar: barValue
+
+ +

The array passed to your load() method will look like this:

+
array(
+    array(
+        'foo' => 'fooValue',
+        'bar' => 'barValue',
+    )
+)
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dealing With Configuration (2/2)

+ + +

The $configs argument is an array of arrays, not just a single flat array +of the configuration values.

+

It's your job to decide how these configurations should be merged together.

+

You might, for example, have later values override previous values or +somehow merge them together:

+
public function load(array $configs, ContainerBuilder $container)
+{
+    $config = array();
+    foreach ($configs as $subConfig) {
+        $config = array_merge($config, $subConfig);
+    }
+
+    // ... now use the flat $config array
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Configuration Class (1/2)

+ + +

Definition

+
// src/Acme/DemoBundle/DependencyInjection/Configuration.php
+namespace Acme\DemoBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+class Configuration implements ConfigurationInterface
+{
+    public function getConfigTreeBuilder()
+    {
+        $treeBuilder = new TreeBuilder();
+        $rootNode    = $treeBuilder->root('acme_demo');
+
+        $rootNode
+            ->children()
+                ->scalarNode('my_type')->defaultValue('bar')->end()
+            ->end();
+
+        return $treeBuilder;
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Configuration Class (2/2)

+ + +

Usage

+
public function load(array $configs, ContainerBuilder $container)
+{
+    $configuration = new Configuration();
+
+    $config = $this->processConfiguration($configuration, $configs);
+
+    // ...
+}
+
+ +

The processConfiguration() method uses the configuration tree you've defined +in the Configuration class to validate, normalize and merge all of +the configuration arrays together.

+
+

Read more on How to expose a Semantic Configuration for a Bundle: +http://symfony.com/doc/master/cookbook/bundles/extension.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

More On The Service Container

+ + +

Tags

+

In the service container, a tag implies that the service is meant to be used +for a specific purpose.

+
<service id="my_bundle.twig.foo" class="My\Bundle\Twig\FooExtension">
+    <tag name="twig.extension" />
+</service>
+
+ +

Twig finds all services tagged with twig.extension and automatically registers +them as extensions.

+

Debugging Services

+
$ php app/console container:debug
+
+$ php app/console container:debug foo
+
+ +
+

Documentation at: +http://symfony.com/doc/master/book/service_container.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Symfony2 Commands

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Built-in Commands (1/2)

+ + +
$ php app/console
+
+ +

Global Options

+

You can get help information:

+
$ php app/console help cmd
+$ php app/console cmd --help
+$ php app/console cmd -h
+
+ +

You can get more verbose messages:

+
$ php app/console cmd --verbose
+$ php app/console cmd -v
+
+ +

You can suppress output:

+
$ php app/console cmd --quiet
+$ php app/console cmd -q
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Built-in Commands (2/2)

+ + +
assets
+  assets:install          Installs bundles web assets under a public
+                          web directory
+cache
+  cache:clear             Clears the cache
+  cache:warmup            Warms up an empty cache
+config
+  config:dump-reference   Dumps default configuration for an extension
+container
+  container:debug         Displays current services for an application
+init
+  init:acl                Mounts ACL tables in the database
+router
+  router:debug            Displays current routes for an application
+  router:dump-apache      Dumps all routes as Apache rewrite rules
+  router:match            Helps debug routes by simulating a path info
+                          match
+server
+  server:run              Runs PHP built-in web server
+translation
+  translation:update      Updates the translation file
+twig
+  twig:lint               Lints a template and outputs encountered
+                          errors
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Creating Commands

+ + +

Create a Command directory inside your bundle and create a php file suffixed +with Command.php for each command that you want to provide:

+
// src/Acme/DemoBundle/Command/GreetCommand.php
+namespace Acme\DemoBundle\Command;
+
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class GreetCommand extends ContainerAwareCommand
+{
+    protected function configure()
+    {
+        $this->setName('demo:greet');
+    }
+
+    protected function execute(InputInterface $input,
+        OutputInterface $output) {
+        // code ...
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Command Arguments

+ + +

Arguments are the strings, separated by spaces, that come after the command +name itself. They are ordered, and can be optional or required.

+
protected function configure()
+{
+    $this
+        // ...
+        ->addArgument(
+            'name',
+            InputArgument::REQUIRED,
+            'Who do you want to greet?'
+        )
+        ->addArgument(
+            'last_name',
+            InputArgument::OPTIONAL,
+            'Your last name?'
+        );
+}
+
+ +

Usage

+
$input->getArgument('last_name');
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Command Options (1/2)

+ + +

Unlike arguments, options are not ordered, always optional, and can be +setup to accept a value or simply as a boolean flag without a value.

+
protected function configure()
+{
+    $this
+        // ...
+        ->addOption(
+            'yell',
+            null,
+            InputOption::VALUE_NONE,
+            'If set, the task will yell in uppercase letters'
+        );
+}
+
+ +

Usage

+
// php app/console demo:greet --yell
+
+if ($input->getOption('yell')) {
+    // ...
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Command Options (2/2)

+ + +
protected function configure()
+{
+    $this
+        // ...
+        ->addOption(
+            'iterations',
+            null,
+            InputOption::VALUE_REQUIRED,
+            'How many times should the message be printed?',
+            1
+        );
+}
+
+ +

Usage

+
// php app/console demo:greet --iterations=10
+
+for ($i = 0; $i < $input->getOption('iterations'); $i++) {
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

More On Commands

+ + +

Getting Services from the Service Container

+
protected function execute(InputInterface $input,
+    OutputInterface $output) {
+    $translator = $this->getContainer()->get('translator');
+    // ...
+}
+
+ +

Calling an existing Command

+
$command   = $this->getApplication()->find('demo:greet');
+$arguments = array(
+    'command' => 'demo:greet',
+    'name'    => 'Fabien',
+    'yell'    => true,
+);
+
+$returnCode = $command->run(new ArrayInput($arguments), $output);
+
+ +
+

Read more on How to create a Console Command: +http://symfony.com/doc/master/cookbook/console/console_command.html.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Forms

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Building Your First Form

+ + +
public function newAction(Request $request)
+{
+    $form = $formFactory
+        ->createFormBuilder()
+        ->add('name')
+        ->add('bio', 'textarea')
+        ->add('birthday', 'date')
+        ->getForm();
+
+    return $this->render('AcmeDemoBundle:Default:new.html.twig', [
+        'form' => $form->createView(),
+    ]);
+}
+
+ +

In order to display the Form, you need to pass a special view object to the +View layer. It's achieved through the createView() method.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Rendering The Form

+ + +

+

+
{# src/Acme/DemoBundle/Resources/views/Default/new.html.twig #}
+<form action="{{ path('acme_demo.default_new') }}" method="post">
+    {{ form_widget(form) }}
+
+    <input type="submit" />
+</form>
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Handling Forms: The Right Way

+ + +
    +
  1. +

    When initially loading the page in a browser, the request method is GET +and the form is simply created and rendered;

    +
  2. +
  3. +

    When the user submits the form (i.e. the method is POST) with invalid +data, the form is bound and then rendered, this time displaying all +validation errors;

    +
  4. +
  5. +

    When the user submits the form with valid data, the form is bound and you have +the opportunity to perform some actions before redirecting the user to some +other page (e.g. a "success" page).

    +
  6. +
+

Redirecting a user after a successful form submission prevents the user from +being able to hit "refresh" and re-post the data.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Handling Form Submissions

+ + +
public function newAction(Request $request)
+{
+    $form = $formFactory
+        ->createFormBuilder()
+        ->add('name')
+        ->add('bio', 'textarea')
+        ->add('birthday', 'date')
+        ->getForm();
+
+    if ($request->isMethod('POST')) {
+        $form->bind($request);
+
+        if ($form->isValid()) {
+            $data = $form->getData();
+            // do something ...
+
+            return $this->redirect($this->generateUrl('success'));
+        }
+    }
+
+    // ...
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Built-in Form Types

+ + +

Everything is a Type!

+

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Creating A Custom Type (Form Class)

+ + +
use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+
+class PersonType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder,
+        array $options) {
+        $builder
+            ->add('name')
+            ->add('bio', 'textarea')
+            ->add('birthday', 'date');
+    }
+
+    public function setDefaultOptions(
+        OptionsResolverInterface $resolver) {
+        $resolver->setDefaults(array('data_class' => 'My\Person'));
+    }
+
+    public function getName()
+    {
+        return 'person';
+    }
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Dealing With Objects

+ + +
public function newAction(Request $request)
+{
+    $person = new Person();
+    $form   = $this->createForm(new PersonType(), $person);
+
+    if ($request->isMethod('POST')) {
+        $form->bind($request);
+
+        if ($form->isValid()) {
+            $person->save(); // insert a new `person`
+
+            return $this->redirect($this->generateUrl('success'));
+        }
+    }
+
+    // ...
+}
+
+ +

Placing the form logic into its own class means that the form can be easily +reused elsewhere in your project.

+

This is the best way to create forms, but the choice is up to you!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The processForm() Method (1/2)

+ + +

Saving or updating an object is pretty much the same thing. In order to avoid +code duplication, you can use a processForm() method that can be used in both +the newAction() and the updateAction():

+
/**
+ * Create a new Person
+ */
+public function newAction()
+{
+    return $this->processForm(new Person());
+}
+
+/**
+ * Update an existing Person
+ */
+public function updateAction($id)
+{
+    $person = ...; // get a `Person` by its $id
+
+    return $this->processForm($person);
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The processForm() Method (2/2)

+ + +
/**
+ * @param Person $person
+ *
+ * @return Response
+ */
+private function processForm(Person $person)
+{
+    $form = $this->createForm(new PersonType(), $person);
+
+    if ($this->getRequest()->isMethod('POST')) {
+        $form->bind($this->getRequest());
+
+        if ($form->isValid()) {
+            $person->save();
+
+            return $this->redirect($this->generateUrl('success'));
+        }
+    }
+
+    return $this->render('AcmeDemoBundle:Default:new.html.twig', [
+        'form' => $form->createView(),
+    ]);
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Cross-Site Request Forgery Protection

+ + +

CSRF is a method by which a malicious user attempts to make your legitimate +users unknowingly submit data that they don't intend to submit. Fortunately, +CSRF attacks can be prevented by using a CSRF token inside your forms.

+

CSRF protection works by adding a hidden field to your form, called _token +by default that contains a value that only you and your user knows.

+

This ensures that the user is submitting the given data. Symfony automatically +validates the presence and accuracy of this token.

+

The _token field is a hidden field and will be automatically rendered if you +include the form_rest() function in your template, which ensures that all +un-rendered fields are output.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Rendering a Form in a Template (1/2)

+ + +
<form action="" method="post" {{ form_enctype(form) }}>
+    {{ form_errors(form) }}
+
+    {{ form_row(form.name) }}
+
+    {{ form_row(form.bio) }}
+
+    {{ form_row(form.birthday) }}
+
+    {{ form_rest(form) }}
+
+    <input type="submit" />
+</form>
+
+ +
+

Read more: +http://symfony.com/doc/master/book/forms.html#rendering-a-form-in-a-template.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Rendering a Form in a Template (2/2)

+ + +
    +
  • +

    form_enctype(form): if at least one field is a file upload field, this renders + the obligatory enctype="multipart/form-data";

    +
  • +
  • +

    form_errors(form): renders any errors global to the whole form (field-specific + errors are displayed next to each field);

    +
  • +
  • +

    form_row(form.name): renders the label, any errors, and the HTML form widget + for the given field inside, by default, a div element;

    +
  • +
  • +

    form_rest(form): renders any fields that have not yet been rendered. It's + usually a good idea to place a call to this helper at the bottom of each form + This helper is also useful for taking advantage of the automatic CSRF Protection.

    +
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Validation

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

About Form Validation

+ + +

In the previous section, you learned how a form can be submitted with valid or +invalid data. In Symfony2, validation is applied to the underlying object.

+

In other words, the question isn't whether the "form" is valid, but whether or +not the object is valid after the form has applied the submitted data to it.

+

Calling $form->isValid() is a shortcut that asks the object whether or not +it has valid data.

+

Validation is done by adding a set of rules (called constraints) to a class.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Validator Component

+ + +

This component is based on the JSR303 Bean Validation +specification.

+

Example

+

Given the following class:

+
namespace Acme\DemoBundle\Entity;
+
+class Author
+{
+    public $name;
+}
+
+ +

You can configure a set of constraints on this class:

+
# src/Acme/DemoBundle/Resources/config/validation.yml
+Acme\DemoBundle\Entity\Author:
+    properties:
+        name:
+            - NotBlank: ~
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using the validator Service

+ + +
$author = new Author();
+// ... do something to the $author object
+
+$validator = $this->get('validator');
+$errors    = $validator->validate($author);
+
+if (count($errors) > 0) {
+    // Ooops, errors!
+} else {
+    // Everything is ok :-)
+}
+
+ +

If the $name property is empty, you will see the following error message:

+
Acme\DemoBundle\Author.name:
+    This value should not be blank
+
+

Most of the time, you won't interact directly with the validator service or need +to worry about printing out the errors. Most of the time, you'll use validation +indirectly when handling submitted form data.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Constraints

+ + +

+
+

See all constraints: +http://symfony.com/doc/master/book/validation.html#constraints.

+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Constraint Targets (1/2)

+ + +

Constraints can be applied to a class property or a public getter method +(e.g. getFullName()). The first is the most common and easy to use, but the +second allows you to specify more complex validation rules.

+

Properties

+

Validating class properties is the most basic validation technique. Symfony2 +allows you to validate private, protected or public properties.

+
# src/Acme/DemoBundle/Resources/config/validation.yml
+Acme\DemoBundle\Entity\Author:
+    properties:
+        firstName:
+            - NotBlank: ~
+
+ +

Classes

+

Some constraints apply to the entire class being validated. For example, the +Callback constraint is a generic constraint that's applied to the clas +itself.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Constraint Targets (2/2)

+ + +

Getters

+

Constraints can also be applied to the return value of a method. Symfony2 +allows you to add a constraint to any public method whose name starts with +get or is.

+
# src/Acme/DemoBundle/Resources/config/validation.yml
+Acme\DemoBundle\Entity\Author:
+    getters:
+        passwordLegal:
+            - "False":
+                message: "The password cannot match your first name"
+
+ +

With the following code in the Author class:

+
public function isPasswordLegal()
+{
+    return ($this->firstName !== $this->password);
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Validation Groups (1/2)

+ + +

In some cases, you will need to validate an object against only some of the +constraints on that class.

+

You can organize each constraint into one or more validation groups, and +then apply validation against just one group of constraints.

+

Example

+
# src/Acme/DemoBundle/Resources/config/validation.yml
+Acme\DemoBundle\Entity\User:
+    properties:
+        email:
+            - Email:    { groups: [ registration ] }
+        password:
+            - NotBlank: { groups: [ registration ] }
+            - Length:   { groups: [ registration ], min: 7 }
+        city:
+            - Length:
+                min: 2
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Validation Groups (2/2)

+ + +

With the configuration seen before, there are two validation groups:

+
    +
  • Default: contains the constraints not assigned to any other group;
  • +
  • registration: contains the constraints on the email and password fields only.
  • +
+

To tell the validator to use a specific group, pass one or more group names as +the second argument to the validate() method:

+
$errors = $validator->validate($author, array('registration'));
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using Validation Groups In Forms

+ + +

If your object takes advantage of validation groups, you'll need to specify +which validation group(s) your form should use:

+
$form = $this->createFormBuilder($users, array(
+    'validation_groups' => array('registration'),
+))->add(...);
+
+ +

If you're creating form classes, then you'll need to add the following to +the setDefaultOptions() method:

+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+
+public function setDefaultOptions(OptionsResolverInterface $resolver)
+{
+    $resolver->setDefaults(array(
+        'validation_groups' => array('registration'),
+    ));
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Validating Values and Arrays

+ + +
use Symfony\Component\Validator\Constraints\Email;
+
+$emailConstraint = new Email();
+$emailConstraint->message = 'Invalid email address';
+
+$errorList = $this->get('validator')->validateValue(
+    $email, $emailConstraint
+);
+
+if (0 !== count($errorList)) {
+    // this is *not* a valid email address
+    $errorMessage = $errorList[0]->getMessage();
+}
+
+ +

By calling validateValue() on the validator, you can pass in a raw value and +the constraint object that you want to validate that value against.

+

The validateValue() method returns a ConstraintViolationList object, which +acts just like an array of errors.

+

Each error in the collection is a ConstraintViolation object, which holds the +error message on its getMessage() method.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Translations

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Definitions

+ + +

Internationalization

+

The term internationalization (often abbreviated i18n) refers to the +process of abstracting strings and other locale-specific pieces out of your +application and into a layer where they can be translated and converted +based on the user's locale (i.e. language and country).

+

Localization

+

The act of creating translation files is an important part of localization +(often abbreviated l10n). It is the process of adapting a product or +service to a particular language, culture, and desired local +look-and-feel.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Using the translator Service

+ + +
# messages.fr.yml
+Symfony2 is great: J'aime Symfony2
+'Hello %name%': Bonjour %name%
+
+ +

When the following code is executed, Symfony2 will attempt to translate the +message Symfony2 is great based on the locale of the user:

+
echo $this->get('translator')->trans('Symfony2 is great');
+
+ +

Now, if the language of the user's locale is French (e.g. fr_FR or fr_BE), +the message will be translated into J'aime Symfony2.

+

Message Placeholders

+
echo $this->get('translator')->trans('Hello %name%', [
+    '%name%' => 'Will'
+]);
+
+// French:  Bonjour Will
+// Default: Hello Will
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Translation Process

+ + +

To translate the message, Symfony2 uses a simple process:

+
    +
  1. +

    The locale of the current user, which is stored on the request (or stored as +_locale on the session), is determined;

    +
  2. +
  3. +

    A catalog of translated messages is loaded from translation resources defined +for the locale (e.g. fr_FR). Messages from the fallback locale are also loaded +and added to the catalog if they don't already exist. The end result is a large +"dictionary" of translations;

    +
  4. +
  5. +

    If the message is located in the catalog, the translation is returned. If not, +the translator returns the original message.

    +
  6. +
+

When using the trans() method, Symfony2 looks for the exact string inside the +appropriate message catalog and returns it (if it exists).

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Locations and Naming Conventions

+ + +

Symfony2 looks for message files (i.e. translations) in the following locations:

+
    +
  • the <kernel root directory>/Resources/translations directory;
  • +
  • the <kernel root directory>/Resources/<bundle name>/translations directory;
  • +
  • the Resources/translations/ directory of the bundle.
  • +
+

The filename of the translations is also important as Symfony2 uses a convention +to determine details about the translations. Each message file must be named +according to the following path: domain.locale.loader:

+
    +
  • domain: an optional way to organize messages into groups;
  • +
  • locale: the locale that the translations are for (en_GB, en, etc);
  • +
  • loader: how Symfony2 should load and parse the file (xliff, php or yml).
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Pluralization

+ + +

When a translation has different forms due to pluralization, you can provide all +the forms as a string separated by a pipe (|):

+
'There is one apple|There are %count% apples'
+
+ +

To translate pluralized messages, use the transChoice() method:

+
$t = $this->get('translator')->transChoice(
+    'There is one apple|There are %count% apples',
+    10,
+    array('%count%' => 10)
+);
+
+ +

The second argument (10 in this example), is the number of objects being +described and is used to determine which translation to use and also to +populate the %count% placeholder.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Explicit Interval Pluralization

+ + +

Sometimes, you'll need more control or want a different translation for specific +cases (for 0, or when the count is negative, for example). For such cases, you +can use explicit math intervals:

+
'{0} There are no apples|{1} There is one apple|]1,19] There are
+%count% apples|[20,Inf] There are many apples'
+
+ +

The intervals follow the ISO 31-11 +notation.

+

An Interval can represent a finite set of numbers:

+
{1,2,3,4}
+
+ +

Or numbers between two other numbers:

+
[1, +Inf[
+]-1,2[
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Cache

+ + +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Cache

+ + +

The nature of rich web applications means that they're dynamic. No matter how +efficient your application, each request will always contain more overhead +than serving a static file.

+

But as your site grows, that overhead can become a problem. The processing +that's normally performed on every request should be done only once.

+

This is exactly what caching aims to accomplish!

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Terminology (1/2)

+ + +

Gateway Cache

+

A gateway cache, or reverse proxy, is an independent layer that sits in +front of your application.

+

The reverse proxy caches responses as they are returned from your application +and answers requests with cached responses before they hit your application.

+

Symfony2 provides its own reverse proxy, but any reverse proxy can be used.

+

HTTP Cache

+

HTTP cache headers are used to communicate with the gateway cache and any +other caches between your application and the client.

+

Symfony2 provides sensible defaults and a powerful interface for interacting +with the cache headers.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Terminology (2/2)

+ + +

HTTP Expiration

+

HTTP expiration and validation are the two models used for determining +whether cached content is fresh (can be reused from the cache) or stale (should +be regenerated by the application).

+

Edge Side Includes

+

Edge Side Includes (ESI) allow HTTP cache to be used to cache page +fragments (even nested fragments) independently. With ESI, you can even cache +an entire page for 60 minutes, but an embedded sidebar for only 5 minutes.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Caching with a Gateway Cache

+ + +

When caching with HTTP, the cache is separated from your application entirely +and sits between your application and the client making the request.

+

The job of the cache is to accept requests from the client and pass them back +to your application.

+

The cache will also receive responses back from your application and forward +them on to the client. The cache is the middle-man of the request-response +communication between the client and your application.

+

Along the way, the cache will store each response that is deemed cacheable. +If the same resource is requested again, the cache sends the cached response to +the client, ignoring your application entirely.

+

This type of cache is known as a HTTP gateway cache and many exist such as +Varnish, Squid in reverse proxy mode, and the Symfony2 reverse +proxy.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Types of Caches

+ + +

The HTTP cache headers sent by your application are consumed and interpreted by +up to three different types of caches:

+
    +
  • +

    Browser Caches: every browser comes with its own local cache that is mainly +useful for when you hit "back" or for images and other assets. The browser cache +is a private cache as cached resources aren't shared with anyone else;

    +
  • +
  • +

    Proxy Caches: a proxy is a shared cache as many people can be behind a +single one. It's usually installed by large corporations and ISPs to reduce +latency and network traffic;

    +
  • +
  • +

    Gateway Caches: like a proxy, it's also a shared cache but on the +server side. Installed by network administrators, it makes websites more +scalable, reliable and performant.

    +
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

HTTP Caching

+ + +

HTTP specifies four response cache headers that are looked at here:

+
    +
  • Cache-Control
  • +
  • Expires
  • +
  • ETag
  • +
  • Last-Modified
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Public vs Private Responses

+ + +

Both gateway and proxy caches are considered shared caches as the cached +content is shared by more than one user.

+

If a user-specific response were ever mistakenly stored by a shared cache, it +might be returned later to any number of different users. Imagine if your +account information were cached and then returned to every subsequent user who +asked for their account page!

+

To handle this situation, every response may be set to be public or private:

+
    +
  • +

    public: indicates that the response may be cached by both private and +shared caches;

    +
  • +
  • +

    private: indicates that all or part of the response message is intended for +a single user and must not be cached by a shared cache.

    +
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Safe Methods

+ + +

HTTP caching only works for safe HTTP methods (like GET and HEAD). Being +safe means that you never change the application's state on the server when +serving the request.

+

his has two very reasonable consequences:

+
    +
  • +

    You should never change the state of your application when responding to a +GET or HEAD request. Even if you don't use a gateway cache, the presence +of proxy caches mean that any GET or HEAD request may or may not actually +hit your server;

    +
  • +
  • +

    Don't expect PUT, POST or DELETE methods to cache. These methods are +meant to be used when mutating the state of your application. Caching them +would prevent certain requests from hitting and mutating your application.

    +
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Expiration

+ + +

The expiration model is the more efficient and straightforward of the two +caching models and should be used whenever possible.

+

When a response is cached with an expiration, the cache will store the response +and return it directly without hitting the application until it expires.

+

The expiration model can be accomplished using one of two HTTP headers:

+
    +
  • Cache-Control
  • +
  • Expires
  • +
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Cache-Control Header (1/2)

+ + +

The Cache-Control header is unique in that it contains not one, but +various pieces of information about the cacheability of a response.

+

Each piece of information is separated by a comma:

+
Cache-Control: private, max-age=0, must-revalidate
+Cache-Control: max-age=3600, must-revalidate
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Cache-Control Header (2/2)

+ + +

Symfony provides an abstraction around the Cache-Control header:

+
use Symfony\Component\HttpFoundation\Response;
+
+$response = new Response();
+
+// mark the response as either public or private
+$response->setPublic();
+$response->setPrivate();
+
+// set the private or shared max age
+$response->setMaxAge(600);
+$response->setSharedMaxAge(600);
+
+// set a custom Cache-Control directive
+$response->headers->addCacheControlDirective('must-revalidate', true);
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Expires Header

+ + +

The Expires header can be set with the setExpires() Response method. It takes +a DateTime instance as an argument:

+
$date = new DateTime();
+$date->modify('+600 seconds');
+
+$response->setExpires($date);
+
+ +

The resulting HTTP header will look like this:

+
Expires: Thu, 01 Mar 2013 10:00:00 GMT
+
+

The setExpires() method automatically converts the date to the GMT timezone as +required by the specification.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Validation

+ + +

With the expiration model, the application won't be asked to return the updated +response until the cache finally becomes stale. It is not good!

+

The validation model addresses this issue.

+

Under this model, the cache continues to store responses. The difference is +that, for each request, the cache asks the application whether or not the +cached response is still valid.

+

If the cache is still valid, your application should return a 304 status code +and no content. This tells the cache that it's ok to return the cached response.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The ETag Header

+ + +

The ETag header is a string header called entity-tag that uniquely +identifies one representation of the target resource. It's entirely +generated and set by your application.

+

An ETag is like a fingerprint and is used to quickly compare if two +unique across all representations of the same resource.

+
public function indexAction()
+{
+    $response = $this->render('MyBundle:Main:index.html.twig');
+    $response->setETag(md5($response->getContent()));
+    $response->setPublic(); // make sure the response is public/cacheable
+    $response->isNotModified($this->getRequest());
+
+    return $response;
+}
+
+ +

The isNotModified() method compares the ETag sent with the Request with +the one set on the Response. If the two match, the method automatically sets +the Response status code to 304 Not Modified.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Last-Modified Header (1/2)

+ + +

According to the HTTP specification, the Last-Modified header field indicates +the date and time at which the origin server believes the representation was +last modified.

+

In other words, the application decides whether or not the cached content has +been updated based on whether or not it's been updated since the response was +cached.

+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

The Last-Modified Header (2/2)

+ + +
public function showAction($articleSlug)
+{
+    // ...
+
+    $articleDate = new \DateTime($article->getUpdatedAt());
+    $authorDate  = new \DateTime($author->getUpdatedAt());
+
+    $date = $authorDate > $articleDate ? $authorDate : $articleDate;
+
+    $response->setLastModified($date);
+    // Set response as public. Otherwise it will be private by default
+    $response->setPublic();
+
+    if ($response->isNotModified($this->getRequest())) {
+        return $response;
+    }
+
+    // ... do more work to populate the response
+    // with the full content
+
+    return $response;
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Edge Side Includes (ESI)

+ + +

Edge Side Includes or ESI is a small markup language for dynamic +web content assembly at the reverse proxy level. The reverse proxy analyses the +HTML code, parses ESI specific markup and assembles the final result before +flushing it to the client.

+

+
<esi:include src="user.php" />
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ +
+
+ + + + + + + + \ No newline at end of file From a8b0c0f56e979574fb3060967d91686f19da32c6 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 12 Jun 2013 15:47:14 +0200 Subject: [PATCH 02/71] =?UTF-8?q?Publish=20slides=20(Ven=2027=20d=C3=A9c?= =?UTF-8?q?=202013=2000:19:14=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 1500 +++++++++++------ index2.html | 136 +- .../css/font-awesome/css/font-awesome.css | 1338 +++++++++++++++ .../css/font-awesome/css/font-awesome.min.css | 4 + .../css/font-awesome/fonts/FontAwesome.otf | Bin 0 -> 62856 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 38205 bytes .../fonts/fontawesome-webfont.svg | 414 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 80652 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 44432 bytes 9 files changed, 2827 insertions(+), 565 deletions(-) create mode 100644 themes/avalanche/avalanche/css/font-awesome/css/font-awesome.css create mode 100644 themes/avalanche/avalanche/css/font-awesome/css/font-awesome.min.css create mode 100644 themes/avalanche/avalanche/css/font-awesome/fonts/FontAwesome.otf create mode 100755 themes/avalanche/avalanche/css/font-awesome/fonts/fontawesome-webfont.eot create mode 100755 themes/avalanche/avalanche/css/font-awesome/fonts/fontawesome-webfont.svg create mode 100755 themes/avalanche/avalanche/css/font-awesome/fonts/fontawesome-webfont.ttf create mode 100755 themes/avalanche/avalanche/css/font-awesome/fonts/fontawesome-webfont.woff diff --git a/index.html b/index.html index a5e9218..e19bc6b 100644 --- a/index.html +++ b/index.html @@ -968,6 +968,7 @@ + @@ -1410,7 +1515,7 @@
00:00:00 -
+
@@ -1438,7 +1543,7 @@ @@ -1466,7 +1571,7 @@ @@ -1491,56 +1596,17 @@

Open-Source evangelist:

-

twitter.com/couac - | github.com/willdurand - | williamdurand.fr

- - -
-

Notes

-
- -
-
- - - - - -
-
-
- -

Julien MUETTON

- - -

Software developer at IT Networks

-

Graduated from ESIGELEC (Rouen)

-

Co-founder of Carpe Hora (Clermont-Ferrand, France)

-

Worked at:

- -

Passionate front end developer, believe in standards and open source.

-
-

Read the code, not the doc

-
-

twitter.com/themouette - | github.com/themouette

+

+ twitter.com/couac +  |  + github.com/willdurand +  |  + williamdurand.fr +

@@ -1556,7 +1622,7 @@
@@ -1573,7 +1639,8 @@

Week #1

PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server

Week #2

-

Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View Controller

+

Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View +Controller

Week #3

Databases

Week #4

@@ -1593,7 +1660,7 @@

Week #4

@@ -1621,7 +1688,7 @@

Week #4

@@ -1637,7 +1704,7 @@

Week #4

  • Created by Rasmus Lerdorf
  • -
  • 5th language in the world (TIOBE November 2012)
  • +
  • 6th language in the world (TIOBE December 2013)
  • 1st language for web development
  • Running on 75% of all web servers
@@ -1656,7 +1723,7 @@

Week #4

@@ -1692,7 +1759,7 @@

Week #4

@@ -1707,7 +1774,7 @@

Week #4

Mac OS X

-
$ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.4
+
$ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.5
 
@@ -1728,7 +1795,7 @@

Week #4

@@ -1762,7 +1829,7 @@

Week #4

@@ -1790,7 +1857,7 @@

Week #4

@@ -1818,7 +1885,7 @@

Week #4

@@ -1856,7 +1923,7 @@

Week #4

@@ -1905,7 +1972,7 @@

Week #4

@@ -1956,7 +2023,7 @@

Week #4

@@ -1999,7 +2066,7 @@

Abstract class definition

@@ -2034,7 +2101,7 @@

Abstract class definition

-

http://www.php.net/manual/en/language.oop5.basic.php.

+

http://www.php.net/manual/en/language.oop5.basic.php

@@ -2051,7 +2118,7 @@

Abstract class definition

@@ -2090,7 +2157,7 @@

The Rules

@@ -2143,7 +2210,7 @@

The Rules

@@ -2192,7 +2259,7 @@

Type Hinting

@@ -2236,7 +2303,7 @@

Usage

@@ -2284,7 +2351,7 @@

Usage

@@ -2330,7 +2397,7 @@

Usage

@@ -2356,7 +2423,8 @@

Usage

-

http://php.net/manual/en/language.oop5.static.php.

+

Read more: +http://php.net/manual/en/language.oop5.static.php.

@@ -2373,7 +2441,7 @@

Usage

@@ -2422,7 +2490,7 @@

Usage

@@ -2470,7 +2538,54 @@

PSR-0

+ + + + + +
+
+
+ +

The class Keyword

+ + +

Since PHP 5.5.0, class name resolution is possible via ::class.

+
namespace My\Namespace;
+
+class ClassName
+{
+}
+
+ +

Assuming the class definition above, you can get the Fully Qualified +Class Name (FQCN) by doing:

+
echo ClassName::class;
+// My\namespace\ClassName
+
+ +
+

Read more about the class keyword: +http://www.php.net/manual/en/language.oop5.basic.php.

+
+ +
+
+

Notes

+
+ +
+
+
@@ -2522,7 +2637,7 @@

PSR-0

@@ -2536,7 +2651,9 @@

PSR-0

Anonymous Functions

-
$greet = function ($name) {
+            

An anonymous function, also known as lambda function, is a function +defined, and possibly called, without being bound to an identifier.

+
$greet = function ($name) {
     printf("Hello %s\n", $name);
 };
 
@@ -2563,7 +2680,7 @@ 

PSR-0

@@ -2577,7 +2694,8 @@

PSR-0

Closures

-
$fibonacci = function ($n) use (&$fibonacci) {
+            

A closure is an anonymous function that owns a context.

+
$fibonacci = function ($n) use (&$fibonacci) {
     if (0 === $n || 1 === $n) {
         return 1;
     }
@@ -2608,7 +2726,7 @@ 

PSR-0

@@ -2651,7 +2769,47 @@

PSR-0

+ +
+
+ + +
+
+
+ +

Generators

+ + +

A generator function looks just like a normal function, except that instead +of returning a value, a generator yields as many values as it needs to.

+

The heart of a generator function is the yield keyword.

+
+

Read more about generators:

+ +
+ +
+
+

Notes

+
+ +
+
+
@@ -2679,7 +2837,7 @@

PSR-0

@@ -2699,9 +2857,11 @@

PSR-0

Hello, World -
-

Help available by running: php -h.

+
+ +

Help available by running: php -h

+

PHP also provides an interactive shell:

$ php -a
 Interactive Shell
@@ -2729,7 +2889,7 @@ 

PSR-0

@@ -2748,10 +2908,12 @@

PSR-0

No syntax errors detected in my/script.php -
-

A linter is a program that looks for problems in your code (syntax -errors for instance).

+
+ +

A linter is a program that looks for problems in your code + (syntax errors for instance).

+

Embedded web server:

$ php -S localhost:8000
 
@@ -2775,7 +2937,7 @@

PSR-0

@@ -2827,7 +2989,7 @@

PSR-0

@@ -2855,7 +3017,7 @@

PSR-0

@@ -2870,17 +3032,16 @@

PSR-0

A typical client/server request follows this pattern:

-

-
    -
  • -

    Client: Hello server, give me the resource at URI.

    -
  • +

    +
      +
    1. Client: Hello server, give me the resource at URI;
    2. -

      Server: Here is the resource at URI:

      -

      > Content

      +

      Server: Here is the resource at URI:

      +

      Content

    3. -
-

For HTTP, a typical client is a web browser, and a server is a web server.

+ +

For HTTP, a typical client is a web browser, and a server is a web +server.

@@ -2896,7 +3057,7 @@

PSR-0

@@ -2941,7 +3102,7 @@

PSR-0

@@ -2958,7 +3119,7 @@

PSR-0

Response is made of:

  • Some headers to describe the content;
  • -
  • The response status;
  • +
  • The response's status code;
  • The content of the request;

Here is an example:

@@ -2991,7 +3152,7 @@

PSR-0

@@ -3010,10 +3171,12 @@

PSR-0

  • GET: retrieve a resource or a collection of resources;
  • POST: create a new resource;
  • -
  • PUT: update an existing resource;
  • +
  • PUT: update an existing resource or create a new resource at a + given URI;
  • DELETE: delete a given resource;
  • PATCH: partial update of a given resource.
  • -
+ +

Important: this list is not exhaustive.

@@ -3029,7 +3192,7 @@

PSR-0

@@ -3073,7 +3236,7 @@

PSR-0

@@ -3096,15 +3259,15 @@

PSR-0

Will result in:

-
$_GET = array("a" => 1, "id" => 2);
+
$_GET     = [ "a" => 1, "id" => 2 ];
 
-$_POST = array("b" => 3, "city" => 'paris');
+$_POST    = [ "b" => 3, "city" => 'paris' ];
 
-$_REQUEST = array("a" => 1, "id" => 2, "b" => 3, "city" => 'paris');
+$_REQUEST = [ "a" => 1, "id" => 2, "b" => 3, "city" => 'paris' ];
 
 $_SERVER['QUERY_STRING'] = "a=1&id=2";
 
-$HTTP_RAW_POST_DATA = "b=3&city=paris";
+$HTTP_RAW_POST_DATA      = "b=3&city=paris";
 
@@ -3122,7 +3285,7 @@

PSR-0

@@ -3139,21 +3302,17 @@

PSR-0

Each URI represents a unique resource that can be formatted as requested in json, xml, or html.

    -
  • /bananas/joe: URI for banana "Joe"
  • -
  • /bananas/henry: URI for banana "Henry"
  • +
  • /bananas/joe: URI for banana "Joe";
  • +
  • /bananas/henry: URI for banana "Henry".

Those resources are organized into collections:

  • /bananas: collection of all available bananas.

So it makes sense to use HTTP verbs to execute an action:

-

GET /banana/joe will return banana "Joe".

-
-

And:

-
-

DELETE /bananas will delete all bananas in the collection!

-
+

and:

+

DELETE /bananas will delete all bananas in the collection!

@@ -3169,7 +3328,7 @@

PSR-0

@@ -3197,7 +3356,7 @@

PSR-0

@@ -3246,7 +3405,7 @@

PSR-0

@@ -3296,7 +3455,7 @@

PSR-0

@@ -3343,7 +3502,7 @@

PSR-0

@@ -3392,7 +3551,7 @@

PSR-0

@@ -3431,7 +3590,7 @@

spl_autoload_functions()

@@ -3480,7 +3639,7 @@

spl_autoload_unregister()

@@ -3498,27 +3657,28 @@

spl_autoload_unregister()

The new algorithm in pseudo code:

-
1. Does the 'Foo' class exist?
+
1. Does the 'Foo' class exist?
     => Yes
         Go on
 
     => No
          Do we have registered autoload functions?
             => Yes
-                Call each function with 'Foo' as parameter
+                Call each function with 'Foo' as parameter
                 until the class gets included
 
             => No
                 Is there a `__autoload()` method?
                     => Yes
-                        Call `__autoload('Foo')`
+                        Call `__autoload('Foo')`
 
-2. Does the 'Foo' class exist?
+2. Does the 'Foo' class exist?
     => Yes
         Continue
     => No
         Fatal Error
-
+
+
@@ -3534,7 +3694,7 @@

spl_autoload_unregister()

@@ -3562,7 +3722,7 @@

spl_autoload_unregister()

@@ -3576,18 +3736,21 @@

spl_autoload_unregister()

Built-in Interfaces

-

ArrayAccess

+

ArrayAccess

Access properties as an array:

$tom = new MyObject();
 $tom['name'] = 'Tom';
 
-

Serializable

-

Allow the use of serialize() and unserialize().

-

Traversable

+

Serializable, JsonSerializable

+

Allow the use of serialize() and unserialize(). +Objects implementing JsonSerializable can customize their JSON representation +when encoded with json_encode().

+

Traversable

Allow the use of foreach.

-

Read more http://fr2.php.net/manual/en/reserved.interfaces.php.

+

Read more: +http://fr2.php.net/manual/en/reserved.interfaces.php.

@@ -3604,7 +3767,7 @@

Traversable

@@ -3655,7 +3818,7 @@

Traversable

@@ -3688,8 +3851,8 @@

Traversable

-

Read more http://www.php.net/manual/en/book.reflection.php -.

+

Read more: +http://php.net/manual/en/book.reflection.php.

@@ -3706,7 +3869,7 @@

Traversable

@@ -3721,11 +3884,12 @@

Traversable

Provides a collection of classes and interfaces:

-

Datastructures

+

Datastructures

SplStack, SplQueue, SplObjectStorage, etc.

-

Named Exceptions

-

LogicException, InvalidArgumentException, OutOfRangeException, etc.

-

SPL Functions

+

Named Exceptions

+

LogicException, InvalidArgumentException, OutOfRangeException, +RuntimeException, etc.

+

SPL Functions

class_parents(), spl_autoload_register(), spl_autoload_unregister(), etc.

Read more about the SPL: @@ -3746,7 +3910,7 @@

SPL Functions

@@ -3782,7 +3946,7 @@

SPL Functions

-

Read more: php.net/manual/en/class.splobserver.php.

+

Read more: http://php.net/manual/en/class.splobserver.php.

@@ -3799,7 +3963,7 @@

SPL Functions

@@ -3830,7 +3994,8 @@

SPL Functions

-

Read more: http://symfony.com/doc/2.0/components/event_dispatcher/.

+

Read more: +http://symfony.com/doc/master/components/event_dispatcher/.

@@ -3847,7 +4012,7 @@

SPL Functions

@@ -3858,10 +4023,10 @@

SPL Functions

-

Exceptions

+

Exceptions (1/2)

-

try/catch block with multiple catch statements:

+

try-catch block with multiple catch statements:

try {
     // ...
 } catch (RuntimeException $e) {
@@ -3896,7 +4061,89 @@ 

SPL Functions

+ +
+
+ + +
+
+
+ +

Exceptions (2/2)

+ + +

try-catch blocks also supports a finally block for code that should be run +regardless of whether an exception has been thrown or not:

+
try {
+    // ..
+} catch (Exception $e) {
+    // do something
+} finally {
+    // the code here will always be executed
+}
+
+
+ +
+
+

Notes

+
+ +
+
+ +
+
+ + +
+
+
+ +

Password Hashing

+ + +

The password hashing API provides an easy to use wrapper around crypt() to +make it easy to create and manage passwords in a secure manner, since PHP 5.5.0.

+

password_hash() and password_verify() are your new friends!

+
+

Read more about the Password Hashing API: +http://www.php.net/manual/en/book.password.php.

+
+

+ +
+

A userland implementation exists for PHP >= 5.3.7: +password_compat.

+
+ +
+
+

Notes

+
+ +
+
+
@@ -3938,7 +4185,7 @@

SPL Functions

@@ -3966,7 +4213,7 @@

SPL Functions

@@ -3988,7 +4235,7 @@

SPL Functions

A lot of PHP libraries are compatible with Composer and listed on Packagist, the official repository for Composer-compatible PHP libraries.

-
$ curl -s https://getcomposer.org/installer | php
+
$ curl -sS https://getcomposer.org/installer | php
 

This will download composer.phar (a PHP binary archive).

@@ -4011,7 +4258,7 @@

SPL Functions

@@ -4028,7 +4275,7 @@

SPL Functions

Create a composer.json file in your project's root directory:

{
     "require": {
-        "willdurand/geocoder": "1.1.*"
+        "willdurand/geocoder": "~2.0"
     }
 }
 
@@ -4042,6 +4289,8 @@

SPL Functions

<?php
 
 require 'vendor/autoload.php';
+
+// your PHP code
 
@@ -4059,7 +4308,7 @@

SPL Functions

@@ -4077,20 +4326,21 @@

SPL Functions

the Symfony2 Console component:

{
     "require": {
-        "symfony/console": "v2.1.5"
+        "symfony/console": "~2.4"
     }
 }
 

The structure of your application should look like:

-
console-app
+
console-app
 ├── app
 │   └── console
 ├── composer.json
 ├── src
 ├── tests
 └── vendor
-
+
+
@@ -4106,7 +4356,7 @@

SPL Functions

@@ -4133,9 +4383,10 @@

SPL Functions

// configure the name, arguments, options, etc. } - protected function execute(InputInterface $input, - OutputInterface $output) - { + protected function execute( + InputInterface $input, + OutputInterface $output + ) { } } @@ -4155,7 +4406,7 @@

SPL Functions

@@ -4202,7 +4453,7 @@

Execution

@@ -4230,13 +4481,15 @@

Execution

Usage

-
$ app/console demo:greet
+
$ app/console demo:greet
 Hello, World
-$ app/console demo:greet William
+$ app/console demo:greet William
 Hello, William
-
+
+
-

http://symfony.com/doc/master/components/console/introduction.html.

+

Read more: +http://symfony.com/doc/current/components/console/.

@@ -4253,7 +4506,7 @@

Usage

@@ -4281,7 +4534,7 @@

Usage

@@ -4296,7 +4549,7 @@

Usage

Typical client request process in MVC architecture:

-

+

@@ -4324,7 +4577,7 @@

Usage

@@ -4341,15 +4594,16 @@

Usage

Model is the layer in charge of data interaction.

All data related business logic is embedded here. Using it should not require to understand internals.

-

Examples:

+

Examples:

  • Manipulate database records;
  • Communicate with search engine;
  • API calls;
  • etc.
-
-

More on this next week!

+
+ +

More on this next week!

@@ -4366,7 +4620,7 @@

Usage

@@ -4382,8 +4636,7 @@

Usage

PHP is a templating language per se.

Never, ever, ever mix HTML and PHP codes or kittens -will die: you have to separate the presentation from the business logic. -But creating a template engine is ok!

+will die: you have to separate the presentation from the business logic.

class TemplateEngine
 {
     private $templateDir;
@@ -4393,7 +4646,7 @@ 

Usage

$this->templateDir = $templateDir; } - public function render($template, $parameters = array()) + public function render($template, array $parameters = []) { extract($parameters); @@ -4420,7 +4673,7 @@

Usage

@@ -4439,16 +4692,16 @@

Usage

<p>Hello, <?php echo $name; ?>!</p> -

Even better with PHP 5.4:

+

Even better with PHP 5.4+:

<p>Hello, <?= $name ?>!</p>
 

Usage

$engine = new TemplateEngine('/path/to/templates');
 
-echo $engine->render('my_template.html', array(
+echo $engine->render('my_template.html', [
     'name' => 'World',
-));
+]);
 => <p>Hello, World!</p>
 
@@ -4467,7 +4720,7 @@

Usage

@@ -4491,13 +4744,13 @@

Template

Usage

$loader = new Twig_Loader_Filesystem('/path/to/templates');
-$engine = new Twig_Environment($loader, array(
+$engine = new Twig_Environment($loader, [
     'cache' => '/path/to/compilation_cache',
-));
+]);
 
-echo $engine->render('my_template.html', array(
+echo $engine->render('my_template.html', [
     'name' => 'World',
-));
+]);
 => <p>Hello, World!</p>
 
@@ -4516,7 +4769,7 @@

Usage

@@ -4531,12 +4784,13 @@

Usage

Glue between the Model and the View layers.

-

It should not contain any logic.

+

It should not contain any business logic.

class BananaController
 {
-    public function __construct(BananaMapper $mapper,
-            TemplateEngineInterface $engine)
-    {
+    public function __construct(
+        BananaMapper $mapper,
+        TemplateEngineInterface $engine
+    ) {
         $this->mapper = $mapper;
         $this->engine = $engine;
     }
@@ -4545,9 +4799,9 @@ 

Usage

{ $bananas = $this->mapper->findAll(); - return $this->engine->render('list.html', array( + return $this->engine->render('list.html', [ 'bananas' => $bananas, - )); + ]); } }
@@ -4567,7 +4821,7 @@

Usage

@@ -4575,7 +4829,7 @@

Usage

-
+

Routing

@@ -4584,12 +4838,12 @@

Usage

Routing is the process of binding URIs to controllers.

Folder organization

The simplest kind of routing, but also the hardest to maintain:

-
web/
+
web/
 ├ trees/
-│ ├ banana.php
 │ └ pineapple.php
 └ tree.php
-
+
+

Centralized declaration

Modern frameworks all provide a routing component such as Symfony2 Routing component allowing to define all routes in a centralized place and easing @@ -4610,7 +4864,7 @@

Centralized declaration

@@ -4625,7 +4879,7 @@

Centralized declaration

A controller that handles all requests for a web application:

-

+

This controller dispatches the request to the specialized controllers.

It is usually tied to URL rewriting.

@@ -4643,7 +4897,7 @@

Centralized declaration

@@ -4684,7 +4938,7 @@

Centralized declaration

@@ -4712,7 +4966,7 @@

Centralized declaration

@@ -4747,7 +5001,7 @@

Centralized declaration

@@ -4782,7 +5036,7 @@

Centralized declaration

@@ -4823,7 +5077,7 @@

Centralized declaration

@@ -4834,7 +5088,7 @@

Centralized declaration

-

Row Data Gateway

+

Row Data Gateway

@@ -4851,7 +5105,7 @@

Centralized declaration

@@ -4905,7 +5159,7 @@

Centralized declaration

@@ -4951,7 +5205,7 @@

Centralized declaration

@@ -4998,7 +5252,7 @@

Centralized declaration

@@ -5009,7 +5263,7 @@

Centralized declaration

-

Table Data Gateway

+

Table Data Gateway

@@ -5026,7 +5280,7 @@

Centralized declaration

@@ -5074,7 +5328,7 @@

CRUD

@@ -5121,7 +5375,7 @@

CRUD

@@ -5169,7 +5423,7 @@

CRUD

@@ -5221,7 +5475,7 @@

CRUD

@@ -5266,7 +5520,7 @@

CRUD

@@ -5313,7 +5567,7 @@

CRUD

@@ -5324,7 +5578,7 @@

CRUD

-

Active Record

+

Active Record

@@ -5341,7 +5595,7 @@

CRUD

@@ -5388,7 +5642,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5443,7 +5697,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5454,7 +5708,7 @@

Active Record = Row Data Gateway + Domain Logic

-

Data Mapper

+

Data Mapper

@@ -5471,7 +5725,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5524,7 +5778,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5573,7 +5827,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5584,7 +5838,7 @@

Active Record = Row Data Gateway + Domain Logic

-

Identity Map

+

Identity Map

@@ -5601,7 +5855,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5619,7 +5873,7 @@

Active Record = Row Data Gateway + Domain Logic

a map. Looks up objects using the map when referring to them.

class Finder
 {
-    private $identityMap = array();
+    private $identityMap = [];
 
     public function findOneById($id)
     {
@@ -5648,7 +5902,7 @@ 

Active Record = Row Data Gateway + Domain Logic

@@ -5676,7 +5930,7 @@

Active Record = Row Data Gateway + Domain Logic

@@ -5687,12 +5941,12 @@

Active Record = Row Data Gateway + Domain Logic

-

Data Access Layer

+

Data Access Layer / Data Source Name

A Data Access Layer (DAL) is a standard API to manipulate data, -no matter which database server is used.

-

The Data Source Name (DSN) can be used to determine which database +no matter which database server is used. +A Data Source Name (DSN) can be used to determine which database vendor you are using.

PHP Data Object (PDO)

A DSN in PHP looks like: <database>:host=<host>;dbname=<dbname> where:

@@ -5719,7 +5973,7 @@

PHP Data Object (PDO)

@@ -5768,7 +6022,7 @@

Usage

@@ -5794,7 +6048,7 @@

Usage

* * @return bool Returns `true` on success, `false` otherwise */ - public function executeQuery($query, $parameters = array()) + public function executeQuery($query, array $parameters = []) { $stmt = $this->prepare($query); @@ -5822,7 +6076,7 @@

Usage

@@ -5847,10 +6101,10 @@

Usage

{ $query = 'UPDATE bananas SET name = :name WHERE id = :id'; - return $this->con->executeQuery($query, array( + return $this->con->executeQuery($query, [ 'id' => $id, 'name' => $name, - )); + ]); }
@@ -5869,7 +6123,7 @@

Usage

@@ -5897,7 +6151,7 @@

Usage

@@ -5934,7 +6188,7 @@

Usage

@@ -5942,17 +6196,18 @@

Usage

-
+

Object Relational Mapping (2/4)

One-To-One (1-1)

-

-

Example

+

+

Code Snippet

$profile = $banana->getProfile();
 
+
@@ -5969,7 +6224,7 @@

Example

@@ -5977,17 +6232,18 @@

Example

-
+

Object Relational Mapping (3/4)

One-To-Many (1-N)

-

-

Example

+

+

Code Snippet

$bananas = $bananaTree->getBananas();
 
+
@@ -6004,7 +6260,7 @@

Example

@@ -6012,16 +6268,16 @@

Example

-
+

Object Relational Mapping (4/4)

Many-To-Many (N-N)

-

-

Example

-
$roles = array();
+

+

Code Snippet

+
$roles = [];
 foreach ($banana->getBananaRoles() as $bananaRole) {
     $roles[] = $bananaRole->getRole();
 }
@@ -6029,6 +6285,7 @@ 

Example

// Or, better: $roles = $banana->getRoles();
+
@@ -6045,7 +6302,7 @@

Example

@@ -6063,12 +6320,12 @@

Example

An ORM that implements the Table Data Gateway and Row Data Gateway patterns, often seen as an Active Record approach.

-

Documentation: propelorm.org.

+

Documentation: www.propelorm.org.

Doctrine2 ORM

An ORM that implements the Data Mapper pattern.

-

Documentation: doctrine-project.org.

+

Documentation: www.doctrine-project.org.

@@ -6085,35 +6342,7 @@

Doctrine2 ORM

- -
-
- - -
-
-
- -

Your Turn!

- - -
-
-

Notes

-
- -
-
-
@@ -6141,7 +6370,7 @@

Doctrine2 ORM

@@ -6162,7 +6391,7 @@

Doctrine2 ORM

  • easy to use;
  • built-in.
  • -

    Some usecases:

    +

    A few use cases:

    • Keep user authentication and roles;
    • Store cart;
    • @@ -6183,7 +6412,7 @@

      Some usecases:

    @@ -6232,7 +6461,7 @@

    Some usecases:

    @@ -6273,7 +6502,7 @@

    Workarounds

    @@ -6301,7 +6530,7 @@

    Workarounds

    @@ -6332,7 +6561,7 @@

    Workarounds

    @@ -6362,7 +6591,7 @@

    Workarounds

    @@ -6382,12 +6611,12 @@

    Workarounds

    Interceptor Pattern to the rescue!

    The Interceptor Pattern allows you to execute some code during the default application's lifecyle.

    -

    A way to implement this pattern is to use events. It's more or less like +

    A way to implement this pattern is to use events. It is more or less like the Observer/Observable pattern.

    Event Dispatcher

    -

    The application notifies a set of listeners to an event.

    -

    The listeners can register themselves to a particular event.

    -

    An Event Dispatcher manages both the listeners, and the events.

    +

    The application notifies a set of listeners to an event. +The listeners can register themselves to a particular event. +An Event Dispatcher manages both the listeners, and the events.

    @@ -6403,7 +6632,7 @@

    Event Dispatcher

    @@ -6451,7 +6680,7 @@

    Event Dispatcher

    @@ -6503,7 +6732,7 @@

    Event Dispatcher

    @@ -6518,9 +6747,8 @@

    Event Dispatcher

    Now that we can hook into the appplication's lifecycle, we need to write a -Firewall.

    -

    A Firewall needs a whitelist of unsecured routes (routes which don't -require the user to be authenticated):

    +Firewall. This firewall needs a whitelist of unsecured routes (routes +which don't require the user to be authenticated):

    $allowed = [
         '/login'     => [ Request::GET, Request::POST ],
         '/locations' => [ Request::GET ],
    @@ -6553,7 +6781,7 @@ 

    Event Dispatcher

    @@ -6610,7 +6838,7 @@

    Event Dispatcher

    @@ -6640,7 +6868,7 @@

    Event Dispatcher

    @@ -6693,7 +6921,7 @@

    Event Dispatcher

    @@ -6708,8 +6936,8 @@

    Event Dispatcher

    Useful for API authentication.

    -

    OAuth

    -

    http://oauth.net/

    +

    OpenID

    +

    http://openid.net/

    Basic and Digest Access Authentication

    http://pretty-rfc.herokuapp.com/RFC2617

    WSSE Username Token

    @@ -6729,7 +6957,7 @@

    WSSE Username Token

    @@ -6757,7 +6985,7 @@

    WSSE Username Token

    @@ -6776,6 +7004,8 @@

    WSSE Username Token

  • Programming To The Interface
  • Component Driven Development
  • Dependency Injection
  • +
  • From STUPID to SOLID code!
  • +
  • Object Calisthenics
  • @@ -6792,7 +7022,7 @@

    WSSE Username Token

    @@ -6812,15 +7042,15 @@

    WSSE Username Token

    class Foo { - const VERSION = '1.0'; + const VERSION = '1.0'; - public $bar = null; + public $bar = null; - protected $opts = array(); + protected $opts; - private $var3 = 123; + private $var3 = 123; - public function __construct(BarInterface $bar, $opts = array()) + public function __construct(BarInterface $bar, array $opts = []) { $this->bar = $bar; $this->opts = $opts; @@ -6849,7 +7079,7 @@

    WSSE Username Token

    @@ -6866,16 +7096,17 @@

    WSSE Username Token

    The PHP Coding Standards Fixer tool fixes most issues in your code when you want to follow the PHP coding standards as defined in the PSR-1 and PSR-2 documents.

    -

    Installation:

    +

    Installation

    $ wget http://cs.sensiolabs.org/get/php-cs-fixer.phar
     
    -

    Usage:

    +

    Usage

    $ php php-cs-fixer.phar fix /path/to/dir/or/file
     
    -

    http://cs.sensiolabs.org/.

    +

    More information at: +http://cs.sensiolabs.org/.

    @@ -6892,7 +7123,7 @@

    WSSE Username Token

    @@ -6917,7 +7148,7 @@

    WSSE Username Token

    * * @return string */ - public function render($template, array $parameters = array()); + public function render($template, array $parameters = []); } @@ -6937,7 +7168,7 @@

    WSSE Username Token

    @@ -6956,7 +7187,8 @@

    WSSE Username Token

    well, and only one thing.

    How to manage these components in your application?

    -

    Read Component Driven Development: it's like Lego!.

    +

    Read more: Component Driven Development: it's like +Lego!

    @@ -6973,7 +7205,7 @@

    WSSE Username Token

    @@ -7016,7 +7248,7 @@

    WSSE Username Token

    @@ -7058,7 +7290,7 @@

    WSSE Username Token

    @@ -7100,7 +7332,7 @@

    WSSE Username Token

    @@ -7149,7 +7381,7 @@

    WSSE Username Token

    @@ -7198,7 +7430,7 @@

    WSSE Username Token

    @@ -7241,7 +7473,136 @@

    The Symfony2 DependencyInjection Component

    + + + + + +
    +
    +
    + +

    From STUPID to SOLID code! (1/2)

    + + +

    STUPID

    +
      +
    • Singleton
    • +
    • Tight Coupling
    • +
    • Untestability
    • +
    • Premature Optimization
    • +
    • Indescriptive Naming
    • +
    • Duplication
    • +
    +
    +

    Read more: +http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/#stupid-code-seriously.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    From STUPID to SOLID code! (2/2)

    + + +

    SOLID

    +
      +
    • Single Responsibility Principle
    • +
    • Open/Closed Principle
    • +
    • Liskov Substitution Principle
    • +
    • Interface Segregation Principle
    • +
    • Dependency Inversion Principle
    • +
    +
    +

    Read more: +http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/#solid-to-the-rescue.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Object Calisthenics

    + + +

    9 rules invented by Jeff Bay in his book The ThoughWorks +Anthology:

    +
      +
    1. Only One Level Of Indentation Per Method
    2. +
    3. Don't Use The ELSE Keyword
    4. +
    5. Wrap All Primitives And Strings
    6. +
    7. First Class Collections
    8. +
    9. One Dot Per Line
    10. +
    11. Don't Abbreviate
    12. +
    13. Keep All Entities Small
    14. +
    15. No Classes With More Than Two Instance Variables
    16. +
    17. No Getters/Setters/Properties
    18. +
    +
    +

    Read more: +http://williamdurand.fr/2013/06/03/object-calisthenics/.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7269,7 +7630,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7303,7 +7664,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7331,7 +7692,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7352,7 +7713,7 @@

    The Symfony2 DependencyInjection Component

    Install it using Composer:

    {
         "require-dev": {
    -        "phpunit/phpunit": "3.7.*"
    +        "phpunit/phpunit": "~3.7"
         }
     }
     
    @@ -7377,7 +7738,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7388,19 +7749,18 @@

    The Symfony2 DependencyInjection Component

    -

    Using PHPUnit

    +

    PHPUnit — The Rules

    -

    The Rules

    -

    The tests for a class Class go into a class ClassTest.

    -

    ClassTest inherits (most of the time) from PHPUnit_Framework_TestCase, but +

    The tests for a class Class go into a class ClassTest.

    +

    ClassTest should inherit from PHPUnit_Framework_TestCase, but a common practice is to create a TestCase class for a project, and to inherit from it:

    class TestCase extends PHPUnit_Framework_TestCase {}
     
    -

    The tests are public methods that are named test*. -You can also use the @test annotation:

    +

    The tests are public methods that are named test*, but you can also use the +@test annotation:

    class ClassTest extends TestCase
     {
         public function testFoo()
    @@ -7426,7 +7786,7 @@ 

    The Symfony2 DependencyInjection Component

    @@ -7437,7 +7797,7 @@

    The Symfony2 DependencyInjection Component

    -

    PHPUnit Assertions

    +

    PHPUnit — Assertions

      @@ -7446,7 +7806,10 @@

      The Symfony2 DependencyInjection Component

    • assertFalse()
    • etc.
    -

    See all assertion methods: http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html.

    +
    +

    See all assertion methods: +http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html.

    +
    @@ -7462,7 +7825,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7512,7 +7875,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7540,7 +7903,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7555,8 +7918,8 @@

    The Symfony2 DependencyInjection Component

    Also known as acceptance testing.

    -

    Use tools to create automated tests that actually use your application instead -of just verifying that individual units of code are behaving correctly.

    +

    Use tools to create automated tests that actually use your application rather +than only verifying that individual units of code behave correctly.

    @@ -1775,7 +1822,7 @@ @@ -1783,7 +1830,7 @@
    -
    +

    The Symfony2 Components

    @@ -1793,15 +1840,17 @@

    They are the foundation of the Symfony full-stack framework, but they can also be used standalone even if you don't use the framework as they don't have any mandatory dependencies.

    -

    There are more than 21 components, including:

    -
    BrowserKit             EventDispatcher    Routing
    -ClassLoader            Finder             Security
    -Config                 Form               Serializer
    -Console                HttpFoundation     Templating
    -CssSelector            HttpKernel         Translation
    -DependencyInjection    Locale             Validator
    -DomCrawler             Process            Yaml
    -
    +

    There are ~26 components, including:

    +
    BrowserKit              EventDispatcher     OptionsResolver     Translation
    +ClassLoader             ExpressionLanguage  Process             Yaml
    +Config                  Filesystem          PropertyAccess
    +Console                 Finder              Routing
    +CssSelector             Form                Security
    +Debug                   HttpFoundation      Serializer
    +DependencyInjection     HttpKernel          Stopwatch
    +DomCrawler              Intl                Templating
    +
    +
    @@ -1817,7 +1866,7 @@
    @@ -1835,7 +1884,7 @@ component into your composer.json file:

    {
         "require": {
    -        "symfony/yaml": "~2.1"
    +        "symfony/yaml": "~2.4"
         }
     }
     
    @@ -1849,8 +1898,7 @@
    -

    Read more: -http://symfony.com/doc/current/components/yaml/introduction.html.

    +

    http://symfony.com/doc/current/components/yaml/introduction.html

    @@ -1867,7 +1915,7 @@
    @@ -1881,8 +1929,7 @@

    Full-Stack Framework

    -

    The Symfony2 Framework is a PHP library that accomplishes two distinct -tasks:

    +

    The Symfony2 Framework accomplishes two distinct tasks:

    @@ -1912,7 +1958,7 @@ @@ -1940,7 +1986,7 @@ @@ -1992,7 +2038,7 @@ @@ -2042,7 +2088,7 @@ @@ -2065,7 +2111,7 @@ if (in_array($path, array('', '/'))) { $response = new Response('Welcome to the homepage.'); -} elseif ($path == '/hello') { +} elseif ('/hello' === $path) { $response = new Response('hello, World!'); } else { $response = new Response('Page not found.', 404); @@ -2089,7 +2135,7 @@ @@ -2121,7 +2167,7 @@ @@ -2146,10 +2192,11 @@

    The AcmeDemoBundle:Main:hello string is a short syntax that points to a specific PHP method named helloAction() inside a class called MainController.

    -
    -

    Note: this example uses YAML to define the routing configuration. -Routing configuration can also be written in other formats such as XML or -PHP.

    +
    +

    + This example uses YAML to define the routing configuration. + Routing configuration can also be written in other formats such as XML or PHP. +

    @@ -2166,7 +2213,7 @@ @@ -2212,7 +2259,7 @@ @@ -2220,14 +2267,14 @@
    -
    +

    A Symfony2 Project

    Recommended structure of a Symfony2 project:

    -
    path/to/project/
    +
    path/to/project/
         app/
             cache/
             config/
    @@ -2239,7 +2286,8 @@
         web/
             app.php
             ...
    -
    +
    +
    • app/ contains the application kernel, and the configuration;
    • src/ contains your bundles;
    • @@ -2261,7 +2309,7 @@
    @@ -2314,7 +2362,7 @@
    @@ -2353,7 +2401,7 @@
    @@ -2401,7 +2449,7 @@ @@ -2448,7 +2496,7 @@ @@ -2498,7 +2546,7 @@ @@ -2512,7 +2560,7 @@

    The Rules (Well... My Rules)

    -

    The main configuration has to be written in YAML:

    +

    The main configuration MUST be written in YAML:

    # app/config/config.yml
     # ...
     twig:
    @@ -2520,14 +2568,14 @@
         strict_variables: "%kernel.debug%"
     
    -

    The routing definition has to be written in YAML:

    +

    The routing definition MUST be written in YAML:

    # app/config/routing.yml
     hello:
         pattern:  /hello
         defaults: { _controller: AcmeDemoBundle:Main:hello }
     
    -

    The Dependency Injection Container configuration has to be written in XML.

    +

    The DI Container configuration MUST be written in XML:

    <services>
         <service id="acme_demo.controllers.main"
             class="Acme\DemoBundle\MainController" />
    @@ -2549,7 +2597,7 @@
                 
                 
                 
               
             
    @@ -2598,7 +2646,7 @@ @@ -2646,7 +2694,7 @@ @@ -2654,14 +2702,14 @@
    -
    +

    Bundle: Directory Structure

    Recommended structure for a bundle:

    -
    XXX/...
    +
    XXX/...
         DemoBundle/
             DemoBundle.php
             Controller/
    @@ -2675,7 +2723,8 @@
                 views/
                 public/
             Tests/
    -
    +
    +

    The DemoBundle class is mandatory, and both Resources/meta/LICENSE and Resources/doc/index.rst files should be present.

    The XXX directory(ies) reflects the namespace structure of the bundle.

    @@ -2694,7 +2743,7 @@ @@ -2773,7 +2822,7 @@ @@ -2799,7 +2848,7 @@ } -

    You can register your bundle:

    +

    Then, you can register your bundle:

    // app/AppKernel.php
     public function registerBundles()
     {
    @@ -2826,7 +2875,7 @@
                 
                 
                 
               
             
    @@ -2874,7 +2923,7 @@ @@ -2915,7 +2964,7 @@ @@ -2943,7 +2992,7 @@ @@ -2986,7 +3035,7 @@ @@ -3037,7 +3086,7 @@

    Controller Implementation

    @@ -3053,8 +3102,8 @@

    Controller Implementation

    Every route must have a _controller parameter, which dictates which controller should be executed when that route is matched.

    -

    This parameter uses a simple string pattern called the logical controller name.

    -

    The pattern has three parts, each separated by a colon:

    +

    This parameter uses a simple string pattern called the logical controller name. +The pattern has three parts, each separated by a colon:

    bundle:controller:action
     

    For example, a _controller value of AcmeBlogBundle:Blog:show means:

    @@ -3080,7 +3129,7 @@

    Controller Implementation

    @@ -3091,7 +3140,7 @@

    Controller Implementation

    -

    Route Params as Controller Arguments

    +

    Route Params as Controller Args

    Routing Definition

    @@ -3132,7 +3181,7 @@

    Controller Implementation

    @@ -3177,7 +3226,7 @@

    Controller Implementation

    @@ -3227,7 +3276,7 @@

    Rendering Templates

    @@ -3274,7 +3323,7 @@

    Rendering Templates

    @@ -3302,7 +3351,7 @@

    Rendering Templates

    @@ -3329,8 +3378,7 @@

    Rendering Templates

    This route matches the homepage (/) and maps it to the AcmeDemoBundle:Hello:index controller.

    -

    Read more: -http://symfony.com/doc/master/book/routing.html.

    +

    http://symfony.com/doc/master/book/routing.html

    @@ -3347,7 +3395,7 @@

    Rendering Templates

    @@ -3358,7 +3406,7 @@

    Rendering Templates

    -

    Routing with Placeholders

    +

    Routing with Placeholders (1/2)

    Required Placeholders

    @@ -3367,10 +3415,40 @@

    Rendering Templates

    defaults: { _controller: AcmeBlogBundle:Blog:index }
    -

    The path will match anything that looks like /blog/*. Even better, the value -matching the {page} placeholder will be available inside your controller.

    -

    /blog will not match.

    -

    Optional Placeholders

    +

    The path will match anything that looks like /blog/*.

    +

    Even better, the value matching the {page} placeholder will be available +inside your controller.

    +

    /blog will not match.

    + + +
    +

    Notes

    +
    + +
    +
    + + + + + +
    +
    +
    + +

    Routing with Placeholders (2/2)

    + + +

    Optional Placeholders

    blog:
         path:      /blog/{page}
         defaults:  { _controller: AcmeBlogBundle:Blog:index, page: 1 }
    @@ -3394,7 +3472,7 @@ 

    Optional Placeholders

    @@ -3422,13 +3500,8 @@

    HTTP Method Requirements

    acme_demo.hello_hello: pattern: /hello/{name} defaults: { _controller: AcmeDemoBundle:Hello:hello } - requirements: - _method: GET - # _methods: GET|POST - - # New in Symfony2.2! - methods: [ GET ] - # methods: [ GET, POST ] + methods: [ GET ] + # methods: [ GET, POST ]
    @@ -3446,7 +3519,7 @@

    HTTP Method Requirements

    @@ -3470,7 +3543,6 @@

    HTTP Method Requirements

    Prefixing Imported Routes

    -

    You can eventually "prefix" all routes for a given routing configuration:

    # app/config/routing.yml
     acme_demo:
         resource: "@AcmeDemoBundle/Resources/config/routing.yml"
    @@ -3494,7 +3566,7 @@ 

    Prefixing Imported Routes

    @@ -3513,19 +3585,19 @@

    Prefixing Imported Routes

    Relative URLs

    -
    $router->generate('acme_demo.hello_hello', array('name' => 'will'));
    +
    $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ]);
     // /hello/will
     

    Absolute URLs

    -
    $router->generate('acme_demo.hello_hello',
    -    array('name' => 'will'), true);
    +
    $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ], true);
     // http://example.com/hello/will
     

    Query String

    -
    $router->generate('acme_demo.hello_hello',
    -    array('name' => 'will', 'some' => 'thing'));
    +
    $router->generate('acme_demo.hello_hello', [
    +    'name' => 'will', 'some' => 'thing'
    +]);
     // /hello/will?some=thing
     
    @@ -3544,7 +3616,7 @@

    Query String

    @@ -3572,7 +3644,7 @@

    Query String

    @@ -3580,7 +3652,7 @@

    Query String

    -
    +

    @@ -3600,7 +3672,7 @@

    Query String

    @@ -3650,7 +3722,7 @@

    After

    @@ -3672,7 +3744,7 @@

    After

  • {# ... #}: comments.
  • -

    Documentation: http://twig.sensiolabs.org/.

    +

    http://twig.sensiolabs.org/

    @@ -3689,7 +3761,7 @@

    After

    @@ -3739,7 +3811,7 @@

    After

    @@ -3788,7 +3860,7 @@

    Loops

    @@ -3818,8 +3890,7 @@

    Loops

    -

    Documentation for all filters is available at: -http://twig.sensiolabs.org/doc/filters/index.html.

    +

    http://twig.sensiolabs.org/doc/filters/index.html

    @@ -3836,7 +3907,7 @@

    Loops

    @@ -3866,7 +3937,8 @@

    Example

    <p>{{ user.username }}</p>
     
    -

    The result with two users would be:

    +

    +
    <p>William D.</p>
     <p>Julien M.</p>
     
    @@ -3886,7 +3958,7 @@

    Example

    @@ -3939,7 +4011,7 @@

    Example

    @@ -3969,7 +4041,7 @@

    Example

    The parent template is identified by a special string syntax -(::base.html.twig) that indicates that the template lives in +(::base.html.twig) which indicates that the template lives in app/Resources/views/.

    If you need to get the content of a block from the parent template, you can use the {{ parent() }} function.

    @@ -3988,7 +4060,7 @@

    Example

    @@ -4031,7 +4103,7 @@

    Example

    @@ -4039,24 +4111,28 @@

    Example

    -
    +

    Template Naming and Locations (2/2)

    Example

    -
    AcmeBlogBundle:Blog:index.html.twig
    -
    -

    AcmeBlogBundle: (bundle) the template lives inside the AcmeBlogBundle (e.g. -src/Acme/BlogBundle).

    -

    Blog: (controller) indicates that the template lives inside the Blog -subdirectory of Resources/views.

    -

    index.html.twig: (template) the actual name of the file is index.html.twig.

    +
    AcmeBlogBundle:Blog:index.html.twig
    +
    + +
      +
    • AcmeBlogBundle: (bundle) the template lives inside the AcmeBlogBundle (e.g. +src/Acme/BlogBundle);
    • +
    • Blog: (controller) indicates that the template lives inside the Blog +subdirectory of Resources/views;
    • +
    • index.html.twig: (template) the actual name of the file is index.html.twig.
    • +

    Assuming that the AcmeBlogBundle lives at src/Acme/BlogBundle, the final path to the layout would be:

    -
    src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
    -
    +
    src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
    +
    +
    @@ -4072,7 +4148,7 @@

    Example

    @@ -4094,10 +4170,38 @@

    Example

  • app/Resources/FooBarBundle/views/Bar/index.html.twig;
  • src/Foo/BarBundle/Resources/views/Bar/index.html.twig.
  • -

    To override the bundle template, copy the index.html.twig template from the -bundle to: app/Resources/FooBarBundle/views/Bar/index.html.twig.

    -

    Overriding Core Templates

    -

    The core TwigBundle contains a number of different templates that can be +

    In order to override the bundle template, copy the index.html.twig template +from the bundle to: app/Resources/FooBarBundle/views/Bar/index.html.twig.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Overriding Core Templates

    + + +

    The core TwigBundle contains a number of different templates that can be overridden by copying each from the Resources/views/ directory of the TwigBundle to the app/Resources/TwigBundle/views/ directory.

    @@ -4115,7 +4219,7 @@

    Overriding Core Templates

    @@ -4162,7 +4266,7 @@

    Overriding Core Templates

    @@ -4190,7 +4294,7 @@

    Overriding Core Templates

    @@ -4239,7 +4343,7 @@

    Using the Templating Service

    @@ -4290,7 +4394,7 @@

    Using the Templating Service

    @@ -4322,8 +4426,9 @@

    Cache Busting

    The asset_version parameter is used to bust the cache on assets by globally adding a query parameter to all rendered asset paths:

    -
    /images/logo.png?v2
    -
    +
    /images/logo.png?v2
    +
    +
    @@ -4339,7 +4444,7 @@

    Cache Busting

    @@ -4356,7 +4461,7 @@

    Cache Busting

    The FOSJsRoutingBundle allows you to expose your routing in your JavaScript code. That means you'll be able to generate URL with given parameters like you can do with the Router -component provided in Symfony2.

    +component provided by Symfony2.

    # app/config/routing.yml
     my_route_to_expose:
         pattern:  /foo/{id}/bar
    @@ -4389,7 +4494,7 @@ 

    Cache Busting

    @@ -4426,7 +4531,7 @@

    Cache Busting

    @@ -4454,7 +4559,7 @@

    Cache Busting

    @@ -4465,18 +4570,46 @@

    Cache Busting

    -

    Definitions

    +

    What Is A Service?

    -

    What is a Service?

    -

    A Service is a generic term for any PHP object that performs a specific task.

    +

    A Service is a generic term for any PHP object that performs a specific task.

    A service is usually used globally, such as a database connection object or an object that delivers email messages.

    In Symfony2, services are often configured and retrieved from the service -container. An application that has many decoupled services is said to follow a -Service-Oriented Architecture (SOA).

    -

    What is a Service Container?

    -

    A Service Container, also known as a Dependency Injection Container +container.

    +

    An application that has many decoupled services is said to follow a +Service-Oriented Architecture (SOA).

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    What Is A Service Container?

    + + +

    A Service Container, also known as a Dependency Injection Container (DIC), is a special object that manages the instantiation of services inside an application.

    The service container takes care of lazily instantiating and injecting @@ -4496,7 +4629,7 @@

    What is a Service Container?

    @@ -4549,7 +4682,7 @@

    What is a Service Container?

    @@ -4579,10 +4712,9 @@

    What is a Service Container?

    In the definition above, kernel.debug is a parameter defined by the framework -itself.

    -

    The class of the foo service is now parametrized. It becomes easy to -change the implementation of this service by simply overriding the -my_bundle.foo.class parameter.

    +itself. The foo service is now parametrized.

    +

    Also, it becomes easy to change the implementation of this service by simply +overriding the my_bundle.foo.class parameter.

    @@ -4598,7 +4730,7 @@

    What is a Service Container?

    @@ -4651,7 +4783,7 @@

    Optional Dependencies: Setter Injection

    @@ -4695,7 +4827,7 @@

    Container Extensions

    @@ -4747,7 +4879,7 @@

    Container Extensions

    @@ -4797,7 +4929,7 @@

    Container Extensions

    @@ -4842,7 +4974,7 @@

    Container Extensions

    @@ -4895,7 +5027,7 @@

    Container Extensions

    @@ -4942,7 +5074,7 @@

    Container Extensions

    @@ -4973,8 +5105,7 @@

    Debugging Services

    -

    Documentation at: -http://symfony.com/doc/master/book/service_container.html.

    +

    http://symfony.com/doc/master/book/service_container.html

    @@ -4991,7 +5122,7 @@

    Debugging Services

    @@ -5019,7 +5150,7 @@

    Debugging Services

    @@ -5045,7 +5176,7 @@

    Global Options

    You can get more verbose messages:

    $ php app/console cmd --verbose
    -$ php app/console cmd -v
    +$ php app/console cmd -v [-vv] [-vvv]
     

    You can suppress output:

    @@ -5068,7 +5199,7 @@

    Global Options

    @@ -5076,13 +5207,13 @@

    Global Options

    -
    +

    Built-in Commands (2/2)

    -
    assets
    +            
    assets
       assets:install          Installs bundles web assets under a public
                               web directory
     cache
    @@ -5106,7 +5237,8 @@ 

    Global Options

    twig twig:lint Lints a template and outputs encountered errors -
    +
    +
    @@ -5122,7 +5254,7 @@

    Global Options

    @@ -5142,9 +5274,7 @@

    Global Options

    namespace Acme\DemoBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class GreetCommand extends ContainerAwareCommand @@ -5154,8 +5284,10 @@

    Global Options

    $this->setName('demo:greet'); } - protected function execute(InputInterface $input, - OutputInterface $output) { + protected function execute( + InputInterface $input, + OutputInterface $output + ) { // code ... } } @@ -5176,7 +5308,7 @@

    Global Options

    @@ -5228,7 +5360,7 @@

    Usage

    @@ -5280,7 +5412,7 @@

    Usage

    @@ -5330,7 +5462,7 @@

    Usage

    @@ -5345,8 +5477,10 @@

    Usage

    Getting Services from the Service Container

    -
    protected function execute(InputInterface $input,
    -    OutputInterface $output) {
    +
    protected function execute(
    +    InputInterface $input,
    +    OutputInterface $output
    +) {
         $translator = $this->getContainer()->get('translator');
         // ...
     }
    @@ -5364,8 +5498,7 @@ 

    Calling an existing Command

    -

    Read more on How to create a Console Command: -http://symfony.com/doc/master/cookbook/console/console_command.html.

    +

    http://symfony.com/doc/master/cookbook/console/index.html

    @@ -5382,7 +5515,7 @@

    Calling an existing Command

    @@ -5410,7 +5543,7 @@

    Calling an existing Command

    @@ -5456,7 +5589,7 @@

    Calling an existing Command

    @@ -5470,7 +5603,7 @@

    Calling an existing Command

    Rendering The Form

    -

    +


    {# src/Acme/DemoBundle/Resources/views/Default/new.html.twig #}
     <form action="{{ path('acme_demo.default_new') }}" method="post">
    @@ -5495,7 +5628,7 @@ 

    Calling an existing Command

    @@ -5542,7 +5675,7 @@

    Calling an existing Command

    @@ -5566,7 +5699,7 @@

    Calling an existing Command

    ->getForm(); if ($request->isMethod('POST')) { - $form->bind($request); + $form->handleRequest($request); if ($form->isValid()) { $data = $form->getData(); @@ -5595,7 +5728,7 @@

    Calling an existing Command

    @@ -5610,7 +5743,7 @@

    Calling an existing Command

    Everything is a Type!

    -

    +

    @@ -5626,7 +5759,7 @@

    Calling an existing Command

    @@ -5646,17 +5779,19 @@

    Calling an existing Command

    class PersonType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, - array $options) { + public function buildForm(FormBuilderInterface $builder, array $options) + { $builder ->add('name') ->add('bio', 'textarea') ->add('birthday', 'date'); } - public function setDefaultOptions( - OptionsResolverInterface $resolver) { - $resolver->setDefaults(array('data_class' => 'My\Person')); + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'My\Person', + ]); } public function getName() @@ -5681,7 +5816,7 @@

    Calling an existing Command

    @@ -5701,7 +5836,7 @@

    Calling an existing Command

    $form = $this->createForm(new PersonType(), $person); if ($request->isMethod('POST')) { - $form->bind($request); + $form->handleRequest($request); if ($form->isValid()) { $person->save(); // insert a new `person` @@ -5732,7 +5867,7 @@

    Calling an existing Command

    @@ -5783,7 +5918,7 @@

    Calling an existing Command

    @@ -5807,7 +5942,7 @@

    Calling an existing Command

    $form = $this->createForm(new PersonType(), $person); if ($this->getRequest()->isMethod('POST')) { - $form->bind($this->getRequest()); + $form->handleRequest($this->getRequest()); if ($form->isValid()) { $person->save(); @@ -5837,7 +5972,7 @@

    Calling an existing Command

    @@ -5876,7 +6011,7 @@

    Calling an existing Command

    @@ -5924,7 +6059,7 @@

    Calling an existing Command

    @@ -5972,7 +6107,7 @@

    Calling an existing Command

    @@ -6000,7 +6135,7 @@

    Calling an existing Command

    @@ -6036,7 +6171,7 @@

    Calling an existing Command

    @@ -6085,7 +6220,7 @@

    Example

    @@ -6113,12 +6248,13 @@

    Example

    If the $name property is empty, you will see the following error message:

    -
    Acme\DemoBundle\Author.name:
    +
    Acme\DemoBundle\Author.name:
         This value should not be blank
    -
    +
    +

    Most of the time, you won't interact directly with the validator service or need -to worry about printing out the errors. Most of the time, you'll use validation -indirectly when handling submitted form data.

    +to worry about printing out the errors. Most of the time, you will use +validation indirectly when handling submitted form data.

    @@ -6134,7 +6270,7 @@

    Example

    @@ -6148,10 +6284,9 @@

    Example

    Constraints

    -

    +

    -

    See all constraints: -http://symfony.com/doc/master/book/validation.html#constraints.

    +

    http://symfony.com/doc/master/book/validation.html#constraints

    @@ -6168,7 +6303,7 @@

    Example

    @@ -6214,7 +6349,7 @@

    Classes

    @@ -6262,7 +6397,7 @@

    Classes

    @@ -6309,7 +6444,7 @@

    Example

    @@ -6330,7 +6465,7 @@

    Example

    To tell the validator to use a specific group, pass one or more group names as the second argument to the validate() method:

    -
    $errors = $validator->validate($author, array('registration'));
    +
    $errors = $validator->validate($author, [ 'registration' ]);
     
    @@ -6348,7 +6483,7 @@

    Example

    @@ -6364,9 +6499,11 @@

    Example

    If your object takes advantage of validation groups, you'll need to specify which validation group(s) your form should use:

    -
    $form = $this->createFormBuilder($users, array(
    -    'validation_groups' => array('registration'),
    -))->add(...);
    +
    $form = $this
    +    ->createFormBuilder($users, [
    +        'validation_groups' => [ 'registration' ],
    +    ])
    +    ->add(...);
     

    If you're creating form classes, then you'll need to add the following to @@ -6375,9 +6512,9 @@

    Example

    public function setDefaultOptions(OptionsResolverInterface $resolver) { - $resolver->setDefaults(array( - 'validation_groups' => array('registration'), - )); + $resolver->setDefaults([ + 'validation_groups' => [ 'registration' ], + ]); }
    @@ -6396,7 +6533,7 @@

    Example

    @@ -6446,7 +6583,7 @@

    Example

    @@ -6474,7 +6611,7 @@

    Example

    @@ -6513,7 +6650,7 @@

    Localization

    @@ -6563,7 +6700,7 @@

    Message Placeholders

    @@ -6611,7 +6748,7 @@

    Message Placeholders

    @@ -6654,7 +6791,7 @@

    Message Placeholders

    @@ -6699,7 +6836,7 @@

    Message Placeholders

    @@ -6746,7 +6883,64 @@

    Message Placeholders

    + + + + + +
    +
    +
    + +

    BazingaExposeTranslationBundle

    + + +
    # app/Resources/translations/Hello.fr.yml
    +foo: "Bar"
    +ba:
    +    bar: "Hello, World!"
    +
    +place.holder: "Hello, %username%!"
    +
    + +

    + +
    <script src="{{ url('bazinga_exposetranslation_js',
    +    { 'domain_name': 'Hello', '_locale': 'fr' }) }}"></script>
    +
    + +

    A Translator object is now available in your JavaScript:

    +
    Translator.get('Hello:foo');
    +// "bar"
    +
    +Translator.get('Hello:ba.bar');
    +// "Hello, World!"
    +
    +Translator.get('Hello:place.holder');
    +// "Hello, %username%!
    +
    +Translator.get('Hello:place.holder', { "username" : "Will" });
    +// "Hello, Will!"
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6774,7 +6968,7 @@

    Message Placeholders

    @@ -6809,7 +7003,7 @@

    Message Placeholders

    @@ -6849,7 +7043,7 @@

    HTTP Cache

    @@ -6886,7 +7080,7 @@

    Edge Side Includes

    @@ -6928,7 +7122,7 @@

    Edge Side Includes

    @@ -6945,21 +7139,15 @@

    Edge Side Includes

    The HTTP cache headers sent by your application are consumed and interpreted by up to three different types of caches:

      -
    • -

      Browser Caches: every browser comes with its own local cache that is mainly +

    • Browser Caches: every browser comes with its own local cache that is mainly useful for when you hit "back" or for images and other assets. The browser cache -is a private cache as cached resources aren't shared with anyone else;

      -
    • -
    • -

      Proxy Caches: a proxy is a shared cache as many people can be behind a +is a private cache as cached resources aren't shared with anyone else;

    • +
    • Proxy Caches: a proxy is a shared cache as many people can be behind a single one. It's usually installed by large corporations and ISPs to reduce -latency and network traffic;

      -
    • -
    • -

      Gateway Caches: like a proxy, it's also a shared cache but on the +latency and network traffic;

    • +
    • Gateway Caches: like a proxy, it's also a shared cache but on the server side. Installed by network administrators, it makes websites more -scalable, reliable and performant.

      -
    • +scalable, reliable and performant.
    @@ -6976,7 +7164,7 @@

    Edge Side Includes

    @@ -7012,7 +7200,7 @@

    Edge Side Includes

    @@ -7034,14 +7222,10 @@

    Edge Side Includes

    asked for their account page!

    To handle this situation, every response may be set to be public or private:

      -
    • -

      public: indicates that the response may be cached by both private and -shared caches;

      -
    • -
    • -

      private: indicates that all or part of the response message is intended for -a single user and must not be cached by a shared cache.

      -
    • +
    • public: indicates that the response may be cached by both private and +shared caches;
    • +
    • private: indicates that all or part of the response message is intended for +a single user and must not be cached by a shared cache.
    @@ -7058,7 +7242,7 @@

    Edge Side Includes

    @@ -7075,19 +7259,15 @@

    Edge Side Includes

    HTTP caching only works for safe HTTP methods (like GET and HEAD). Being safe means that you never change the application's state on the server when serving the request.

    -

    his has two very reasonable consequences:

    +

    This has two very reasonable consequences:

      -
    • -

      You should never change the state of your application when responding to a +

    • You should never change the state of your application when responding to a GET or HEAD request. Even if you don't use a gateway cache, the presence of proxy caches mean that any GET or HEAD request may or may not actually -hit your server;

      -
    • -
    • -

      Don't expect PUT, POST or DELETE methods to cache. These methods are +hit your server;

    • +
    • Don't expect PUT, POST or DELETE methods to cache. These methods are meant to be used when mutating the state of your application. Caching them -would prevent certain requests from hitting and mutating your application.

      -
    • +would prevent certain requests from hitting and mutating your application.
    @@ -7104,7 +7284,7 @@

    Edge Side Includes

    @@ -7142,7 +7322,7 @@

    Edge Side Includes

    @@ -7150,7 +7330,7 @@

    Edge Side Includes

    -
    +

    The Cache-Control Header (1/2)

    @@ -7159,9 +7339,10 @@

    Edge Side Includes

    The Cache-Control header is unique in that it contains not one, but various pieces of information about the cacheability of a response.

    Each piece of information is separated by a comma:

    -
    Cache-Control: private, max-age=0, must-revalidate
    +
    Cache-Control: private, max-age=0, must-revalidate
     Cache-Control: max-age=3600, must-revalidate
    -
    +
    +
    @@ -7177,7 +7358,7 @@

    Edge Side Includes

    @@ -7223,7 +7404,7 @@

    Edge Side Includes

    @@ -7246,8 +7427,9 @@

    Edge Side Includes

    The resulting HTTP header will look like this:

    -
    Expires: Thu, 01 Mar 2013 10:00:00 GMT
    -
    +
    Expires: Thu, 01 Mar 2013 10:00:00 GMT
    +
    +

    The setExpires() method automatically converts the date to the GMT timezone as required by the specification.

    @@ -7265,7 +7447,7 @@

    Edge Side Includes

    @@ -7302,7 +7484,7 @@

    Edge Side Includes

    @@ -7350,7 +7532,7 @@

    Edge Side Includes

    @@ -7385,7 +7567,7 @@

    Edge Side Includes

    @@ -7438,7 +7620,7 @@

    Edge Side Includes

    @@ -7475,7 +7657,7 @@

    Edge Side Includes

    @@ -7707,7 +7889,7 @@

    Table of Contents

    - Route Params as Controller Arguments + Route Params as Controller Args 37 @@ -7743,563 +7925,587 @@

    Table of Contents

    - Routing with Placeholders + Routing with Placeholders (1/2) 43 - Requirements + Routing with Placeholders (2/2) 44 - Including External Routing Resources + Requirements 45 - Generating URLs + Including External Routing Resources 46 - Templating + Generating URLs 47 - + Templating 48 - Why Twig? + 49 - Getting Familiar With Twig + Why Twig? 50 - Accessing Variables + Getting Familiar With Twig 51 - Control Structure + Accessing Variables 52 - Filters + Control Structure 53 - Including Other Templates + Filters 54 - Template Inheritance (1/2) + Including Other Templates 55 - Template Inheritance (2/2) + Template Inheritance (1/2) 56 - Template Naming and Locations (1/2) + Template Inheritance (2/2) 57 - Template Naming and Locations (2/2) + Template Naming and Locations (1/2) 58 - Overriding Bundle Templates + Template Naming and Locations (2/2) 59 - The Three-Level Approach + Overriding Bundle Templates 60 - Twig Into Symfony2 + Overriding Core Templates 61 - Rendering A Template + The Three-Level Approach 62 - Linking to Pages + Twig Into Symfony2 63 - Linking to Assets + Rendering A Template 64 - Linking To Pages In JavaScript + Linking to Pages 65 - Global Template Variables + Linking to Assets 66 - Service Container + Linking To Pages In JavaScript 67 - Definitions + Global Template Variables 68 - Creating A Service + Service Container 69 - Service Parameters + What Is A Service? 70 - Injecting Services + What Is A Service Container? 71 - Importing Configuration Resources + Creating A Service 72 - Creating an Extension Class + Service Parameters 73 - Dealing With Configuration (1/2) + Injecting Services 74 - Dealing With Configuration (2/2) + Importing Configuration Resources 75 - The Configuration Class (1/2) + Creating an Extension Class 76 - The Configuration Class (2/2) + Dealing With Configuration (1/2) 77 - More On The Service Container + Dealing With Configuration (2/2) 78 - Symfony2 Commands + The Configuration Class (1/2) 79 - Built-in Commands (1/2) + The Configuration Class (2/2) 80 - Built-in Commands (2/2) + More On The Service Container 81 - Creating Commands + Symfony2 Commands 82 - Command Arguments + Built-in Commands (1/2) 83 - Command Options (1/2) + Built-in Commands (2/2) 84 - Command Options (2/2) + Creating Commands 85 - More On Commands + Command Arguments 86 - Forms + Command Options (1/2) 87 - Building Your First Form + Command Options (2/2) 88 - Rendering The Form + More On Commands 89 - Handling Forms: The Right Way + Forms 90 - Handling Form Submissions + Building Your First Form 91 - Built-in Form Types + Rendering The Form 92 - Creating A Custom Type (Form Class) + Handling Forms: The Right Way 93 - Dealing With Objects + Handling Form Submissions 94 - The processForm() Method (1/2) + Built-in Form Types 95 - The processForm() Method (2/2) + Creating A Custom Type (Form Class) 96 - Cross-Site Request Forgery Protection + Dealing With Objects 97 - Rendering a Form in a Template (1/2) + The processForm() Method (1/2) 98 - Rendering a Form in a Template (2/2) + The processForm() Method (2/2) 99 - Validation + Cross-Site Request Forgery Protection 100 - About Form Validation + Rendering a Form in a Template (1/2) 101 - The Validator Component + Rendering a Form in a Template (2/2) 102 - Using the validator Service + Validation 103 - Constraints + About Form Validation 104 - Constraint Targets (1/2) + The Validator Component 105 - Constraint Targets (2/2) + Using the validator Service 106 - Validation Groups (1/2) + Constraints 107 - Validation Groups (2/2) + Constraint Targets (1/2) 108 - Using Validation Groups In Forms + Constraint Targets (2/2) 109 - Validating Values and Arrays + Validation Groups (1/2) 110 - Translations + Validation Groups (2/2) 111 - Definitions + Using Validation Groups In Forms 112 - Using the translator Service + Validating Values and Arrays 113 - The Translation Process + Translations 114 - Locations and Naming Conventions + Definitions 115 - Pluralization + Using the translator Service 116 - Explicit Interval Pluralization + The Translation Process 117 - HTTP Cache + Locations and Naming Conventions 118 - HTTP Cache + Pluralization 119 - Terminology (1/2) + Explicit Interval Pluralization 120 - Terminology (2/2) + BazingaExposeTranslationBundle 121 - Caching with a Gateway Cache + HTTP Cache 122 - Types of Caches + HTTP Cache 123 - HTTP Caching + Terminology (1/2) 124 - Public vs Private Responses + Terminology (2/2) 125 - Safe Methods + Caching with a Gateway Cache 126 - Expiration + Types of Caches 127 - The Cache-Control Header (1/2) + HTTP Caching 128 - The Cache-Control Header (2/2) + Public vs Private Responses 129 - The Expires Header + Safe Methods 130 - Validation + Expiration 131 - The ETag Header + The Cache-Control Header (1/2) 132 - The Last-Modified Header (1/2) + The Cache-Control Header (2/2) 133 - The Last-Modified Header (2/2) + The Expires Header 134 - Edge Side Includes (ESI) + Validation 135 + + The ETag Header + 136 + + + + + The Last-Modified Header (1/2) + 137 + + + + + The Last-Modified Header (2/2) + 138 + + + + + Edge Side Includes (ESI) + 139 + + + From 52830f862365a90cf8a76f8d83932bae8be5e341 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Fri, 27 Dec 2013 15:19:59 +0100 Subject: [PATCH 04/71] =?UTF-8?q?Publish=20slides=20(Ven=2027=20d=C3=A9c?= =?UTF-8?q?=202013=2015:19:59=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 8646fb7..74753cd 100644 --- a/index.html +++ b/index.html @@ -8366,11 +8366,9 @@

    StoryBDD

    -

    Well... Maybe Not.

    +

    Well... Maybe Not.
    PHP Extended

    -

    -

    Notes

    @@ -9373,7 +9371,7 @@

    Table of Contents

    - Well... Maybe Not. + Well... Maybe Not.
    PHP Extended 163 From e5756d269b50ab82619bd84475f24870d4fa7d11 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 31 Dec 2013 17:27:25 +0100 Subject: [PATCH 05/71] =?UTF-8?q?Publish=20slides=20(Mar=2031=20d=C3=A9c?= =?UTF-8?q?=202013=2017:27:25=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 671 +++++++++++++++++++++++++++++----------------------- index2.html | 618 ++++++++++++++++++++++++----------------------- 2 files changed, 701 insertions(+), 588 deletions(-) diff --git a/index.html b/index.html index 74753cd..e853fe4 100644 --- a/index.html +++ b/index.html @@ -1588,7 +1588,7 @@
    @@ -1616,7 +1616,7 @@
    @@ -1667,7 +1667,7 @@ @@ -1689,7 +1689,7 @@

    Week #2

    Week #3

    Databases

    Week #4

    -

    Writing Better Code, Testing, Embracing Open Source

    +

    Sessions, Authentication, Writing Better Code, Testing, Embracing Open Source

    @@ -1705,7 +1705,7 @@

    Week #4

    @@ -1733,7 +1733,7 @@

    Week #4

    @@ -1768,7 +1768,7 @@

    Week #4

    @@ -1804,7 +1804,7 @@

    Week #4

    @@ -1840,7 +1840,7 @@

    Week #4

    @@ -1874,7 +1874,42 @@

    Week #4

    + + + + + +
    +
    +
    + +

    HHVM

    + + +

    HipHop Virtual Machine for PHP, created by Facebook.

    +

    HHVM uses a just-in-time compilation approach to achieve superior performance.

    +

    +
    +

    http://www.hhvm.com

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -1902,7 +1937,7 @@

    Week #4

    @@ -1930,7 +1965,7 @@

    Week #4

    @@ -1968,7 +2003,7 @@

    Week #4

    @@ -2017,7 +2052,7 @@

    Week #4

    @@ -2068,7 +2103,7 @@

    Week #4

    @@ -2111,7 +2146,7 @@

    Abstract class definition

    @@ -2163,7 +2198,7 @@

    Abstract class definition

    @@ -2202,7 +2237,7 @@

    The Rules

    @@ -2255,7 +2290,7 @@

    The Rules

    @@ -2304,7 +2339,7 @@

    Type Hinting

    @@ -2348,7 +2383,7 @@

    Usage

    @@ -2396,7 +2431,7 @@

    Usage

    @@ -2442,7 +2477,7 @@

    Usage

    @@ -2486,7 +2521,7 @@

    Usage

    @@ -2535,7 +2570,7 @@

    Usage

    @@ -2583,7 +2618,7 @@

    PSR-0

    @@ -2630,7 +2665,7 @@

    PSR-0

    @@ -2682,7 +2717,7 @@

    PSR-0

    @@ -2725,7 +2760,7 @@

    PSR-0

    @@ -2771,7 +2806,7 @@

    PSR-0

    @@ -2814,7 +2849,7 @@

    PSR-0

    @@ -2854,7 +2889,7 @@

    PSR-0

    @@ -2882,7 +2917,7 @@

    PSR-0

    @@ -2934,7 +2969,7 @@

    PSR-0

    @@ -2982,7 +3017,7 @@

    PSR-0

    @@ -3034,7 +3069,7 @@

    PSR-0

    @@ -3062,7 +3097,7 @@

    PSR-0

    @@ -3102,7 +3137,7 @@

    PSR-0

    @@ -3147,7 +3182,7 @@

    PSR-0

    @@ -3197,7 +3232,7 @@

    PSR-0

    @@ -3237,7 +3272,7 @@

    PSR-0

    @@ -3281,7 +3316,7 @@

    PSR-0

    @@ -3330,7 +3365,7 @@

    PSR-0

    @@ -3373,7 +3408,7 @@

    PSR-0

    @@ -3401,7 +3436,7 @@

    PSR-0

    @@ -3450,7 +3485,7 @@

    PSR-0

    @@ -3500,7 +3535,7 @@

    PSR-0

    @@ -3547,7 +3582,7 @@

    PSR-0

    @@ -3596,7 +3631,7 @@

    PSR-0

    @@ -3635,7 +3670,7 @@

    spl_autoload_functions()

    @@ -3684,7 +3719,7 @@

    spl_autoload_unregister()

    @@ -3739,7 +3774,7 @@

    spl_autoload_unregister()

    @@ -3767,7 +3802,7 @@

    spl_autoload_unregister()

    @@ -3812,7 +3847,7 @@

    Traversable

    @@ -3863,7 +3898,7 @@

    Traversable

    @@ -3914,7 +3949,7 @@

    Traversable

    @@ -3955,7 +3990,7 @@

    SPL Functions

    @@ -4008,7 +4043,7 @@

    SPL Functions

    @@ -4057,7 +4092,7 @@

    SPL Functions

    @@ -4106,7 +4141,7 @@

    SPL Functions

    @@ -4146,7 +4181,7 @@

    SPL Functions

    @@ -4188,7 +4223,7 @@

    SPL Functions

    @@ -4230,7 +4265,7 @@

    SPL Functions

    @@ -4258,7 +4293,7 @@

    SPL Functions

    @@ -4303,7 +4338,7 @@

    SPL Functions

    @@ -4353,7 +4388,7 @@

    SPL Functions

    @@ -4401,7 +4436,7 @@

    SPL Functions

    @@ -4451,7 +4486,7 @@

    SPL Functions

    @@ -4498,7 +4533,7 @@

    Execution

    @@ -4551,7 +4586,7 @@

    Usage

    @@ -4579,7 +4614,7 @@

    Usage

    @@ -4622,7 +4657,7 @@

    Usage

    @@ -4665,7 +4700,7 @@

    Usage

    @@ -4718,7 +4753,7 @@

    Usage

    @@ -4765,7 +4800,7 @@

    Usage

    @@ -4814,7 +4849,7 @@

    Usage

    @@ -4866,7 +4901,7 @@

    Usage

    @@ -4909,7 +4944,7 @@

    Centralized declaration

    @@ -4942,7 +4977,7 @@

    Centralized declaration

    @@ -4983,7 +5018,7 @@

    Centralized declaration

    @@ -5011,7 +5046,7 @@

    Centralized declaration

    @@ -5046,7 +5081,7 @@

    Centralized declaration

    @@ -5081,7 +5116,7 @@

    Centralized declaration

    @@ -5122,7 +5157,7 @@

    Centralized declaration

    @@ -5150,7 +5185,7 @@

    Centralized declaration

    @@ -5204,7 +5239,7 @@

    Centralized declaration

    @@ -5250,7 +5285,7 @@

    Centralized declaration

    @@ -5297,7 +5332,7 @@

    Centralized declaration

    @@ -5325,7 +5360,7 @@

    Centralized declaration

    @@ -5373,7 +5408,7 @@

    CRUD

    @@ -5420,7 +5455,7 @@

    CRUD

    @@ -5468,7 +5503,7 @@

    CRUD

    @@ -5520,7 +5555,7 @@

    CRUD

    @@ -5565,7 +5600,7 @@

    CRUD

    @@ -5612,7 +5647,7 @@

    CRUD

    @@ -5640,7 +5675,7 @@

    CRUD

    @@ -5687,7 +5722,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5742,7 +5777,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5770,7 +5805,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5823,7 +5858,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5872,7 +5907,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5900,7 +5935,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5947,7 +5982,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5975,7 +6010,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6018,7 +6053,7 @@

    PHP Data Object (PDO)

    @@ -6067,7 +6102,7 @@

    Usage

    @@ -6121,7 +6156,7 @@

    Usage

    @@ -6168,7 +6203,7 @@

    Usage

    @@ -6196,7 +6231,7 @@

    Usage

    @@ -6233,7 +6268,7 @@

    Usage

    @@ -6269,7 +6304,7 @@

    Code Snippet

    @@ -6305,7 +6340,7 @@

    Code Snippet

    @@ -6347,7 +6382,7 @@

    Code Snippet

    @@ -6387,7 +6422,7 @@

    Doctrine2 ORM

    @@ -6415,7 +6450,7 @@

    Doctrine2 ORM

    @@ -6457,7 +6492,7 @@

    A few use cases:

    @@ -6506,7 +6541,7 @@

    A few use cases:

    @@ -6547,7 +6582,7 @@

    Workarounds

    @@ -6575,7 +6610,7 @@

    Workarounds

    @@ -6606,7 +6641,7 @@

    Workarounds

    @@ -6636,7 +6671,7 @@

    Workarounds

    @@ -6677,7 +6712,7 @@

    Event Dispatcher

    @@ -6725,7 +6760,7 @@

    Event Dispatcher

    @@ -6777,7 +6812,7 @@

    Event Dispatcher

    @@ -6826,7 +6861,7 @@

    Event Dispatcher

    @@ -6883,7 +6918,7 @@

    Event Dispatcher

    @@ -6913,7 +6948,7 @@

    Event Dispatcher

    @@ -6966,7 +7001,7 @@

    Event Dispatcher

    @@ -7002,7 +7037,7 @@

    WSSE Username Token

    @@ -7030,7 +7065,7 @@

    WSSE Username Token

    @@ -7067,7 +7102,7 @@

    WSSE Username Token

    @@ -7124,7 +7159,7 @@

    WSSE Username Token

    @@ -7168,7 +7203,7 @@

    Usage

    @@ -7213,7 +7248,7 @@

    Usage

    @@ -7250,7 +7285,7 @@

    Usage

    @@ -7293,7 +7328,7 @@

    Usage

    @@ -7335,7 +7370,7 @@

    Usage

    @@ -7377,7 +7412,7 @@

    Usage

    @@ -7426,7 +7461,7 @@

    Usage

    @@ -7475,7 +7510,7 @@

    Usage

    @@ -7518,7 +7553,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7560,7 +7595,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7601,7 +7636,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7647,7 +7682,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7675,7 +7710,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7709,7 +7744,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7737,7 +7772,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7783,7 +7818,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7831,7 +7866,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7870,7 +7905,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7920,7 +7955,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7948,7 +7983,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7985,7 +8020,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8013,7 +8048,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8056,7 +8091,7 @@

    StoryBDD

    @@ -8102,7 +8137,7 @@

    StoryBDD

    @@ -8150,7 +8185,7 @@

    StoryBDD

    @@ -8203,7 +8238,7 @@

    StoryBDD

    @@ -8231,7 +8266,7 @@

    StoryBDD

    @@ -8259,7 +8294,35 @@

    StoryBDD

    + + + + + +
    +
    +
    + +

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -8287,7 +8350,7 @@

    StoryBDD

    @@ -8327,7 +8390,7 @@

    StoryBDD

    @@ -8355,7 +8418,7 @@

    StoryBDD

    @@ -8383,7 +8446,7 @@

    StoryBDD

    @@ -8453,385 +8516,385 @@

    Table of Contents

    - RTFM: http://www.php.net + HHVM 10 - The PHP Syntax + RTFM: http://www.php.net 11 - Primitive Types + The PHP Syntax 12 - Comparison Operators + Primitive Types 13 - Operators + Comparison Operators 14 - Classes (1/2) + Operators 15 - Classes (2/2) + Classes (1/2) 16 - Visibility + Classes (2/2) 17 - Attributes + Visibility 18 - Methods (1/3) + Attributes 19 - Methods (2/3) + Methods (1/3) 20 - Methods (3/3) + Methods (2/3) 21 - Static Keyword (1/2) + Methods (3/3) 22 - Static Keyword (2/2) + Static Keyword (1/2) 23 - Interfaces + Static Keyword (2/2) 24 - Namespaces + Interfaces 25 - The class Keyword + Namespaces 26 - Traits + The class Keyword 27 - Anonymous Functions + Traits 28 - Closures + Anonymous Functions 29 - Magic Methods + Closures 30 - Generators + Magic Methods 31 - The PHP Command Line + Generators 32 - The PHP Command Line (1/2) + The PHP Command Line 33 - The PHP Command Line (2/2) + The PHP Command Line (1/2) 34 - Writing a CLI program + The PHP Command Line (2/2) 35 - Client/Server + Writing a CLI program 36 - Client/Server Basics + Client/Server 37 - HTTP Request + Client/Server Basics 38 - HTTP Response + HTTP Request 39 - HTTP Verbs + HTTP Response 40 - HTTP Parameters (1/2) + HTTP Verbs 41 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 42 - REST (REpresentational State Transfer) + HTTP Parameters (2/2) 43 - PHP Autoloading + REST (REpresentational State Transfer) 44 - Why Is It Necessary? + PHP Autoloading 45 - The require() Way + Why Is It Necessary? 46 - The require_once() Way + The require() Way 47 - Working With Multiple Files + The require_once() Way 48 - Rethinking The Way We Load Classes + Working With Multiple Files 49 - Examples + Rethinking The Way We Load Classes 50 - Under The Hood + Examples 51 - Leveraging PHP APIs + Under The Hood 52 - Built-in Interfaces + Leveraging PHP APIs 53 - The Reflection API (1/2) + Built-in Interfaces 54 - The Reflection API (2/2) + The Reflection API (1/2) 55 - The Standard PHP Library (SPL) + The Reflection API (2/2) 56 - Observer/Observable (1/2) + The Standard PHP Library (SPL) 57 - Observer/Observable (2/2) + Observer/Observable (1/2) 58 - Exceptions (1/2) + Observer/Observable (2/2) 59 - Exceptions (2/2) + Exceptions (1/2) 60 - Password Hashing + Exceptions (2/2) 61 - PHP Archive (PHAR) + Password Hashing 62 - Dependency Management in PHP + PHP Archive (PHAR) 63 - Dependency Management + Dependency Management in PHP 64 - Composer + Dependency Management 65 - Example + Composer 66 - The Symfony2 Console Component + Example 67 - A Basic Command (1/2) + The Symfony2 Console Component 68 - A Basic Command (2/2) + A Basic Command (1/2) 69 - Model View Controller + A Basic Command (2/2) 70 - MVC Overview + Model View Controller 71 - The Model + MVC Overview 72 - The View + The Model 73 @@ -8849,61 +8912,61 @@

    Table of Contents

    - The Controller + The View 76 - Routing + The Controller 77 - Front Controller Pattern + Routing 78 - Interact With Multiple Services + Front Controller Pattern 79 - Databases + Interact With Multiple Services 80 - Agenda + Databases 81 - Quick note + Agenda 82 - Database Design Patterns + Quick note 83 - Row Data Gateway + Database Design Patterns 84 - Row Data Gateway + Row Data Gateway 85 @@ -8921,13 +8984,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 88 - Table Data Gateway + Table Data Gateway 89 @@ -8963,13 +9026,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 95 - Active Record + Active Record 96 @@ -8981,13 +9044,13 @@

    Table of Contents

    - Data Mapper + Active Record 98 - Data Mapper + Data Mapper 99 @@ -8999,31 +9062,31 @@

    Table of Contents

    - Identity Map + Data Mapper 101 - Identity Map + Identity Map 102 - Data Access Layer + Identity Map 103 - Data Access Layer / Data Source Name + Data Access Layer 104 - Data Access Layer + Data Access Layer / Data Source Name 105 @@ -9041,169 +9104,169 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 108 - Object Relational Mapping (1/4) + Object Relational Mapping 109 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 110 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 111 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 112 - Existing Components + Object Relational Mapping (4/4) 113 - Sessions + Existing Components 114 - Overview + Sessions 115 - Code Please + Overview 116 - Security Concerns + Code Please 117 - Authentication + Security Concerns 118 - What You Have Right Now + Authentication 119 - The Big Picture + What You Have Right Now 120 - The Interceptor Pattern + The Big Picture 121 - Introducing the Event Dispatcher + The Interceptor Pattern 122 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 123 - The Firewall + Using the EventDispatcherTrait 124 - Implementing The Firewall + The Firewall 125 - Authentication Mechanism + Implementing The Firewall 126 - Adding New Routes + Authentication Mechanism 127 - Stateless Authentication + Adding New Routes 128 - Writing Better Code + Stateless Authentication 129 - Agenda + Writing Better Code 130 - Coding Standards + Agenda 131 - PHP Coding Standards Fixer + Coding Standards 132 - Programming To The Interface + PHP Coding Standards Fixer 133 - Component Driven Development + Programming To The Interface 134 - Dependency Injection + Component Driven Development 135 @@ -9227,7 +9290,7 @@

    Table of Contents

    - PHP Implementations + Dependency Injection 139 @@ -9239,37 +9302,37 @@

    Table of Contents

    - From STUPID to SOLID code! (1/2) + PHP Implementations 141 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 142 - Object Calisthenics + From STUPID to SOLID code! (2/2) 143 - Testing + Object Calisthenics 144 - Agenda + Testing 145 - Unit Testing + Agenda 146 @@ -9281,25 +9344,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 148 - PHPUnit — Assertions + PHPUnit — The Rules 149 - Running PHPUnit + PHPUnit — Assertions 150 - Functional Testing + Running PHPUnit 151 @@ -9311,7 +9374,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 153 @@ -9323,59 +9386,71 @@

    Table of Contents

    - Behat + Behavior Driven Development 155 - Using Behat (1/2) + Behat 156 - Using Behat (2/2) + Using Behat (1/2) 157 - Embracing Open Source + Using Behat (2/2) 158 - + Embracing Open Source 159 - + 160 - Golden Rules + 161 - The End. + 162 - Well... Maybe Not.
    PHP Extended + Golden Rules 163 + + The End. + 164 + + + + + Well... Maybe Not.
    PHP Extended + 165 + + + diff --git a/index2.html b/index2.html index d509d7b..74e574b 100644 --- a/index2.html +++ b/index2.html @@ -1588,7 +1588,7 @@ @@ -1616,7 +1616,40 @@ + + + + + +
    +
    +
    + +

    Agenda

    + + +

    Symfony2

    +

    Controllers, Templating, Dependency Injection, Command Line, Forms, Validation, +Translation, HTTP Cache

    +

    Stack PHP

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -1658,7 +1691,7 @@
    @@ -1686,7 +1719,7 @@ @@ -1728,7 +1761,7 @@ @@ -1756,7 +1789,7 @@ @@ -1784,7 +1817,7 @@ @@ -1822,7 +1855,7 @@ @@ -1866,7 +1899,7 @@ @@ -1915,7 +1948,7 @@ @@ -1958,7 +1991,7 @@ @@ -1986,7 +2019,7 @@ @@ -2038,7 +2071,7 @@ @@ -2088,7 +2121,7 @@ @@ -2135,7 +2168,7 @@ @@ -2167,7 +2200,7 @@ @@ -2213,7 +2246,7 @@ @@ -2259,7 +2292,7 @@ @@ -2309,7 +2342,7 @@ @@ -2362,7 +2395,7 @@ @@ -2401,7 +2434,7 @@ @@ -2449,7 +2482,7 @@ @@ -2496,7 +2529,7 @@ @@ -2546,7 +2579,7 @@ @@ -2597,7 +2630,7 @@ @@ -2646,7 +2679,7 @@ @@ -2694,7 +2727,7 @@ @@ -2743,7 +2776,7 @@ @@ -2822,7 +2855,7 @@ @@ -2875,7 +2908,7 @@ @@ -2923,7 +2956,7 @@ @@ -2964,7 +2997,7 @@ @@ -2992,7 +3025,7 @@ @@ -3035,7 +3068,7 @@ @@ -3086,7 +3119,7 @@

    Controller Implementation

    @@ -3129,7 +3162,7 @@

    Controller Implementation

    @@ -3181,7 +3214,7 @@

    Controller Implementation

    @@ -3226,7 +3259,7 @@

    Controller Implementation

    @@ -3276,7 +3309,7 @@

    Rendering Templates

    @@ -3323,7 +3356,7 @@

    Rendering Templates

    @@ -3351,7 +3384,7 @@

    Rendering Templates

    @@ -3395,7 +3428,7 @@

    Rendering Templates

    @@ -3434,7 +3467,7 @@

    Rendering Templates

    @@ -3472,7 +3505,7 @@

    Rendering Templates

    @@ -3519,7 +3552,7 @@

    HTTP Method Requirements

    @@ -3566,7 +3599,7 @@

    Prefixing Imported Routes

    @@ -3616,7 +3649,7 @@

    Query String

    @@ -3644,7 +3677,7 @@

    Query String

    @@ -3672,7 +3705,7 @@

    Query String

    @@ -3722,7 +3755,7 @@

    After

    @@ -3761,7 +3794,7 @@

    After

    @@ -3811,7 +3844,7 @@

    After

    @@ -3860,7 +3893,7 @@

    Loops

    @@ -3907,7 +3940,7 @@

    Loops

    @@ -3958,7 +3991,7 @@

    Example

    @@ -4011,7 +4044,7 @@

    Example

    @@ -4060,7 +4093,7 @@

    Example

    @@ -4103,7 +4136,7 @@

    Example

    @@ -4148,7 +4181,7 @@

    Example

    @@ -4187,7 +4220,7 @@

    Example

    @@ -4219,7 +4252,7 @@

    Example

    @@ -4266,7 +4299,7 @@

    Example

    @@ -4294,7 +4327,7 @@

    Example

    @@ -4343,7 +4376,7 @@

    Using the Templating Service

    @@ -4394,7 +4427,7 @@

    Using the Templating Service

    @@ -4444,7 +4477,7 @@

    Cache Busting

    @@ -4494,7 +4527,7 @@

    Cache Busting

    @@ -4531,7 +4564,7 @@

    Cache Busting

    @@ -4559,7 +4592,7 @@

    Cache Busting

    @@ -4595,7 +4628,7 @@

    Cache Busting

    @@ -4629,7 +4662,7 @@

    Cache Busting

    @@ -4682,7 +4715,7 @@

    Cache Busting

    @@ -4730,7 +4763,7 @@

    Cache Busting

    @@ -4783,7 +4816,7 @@

    Optional Dependencies: Setter Injection

    @@ -4827,7 +4860,7 @@

    Container Extensions

    @@ -4879,7 +4912,7 @@

    Container Extensions

    @@ -4929,7 +4962,7 @@

    Container Extensions

    @@ -4974,7 +5007,7 @@

    Container Extensions

    @@ -5027,7 +5060,7 @@

    Container Extensions

    @@ -5074,7 +5107,7 @@

    Container Extensions

    @@ -5122,7 +5155,7 @@

    Debugging Services

    @@ -5150,7 +5183,7 @@

    Debugging Services

    @@ -5199,7 +5232,7 @@

    Global Options

    @@ -5254,7 +5287,7 @@

    Global Options

    @@ -5308,7 +5341,7 @@

    Global Options

    @@ -5360,7 +5393,7 @@

    Usage

    @@ -5412,7 +5445,7 @@

    Usage

    @@ -5462,7 +5495,7 @@

    Usage

    @@ -5515,7 +5548,7 @@

    Calling an existing Command

    @@ -5543,7 +5576,7 @@

    Calling an existing Command

    @@ -5589,7 +5622,7 @@

    Calling an existing Command

    @@ -5628,7 +5661,7 @@

    Calling an existing Command

    @@ -5675,7 +5708,7 @@

    Calling an existing Command

    @@ -5728,7 +5761,7 @@

    Calling an existing Command

    @@ -5759,7 +5792,7 @@

    Calling an existing Command

    @@ -5816,7 +5849,7 @@

    Calling an existing Command

    @@ -5867,7 +5900,7 @@

    Calling an existing Command

    @@ -5918,7 +5951,7 @@

    Calling an existing Command

    @@ -5972,7 +6005,7 @@

    Calling an existing Command

    @@ -6011,7 +6044,7 @@

    Calling an existing Command

    @@ -6059,7 +6092,7 @@

    Calling an existing Command

    @@ -6107,7 +6140,7 @@

    Calling an existing Command

    @@ -6135,7 +6168,7 @@

    Calling an existing Command

    @@ -6171,7 +6204,7 @@

    Calling an existing Command

    @@ -6220,7 +6253,7 @@

    Example

    @@ -6270,7 +6303,7 @@

    Example

    @@ -6303,7 +6336,7 @@

    Example

    @@ -6349,7 +6382,7 @@

    Classes

    @@ -6397,7 +6430,7 @@

    Classes

    @@ -6444,7 +6477,7 @@

    Example

    @@ -6483,7 +6516,7 @@

    Example

    @@ -6533,7 +6566,7 @@

    Example

    @@ -6583,7 +6616,7 @@

    Example

    @@ -6611,7 +6644,7 @@

    Example

    @@ -6650,7 +6683,7 @@

    Localization

    @@ -6700,7 +6733,7 @@

    Message Placeholders

    @@ -6748,7 +6781,7 @@

    Message Placeholders

    @@ -6791,7 +6824,7 @@

    Message Placeholders

    @@ -6836,7 +6869,7 @@

    Message Placeholders

    @@ -6883,7 +6916,7 @@

    Message Placeholders

    @@ -6894,35 +6927,34 @@

    Message Placeholders

    -

    BazingaExposeTranslationBundle

    +

    BazingaJsTranslationBundle

    # app/Resources/translations/Hello.fr.yml
    -foo: "Bar"
     ba:
    -    bar: "Hello, World!"
    -
    -place.holder: "Hello, %username%!"
    +    bar:      Bonjour.
    +place.holder: Bonjour %username%!
    +plural:       Il y a %count% pomme|Il y a %count% pommes
     

    -
    <script src="{{ url('bazinga_exposetranslation_js',
    -    { 'domain_name': 'Hello', '_locale': 'fr' }) }}"></script>
    +
    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'Hello' }) }}">
    +</script>
     

    A Translator object is now available in your JavaScript:

    -
    Translator.get('Hello:foo');
    -// "bar"
    +
    Translator.trans('ba.bar', {}, 'Hello', 'fr');
    +// "Bonjour."
     
    -Translator.get('Hello:ba.bar');
    -// "Hello, World!"
    +Translator.trans('place.holder', { "username" : "Will" }, 'Hello');
    +// "Bonjour Will!"
     
    -Translator.get('Hello:place.holder');
    -// "Hello, %username%!
    +Translator.transChoice('plural', 1, { "count": 1 }, 'Hello');
    +// "Il y a 1 pomme"
     
    -Translator.get('Hello:place.holder', { "username" : "Will" });
    -// "Hello, Will!"
    +Translator.transChoice('plural', 10, { "count": 10 }, 'Hello');
    +// "Il y a 10 pommes"
     
    @@ -6940,7 +6972,7 @@

    Message Placeholders

    @@ -6968,7 +7000,7 @@

    Message Placeholders

    @@ -7003,7 +7035,7 @@

    Message Placeholders

    @@ -7043,7 +7075,7 @@

    HTTP Cache

    @@ -7080,7 +7112,7 @@

    Edge Side Includes

    @@ -7122,7 +7154,7 @@

    Edge Side Includes

    @@ -7164,7 +7196,7 @@

    Edge Side Includes

    @@ -7200,7 +7232,7 @@

    Edge Side Includes

    @@ -7242,7 +7274,7 @@

    Edge Side Includes

    @@ -7284,7 +7316,7 @@

    Edge Side Includes

    @@ -7322,7 +7354,7 @@

    Edge Side Includes

    @@ -7358,7 +7390,7 @@

    Edge Side Includes

    @@ -7404,7 +7436,7 @@

    Edge Side Includes

    @@ -7447,7 +7479,7 @@

    Edge Side Includes

    @@ -7484,7 +7516,7 @@

    Edge Side Includes

    @@ -7532,7 +7564,7 @@

    Edge Side Includes

    @@ -7567,7 +7599,7 @@

    Edge Side Includes

    @@ -7620,7 +7652,7 @@

    Edge Side Includes

    @@ -7657,7 +7689,7 @@

    Edge Side Includes

    @@ -7685,721 +7717,721 @@

    Table of Contents

    - A Framework To Simplify Developments + Agenda 3 - + A Framework To Simplify Developments 4 - What Is Symfony2? + 5 - Is Symfony2 A MVC Framework? + What Is Symfony2? 6 - NO! + Is Symfony2 A MVC Framework? 7 - Why You Should Use Symfony2 + NO! 8 - The Symfony2 Components + Why You Should Use Symfony2 9 - Getting Ready With Components + The Symfony2 Components 10 - Full-Stack Framework + Getting Ready With Components 11 - Overall Architecture + Full-Stack Framework 12 - The Symfony2 Request + Overall Architecture 13 - The Symfony2 Response + The Symfony2 Request 14 - The Simplest Front Controller Ever + The Symfony2 Response 15 - The Symfony Application Flow + The Simplest Front Controller Ever 16 - Routing Definition + The Symfony Application Flow 17 - Your First Controller + Routing Definition 18 - A Symfony2 Project + Your First Controller 19 - Application Kernel + A Symfony2 Project 20 - Application Configuration + Application Kernel 21 - YAML Configuration + Application Configuration 22 - XML Configuration + YAML Configuration 23 - PHP Configuration + XML Configuration 24 - The Rules (Well... My Rules) + PHP Configuration 25 - Environments + The Rules (Well... My Rules) 26 - What Is A Bundle? + Environments 27 - Bundle: Directory Structure + What Is A Bundle? 28 - Bundle: Where To Put Your Classes? + Bundle: Directory Structure 29 - Creating a Bundle + Bundle: Where To Put Your Classes? 30 - The Web Directory + Creating a Bundle 31 - Summary + The Web Directory 32 - Controllers + Summary 33 - Request, Controller, Response + Controllers 34 - The Simplest Page Ever + Request, Controller, Response 35 - Controller Naming Pattern + The Simplest Page Ever 36 - Route Params as Controller Args + Controller Naming Pattern 37 - The Request as a Controller Argument + Route Params as Controller Args 38 - The Base Controller Class + The Request as a Controller Argument 39 - The Response + The Base Controller Class 40 - Routing + The Response 41 - Basic Route Configuration + Routing 42 - Routing with Placeholders (1/2) + Basic Route Configuration 43 - Routing with Placeholders (2/2) + Routing with Placeholders (1/2) 44 - Requirements + Routing with Placeholders (2/2) 45 - Including External Routing Resources + Requirements 46 - Generating URLs + Including External Routing Resources 47 - Templating + Generating URLs 48 - + Templating 49 - Why Twig? + 50 - Getting Familiar With Twig + Why Twig? 51 - Accessing Variables + Getting Familiar With Twig 52 - Control Structure + Accessing Variables 53 - Filters + Control Structure 54 - Including Other Templates + Filters 55 - Template Inheritance (1/2) + Including Other Templates 56 - Template Inheritance (2/2) + Template Inheritance (1/2) 57 - Template Naming and Locations (1/2) + Template Inheritance (2/2) 58 - Template Naming and Locations (2/2) + Template Naming and Locations (1/2) 59 - Overriding Bundle Templates + Template Naming and Locations (2/2) 60 - Overriding Core Templates + Overriding Bundle Templates 61 - The Three-Level Approach + Overriding Core Templates 62 - Twig Into Symfony2 + The Three-Level Approach 63 - Rendering A Template + Twig Into Symfony2 64 - Linking to Pages + Rendering A Template 65 - Linking to Assets + Linking to Pages 66 - Linking To Pages In JavaScript + Linking to Assets 67 - Global Template Variables + Linking To Pages In JavaScript 68 - Service Container + Global Template Variables 69 - What Is A Service? + Service Container 70 - What Is A Service Container? + What Is A Service? 71 - Creating A Service + What Is A Service Container? 72 - Service Parameters + Creating A Service 73 - Injecting Services + Service Parameters 74 - Importing Configuration Resources + Injecting Services 75 - Creating an Extension Class + Importing Configuration Resources 76 - Dealing With Configuration (1/2) + Creating an Extension Class 77 - Dealing With Configuration (2/2) + Dealing With Configuration (1/2) 78 - The Configuration Class (1/2) + Dealing With Configuration (2/2) 79 - The Configuration Class (2/2) + The Configuration Class (1/2) 80 - More On The Service Container + The Configuration Class (2/2) 81 - Symfony2 Commands + More On The Service Container 82 - Built-in Commands (1/2) + Symfony2 Commands 83 - Built-in Commands (2/2) + Built-in Commands (1/2) 84 - Creating Commands + Built-in Commands (2/2) 85 - Command Arguments + Creating Commands 86 - Command Options (1/2) + Command Arguments 87 - Command Options (2/2) + Command Options (1/2) 88 - More On Commands + Command Options (2/2) 89 - Forms + More On Commands 90 - Building Your First Form + Forms 91 - Rendering The Form + Building Your First Form 92 - Handling Forms: The Right Way + Rendering The Form 93 - Handling Form Submissions + Handling Forms: The Right Way 94 - Built-in Form Types + Handling Form Submissions 95 - Creating A Custom Type (Form Class) + Built-in Form Types 96 - Dealing With Objects + Creating A Custom Type (Form Class) 97 - The processForm() Method (1/2) + Dealing With Objects 98 - The processForm() Method (2/2) + The processForm() Method (1/2) 99 - Cross-Site Request Forgery Protection + The processForm() Method (2/2) 100 - Rendering a Form in a Template (1/2) + Cross-Site Request Forgery Protection 101 - Rendering a Form in a Template (2/2) + Rendering a Form in a Template (1/2) 102 - Validation + Rendering a Form in a Template (2/2) 103 - About Form Validation + Validation 104 - The Validator Component + About Form Validation 105 - Using the validator Service + The Validator Component 106 - Constraints + Using the validator Service 107 - Constraint Targets (1/2) + Constraints 108 - Constraint Targets (2/2) + Constraint Targets (1/2) 109 - Validation Groups (1/2) + Constraint Targets (2/2) 110 - Validation Groups (2/2) + Validation Groups (1/2) 111 - Using Validation Groups In Forms + Validation Groups (2/2) 112 - Validating Values and Arrays + Using Validation Groups In Forms 113 - Translations + Validating Values and Arrays 114 - Definitions + Translations 115 - Using the translator Service + Definitions 116 - The Translation Process + Using the translator Service 117 - Locations and Naming Conventions + The Translation Process 118 - Pluralization + Locations and Naming Conventions 119 - Explicit Interval Pluralization + Pluralization 120 - BazingaExposeTranslationBundle + Explicit Interval Pluralization 121 - HTTP Cache + BazingaJsTranslationBundle 122 @@ -8411,101 +8443,107 @@

    Table of Contents

    - Terminology (1/2) + HTTP Cache 124 - Terminology (2/2) + Terminology (1/2) 125 - Caching with a Gateway Cache + Terminology (2/2) 126 - Types of Caches + Caching with a Gateway Cache 127 - HTTP Caching + Types of Caches 128 - Public vs Private Responses + HTTP Caching 129 - Safe Methods + Public vs Private Responses 130 - Expiration + Safe Methods 131 - The Cache-Control Header (1/2) + Expiration 132 - The Cache-Control Header (2/2) + The Cache-Control Header (1/2) 133 - The Expires Header + The Cache-Control Header (2/2) 134 - Validation + The Expires Header 135 - The ETag Header + Validation 136 - The Last-Modified Header (1/2) + The ETag Header 137 - The Last-Modified Header (2/2) + The Last-Modified Header (1/2) 138 - Edge Side Includes (ESI) + The Last-Modified Header (2/2) 139 + + Edge Side Includes (ESI) + 140 + + + From 245b648eb014759b305acfb3a0d9f598938b1cfb Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 1 Jan 2014 19:55:09 +0100 Subject: [PATCH 06/71] Publish slides (Mer 1 jan 2014 19:55:09 CET) --- index.html | 799 +++++++++++++++++++++++++++++++++------------------- index2.html | 477 +++++++++++++++++++++---------- 2 files changed, 842 insertions(+), 434 deletions(-) diff --git a/index.html b/index.html index e853fe4..4cfaa03 100644 --- a/index.html +++ b/index.html @@ -1164,6 +1164,7 @@ .slides .color-red h1 { color: #C82D26; + font-size: 8em !important; } @@ -1588,7 +1589,7 @@ @@ -1616,7 +1617,7 @@ @@ -1667,7 +1668,7 @@ @@ -1705,7 +1706,7 @@

    Week #4

    @@ -1733,7 +1734,7 @@

    Week #4

    @@ -1768,7 +1769,7 @@

    Week #4

    @@ -1804,7 +1805,7 @@

    Week #4

    @@ -1840,7 +1841,7 @@

    Week #4

    @@ -1874,7 +1875,7 @@

    Week #4

    @@ -1909,7 +1910,7 @@

    Week #4

    @@ -1937,7 +1938,7 @@

    Week #4

    @@ -1965,7 +1966,7 @@

    Week #4

    @@ -2003,7 +2004,7 @@

    Week #4

    @@ -2052,7 +2053,7 @@

    Week #4

    @@ -2103,7 +2104,7 @@

    Week #4

    @@ -2146,7 +2147,7 @@

    Abstract class definition

    @@ -2198,7 +2199,7 @@

    Abstract class definition

    @@ -2237,7 +2238,7 @@

    The Rules

    @@ -2290,7 +2291,7 @@

    The Rules

    @@ -2339,7 +2340,7 @@

    Type Hinting

    @@ -2383,7 +2384,7 @@

    Usage

    @@ -2431,7 +2432,7 @@

    Usage

    @@ -2477,7 +2478,7 @@

    Usage

    @@ -2521,7 +2522,7 @@

    Usage

    @@ -2570,7 +2571,7 @@

    Usage

    @@ -2618,7 +2619,7 @@

    PSR-0

    @@ -2665,7 +2666,7 @@

    PSR-0

    @@ -2717,7 +2718,7 @@

    PSR-0

    @@ -2760,7 +2761,7 @@

    PSR-0

    @@ -2806,7 +2807,7 @@

    PSR-0

    @@ -2849,7 +2850,7 @@

    PSR-0

    @@ -2889,7 +2890,7 @@

    PSR-0

    @@ -2917,7 +2918,7 @@

    PSR-0

    @@ -2969,7 +2970,7 @@

    PSR-0

    @@ -3017,7 +3018,7 @@

    PSR-0

    @@ -3069,7 +3070,7 @@

    PSR-0

    @@ -3097,7 +3098,7 @@

    PSR-0

    @@ -3137,7 +3138,7 @@

    PSR-0

    @@ -3182,7 +3183,7 @@

    PSR-0

    @@ -3232,7 +3233,7 @@

    PSR-0

    @@ -3272,7 +3273,7 @@

    PSR-0

    @@ -3316,7 +3317,7 @@

    PSR-0

    @@ -3365,7 +3366,7 @@

    PSR-0

    @@ -3408,7 +3409,7 @@

    PSR-0

    @@ -3436,7 +3437,7 @@

    PSR-0

    @@ -3485,7 +3486,7 @@

    PSR-0

    @@ -3535,7 +3536,7 @@

    PSR-0

    @@ -3582,7 +3583,7 @@

    PSR-0

    @@ -3631,7 +3632,7 @@

    PSR-0

    @@ -3642,7 +3643,7 @@

    PSR-0

    -

    Rethinking The Way We Load Classes

    +

    Rethinking The Way You Load Classes

    PHP 5.2 and upper provides a usable autoloading API with performances close to @@ -3670,7 +3671,7 @@

    spl_autoload_functions()

    @@ -3719,7 +3720,7 @@

    spl_autoload_unregister()

    @@ -3742,7 +3743,7 @@

    spl_autoload_unregister()

    Go on => No - Do we have registered autoload functions? + Do you have registered autoload functions? => Yes Call each function with 'Foo' as parameter until the class gets included @@ -3774,7 +3775,7 @@

    spl_autoload_unregister()

    @@ -3802,7 +3803,7 @@

    spl_autoload_unregister()

    @@ -3847,7 +3848,7 @@

    Traversable

    @@ -3898,7 +3899,7 @@

    Traversable

    @@ -3949,7 +3950,7 @@

    Traversable

    @@ -3990,7 +3991,7 @@

    SPL Functions

    @@ -4043,7 +4044,7 @@

    SPL Functions

    @@ -4092,7 +4093,7 @@

    SPL Functions

    @@ -4141,7 +4142,7 @@

    SPL Functions

    @@ -4181,7 +4182,7 @@

    SPL Functions

    @@ -4189,7 +4190,7 @@

    SPL Functions

    -
    +

    Password Hashing

    @@ -4198,6 +4199,15 @@

    SPL Functions

    The password hashing API provides an easy to use wrapper around crypt() to make it easy to create and manage passwords in a secure manner, since PHP 5.5.0.

    password_hash() and password_verify() are your new friends!

    +
    $passwordHash = password_hash('secret-password', PASSWORD_DEFAULT);
    +
    +if (password_verify('bad-password', $passwordHash)) {
    +    // Correct Password
    +} else {
    +    // Wrong password
    +}
    +
    +

    Read more about the Password Hashing API: http://www.php.net/manual/en/book.password.php.

    @@ -4223,7 +4233,7 @@

    SPL Functions

    @@ -4265,7 +4275,7 @@

    SPL Functions

    @@ -4293,7 +4303,7 @@

    SPL Functions

    @@ -4304,7 +4314,7 @@

    SPL Functions

    -

    Dependency Management

    +

    Composer

    There are a ton of PHP libraries, frameworks, and components to choose from. @@ -4312,16 +4322,15 @@

    SPL Functions

    Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you.

    -

    A lot of PHP libraries are compatible with Composer and listed on -Packagist, the official repository for Composer-compatible -PHP libraries.

    +

    A lot of awesome PHP libraries are +compatible with Composer and listed on Packagist, the +official repository for Composer-compatible PHP libraries.

    $ curl -sS https://getcomposer.org/installer | php
     

    This will download composer.phar (a PHP binary archive).

    -

    Read more about Composer: -http://getcomposer.org/doc/00-intro.md.

    +

    http://getcomposer.org/doc/00-intro.md

    @@ -4338,7 +4347,7 @@

    SPL Functions

    @@ -4349,7 +4358,7 @@

    SPL Functions

    -

    Composer

    +

    composer install

    Create a composer.json file in your project's root directory:

    @@ -4360,19 +4369,62 @@

    SPL Functions

    }
    +

    You can also require a library by using the composer command:

    +
    $ php composer.phar require "willdurand/geocoder:~2.0"
    +
    +

    Run the following command to download and install the project dependencies into a vendor directory:

    $ php composer.phar install
     
    -

    Require the generated autoloader in your project:

    +
    +

    Composer Version +Constraints

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    Composer Autoloader

    + + +

    Composer automatically generates a PSR-0 compliant and optimized autoloader for +your entire application. Thanks to Composer, you don't have to take care about +how to autoload classes/functions anymore.

    +

    Require the generated autoloader in your project as follows:

    <?php
     
     require 'vendor/autoload.php';
     
     // your PHP code
     
    -
    + +
    +

    Must read: Composer Primer.

    +
    @@ -4388,7 +4440,7 @@

    SPL Functions

    @@ -4436,7 +4488,7 @@

    SPL Functions

    @@ -4486,7 +4538,7 @@

    SPL Functions

    @@ -4533,7 +4585,7 @@

    Execution

    @@ -4586,7 +4638,7 @@

    Usage

    @@ -4614,7 +4666,7 @@

    Usage

    @@ -4657,7 +4709,7 @@

    Usage

    @@ -4700,7 +4752,7 @@

    Usage

    @@ -4753,7 +4805,7 @@

    Usage

    @@ -4800,7 +4852,7 @@

    Usage

    @@ -4849,7 +4901,7 @@

    Usage

    @@ -4901,7 +4953,7 @@

    Usage

    @@ -4944,7 +4996,7 @@

    Centralized declaration

    @@ -4977,7 +5029,7 @@

    Centralized declaration

    @@ -5018,7 +5070,7 @@

    Centralized declaration

    @@ -5046,7 +5098,7 @@

    Centralized declaration

    @@ -5081,7 +5133,7 @@

    Centralized declaration

    @@ -5116,7 +5168,7 @@

    Centralized declaration

    @@ -5157,7 +5209,7 @@

    Centralized declaration

    @@ -5185,7 +5237,7 @@

    Centralized declaration

    @@ -5239,7 +5291,7 @@

    Centralized declaration

    @@ -5285,7 +5337,7 @@

    Centralized declaration

    @@ -5332,7 +5384,7 @@

    Centralized declaration

    @@ -5360,7 +5412,7 @@

    Centralized declaration

    @@ -5408,7 +5460,7 @@

    CRUD

    @@ -5455,7 +5507,7 @@

    CRUD

    @@ -5503,7 +5555,7 @@

    CRUD

    @@ -5555,7 +5607,7 @@

    CRUD

    @@ -5600,7 +5652,7 @@

    CRUD

    @@ -5647,7 +5699,7 @@

    CRUD

    @@ -5675,7 +5727,7 @@

    CRUD

    @@ -5722,7 +5774,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5777,7 +5829,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5805,7 +5857,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5858,7 +5910,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5907,7 +5959,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5935,7 +5987,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5982,7 +6034,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6010,7 +6062,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6053,7 +6105,7 @@

    PHP Data Object (PDO)

    @@ -6077,7 +6129,7 @@

    PHP Data Object (PDO)

    $stmt->execute(); -

    Looks like the Connection class we used before, right?

    +

    Looks like the Connection class you used before, right?

    class Connection extends PDO
     {
     }
    @@ -6102,7 +6154,7 @@ 

    Usage

    @@ -6156,7 +6208,7 @@

    Usage

    @@ -6203,7 +6255,7 @@

    Usage

    @@ -6231,7 +6283,7 @@

    Usage

    @@ -6268,7 +6320,7 @@

    Usage

    @@ -6304,7 +6356,7 @@

    Code Snippet

    @@ -6340,7 +6392,7 @@

    Code Snippet

    @@ -6382,7 +6434,7 @@

    Code Snippet

    @@ -6422,7 +6474,7 @@

    Doctrine2 ORM

    @@ -6450,7 +6502,7 @@

    Doctrine2 ORM

    @@ -6492,7 +6544,7 @@

    A few use cases:

    @@ -6541,7 +6593,7 @@

    A few use cases:

    @@ -6582,7 +6634,7 @@

    Workarounds

    @@ -6610,7 +6662,7 @@

    Workarounds

    @@ -6641,7 +6693,7 @@

    Workarounds

    @@ -6671,7 +6723,7 @@

    Workarounds

    @@ -6687,7 +6739,7 @@

    Workarounds

    The Security Layer, as seen before, has to intercept the process of converting a request into a response in order to perform some checks.

    -

    We need a way to hook into this process before invoking the controller: +

    You need a way to hook into this process before invoking the controller: Interceptor Pattern to the rescue!

    The Interceptor Pattern allows you to execute some code during the default application's lifecyle.

    @@ -6712,7 +6764,7 @@

    Event Dispatcher

    @@ -6760,7 +6812,7 @@

    Event Dispatcher

    @@ -6774,8 +6826,8 @@

    Event Dispatcher

    Using the EventDispatcherTrait

    -

    In order to intercept the process described before, we have to notify some -listeners once we enter in the process() method by dispatching the event:

    +

    In order to intercept the process described before, you have to notify some +listeners once you enter in the process() method by dispatching the event:

    class App
     {
         use EventDispatcherTrait;
    @@ -6812,7 +6864,7 @@ 

    Event Dispatcher

    @@ -6823,20 +6875,55 @@

    Event Dispatcher

    -

    The Firewall

    +

    The Firewall (1/2)

    -

    Now that we can hook into the appplication's lifecycle, we need to write a -Firewall. This firewall needs a whitelist of unsecured routes (routes -which don't require the user to be authenticated):

    +

    Now that you can hook into the application's lifecycle, you can to write a basic +but powerful Firewall.

    +

    This firewall needs a whitelist of unsecured routes (i.e. routes that +don't require the user to be authenticated) associated with their allowed HTTP +methods:

    $allowed = [
         '/login'     => [ Request::GET, Request::POST ],
         '/locations' => [ Request::GET ],
     ];
     
    -

    The Firewall leverages the session to determine whether the user is -authenticated:

    +
    +

    Never Blacklist; Only +Whitelist

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    The Firewall (2/2)

    + + +

    The Firewall leverages the session to determine whether the user is +authenticated or not:

    session_start();
     
     if (isset($_SESSION['is_authenticated'])
    @@ -6861,7 +6948,7 @@ 

    Event Dispatcher

    @@ -6918,7 +7005,7 @@

    Event Dispatcher

    @@ -6948,7 +7035,7 @@

    Event Dispatcher

    @@ -7001,7 +7088,7 @@

    Event Dispatcher

    @@ -7037,7 +7124,51 @@

    WSSE Username Token

    + + + + + +
    +
    +
    + +

    Basic Security Thinking

    + + +
      +
    1. Trust nobody and nothing;
    2. +
    3. Assume a worse-case scenario;
    4. +
    5. Apply Defense-In-Depth;
    6. +
    7. Keep It Simple Stupid (KISS);
    8. +
    9. Principle of Least Privilege;
    10. +
    11. Attackers can smell obscurity;
    12. +
    13. RTFM but never trust it;
    14. +
    15. If it wasn’t tested, it doesn’t work;
    16. +
    17. It’s always your fault!
    18. +
    +
    +

    Survive The Deep End: PHP +Security

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7065,7 +7196,7 @@

    WSSE Username Token

    @@ -7102,7 +7233,7 @@

    WSSE Username Token

    @@ -7159,7 +7290,7 @@

    WSSE Username Token

    @@ -7203,7 +7334,7 @@

    Usage

    @@ -7248,7 +7379,7 @@

    Usage

    @@ -7285,7 +7416,7 @@

    Usage

    @@ -7328,7 +7459,7 @@

    Usage

    @@ -7370,7 +7501,7 @@

    Usage

    @@ -7412,7 +7543,7 @@

    Usage

    @@ -7461,7 +7592,7 @@

    Usage

    @@ -7510,7 +7641,7 @@

    Usage

    @@ -7553,7 +7684,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7595,7 +7726,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7636,7 +7767,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7682,7 +7813,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7710,7 +7841,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7744,7 +7875,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7772,7 +7903,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7818,7 +7949,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7866,7 +7997,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7905,7 +8036,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7955,7 +8086,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7983,7 +8114,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8020,7 +8151,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8048,7 +8179,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8091,7 +8222,7 @@

    StoryBDD

    @@ -8137,7 +8268,7 @@

    StoryBDD

    @@ -8185,7 +8316,7 @@

    StoryBDD

    @@ -8238,13 +8369,73 @@

    StoryBDD

    - + +
    +
    +
    + +

    Awesome Projects

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    + + +

    Event-driven, non-blocking I/O with PHP: +http://reactphp.org/.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + +
    @@ -8262,17 +8453,17 @@

    StoryBDD

    - +
    @@ -8290,17 +8481,17 @@

    StoryBDD

    - +
    @@ -8318,17 +8509,17 @@

    StoryBDD

    - +
    @@ -8346,17 +8537,17 @@

    StoryBDD

    - +
    @@ -8386,17 +8577,17 @@

    StoryBDD

    - +
    @@ -8414,17 +8605,17 @@

    StoryBDD

    - +
    @@ -8442,11 +8633,11 @@

    StoryBDD

    @@ -8756,7 +8947,7 @@

    Table of Contents

    - Rethinking The Way We Load Classes + Rethinking The Way You Load Classes 50 @@ -8846,61 +9037,61 @@

    Table of Contents

    - Dependency Management + Composer 65 - Composer + composer install 66 - Example + Composer Autoloader 67 - The Symfony2 Console Component + Example 68 - A Basic Command (1/2) + The Symfony2 Console Component 69 - A Basic Command (2/2) + A Basic Command (1/2) 70 - Model View Controller + A Basic Command (2/2) 71 - MVC Overview + Model View Controller 72 - The Model + MVC Overview 73 - The View + The Model 74 @@ -8918,61 +9109,61 @@

    Table of Contents

    - The Controller + The View 77 - Routing + The Controller 78 - Front Controller Pattern + Routing 79 - Interact With Multiple Services + Front Controller Pattern 80 - Databases + Interact With Multiple Services 81 - Agenda + Databases 82 - Quick note + Agenda 83 - Database Design Patterns + Quick note 84 - Row Data Gateway + Database Design Patterns 85 - Row Data Gateway + Row Data Gateway 86 @@ -8990,13 +9181,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 89 - Table Data Gateway + Table Data Gateway 90 @@ -9032,13 +9223,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 96 - Active Record + Active Record 97 @@ -9050,13 +9241,13 @@

    Table of Contents

    - Data Mapper + Active Record 99 - Data Mapper + Data Mapper 100 @@ -9068,31 +9259,31 @@

    Table of Contents

    - Identity Map + Data Mapper 102 - Identity Map + Identity Map 103 - Data Access Layer + Identity Map 104 - Data Access Layer / Data Source Name + Data Access Layer 105 - Data Access Layer + Data Access Layer / Data Source Name 106 @@ -9110,181 +9301,181 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 109 - Object Relational Mapping (1/4) + Object Relational Mapping 110 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 111 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 112 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 113 - Existing Components + Object Relational Mapping (4/4) 114 - Sessions + Existing Components 115 - Overview + Sessions 116 - Code Please + Overview 117 - Security Concerns + Code Please 118 - Authentication + Security Concerns 119 - What You Have Right Now + Authentication 120 - The Big Picture + What You Have Right Now 121 - The Interceptor Pattern + The Big Picture 122 - Introducing the Event Dispatcher + The Interceptor Pattern 123 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 124 - The Firewall + Using the EventDispatcherTrait 125 - Implementing The Firewall + The Firewall (1/2) 126 - Authentication Mechanism + The Firewall (2/2) 127 - Adding New Routes + Implementing The Firewall 128 - Stateless Authentication + Authentication Mechanism 129 - Writing Better Code + Adding New Routes 130 - Agenda + Stateless Authentication 131 - Coding Standards + Basic Security Thinking 132 - PHP Coding Standards Fixer + Writing Better Code 133 - Programming To The Interface + Agenda 134 - Component Driven Development + Coding Standards 135 - Dependency Injection + PHP Coding Standards Fixer 136 - Dependency Injection + Programming To The Interface 137 - Dependency Injection + Component Driven Development 138 @@ -9296,161 +9487,191 @@

    Table of Contents

    - PHP Implementations + Dependency Injection 140 - PHP Implementations + Dependency Injection 141 - From STUPID to SOLID code! (1/2) + Dependency Injection 142 - From STUPID to SOLID code! (2/2) + PHP Implementations 143 - Object Calisthenics + PHP Implementations 144 - Testing + From STUPID to SOLID code! (1/2) 145 - Agenda + From STUPID to SOLID code! (2/2) 146 - Unit Testing + Object Calisthenics 147 - Unit Testing + Testing 148 - PHPUnit — The Rules + Agenda 149 - PHPUnit — Assertions + Unit Testing 150 - Running PHPUnit + Unit Testing 151 - Functional Testing + PHPUnit — The Rules 152 - Functional Testing + PHPUnit — Assertions 153 - Behavior Driven Development + Running PHPUnit 154 - Behavior Driven Development + Functional Testing 155 - Behat + Functional Testing 156 - Using Behat (1/2) + Behavior Driven Development 157 - Using Behat (2/2) + Behavior Driven Development 158 - Embracing Open Source + Behat 159 - + Using Behat (1/2) 160 - + Using Behat (2/2) 161 - + Awesome Projects 162 - Golden Rules + 163 - The End. + Embracing Open Source 164 - Well... Maybe Not.
    PHP Extended + 165 + + + 166 + + + + + + 167 + + + + + Golden Rules + 168 + + + + + The End. + 169 + + + + + Well... Maybe Not.
    PHP Extended + 170 + + +
    diff --git a/index2.html b/index2.html index 74e574b..da0359c 100644 --- a/index2.html +++ b/index2.html @@ -1164,6 +1164,7 @@ .slides .color-red h1 { color: #C82D26; + font-size: 8em !important; } @@ -1588,7 +1589,7 @@
    @@ -1616,7 +1617,7 @@
    @@ -1630,10 +1631,20 @@

    Agenda

    -

    Symfony2

    -

    Controllers, Templating, Dependency Injection, Command Line, Forms, Validation, -Translation, HTTP Cache

    -

    Stack PHP

    +
      +
    • Symfony
        +
      • Controllers
      • +
      • Templating
      • +
      • Dependency Injection
      • +
      • Command Line
      • +
      • Forms
      • +
      • Validation
      • +
      • Translation
      • +
      • HTTP Cache
      • +
      +
    • +
    • Stack PHP
    • +
    @@ -1649,7 +1660,7 @@
    @@ -1691,7 +1702,7 @@
    @@ -1719,7 +1730,7 @@
    @@ -1761,7 +1772,7 @@
    @@ -1789,7 +1800,7 @@
    @@ -1817,7 +1828,7 @@ @@ -1855,7 +1866,7 @@ @@ -1899,7 +1910,7 @@ @@ -1948,7 +1959,7 @@ @@ -1991,7 +2002,7 @@ @@ -2019,7 +2030,7 @@ @@ -2071,7 +2082,7 @@ @@ -2121,7 +2132,7 @@ @@ -2168,7 +2179,7 @@ @@ -2200,7 +2211,7 @@ @@ -2246,7 +2257,7 @@ @@ -2292,7 +2303,7 @@ @@ -2342,7 +2353,7 @@ @@ -2395,7 +2406,7 @@ @@ -2434,7 +2445,7 @@ @@ -2482,7 +2493,7 @@ @@ -2529,7 +2540,7 @@ @@ -2579,7 +2590,7 @@ @@ -2630,7 +2641,7 @@ @@ -2679,7 +2690,7 @@ @@ -2727,7 +2738,7 @@ @@ -2776,7 +2787,7 @@ @@ -2855,7 +2866,7 @@ @@ -2908,7 +2919,7 @@ @@ -2956,7 +2967,7 @@ @@ -2997,7 +3008,7 @@ @@ -3025,7 +3036,7 @@ @@ -3068,7 +3079,7 @@ @@ -3119,7 +3130,7 @@

    Controller Implementation

    @@ -3162,7 +3173,7 @@

    Controller Implementation

    @@ -3214,7 +3225,7 @@

    Controller Implementation

    @@ -3259,7 +3270,7 @@

    Controller Implementation

    @@ -3309,7 +3320,7 @@

    Rendering Templates

    @@ -3356,7 +3367,7 @@

    Rendering Templates

    @@ -3384,7 +3395,7 @@

    Rendering Templates

    @@ -3428,7 +3439,7 @@

    Rendering Templates

    @@ -3467,7 +3478,7 @@

    Rendering Templates

    @@ -3505,7 +3516,7 @@

    Rendering Templates

    @@ -3552,7 +3563,7 @@

    HTTP Method Requirements

    @@ -3599,7 +3610,7 @@

    Prefixing Imported Routes

    @@ -3649,7 +3660,7 @@

    Query String

    @@ -3677,7 +3688,7 @@

    Query String

    @@ -3705,7 +3716,7 @@

    Query String

    @@ -3755,7 +3766,7 @@

    After

    @@ -3794,7 +3805,7 @@

    After

    @@ -3844,7 +3855,7 @@

    After

    @@ -3893,7 +3904,7 @@

    Loops

    @@ -3940,7 +3951,7 @@

    Loops

    @@ -3991,7 +4002,7 @@

    Example

    @@ -4044,7 +4055,7 @@

    Example

    @@ -4093,7 +4104,7 @@

    Example

    @@ -4136,7 +4147,7 @@

    Example

    @@ -4181,7 +4192,7 @@

    Example

    @@ -4220,7 +4231,7 @@

    Example

    @@ -4252,7 +4263,7 @@

    Example

    @@ -4299,7 +4310,7 @@

    Example

    @@ -4327,7 +4338,7 @@

    Example

    @@ -4376,7 +4387,7 @@

    Using the Templating Service

    @@ -4427,7 +4438,7 @@

    Using the Templating Service

    @@ -4477,7 +4488,7 @@

    Cache Busting

    @@ -4527,7 +4538,7 @@

    Cache Busting

    @@ -4564,7 +4575,7 @@

    Cache Busting

    @@ -4592,7 +4603,7 @@

    Cache Busting

    @@ -4628,7 +4639,7 @@

    Cache Busting

    @@ -4662,7 +4673,7 @@

    Cache Busting

    @@ -4715,7 +4726,7 @@

    Cache Busting

    @@ -4730,7 +4741,7 @@

    Cache Busting

    The service definition described before is not flexible enough. For instance, -we never configure the $debug argument.

    +$debug argument is never configured.

    Parameters make defining services more organized and flexible:

    <parameters>
         <parameter key="my_bundle.foo.class">My\Bundle\Foo</parameter>
    @@ -4763,7 +4774,7 @@ 

    Cache Busting

    @@ -4816,7 +4827,7 @@

    Optional Dependencies: Setter Injection

    @@ -4860,7 +4871,7 @@

    Container Extensions

    @@ -4912,7 +4923,7 @@

    Container Extensions

    @@ -4962,7 +4973,7 @@

    Container Extensions

    @@ -5007,7 +5018,7 @@

    Container Extensions

    @@ -5060,7 +5071,7 @@

    Container Extensions

    @@ -5107,7 +5118,7 @@

    Container Extensions

    @@ -5155,7 +5166,7 @@

    Debugging Services

    @@ -5183,7 +5194,7 @@

    Debugging Services

    @@ -5232,7 +5243,7 @@

    Global Options

    @@ -5287,7 +5298,7 @@

    Global Options

    @@ -5341,7 +5352,7 @@

    Global Options

    @@ -5393,7 +5404,7 @@

    Usage

    @@ -5445,7 +5456,7 @@

    Usage

    @@ -5495,7 +5506,7 @@

    Usage

    @@ -5548,7 +5559,7 @@

    Calling an existing Command

    @@ -5576,7 +5587,7 @@

    Calling an existing Command

    @@ -5622,7 +5633,7 @@

    Calling an existing Command

    @@ -5661,7 +5672,7 @@

    Calling an existing Command

    @@ -5708,7 +5719,7 @@

    Calling an existing Command

    @@ -5761,7 +5772,7 @@

    Calling an existing Command

    @@ -5792,7 +5803,7 @@

    Calling an existing Command

    @@ -5849,7 +5860,7 @@

    Calling an existing Command

    @@ -5900,7 +5911,7 @@

    Calling an existing Command

    @@ -5951,7 +5962,7 @@

    Calling an existing Command

    @@ -6005,7 +6016,7 @@

    Calling an existing Command

    @@ -6044,7 +6055,7 @@

    Calling an existing Command

    @@ -6092,7 +6103,7 @@

    Calling an existing Command

    @@ -6140,7 +6151,7 @@

    Calling an existing Command

    @@ -6168,7 +6179,7 @@

    Calling an existing Command

    @@ -6204,7 +6215,7 @@

    Calling an existing Command

    @@ -6253,7 +6264,7 @@

    Example

    @@ -6303,7 +6314,7 @@

    Example

    @@ -6336,7 +6347,7 @@

    Example

    @@ -6382,7 +6393,7 @@

    Classes

    @@ -6430,7 +6441,7 @@

    Classes

    @@ -6477,7 +6488,7 @@

    Example

    @@ -6516,7 +6527,7 @@

    Example

    @@ -6566,7 +6577,7 @@

    Example

    @@ -6616,7 +6627,7 @@

    Example

    @@ -6644,7 +6655,7 @@

    Example

    @@ -6683,7 +6694,7 @@

    Localization

    @@ -6733,7 +6744,7 @@

    Message Placeholders

    @@ -6781,7 +6792,7 @@

    Message Placeholders

    @@ -6824,7 +6835,7 @@

    Message Placeholders

    @@ -6869,7 +6880,7 @@

    Message Placeholders

    @@ -6916,7 +6927,7 @@

    Message Placeholders

    @@ -6972,7 +6983,7 @@

    Message Placeholders

    @@ -7000,7 +7011,7 @@

    Message Placeholders

    @@ -7035,7 +7046,7 @@

    Message Placeholders

    @@ -7075,7 +7086,7 @@

    HTTP Cache

    @@ -7112,7 +7123,7 @@

    Edge Side Includes

    @@ -7154,7 +7165,7 @@

    Edge Side Includes

    @@ -7196,7 +7207,7 @@

    Edge Side Includes

    @@ -7232,7 +7243,7 @@

    Edge Side Includes

    @@ -7274,7 +7285,7 @@

    Edge Side Includes

    @@ -7316,7 +7327,7 @@

    Edge Side Includes

    @@ -7354,7 +7365,7 @@

    Edge Side Includes

    @@ -7390,7 +7401,7 @@

    Edge Side Includes

    @@ -7436,7 +7447,7 @@

    Edge Side Includes

    @@ -7479,7 +7490,7 @@

    Edge Side Includes

    @@ -7516,7 +7527,7 @@

    Edge Side Includes

    @@ -7564,7 +7575,7 @@

    Edge Side Includes

    @@ -7599,7 +7610,7 @@

    Edge Side Includes

    @@ -7652,7 +7663,7 @@

    Edge Side Includes

    @@ -7689,7 +7700,159 @@

    Edge Side Includes

    + + + + + +
    +
    +
    + +

    Stack PHP

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    HttpKernel

    + + +


    +
    +

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is Stack?

    + + +

    A convention for composing HttpKernelInterface middlewares:

    +

    +
    +

    http://stackphp.com/

    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Implementation

    + + +
    use Symfony\Component\HttpFoundation\Request;
    +use Symfony\Component\HttpKernel\HttpKernelInterface;
    +
    +class MyStackMiddleware implements HttpKernelInterface
    +{
    +    private $app;
    +
    +    public function __construct(HttpKernelInterface $app)
    +    {
    +        $this->app = $app;
    +    }
    +
    +    /**
    +     * {@inheritDoc}
    +     */
    +    public function handle(
    +        Request $request,
    +        $type = HttpKernelInterface::MASTER_REQUEST,
    +        $catch = true
    +    ) {
    +        // do something awesome
    +
    +        return $this->app->handle($request, $type, $catch);
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -8544,6 +8707,30 @@

    Table of Contents

    + + Stack PHP + 141 + + + + + HttpKernel + 142 + + + + + What Is Stack? + 143 + + + + + Implementation + 144 + + +
    From 202b7773ec846ce12c852e2a57517960bc47bad7 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 1 Jan 2014 19:58:46 +0100 Subject: [PATCH 07/71] Publish slides (Mer 1 jan 2014 19:58:45 CET) --- index.html | 1 + index2.html | 1 + 2 files changed, 2 insertions(+) diff --git a/index.html b/index.html index 4cfaa03..612f404 100644 --- a/index.html +++ b/index.html @@ -9725,5 +9725,6 @@

    Help

    $().landslide(); $('.page_number').toggle(); + Fork me on GitHub \ No newline at end of file diff --git a/index2.html b/index2.html index da0359c..550e781 100644 --- a/index2.html +++ b/index2.html @@ -8784,5 +8784,6 @@

    Help

    $().landslide(); $('.page_number').toggle(); + Fork me on GitHub \ No newline at end of file From c98802bac3a860c60f702a4a04e6ae7b9a6d67e5 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 1 Jan 2014 20:01:21 +0100 Subject: [PATCH 08/71] Publish slides (Mer 1 jan 2014 20:01:21 CET) --- index.html | 2 +- index2.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 612f404..19e19c0 100644 --- a/index.html +++ b/index.html @@ -9725,6 +9725,6 @@

    Help

    $().landslide(); $('.page_number').toggle(); - Fork me on GitHub + Fork me on GitHub \ No newline at end of file diff --git a/index2.html b/index2.html index 550e781..28e7f38 100644 --- a/index2.html +++ b/index2.html @@ -8784,6 +8784,6 @@

    Help

    $().landslide(); $('.page_number').toggle(); - Fork me on GitHub + Fork me on GitHub \ No newline at end of file From 9bb79c0a8dabfcbbbad2456675e0cc963dfce2af Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 1 Jan 2014 21:11:34 +0100 Subject: [PATCH 09/71] Publish slides (Mer 1 jan 2014 21:11:34 CET) --- index.html | 664 ++++++++++++++++++++++++++++------------------------- 1 file changed, 349 insertions(+), 315 deletions(-) diff --git a/index.html b/index.html index 19e19c0..33703fd 100644 --- a/index.html +++ b/index.html @@ -1589,7 +1589,7 @@ @@ -1617,7 +1617,7 @@ @@ -1668,7 +1668,35 @@ + + + + + +
    +
    +
    + +

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -1706,7 +1734,7 @@

    Week #4

    @@ -1734,7 +1762,7 @@

    Week #4

    @@ -1769,7 +1797,7 @@

    Week #4

    @@ -1805,7 +1833,7 @@

    Week #4

    @@ -1841,7 +1869,7 @@

    Week #4

    @@ -1875,7 +1903,7 @@

    Week #4

    @@ -1910,7 +1938,7 @@

    Week #4

    @@ -1938,7 +1966,7 @@

    Week #4

    @@ -1966,7 +1994,7 @@

    Week #4

    @@ -2004,7 +2032,7 @@

    Week #4

    @@ -2053,7 +2081,7 @@

    Week #4

    @@ -2104,7 +2132,7 @@

    Week #4

    @@ -2147,7 +2175,7 @@

    Abstract class definition

    @@ -2199,7 +2227,7 @@

    Abstract class definition

    @@ -2238,7 +2266,7 @@

    The Rules

    @@ -2291,7 +2319,7 @@

    The Rules

    @@ -2340,7 +2368,7 @@

    Type Hinting

    @@ -2384,7 +2412,7 @@

    Usage

    @@ -2432,7 +2460,7 @@

    Usage

    @@ -2478,7 +2506,7 @@

    Usage

    @@ -2522,7 +2550,7 @@

    Usage

    @@ -2571,7 +2599,7 @@

    Usage

    @@ -2619,7 +2647,7 @@

    PSR-0

    @@ -2666,7 +2694,7 @@

    PSR-0

    @@ -2718,7 +2746,7 @@

    PSR-0

    @@ -2761,7 +2789,7 @@

    PSR-0

    @@ -2807,7 +2835,7 @@

    PSR-0

    @@ -2850,7 +2878,7 @@

    PSR-0

    @@ -2890,7 +2918,7 @@

    PSR-0

    @@ -2918,7 +2946,7 @@

    PSR-0

    @@ -2970,7 +2998,7 @@

    PSR-0

    @@ -3018,7 +3046,7 @@

    PSR-0

    @@ -3070,7 +3098,7 @@

    PSR-0

    @@ -3098,7 +3126,7 @@

    PSR-0

    @@ -3138,7 +3166,7 @@

    PSR-0

    @@ -3183,7 +3211,7 @@

    PSR-0

    @@ -3233,7 +3261,7 @@

    PSR-0

    @@ -3273,7 +3301,7 @@

    PSR-0

    @@ -3317,7 +3345,7 @@

    PSR-0

    @@ -3366,7 +3394,7 @@

    PSR-0

    @@ -3409,7 +3437,7 @@

    PSR-0

    @@ -3437,7 +3465,7 @@

    PSR-0

    @@ -3486,7 +3514,7 @@

    PSR-0

    @@ -3536,7 +3564,7 @@

    PSR-0

    @@ -3583,7 +3611,7 @@

    PSR-0

    @@ -3632,7 +3660,7 @@

    PSR-0

    @@ -3671,7 +3699,7 @@

    spl_autoload_functions()

    @@ -3720,7 +3748,7 @@

    spl_autoload_unregister()

    @@ -3775,7 +3803,7 @@

    spl_autoload_unregister()

    @@ -3803,7 +3831,7 @@

    spl_autoload_unregister()

    @@ -3848,7 +3876,7 @@

    Traversable

    @@ -3899,7 +3927,7 @@

    Traversable

    @@ -3950,7 +3978,7 @@

    Traversable

    @@ -3991,7 +4019,7 @@

    SPL Functions

    @@ -4044,7 +4072,7 @@

    SPL Functions

    @@ -4093,7 +4121,7 @@

    SPL Functions

    @@ -4142,7 +4170,7 @@

    SPL Functions

    @@ -4182,7 +4210,7 @@

    SPL Functions

    @@ -4233,7 +4261,7 @@

    SPL Functions

    @@ -4275,7 +4303,7 @@

    SPL Functions

    @@ -4303,7 +4331,7 @@

    SPL Functions

    @@ -4347,7 +4375,7 @@

    SPL Functions

    @@ -4397,7 +4425,7 @@

    SPL Functions

    @@ -4440,7 +4468,7 @@

    SPL Functions

    @@ -4488,7 +4516,7 @@

    SPL Functions

    @@ -4538,7 +4566,7 @@

    SPL Functions

    @@ -4585,7 +4613,7 @@

    Execution

    @@ -4638,7 +4666,7 @@

    Usage

    @@ -4666,7 +4694,7 @@

    Usage

    @@ -4709,7 +4737,7 @@

    Usage

    @@ -4752,7 +4780,7 @@

    Usage

    @@ -4805,7 +4833,7 @@

    Usage

    @@ -4852,7 +4880,7 @@

    Usage

    @@ -4901,7 +4929,7 @@

    Usage

    @@ -4953,7 +4981,7 @@

    Usage

    @@ -4996,7 +5024,7 @@

    Centralized declaration

    @@ -5029,7 +5057,7 @@

    Centralized declaration

    @@ -5070,7 +5098,7 @@

    Centralized declaration

    @@ -5098,7 +5126,7 @@

    Centralized declaration

    @@ -5133,7 +5161,7 @@

    Centralized declaration

    @@ -5168,7 +5196,7 @@

    Centralized declaration

    @@ -5209,7 +5237,7 @@

    Centralized declaration

    @@ -5237,7 +5265,7 @@

    Centralized declaration

    @@ -5291,7 +5319,7 @@

    Centralized declaration

    @@ -5337,7 +5365,7 @@

    Centralized declaration

    @@ -5384,7 +5412,7 @@

    Centralized declaration

    @@ -5412,7 +5440,7 @@

    Centralized declaration

    @@ -5460,7 +5488,7 @@

    CRUD

    @@ -5507,7 +5535,7 @@

    CRUD

    @@ -5555,7 +5583,7 @@

    CRUD

    @@ -5607,7 +5635,7 @@

    CRUD

    @@ -5652,7 +5680,7 @@

    CRUD

    @@ -5699,7 +5727,7 @@

    CRUD

    @@ -5727,7 +5755,7 @@

    CRUD

    @@ -5774,7 +5802,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5829,7 +5857,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5857,7 +5885,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5910,7 +5938,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5959,7 +5987,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5987,7 +6015,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6034,7 +6062,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6062,7 +6090,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6105,7 +6133,7 @@

    PHP Data Object (PDO)

    @@ -6154,7 +6182,7 @@

    Usage

    @@ -6208,7 +6236,7 @@

    Usage

    @@ -6255,7 +6283,7 @@

    Usage

    @@ -6283,7 +6311,7 @@

    Usage

    @@ -6320,7 +6348,7 @@

    Usage

    @@ -6356,7 +6384,7 @@

    Code Snippet

    @@ -6392,7 +6420,7 @@

    Code Snippet

    @@ -6434,7 +6462,7 @@

    Code Snippet

    @@ -6474,7 +6502,7 @@

    Doctrine2 ORM

    @@ -6502,7 +6530,7 @@

    Doctrine2 ORM

    @@ -6544,7 +6572,7 @@

    A few use cases:

    @@ -6593,7 +6621,7 @@

    A few use cases:

    @@ -6634,7 +6662,7 @@

    Workarounds

    @@ -6662,7 +6690,7 @@

    Workarounds

    @@ -6693,7 +6721,7 @@

    Workarounds

    @@ -6723,7 +6751,7 @@

    Workarounds

    @@ -6764,7 +6792,7 @@

    Event Dispatcher

    @@ -6812,7 +6840,7 @@

    Event Dispatcher

    @@ -6864,7 +6892,7 @@

    Event Dispatcher

    @@ -6908,7 +6936,7 @@

    Event Dispatcher

    @@ -6948,7 +6976,7 @@

    Event Dispatcher

    @@ -7005,7 +7033,7 @@

    Event Dispatcher

    @@ -7035,7 +7063,7 @@

    Event Dispatcher

    @@ -7088,7 +7116,7 @@

    Event Dispatcher

    @@ -7124,7 +7152,7 @@

    WSSE Username Token

    @@ -7168,7 +7196,7 @@

    WSSE Username Token

    @@ -7196,7 +7224,7 @@

    WSSE Username Token

    @@ -7233,7 +7261,7 @@

    WSSE Username Token

    @@ -7290,7 +7318,7 @@

    WSSE Username Token

    @@ -7334,7 +7362,7 @@

    Usage

    @@ -7379,7 +7407,7 @@

    Usage

    @@ -7416,7 +7444,7 @@

    Usage

    @@ -7459,7 +7487,7 @@

    Usage

    @@ -7501,7 +7529,7 @@

    Usage

    @@ -7543,7 +7571,7 @@

    Usage

    @@ -7592,7 +7620,7 @@

    Usage

    @@ -7641,7 +7669,7 @@

    Usage

    @@ -7684,7 +7712,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7726,7 +7754,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7767,7 +7795,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7813,7 +7841,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7841,7 +7869,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7875,7 +7903,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7903,7 +7931,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7949,7 +7977,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7997,7 +8025,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8036,7 +8064,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8086,7 +8114,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8114,7 +8142,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8151,7 +8179,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8179,7 +8207,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8222,7 +8250,7 @@

    StoryBDD

    @@ -8268,7 +8296,7 @@

    StoryBDD

    @@ -8316,7 +8344,7 @@

    StoryBDD

    @@ -8369,7 +8397,7 @@

    StoryBDD

    @@ -8397,7 +8425,7 @@

    StoryBDD

    @@ -8429,7 +8457,7 @@

    StoryBDD

    @@ -8457,7 +8485,7 @@

    StoryBDD

    @@ -8485,7 +8513,7 @@

    StoryBDD

    @@ -8513,7 +8541,7 @@

    StoryBDD

    @@ -8541,7 +8569,7 @@

    StoryBDD

    @@ -8581,7 +8609,7 @@

    StoryBDD

    @@ -8609,7 +8637,7 @@

    StoryBDD

    @@ -8637,7 +8665,7 @@

    StoryBDD

    @@ -8671,25 +8699,25 @@

    Table of Contents

    - Agenda + 4 - PHP: Hypertext Preprocessor + Agenda 5 - History & Numbers + PHP: Hypertext Preprocessor 6 - Getting Started + History & Numbers 7 @@ -8707,397 +8735,397 @@

    Table of Contents

    - HHVM + Getting Started 10 - RTFM: http://www.php.net + HHVM 11 - The PHP Syntax + RTFM: http://www.php.net 12 - Primitive Types + The PHP Syntax 13 - Comparison Operators + Primitive Types 14 - Operators + Comparison Operators 15 - Classes (1/2) + Operators 16 - Classes (2/2) + Classes (1/2) 17 - Visibility + Classes (2/2) 18 - Attributes + Visibility 19 - Methods (1/3) + Attributes 20 - Methods (2/3) + Methods (1/3) 21 - Methods (3/3) + Methods (2/3) 22 - Static Keyword (1/2) + Methods (3/3) 23 - Static Keyword (2/2) + Static Keyword (1/2) 24 - Interfaces + Static Keyword (2/2) 25 - Namespaces + Interfaces 26 - The class Keyword + Namespaces 27 - Traits + The class Keyword 28 - Anonymous Functions + Traits 29 - Closures + Anonymous Functions 30 - Magic Methods + Closures 31 - Generators + Magic Methods 32 - The PHP Command Line + Generators 33 - The PHP Command Line (1/2) + The PHP Command Line 34 - The PHP Command Line (2/2) + The PHP Command Line (1/2) 35 - Writing a CLI program + The PHP Command Line (2/2) 36 - Client/Server + Writing a CLI program 37 - Client/Server Basics + Client/Server 38 - HTTP Request + Client/Server Basics 39 - HTTP Response + HTTP Request 40 - HTTP Verbs + HTTP Response 41 - HTTP Parameters (1/2) + HTTP Verbs 42 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 43 - REST (REpresentational State Transfer) + HTTP Parameters (2/2) 44 - PHP Autoloading + REST (REpresentational State Transfer) 45 - Why Is It Necessary? + PHP Autoloading 46 - The require() Way + Why Is It Necessary? 47 - The require_once() Way + The require() Way 48 - Working With Multiple Files + The require_once() Way 49 - Rethinking The Way You Load Classes + Working With Multiple Files 50 - Examples + Rethinking The Way You Load Classes 51 - Under The Hood + Examples 52 - Leveraging PHP APIs + Under The Hood 53 - Built-in Interfaces + Leveraging PHP APIs 54 - The Reflection API (1/2) + Built-in Interfaces 55 - The Reflection API (2/2) + The Reflection API (1/2) 56 - The Standard PHP Library (SPL) + The Reflection API (2/2) 57 - Observer/Observable (1/2) + The Standard PHP Library (SPL) 58 - Observer/Observable (2/2) + Observer/Observable (1/2) 59 - Exceptions (1/2) + Observer/Observable (2/2) 60 - Exceptions (2/2) + Exceptions (1/2) 61 - Password Hashing + Exceptions (2/2) 62 - PHP Archive (PHAR) + Password Hashing 63 - Dependency Management in PHP + PHP Archive (PHAR) 64 - Composer + Dependency Management in PHP 65 - composer install + Composer 66 - Composer Autoloader + composer install 67 - Example + Composer Autoloader 68 - The Symfony2 Console Component + Example 69 - A Basic Command (1/2) + The Symfony2 Console Component 70 - A Basic Command (2/2) + A Basic Command (1/2) 71 - Model View Controller + A Basic Command (2/2) 72 - MVC Overview + Model View Controller 73 - The Model + MVC Overview 74 - The View + The Model 75 @@ -9115,61 +9143,61 @@

    Table of Contents

    - The Controller + The View 78 - Routing + The Controller 79 - Front Controller Pattern + Routing 80 - Interact With Multiple Services + Front Controller Pattern 81 - Databases + Interact With Multiple Services 82 - Agenda + Databases 83 - Quick note + Agenda 84 - Database Design Patterns + Quick note 85 - Row Data Gateway + Database Design Patterns 86 - Row Data Gateway + Row Data Gateway 87 @@ -9187,13 +9215,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 90 - Table Data Gateway + Table Data Gateway 91 @@ -9229,13 +9257,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 97 - Active Record + Active Record 98 @@ -9247,13 +9275,13 @@

    Table of Contents

    - Data Mapper + Active Record 100 - Data Mapper + Data Mapper 101 @@ -9265,31 +9293,31 @@

    Table of Contents

    - Identity Map + Data Mapper 103 - Identity Map + Identity Map 104 - Data Access Layer + Identity Map 105 - Data Access Layer / Data Source Name + Data Access Layer 106 - Data Access Layer + Data Access Layer / Data Source Name 107 @@ -9307,181 +9335,181 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 110 - Object Relational Mapping (1/4) + Object Relational Mapping 111 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 112 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 113 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 114 - Existing Components + Object Relational Mapping (4/4) 115 - Sessions + Existing Components 116 - Overview + Sessions 117 - Code Please + Overview 118 - Security Concerns + Code Please 119 - Authentication + Security Concerns 120 - What You Have Right Now + Authentication 121 - The Big Picture + What You Have Right Now 122 - The Interceptor Pattern + The Big Picture 123 - Introducing the Event Dispatcher + The Interceptor Pattern 124 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 125 - The Firewall (1/2) + Using the EventDispatcherTrait 126 - The Firewall (2/2) + The Firewall (1/2) 127 - Implementing The Firewall + The Firewall (2/2) 128 - Authentication Mechanism + Implementing The Firewall 129 - Adding New Routes + Authentication Mechanism 130 - Stateless Authentication + Adding New Routes 131 - Basic Security Thinking + Stateless Authentication 132 - Writing Better Code + Basic Security Thinking 133 - Agenda + Writing Better Code 134 - Coding Standards + Agenda 135 - PHP Coding Standards Fixer + Coding Standards 136 - Programming To The Interface + PHP Coding Standards Fixer 137 - Component Driven Development + Programming To The Interface 138 - Dependency Injection + Component Driven Development 139 @@ -9505,7 +9533,7 @@

    Table of Contents

    - PHP Implementations + Dependency Injection 143 @@ -9517,37 +9545,37 @@

    Table of Contents

    - From STUPID to SOLID code! (1/2) + PHP Implementations 145 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 146 - Object Calisthenics + From STUPID to SOLID code! (2/2) 147 - Testing + Object Calisthenics 148 - Agenda + Testing 149 - Unit Testing + Agenda 150 @@ -9559,25 +9587,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 152 - PHPUnit — Assertions + PHPUnit — The Rules 153 - Running PHPUnit + PHPUnit — Assertions 154 - Functional Testing + Running PHPUnit 155 @@ -9589,7 +9617,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 157 @@ -9601,77 +9629,83 @@

    Table of Contents

    - Behat + Behavior Driven Development 159 - Using Behat (1/2) + Behat 160 - Using Behat (2/2) + Using Behat (1/2) 161 - Awesome Projects + Using Behat (2/2) 162 - + Awesome Projects 163 - Embracing Open Source + 164 - + Embracing Open Source 165 - + 166 - + 167 - Golden Rules + 168 - The End. + Golden Rules 169 - Well... Maybe Not.
    PHP Extended + The End. 170 + + Well... Maybe Not.
    PHP Extended + 171 + + + From 1d5662f2f02244de293a2b77591b84c2c5e280ca Mon Sep 17 00:00:00 2001 From: William DURAND Date: Fri, 3 Jan 2014 17:22:27 +0100 Subject: [PATCH 10/71] Publish slides (Ven 3 jan 2014 17:22:27 CET) --- index.html | 803 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 496 insertions(+), 307 deletions(-) diff --git a/index.html b/index.html index 33703fd..4cc7567 100644 --- a/index.html +++ b/index.html @@ -1589,7 +1589,7 @@ @@ -1617,7 +1617,7 @@ @@ -1668,7 +1668,7 @@ @@ -1696,7 +1696,7 @@ @@ -1734,7 +1734,7 @@

    Week #4

    @@ -1762,7 +1762,7 @@

    Week #4

    @@ -1797,7 +1797,7 @@

    Week #4

    @@ -1833,7 +1833,7 @@

    Week #4

    @@ -1869,7 +1869,7 @@

    Week #4

    @@ -1903,7 +1903,7 @@

    Week #4

    @@ -1938,7 +1938,7 @@

    Week #4

    @@ -1966,7 +1966,7 @@

    Week #4

    @@ -1994,7 +1994,7 @@

    Week #4

    @@ -2032,7 +2032,7 @@

    Week #4

    @@ -2081,7 +2081,7 @@

    Week #4

    @@ -2132,7 +2132,7 @@

    Week #4

    @@ -2175,7 +2175,7 @@

    Abstract class definition

    @@ -2227,7 +2227,7 @@

    Abstract class definition

    @@ -2266,7 +2266,7 @@

    The Rules

    @@ -2319,7 +2319,7 @@

    The Rules

    @@ -2368,7 +2368,7 @@

    Type Hinting

    @@ -2412,7 +2412,7 @@

    Usage

    @@ -2460,7 +2460,7 @@

    Usage

    @@ -2506,7 +2506,7 @@

    Usage

    @@ -2550,7 +2550,7 @@

    Usage

    @@ -2599,7 +2599,7 @@

    Usage

    @@ -2647,7 +2647,7 @@

    PSR-0

    @@ -2694,7 +2694,7 @@

    PSR-0

    @@ -2746,7 +2746,7 @@

    PSR-0

    @@ -2789,7 +2789,7 @@

    PSR-0

    @@ -2835,7 +2835,7 @@

    PSR-0

    @@ -2878,7 +2878,7 @@

    PSR-0

    @@ -2918,7 +2918,7 @@

    PSR-0

    @@ -2946,7 +2946,7 @@

    PSR-0

    @@ -2998,7 +2998,7 @@

    PSR-0

    @@ -3046,7 +3046,7 @@

    PSR-0

    @@ -3098,7 +3098,7 @@

    PSR-0

    @@ -3126,7 +3126,7 @@

    PSR-0

    @@ -3166,7 +3166,7 @@

    PSR-0

    @@ -3211,7 +3211,7 @@

    PSR-0

    @@ -3261,7 +3261,7 @@

    PSR-0

    @@ -3301,7 +3301,7 @@

    PSR-0

    @@ -3328,8 +3328,7 @@

    PSR-0

  • query string: $_SERVER['QUERY_STRING'];
  • request body: $HTTP_RAW_POST_DATA.
  • -

    Note: Don't use $_REQUEST, as there is a collision risk!

    -

    Also, never trust user input, never!

    +

    Note: Don't use $_REQUEST, as there is a collision risk!

    @@ -3345,7 +3344,7 @@

    PSR-0

    @@ -3378,7 +3377,8 @@

    PSR-0

    $HTTP_RAW_POST_DATA = "b=3&city=paris"; -
    + +

    Important: never trust user input, never!

    @@ -3394,7 +3394,7 @@

    PSR-0

    @@ -3408,20 +3408,185 @@

    PSR-0

    REST (REpresentational State Transfer)

    -

    Each URI represents a unique resource that can be formatted as requested in -json, xml, or html.

    +

    REST is the underlying architectural principle of the web.

    +

    An API that adheres to the principles of REST does not require the client to +know anything about the structure of the API. +Rather, the server needs to provide whatever information the client needs to +interact with the service.

    + + +
    +

    Notes

    +
    + +
    +
    + + + + + +
    +
    +
    + +

    Unified Resource Identifier

    + + +
      +
    • URIs identify resources;
    • +
    • URIs are format independent;
    • +
    • URI "file extensions" != RESTful.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Media Types

    + + +
      +
    • Identifies a representation format;
    • +
    • Custom types use application/vnd.[XYZ];
    • +
    • Used inside the Accept / Content-Type headers.
    • +
    + + + + + + + + + + + +
    HeaderDescription
    `Content-Type`HTTP message format
    `Accept`HTTP response format preference
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Content Type Negotiation

    + + +

    Content Type Negotiation is the principle to find appropriate response formats.

    +

    No standardized algorithm available, even if the Apache +mod_negotiation +algorithm is documented. This also covers encoding (Accept-Encoding) and +language (Accept-Language) negotiation.

    +
    Accept: application/json, application/xml;q=0.9, text/html;q=0.8,
    +    text/*;q=0.7, */*;q=0.5
    +
    + + + + + + + + + + + + + +
    PriorityMime Type
    `q=1.0``application/json`
    `q=0.9``application/xml`
    `q=0.8``text/html`
    `q=0.7``text/*` (ie. any text)
    `q=0.5``*/*` (ie. any media type)
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Examples

    + + +

    Resources

      -
    • /bananas/joe: URI for banana "Joe";
    • -
    • /bananas/henry: URI for banana "Henry".
    • +
    • /bananas/joe: URI for banana "Joe"
    • +
    • /bananas/henry: URI for banana "Henry"
    -

    Those resources are organized into collections:

    +

    Collections

      -
    • /bananas: collection of all available bananas.
    • +
    • /bananas: collection of all available bananas
    -

    So it makes sense to use HTTP verbs to execute an action:

    -

    GET /banana/joe will return banana "Joe".

    -

    and:

    -

    DELETE /bananas will delete all bananas in the collection!

    +

    Actions

    +
      +
    • GET /banana/joe will return banana "Joe"
    • +
    • DELETE /bananas will delete all bananas in the collection!
    • +
    @@ -3437,7 +3602,7 @@

    PSR-0

    @@ -3465,7 +3630,7 @@

    PSR-0

    @@ -3514,7 +3679,7 @@

    PSR-0

    @@ -3564,7 +3729,7 @@

    PSR-0

    @@ -3611,7 +3776,7 @@

    PSR-0

    @@ -3660,7 +3825,7 @@

    PSR-0

    @@ -3699,7 +3864,7 @@

    spl_autoload_functions()

    @@ -3748,7 +3913,7 @@

    spl_autoload_unregister()

    @@ -3803,7 +3968,7 @@

    spl_autoload_unregister()

    @@ -3831,7 +3996,7 @@

    spl_autoload_unregister()

    @@ -3876,7 +4041,7 @@

    Traversable

    @@ -3927,7 +4092,7 @@

    Traversable

    @@ -3978,7 +4143,7 @@

    Traversable

    @@ -4019,7 +4184,7 @@

    SPL Functions

    @@ -4072,7 +4237,7 @@

    SPL Functions

    @@ -4121,7 +4286,7 @@

    SPL Functions

    @@ -4170,7 +4335,7 @@

    SPL Functions

    @@ -4210,7 +4375,7 @@

    SPL Functions

    @@ -4261,7 +4426,7 @@

    SPL Functions

    @@ -4303,7 +4468,7 @@

    SPL Functions

    @@ -4331,7 +4496,7 @@

    SPL Functions

    @@ -4375,7 +4540,7 @@

    SPL Functions

    @@ -4425,7 +4590,7 @@

    SPL Functions

    @@ -4468,7 +4633,7 @@

    SPL Functions

    @@ -4516,7 +4681,7 @@

    SPL Functions

    @@ -4566,7 +4731,7 @@

    SPL Functions

    @@ -4613,7 +4778,7 @@

    Execution

    @@ -4666,7 +4831,7 @@

    Usage

    @@ -4694,7 +4859,7 @@

    Usage

    @@ -4737,7 +4902,7 @@

    Usage

    @@ -4780,7 +4945,7 @@

    Usage

    @@ -4833,7 +4998,7 @@

    Usage

    @@ -4880,7 +5045,7 @@

    Usage

    @@ -4929,7 +5094,7 @@

    Usage

    @@ -4981,7 +5146,7 @@

    Usage

    @@ -5024,7 +5189,7 @@

    Centralized declaration

    @@ -5057,7 +5222,7 @@

    Centralized declaration

    @@ -5098,7 +5263,7 @@

    Centralized declaration

    @@ -5126,7 +5291,7 @@

    Centralized declaration

    @@ -5161,7 +5326,7 @@

    Centralized declaration

    @@ -5196,7 +5361,7 @@

    Centralized declaration

    @@ -5237,7 +5402,7 @@

    Centralized declaration

    @@ -5265,7 +5430,7 @@

    Centralized declaration

    @@ -5319,7 +5484,7 @@

    Centralized declaration

    @@ -5365,7 +5530,7 @@

    Centralized declaration

    @@ -5412,7 +5577,7 @@

    Centralized declaration

    @@ -5440,7 +5605,7 @@

    Centralized declaration

    @@ -5488,7 +5653,7 @@

    CRUD

    @@ -5535,7 +5700,7 @@

    CRUD

    @@ -5583,7 +5748,7 @@

    CRUD

    @@ -5635,7 +5800,7 @@

    CRUD

    @@ -5680,7 +5845,7 @@

    CRUD

    @@ -5727,7 +5892,7 @@

    CRUD

    @@ -5755,7 +5920,7 @@

    CRUD

    @@ -5802,7 +5967,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5857,7 +6022,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5885,7 +6050,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5938,7 +6103,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5987,7 +6152,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6015,7 +6180,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6062,7 +6227,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6090,7 +6255,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6133,7 +6298,7 @@

    PHP Data Object (PDO)

    @@ -6182,7 +6347,7 @@

    Usage

    @@ -6236,7 +6401,7 @@

    Usage

    @@ -6283,7 +6448,7 @@

    Usage

    @@ -6311,7 +6476,7 @@

    Usage

    @@ -6348,7 +6513,7 @@

    Usage

    @@ -6384,7 +6549,7 @@

    Code Snippet

    @@ -6420,7 +6585,7 @@

    Code Snippet

    @@ -6462,7 +6627,7 @@

    Code Snippet

    @@ -6502,7 +6667,7 @@

    Doctrine2 ORM

    @@ -6530,7 +6695,7 @@

    Doctrine2 ORM

    @@ -6572,7 +6737,7 @@

    A few use cases:

    @@ -6621,7 +6786,7 @@

    A few use cases:

    @@ -6662,7 +6827,7 @@

    Workarounds

    @@ -6690,7 +6855,7 @@

    Workarounds

    @@ -6721,7 +6886,7 @@

    Workarounds

    @@ -6751,7 +6916,7 @@

    Workarounds

    @@ -6792,7 +6957,7 @@

    Event Dispatcher

    @@ -6840,7 +7005,7 @@

    Event Dispatcher

    @@ -6892,7 +7057,7 @@

    Event Dispatcher

    @@ -6936,7 +7101,7 @@

    Event Dispatcher

    @@ -6976,7 +7141,7 @@

    Event Dispatcher

    @@ -7033,7 +7198,7 @@

    Event Dispatcher

    @@ -7063,7 +7228,7 @@

    Event Dispatcher

    @@ -7116,7 +7281,7 @@

    Event Dispatcher

    @@ -7152,7 +7317,7 @@

    WSSE Username Token

    @@ -7196,7 +7361,7 @@

    WSSE Username Token

    @@ -7224,7 +7389,7 @@

    WSSE Username Token

    @@ -7261,7 +7426,7 @@

    WSSE Username Token

    @@ -7318,7 +7483,7 @@

    WSSE Username Token

    @@ -7362,7 +7527,7 @@

    Usage

    @@ -7407,7 +7572,7 @@

    Usage

    @@ -7444,7 +7609,7 @@

    Usage

    @@ -7487,7 +7652,7 @@

    Usage

    @@ -7529,7 +7694,7 @@

    Usage

    @@ -7571,7 +7736,7 @@

    Usage

    @@ -7620,7 +7785,7 @@

    Usage

    @@ -7669,7 +7834,7 @@

    Usage

    @@ -7712,7 +7877,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7754,7 +7919,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7795,7 +7960,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7841,7 +8006,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7869,7 +8034,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7903,7 +8068,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7931,7 +8096,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7977,7 +8142,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8025,7 +8190,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8064,7 +8229,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8114,7 +8279,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8142,7 +8307,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8179,7 +8344,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8207,7 +8372,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8250,7 +8415,7 @@

    StoryBDD

    @@ -8296,7 +8461,7 @@

    StoryBDD

    @@ -8344,7 +8509,7 @@

    StoryBDD

    @@ -8397,7 +8562,7 @@

    StoryBDD

    @@ -8425,7 +8590,7 @@

    StoryBDD

    @@ -8457,7 +8622,7 @@

    StoryBDD

    @@ -8485,7 +8650,7 @@

    StoryBDD

    @@ -8513,7 +8678,7 @@

    StoryBDD

    @@ -8541,7 +8706,7 @@

    StoryBDD

    @@ -8569,7 +8734,7 @@

    StoryBDD

    @@ -8609,7 +8774,7 @@

    StoryBDD

    @@ -8637,7 +8802,7 @@

    StoryBDD

    @@ -8665,7 +8830,7 @@

    StoryBDD

    @@ -8951,301 +9116,301 @@

    Table of Contents

    - PHP Autoloading + Unified Resource Identifier 46 - Why Is It Necessary? + Media Types 47 - The require() Way + Content Type Negotiation 48 - The require_once() Way + Examples 49 - Working With Multiple Files + PHP Autoloading 50 - Rethinking The Way You Load Classes + Why Is It Necessary? 51 - Examples + The require() Way 52 - Under The Hood + The require_once() Way 53 - Leveraging PHP APIs + Working With Multiple Files 54 - Built-in Interfaces + Rethinking The Way You Load Classes 55 - The Reflection API (1/2) + Examples 56 - The Reflection API (2/2) + Under The Hood 57 - The Standard PHP Library (SPL) + Leveraging PHP APIs 58 - Observer/Observable (1/2) + Built-in Interfaces 59 - Observer/Observable (2/2) + The Reflection API (1/2) 60 - Exceptions (1/2) + The Reflection API (2/2) 61 - Exceptions (2/2) + The Standard PHP Library (SPL) 62 - Password Hashing + Observer/Observable (1/2) 63 - PHP Archive (PHAR) + Observer/Observable (2/2) 64 - Dependency Management in PHP + Exceptions (1/2) 65 - Composer + Exceptions (2/2) 66 - composer install + Password Hashing 67 - Composer Autoloader + PHP Archive (PHAR) 68 - Example + Dependency Management in PHP 69 - The Symfony2 Console Component + Composer 70 - A Basic Command (1/2) + composer install 71 - A Basic Command (2/2) + Composer Autoloader 72 - Model View Controller + Example 73 - MVC Overview + The Symfony2 Console Component 74 - The Model + A Basic Command (1/2) 75 - The View + A Basic Command (2/2) 76 - The View + Model View Controller 77 - The View + MVC Overview 78 - The Controller + The Model 79 - Routing + The View 80 - Front Controller Pattern + The View 81 - Interact With Multiple Services + The View 82 - Databases + The Controller 83 - Agenda + Routing 84 - Quick note + Front Controller Pattern 85 - Database Design Patterns + Interact With Multiple Services 86 - Row Data Gateway + Databases 87 - Row Data Gateway + Agenda 88 - Row Data Gateway + Quick note 89 - Row Data Gateway + Database Design Patterns 90 - Table Data Gateway + Row Data Gateway 91 - Table Data Gateway + Row Data Gateway 92 - Table Data Gateway + Row Data Gateway 93 - Table Data Gateway + Row Data Gateway 94 - Table Data Gateway + Table Data Gateway 95 @@ -9263,73 +9428,73 @@

    Table of Contents

    - Active Record + Table Data Gateway 98 - Active Record + Table Data Gateway 99 - Active Record + Table Data Gateway 100 - Data Mapper + Table Data Gateway 101 - Data Mapper + Active Record 102 - Data Mapper + Active Record 103 - Identity Map + Active Record 104 - Identity Map + Data Mapper 105 - Data Access Layer + Data Mapper 106 - Data Access Layer / Data Source Name + Data Mapper 107 - Data Access Layer + Identity Map 108 - Data Access Layer + Identity Map 109 @@ -9341,371 +9506,395 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer / Data Source Name 111 - Object Relational Mapping (1/4) + Data Access Layer 112 - Object Relational Mapping (2/4) + Data Access Layer 113 - Object Relational Mapping (3/4) + Data Access Layer 114 - Object Relational Mapping (4/4) + Object Relational Mapping 115 - Existing Components + Object Relational Mapping (1/4) 116 - Sessions + Object Relational Mapping (2/4) 117 - Overview + Object Relational Mapping (3/4) 118 - Code Please + Object Relational Mapping (4/4) 119 - Security Concerns + Existing Components 120 - Authentication + Sessions 121 - What You Have Right Now + Overview 122 - The Big Picture + Code Please 123 - The Interceptor Pattern + Security Concerns 124 - Introducing the Event Dispatcher + Authentication 125 - Using the EventDispatcherTrait + What You Have Right Now 126 - The Firewall (1/2) + The Big Picture 127 - The Firewall (2/2) + The Interceptor Pattern 128 - Implementing The Firewall + Introducing the Event Dispatcher 129 - Authentication Mechanism + Using the EventDispatcherTrait 130 - Adding New Routes + The Firewall (1/2) 131 - Stateless Authentication + The Firewall (2/2) 132 - Basic Security Thinking + Implementing The Firewall 133 - Writing Better Code + Authentication Mechanism 134 - Agenda + Adding New Routes 135 - Coding Standards + Stateless Authentication 136 - PHP Coding Standards Fixer + Basic Security Thinking 137 - Programming To The Interface + Writing Better Code 138 - Component Driven Development + Agenda 139 - Dependency Injection + Coding Standards 140 - Dependency Injection + PHP Coding Standards Fixer 141 - Dependency Injection + Programming To The Interface 142 - Dependency Injection + Component Driven Development 143 - PHP Implementations + Dependency Injection 144 - PHP Implementations + Dependency Injection 145 - From STUPID to SOLID code! (1/2) + Dependency Injection 146 - From STUPID to SOLID code! (2/2) + Dependency Injection 147 - Object Calisthenics + PHP Implementations 148 - Testing + PHP Implementations 149 - Agenda + From STUPID to SOLID code! (1/2) 150 - Unit Testing + From STUPID to SOLID code! (2/2) 151 - Unit Testing + Object Calisthenics 152 - PHPUnit — The Rules + Testing 153 - PHPUnit — Assertions + Agenda 154 - Running PHPUnit + Unit Testing 155 - Functional Testing + Unit Testing 156 - Functional Testing + PHPUnit — The Rules 157 - Behavior Driven Development + PHPUnit — Assertions 158 - Behavior Driven Development + Running PHPUnit 159 - Behat + Functional Testing 160 - Using Behat (1/2) + Functional Testing 161 - Using Behat (2/2) + Behavior Driven Development 162 - Awesome Projects + Behavior Driven Development 163 - + Behat 164 - Embracing Open Source + Using Behat (1/2) 165 - + Using Behat (2/2) 166 - + Awesome Projects 167 - + 168 - Golden Rules + Embracing Open Source 169 - The End. + 170 - Well... Maybe Not.
    PHP Extended + 171 + + + 172 + + + + + Golden Rules + 173 + + + + + The End. + 174 + + + + + Well... Maybe Not.
    PHP Extended + 175 + + + From 152c18ec81438049299fee4e7027366c7c10580d Mon Sep 17 00:00:00 2001 From: William DURAND Date: Sat, 4 Jan 2014 01:49:59 +0100 Subject: [PATCH 11/71] Publish slides (Sam 4 jan 2014 01:49:59 CET) --- index.html | 769 ++++++++++++++++++++++++++++++---------------------- index2.html | 4 + 2 files changed, 443 insertions(+), 330 deletions(-) diff --git a/index.html b/index.html index 4cc7567..c234b74 100644 --- a/index.html +++ b/index.html @@ -1167,6 +1167,10 @@ font-size: 8em !important; } +table { + margin-bottom: 3%; +} + @@ -1589,7 +1593,7 @@ @@ -1617,7 +1621,7 @@ @@ -1668,7 +1672,7 @@ @@ -1696,7 +1700,7 @@ @@ -1734,7 +1738,7 @@

    Week #4

    @@ -1762,7 +1766,7 @@

    Week #4

    @@ -1797,7 +1801,7 @@

    Week #4

    @@ -1833,7 +1837,7 @@

    Week #4

    @@ -1869,7 +1873,7 @@

    Week #4

    @@ -1903,7 +1907,7 @@

    Week #4

    @@ -1938,7 +1942,7 @@

    Week #4

    @@ -1966,7 +1970,7 @@

    Week #4

    @@ -1994,7 +1998,7 @@

    Week #4

    @@ -2032,7 +2036,7 @@

    Week #4

    @@ -2081,7 +2085,7 @@

    Week #4

    @@ -2132,7 +2136,7 @@

    Week #4

    @@ -2175,7 +2179,7 @@

    Abstract class definition

    @@ -2227,7 +2231,7 @@

    Abstract class definition

    @@ -2266,7 +2270,7 @@

    The Rules

    @@ -2319,7 +2323,7 @@

    The Rules

    @@ -2368,7 +2372,7 @@

    Type Hinting

    @@ -2412,7 +2416,7 @@

    Usage

    @@ -2460,7 +2464,7 @@

    Usage

    @@ -2506,7 +2510,7 @@

    Usage

    @@ -2550,7 +2554,7 @@

    Usage

    @@ -2599,7 +2603,7 @@

    Usage

    @@ -2647,7 +2651,7 @@

    PSR-0

    @@ -2694,7 +2698,7 @@

    PSR-0

    @@ -2746,7 +2750,7 @@

    PSR-0

    @@ -2789,7 +2793,7 @@

    PSR-0

    @@ -2835,7 +2839,7 @@

    PSR-0

    @@ -2878,7 +2882,7 @@

    PSR-0

    @@ -2918,7 +2922,7 @@

    PSR-0

    @@ -2946,7 +2950,7 @@

    PSR-0

    @@ -2998,7 +3002,7 @@

    PSR-0

    @@ -3046,7 +3050,7 @@

    PSR-0

    @@ -3098,7 +3102,7 @@

    PSR-0

    @@ -3126,7 +3130,7 @@

    PSR-0

    @@ -3166,7 +3170,51 @@

    PSR-0

    + + + + + +
    +
    +
    + +

    Unified Resource Identifier (URI)

    + + +

    In A Nutshell

    +
      +
    • URIs identify resources;
    • +
    • URIs are format independent;
    • +
    • URI "file extensions" != RESTful.
    • +
    +

    Resources

    +
      +
    • /bananas/joe: URI for banana "Joe"
    • +
    • /bananas/henry: URI for banana "Henry"
    • +
    +

    Collections

    +
      +
    • /bananas: collection of all available bananas
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3211,7 +3259,7 @@

    PSR-0

    @@ -3261,7 +3309,7 @@

    PSR-0

    @@ -3301,7 +3349,7 @@

    PSR-0

    @@ -3344,7 +3392,7 @@

    PSR-0

    @@ -3394,7 +3442,7 @@

    PSR-0

    @@ -3408,11 +3456,18 @@

    PSR-0

    REST (REpresentational State Transfer)

    -

    REST is the underlying architectural principle of the web.

    -

    An API that adheres to the principles of REST does not require the client to -know anything about the structure of the API. +

    REST is the underlying architectural principle of the web, formalized as a set +of constraints, described in Roy Fielding's dissertation.

    +

    An API (i.e. a web service) that adheres to the principles of REST does not +require the client to know anything about the structure of this API. Rather, the server needs to provide whatever information the client needs to -interact with the service.

    +interact with the service.

    +

    The key abstraction of information in REST is a resource. Any information +that can be named can be a resource, and is identified by a Unified Resource +Identifier (URI).

    +
    +

    It heavily relies on the HTTP protocol: RFC 2616.

    +
    @@ -3428,7 +3483,7 @@

    PSR-0

    @@ -3439,14 +3494,12 @@

    PSR-0

    -

    Unified Resource Identifier

    +

    Richardson Maturity Model

    -
      -
    • URIs identify resources;
    • -
    • URIs are format independent;
    • -
    • URI "file extensions" != RESTful.
    • -
    +


    +
    +

    @@ -3462,7 +3515,35 @@

    PSR-0

    + +
    +
    + + +
    +
    +
    + +

    Level 3 = Content Negotiation + HATEOAS

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3476,7 +3557,8 @@

    PSR-0

    Media Types

    -
      +

      In A Nutshell

      +
      • Identifies a representation format;
      • Custom types use application/vnd.[XYZ];
      • Used inside the Accept / Content-Type headers.
      • @@ -3492,7 +3574,12 @@

        PSR-0

        `Content-Type`HTTP message format `Accept`HTTP response format preference -
      + + +

      Hyper Media Types

      +

      Hyper Media Types are MIME media types that contain native hyper-linking +semantics that induce application flow: application/hal+json, +application/collection+json, etc.

    @@ -3508,7 +3595,7 @@

    PSR-0

    @@ -3522,7 +3609,8 @@

    PSR-0

    Content Type Negotiation

    -

    Content Type Negotiation is the principle to find appropriate response formats.

    +

    Content Type Negotiation is the principle of finding appropriate response +formats based on client requirements.

    No standardized algorithm available, even if the Apache mod_negotiation algorithm is documented. This also covers encoding (Accept-Encoding) and @@ -3559,7 +3647,7 @@

    PSR-0

    @@ -3567,26 +3655,35 @@

    PSR-0

    -
    +
    -

    Examples

    +

    HATEOAS

    -

    Resources

    -
      -
    • /bananas/joe: URI for banana "Joe"
    • -
    • /bananas/henry: URI for banana "Henry"
    • -
    -

    Collections

    -
      -
    • /bananas: collection of all available bananas
    • -
    -

    Actions

    -
      -
    • GET /banana/joe will return banana "Joe"
    • -
    • DELETE /bananas will delete all bananas in the collection!
    • -
    +

    HATEOAS stands for Hypertext As The Engine Of +Application State. It means that hypertext should be used to find your +way through the API.

    +

    It is all about state transitions. Your application is just a big state +machine. +There should be a single endpoint for the resource, and all of the other +actions you would need to undertake should be able to be discovered by +inspecting that resource.

    +
    <?xml version="1.0" encoding="UTF-8"?>
    +<collection page="1" limit="10" pages="1">
    +    <user id="123"></user>
    +    <user id="456"></user>
    +
    +    <link rel="self" href="/api/users?page=1&amp;limit=10" />
    +    <link rel="first" href="/api/users?page=1&amp;limit=10" />
    +    <link rel="last" href="/api/users?page=1&amp;limit=10" />
    +</collection>
    +
    + +
    +

    Must read: Haters gonna +HATEOAS.

    +
    @@ -3602,7 +3699,7 @@

    Actions

    @@ -3630,7 +3727,7 @@

    Actions

    @@ -3679,7 +3776,7 @@

    Actions

    @@ -3729,7 +3826,7 @@

    Actions

    @@ -3776,7 +3873,7 @@

    Actions

    @@ -3825,7 +3922,7 @@

    Actions

    @@ -3864,7 +3961,7 @@

    spl_autoload_functions()

    @@ -3913,7 +4010,7 @@

    spl_autoload_unregister()

    @@ -3968,7 +4065,7 @@

    spl_autoload_unregister()

    @@ -3996,7 +4093,7 @@

    spl_autoload_unregister()

    @@ -4041,7 +4138,7 @@

    Traversable

    @@ -4092,7 +4189,7 @@

    Traversable

    @@ -4143,7 +4240,7 @@

    Traversable

    @@ -4184,7 +4281,7 @@

    SPL Functions

    @@ -4237,7 +4334,7 @@

    SPL Functions

    @@ -4286,7 +4383,7 @@

    SPL Functions

    @@ -4335,7 +4432,7 @@

    SPL Functions

    @@ -4375,7 +4472,7 @@

    SPL Functions

    @@ -4426,7 +4523,7 @@

    SPL Functions

    @@ -4468,7 +4565,7 @@

    SPL Functions

    @@ -4496,7 +4593,7 @@

    SPL Functions

    @@ -4540,7 +4637,7 @@

    SPL Functions

    @@ -4590,7 +4687,7 @@

    SPL Functions

    @@ -4633,7 +4730,7 @@

    SPL Functions

    @@ -4681,7 +4778,7 @@

    SPL Functions

    @@ -4731,7 +4828,7 @@

    SPL Functions

    @@ -4778,7 +4875,7 @@

    Execution

    @@ -4831,7 +4928,7 @@

    Usage

    @@ -4859,7 +4956,7 @@

    Usage

    @@ -4902,7 +4999,7 @@

    Usage

    @@ -4945,7 +5042,7 @@

    Usage

    @@ -4998,7 +5095,7 @@

    Usage

    @@ -5045,7 +5142,7 @@

    Usage

    @@ -5094,7 +5191,7 @@

    Usage

    @@ -5146,7 +5243,7 @@

    Usage

    @@ -5189,7 +5286,7 @@

    Centralized declaration

    @@ -5222,7 +5319,7 @@

    Centralized declaration

    @@ -5263,7 +5360,7 @@

    Centralized declaration

    @@ -5291,7 +5388,7 @@

    Centralized declaration

    @@ -5326,7 +5423,7 @@

    Centralized declaration

    @@ -5361,7 +5458,7 @@

    Centralized declaration

    @@ -5402,7 +5499,7 @@

    Centralized declaration

    @@ -5430,7 +5527,7 @@

    Centralized declaration

    @@ -5484,7 +5581,7 @@

    Centralized declaration

    @@ -5530,7 +5627,7 @@

    Centralized declaration

    @@ -5577,7 +5674,7 @@

    Centralized declaration

    @@ -5605,7 +5702,7 @@

    Centralized declaration

    @@ -5653,7 +5750,7 @@

    CRUD

    @@ -5700,7 +5797,7 @@

    CRUD

    @@ -5748,7 +5845,7 @@

    CRUD

    @@ -5800,7 +5897,7 @@

    CRUD

    @@ -5845,7 +5942,7 @@

    CRUD

    @@ -5892,7 +5989,7 @@

    CRUD

    @@ -5920,7 +6017,7 @@

    CRUD

    @@ -5967,7 +6064,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6022,7 +6119,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6050,7 +6147,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6103,7 +6200,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6152,7 +6249,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6180,7 +6277,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6227,7 +6324,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6255,7 +6352,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6298,7 +6395,7 @@

    PHP Data Object (PDO)

    @@ -6347,7 +6444,7 @@

    Usage

    @@ -6401,7 +6498,7 @@

    Usage

    @@ -6448,7 +6545,7 @@

    Usage

    @@ -6476,7 +6573,7 @@

    Usage

    @@ -6513,7 +6610,7 @@

    Usage

    @@ -6549,7 +6646,7 @@

    Code Snippet

    @@ -6585,7 +6682,7 @@

    Code Snippet

    @@ -6627,7 +6724,7 @@

    Code Snippet

    @@ -6667,7 +6764,7 @@

    Doctrine2 ORM

    @@ -6695,7 +6792,7 @@

    Doctrine2 ORM

    @@ -6737,7 +6834,7 @@

    A few use cases:

    @@ -6786,7 +6883,7 @@

    A few use cases:

    @@ -6827,7 +6924,7 @@

    Workarounds

    @@ -6855,7 +6952,7 @@

    Workarounds

    @@ -6886,7 +6983,7 @@

    Workarounds

    @@ -6916,7 +7013,7 @@

    Workarounds

    @@ -6957,7 +7054,7 @@

    Event Dispatcher

    @@ -7005,7 +7102,7 @@

    Event Dispatcher

    @@ -7057,7 +7154,7 @@

    Event Dispatcher

    @@ -7101,7 +7198,7 @@

    Event Dispatcher

    @@ -7141,7 +7238,7 @@

    Event Dispatcher

    @@ -7198,7 +7295,7 @@

    Event Dispatcher

    @@ -7228,7 +7325,7 @@

    Event Dispatcher

    @@ -7281,7 +7378,7 @@

    Event Dispatcher

    @@ -7317,7 +7414,7 @@

    WSSE Username Token

    @@ -7361,7 +7458,7 @@

    WSSE Username Token

    @@ -7389,7 +7486,7 @@

    WSSE Username Token

    @@ -7426,7 +7523,7 @@

    WSSE Username Token

    @@ -7483,7 +7580,7 @@

    WSSE Username Token

    @@ -7527,7 +7624,7 @@

    Usage

    @@ -7572,7 +7669,7 @@

    Usage

    @@ -7609,7 +7706,7 @@

    Usage

    @@ -7652,7 +7749,7 @@

    Usage

    @@ -7694,7 +7791,7 @@

    Usage

    @@ -7736,7 +7833,7 @@

    Usage

    @@ -7785,7 +7882,7 @@

    Usage

    @@ -7834,7 +7931,7 @@

    Usage

    @@ -7877,7 +7974,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7919,7 +8016,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7960,7 +8057,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8006,7 +8103,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8034,7 +8131,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8068,7 +8165,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8096,7 +8193,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8142,7 +8239,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8190,7 +8287,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8229,7 +8326,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8279,7 +8376,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8307,7 +8404,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8344,7 +8441,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8372,7 +8469,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8415,7 +8512,7 @@

    StoryBDD

    @@ -8461,7 +8558,7 @@

    StoryBDD

    @@ -8509,7 +8606,7 @@

    StoryBDD

    @@ -8562,7 +8659,7 @@

    StoryBDD

    @@ -8590,7 +8687,7 @@

    StoryBDD

    @@ -8622,7 +8719,7 @@

    StoryBDD

    @@ -8650,7 +8747,7 @@

    StoryBDD

    @@ -8678,7 +8775,7 @@

    StoryBDD

    @@ -8706,7 +8803,7 @@

    StoryBDD

    @@ -8734,7 +8831,7 @@

    StoryBDD

    @@ -8774,7 +8871,7 @@

    StoryBDD

    @@ -8802,7 +8899,7 @@

    StoryBDD

    @@ -8830,7 +8927,7 @@

    StoryBDD

    @@ -9080,253 +9177,253 @@

    Table of Contents

    - HTTP Request + Unified Resource Identifier (URI) 40 - HTTP Response + HTTP Request 41 - HTTP Verbs + HTTP Response 42 - HTTP Parameters (1/2) + HTTP Verbs 43 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 44 - REST (REpresentational State Transfer) + HTTP Parameters (2/2) 45 - Unified Resource Identifier + REST (REpresentational State Transfer) 46 - Media Types + Richardson Maturity Model 47 - Content Type Negotiation + Level 3 = Content Negotiation + HATEOAS 48 - Examples + Media Types 49 - PHP Autoloading + Content Type Negotiation 50 - Why Is It Necessary? + HATEOAS 51 - The require() Way + PHP Autoloading 52 - The require_once() Way + Why Is It Necessary? 53 - Working With Multiple Files + The require() Way 54 - Rethinking The Way You Load Classes + The require_once() Way 55 - Examples + Working With Multiple Files 56 - Under The Hood + Rethinking The Way You Load Classes 57 - Leveraging PHP APIs + Examples 58 - Built-in Interfaces + Under The Hood 59 - The Reflection API (1/2) + Leveraging PHP APIs 60 - The Reflection API (2/2) + Built-in Interfaces 61 - The Standard PHP Library (SPL) + The Reflection API (1/2) 62 - Observer/Observable (1/2) + The Reflection API (2/2) 63 - Observer/Observable (2/2) + The Standard PHP Library (SPL) 64 - Exceptions (1/2) + Observer/Observable (1/2) 65 - Exceptions (2/2) + Observer/Observable (2/2) 66 - Password Hashing + Exceptions (1/2) 67 - PHP Archive (PHAR) + Exceptions (2/2) 68 - Dependency Management in PHP + Password Hashing 69 - Composer + PHP Archive (PHAR) 70 - composer install + Dependency Management in PHP 71 - Composer Autoloader + Composer 72 - Example + composer install 73 - The Symfony2 Console Component + Composer Autoloader 74 - A Basic Command (1/2) + Example 75 - A Basic Command (2/2) + The Symfony2 Console Component 76 - Model View Controller + A Basic Command (1/2) 77 - MVC Overview + A Basic Command (2/2) 78 - The Model + Model View Controller 79 - The View + MVC Overview 80 - The View + The Model 81 @@ -9338,67 +9435,67 @@

    Table of Contents

    - The Controller + The View 83 - Routing + The View 84 - Front Controller Pattern + The Controller 85 - Interact With Multiple Services + Routing 86 - Databases + Front Controller Pattern 87 - Agenda + Interact With Multiple Services 88 - Quick note + Databases 89 - Database Design Patterns + Agenda 90 - Row Data Gateway + Quick note 91 - Row Data Gateway + Database Design Patterns 92 - Row Data Gateway + Row Data Gateway 93 @@ -9410,19 +9507,19 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 95 - Table Data Gateway + Row Data Gateway 96 - Table Data Gateway + Table Data Gateway 97 @@ -9452,61 +9549,61 @@

    Table of Contents

    - Active Record + Table Data Gateway 102 - Active Record + Table Data Gateway 103 - Active Record + Active Record 104 - Data Mapper + Active Record 105 - Data Mapper + Active Record 106 - Data Mapper + Data Mapper 107 - Identity Map + Data Mapper 108 - Identity Map + Data Mapper 109 - Data Access Layer + Identity Map 110 - Data Access Layer / Data Source Name + Identity Map 111 @@ -9518,7 +9615,7 @@

    Table of Contents

    - Data Access Layer + Data Access Layer / Data Source Name 113 @@ -9530,187 +9627,187 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 115 - Object Relational Mapping (1/4) + Data Access Layer 116 - Object Relational Mapping (2/4) + Object Relational Mapping 117 - Object Relational Mapping (3/4) + Object Relational Mapping (1/4) 118 - Object Relational Mapping (4/4) + Object Relational Mapping (2/4) 119 - Existing Components + Object Relational Mapping (3/4) 120 - Sessions + Object Relational Mapping (4/4) 121 - Overview + Existing Components 122 - Code Please + Sessions 123 - Security Concerns + Overview 124 - Authentication + Code Please 125 - What You Have Right Now + Security Concerns 126 - The Big Picture + Authentication 127 - The Interceptor Pattern + What You Have Right Now 128 - Introducing the Event Dispatcher + The Big Picture 129 - Using the EventDispatcherTrait + The Interceptor Pattern 130 - The Firewall (1/2) + Introducing the Event Dispatcher 131 - The Firewall (2/2) + Using the EventDispatcherTrait 132 - Implementing The Firewall + The Firewall (1/2) 133 - Authentication Mechanism + The Firewall (2/2) 134 - Adding New Routes + Implementing The Firewall 135 - Stateless Authentication + Authentication Mechanism 136 - Basic Security Thinking + Adding New Routes 137 - Writing Better Code + Stateless Authentication 138 - Agenda + Basic Security Thinking 139 - Coding Standards + Writing Better Code 140 - PHP Coding Standards Fixer + Agenda 141 - Programming To The Interface + Coding Standards 142 - Component Driven Development + PHP Coding Standards Fixer 143 - Dependency Injection + Programming To The Interface 144 - Dependency Injection + Component Driven Development 145 @@ -9728,173 +9825,185 @@

    Table of Contents

    - PHP Implementations + Dependency Injection 148 - PHP Implementations + Dependency Injection 149 - From STUPID to SOLID code! (1/2) + PHP Implementations 150 - From STUPID to SOLID code! (2/2) + PHP Implementations 151 - Object Calisthenics + From STUPID to SOLID code! (1/2) 152 - Testing + From STUPID to SOLID code! (2/2) 153 - Agenda + Object Calisthenics 154 - Unit Testing + Testing 155 - Unit Testing + Agenda 156 - PHPUnit — The Rules + Unit Testing 157 - PHPUnit — Assertions + Unit Testing 158 - Running PHPUnit + PHPUnit — The Rules 159 - Functional Testing + PHPUnit — Assertions 160 - Functional Testing + Running PHPUnit 161 - Behavior Driven Development + Functional Testing 162 - Behavior Driven Development + Functional Testing 163 - Behat + Behavior Driven Development 164 - Using Behat (1/2) + Behavior Driven Development 165 - Using Behat (2/2) + Behat 166 - Awesome Projects + Using Behat (1/2) 167 - + Using Behat (2/2) 168 - Embracing Open Source + Awesome Projects 169 - + 170 - + Embracing Open Source 171 - + 172 - Golden Rules + 173 - The End. + 174 - Well... Maybe Not.
    PHP Extended + Golden Rules 175 + + The End. + 176 + + + + + Well... Maybe Not.
    PHP Extended + 177 + + + diff --git a/index2.html b/index2.html index 28e7f38..64840b8 100644 --- a/index2.html +++ b/index2.html @@ -1167,6 +1167,10 @@ font-size: 8em !important; } +table { + margin-bottom: 3%; +} + From d651a30d6a90b5b610b8bfc3dd849a04549c4e63 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Sat, 4 Jan 2014 01:54:36 +0100 Subject: [PATCH 12/71] Publish slides (Sam 4 jan 2014 01:54:36 CET) --- index.html | 7 +- index2.html | 322 +++++++++++++++++++++++++++++----------------------- 2 files changed, 182 insertions(+), 147 deletions(-) diff --git a/index.html b/index.html index c234b74..2a463e8 100644 --- a/index.html +++ b/index.html @@ -1722,7 +1722,8 @@

    Week #2

    Week #3

    Databases

    Week #4

    -

    Sessions, Authentication, Writing Better Code, Testing, Embracing Open Source

    +

    Sessions, Authentication, Writing Better Code, Testing, Awesome Projects, +Embracing Open Source

    @@ -8698,7 +8699,7 @@

    StoryBDD

    -

    +


    Event-driven, non-blocking I/O with PHP: @@ -9957,7 +9958,7 @@

    Table of Contents

    - +
    170 diff --git a/index2.html b/index2.html index 64840b8..1d85a31 100644 --- a/index2.html +++ b/index2.html @@ -1593,7 +1593,7 @@
    @@ -1621,7 +1621,7 @@
    @@ -1664,7 +1664,7 @@
    @@ -1706,7 +1706,7 @@ @@ -1734,7 +1734,7 @@ @@ -1776,7 +1776,7 @@ @@ -1804,7 +1804,7 @@ @@ -1832,7 +1832,7 @@ @@ -1870,7 +1870,7 @@ @@ -1914,7 +1914,7 @@ @@ -1963,7 +1963,7 @@ @@ -2006,7 +2006,7 @@ @@ -2034,7 +2034,7 @@ @@ -2086,7 +2086,7 @@ @@ -2136,7 +2136,7 @@ @@ -2183,7 +2183,7 @@ @@ -2215,7 +2215,7 @@ @@ -2261,7 +2261,7 @@ @@ -2307,7 +2307,7 @@ @@ -2357,7 +2357,7 @@ @@ -2410,7 +2410,7 @@ @@ -2449,7 +2449,7 @@ @@ -2497,7 +2497,7 @@ @@ -2544,7 +2544,7 @@ @@ -2594,7 +2594,7 @@ @@ -2645,7 +2645,7 @@ @@ -2694,7 +2694,7 @@ @@ -2742,7 +2742,7 @@ @@ -2791,7 +2791,7 @@ @@ -2870,7 +2870,7 @@ @@ -2923,7 +2923,7 @@ @@ -2971,7 +2971,7 @@ @@ -3012,7 +3012,7 @@ @@ -3040,7 +3040,7 @@ @@ -3083,7 +3083,7 @@ @@ -3134,7 +3134,7 @@

    Controller Implementation

    @@ -3177,7 +3177,7 @@

    Controller Implementation

    @@ -3229,7 +3229,7 @@

    Controller Implementation

    @@ -3274,7 +3274,7 @@

    Controller Implementation

    @@ -3324,7 +3324,7 @@

    Rendering Templates

    @@ -3371,7 +3371,7 @@

    Rendering Templates

    @@ -3399,7 +3399,7 @@

    Rendering Templates

    @@ -3443,7 +3443,7 @@

    Rendering Templates

    @@ -3482,7 +3482,7 @@

    Rendering Templates

    @@ -3520,7 +3520,7 @@

    Rendering Templates

    @@ -3567,7 +3567,7 @@

    HTTP Method Requirements

    @@ -3614,7 +3614,7 @@

    Prefixing Imported Routes

    @@ -3664,7 +3664,7 @@

    Query String

    @@ -3692,7 +3692,7 @@

    Query String

    @@ -3720,7 +3720,7 @@

    Query String

    @@ -3770,7 +3770,7 @@

    After

    @@ -3809,7 +3809,7 @@

    After

    @@ -3859,7 +3859,7 @@

    After

    @@ -3908,7 +3908,7 @@

    Loops

    @@ -3955,7 +3955,7 @@

    Loops

    @@ -4006,7 +4006,7 @@

    Example

    @@ -4059,7 +4059,7 @@

    Example

    @@ -4108,7 +4108,7 @@

    Example

    @@ -4151,7 +4151,7 @@

    Example

    @@ -4196,7 +4196,7 @@

    Example

    @@ -4235,7 +4235,7 @@

    Example

    @@ -4267,7 +4267,7 @@

    Example

    @@ -4314,7 +4314,7 @@

    Example

    @@ -4342,7 +4342,7 @@

    Example

    @@ -4391,7 +4391,7 @@

    Using the Templating Service

    @@ -4442,7 +4442,7 @@

    Using the Templating Service

    @@ -4492,7 +4492,7 @@

    Cache Busting

    @@ -4542,7 +4542,7 @@

    Cache Busting

    @@ -4579,7 +4579,7 @@

    Cache Busting

    @@ -4607,7 +4607,7 @@

    Cache Busting

    @@ -4643,7 +4643,7 @@

    Cache Busting

    @@ -4677,7 +4677,7 @@

    Cache Busting

    @@ -4730,7 +4730,7 @@

    Cache Busting

    @@ -4778,7 +4778,7 @@

    Cache Busting

    @@ -4831,7 +4831,7 @@

    Optional Dependencies: Setter Injection

    @@ -4875,7 +4875,7 @@

    Container Extensions

    @@ -4927,7 +4927,7 @@

    Container Extensions

    @@ -4977,7 +4977,7 @@

    Container Extensions

    @@ -5022,7 +5022,7 @@

    Container Extensions

    @@ -5075,7 +5075,7 @@

    Container Extensions

    @@ -5122,7 +5122,7 @@

    Container Extensions

    @@ -5170,7 +5170,7 @@

    Debugging Services

    @@ -5198,7 +5198,7 @@

    Debugging Services

    @@ -5247,7 +5247,7 @@

    Global Options

    @@ -5302,7 +5302,7 @@

    Global Options

    @@ -5356,7 +5356,7 @@

    Global Options

    @@ -5408,7 +5408,7 @@

    Usage

    @@ -5460,7 +5460,7 @@

    Usage

    @@ -5510,7 +5510,7 @@

    Usage

    @@ -5563,7 +5563,7 @@

    Calling an existing Command

    @@ -5591,7 +5591,7 @@

    Calling an existing Command

    @@ -5637,7 +5637,7 @@

    Calling an existing Command

    @@ -5676,7 +5676,7 @@

    Calling an existing Command

    @@ -5723,7 +5723,7 @@

    Calling an existing Command

    @@ -5776,7 +5776,7 @@

    Calling an existing Command

    @@ -5807,7 +5807,7 @@

    Calling an existing Command

    @@ -5864,7 +5864,7 @@

    Calling an existing Command

    @@ -5915,7 +5915,7 @@

    Calling an existing Command

    @@ -5966,7 +5966,7 @@

    Calling an existing Command

    @@ -6020,7 +6020,7 @@

    Calling an existing Command

    @@ -6059,7 +6059,7 @@

    Calling an existing Command

    @@ -6107,7 +6107,7 @@

    Calling an existing Command

    @@ -6155,7 +6155,7 @@

    Calling an existing Command

    @@ -6183,7 +6183,7 @@

    Calling an existing Command

    @@ -6219,7 +6219,7 @@

    Calling an existing Command

    @@ -6268,7 +6268,7 @@

    Example

    @@ -6318,7 +6318,7 @@

    Example

    @@ -6351,7 +6351,7 @@

    Example

    @@ -6397,7 +6397,7 @@

    Classes

    @@ -6445,7 +6445,7 @@

    Classes

    @@ -6492,7 +6492,7 @@

    Example

    @@ -6531,7 +6531,7 @@

    Example

    @@ -6581,7 +6581,7 @@

    Example

    @@ -6631,7 +6631,7 @@

    Example

    @@ -6659,7 +6659,7 @@

    Example

    @@ -6698,7 +6698,7 @@

    Localization

    @@ -6748,7 +6748,7 @@

    Message Placeholders

    @@ -6796,7 +6796,7 @@

    Message Placeholders

    @@ -6839,7 +6839,7 @@

    Message Placeholders

    @@ -6884,7 +6884,7 @@

    Message Placeholders

    @@ -6931,7 +6931,7 @@

    Message Placeholders

    @@ -6987,7 +6987,7 @@

    Message Placeholders

    @@ -7015,7 +7015,7 @@

    Message Placeholders

    @@ -7050,7 +7050,7 @@

    Message Placeholders

    @@ -7090,7 +7090,7 @@

    HTTP Cache

    @@ -7127,7 +7127,7 @@

    Edge Side Includes

    @@ -7169,7 +7169,7 @@

    Edge Side Includes

    @@ -7211,7 +7211,7 @@

    Edge Side Includes

    @@ -7247,7 +7247,7 @@

    Edge Side Includes

    @@ -7289,7 +7289,7 @@

    Edge Side Includes

    @@ -7331,7 +7331,7 @@

    Edge Side Includes

    @@ -7369,7 +7369,7 @@

    Edge Side Includes

    @@ -7405,7 +7405,7 @@

    Edge Side Includes

    @@ -7451,7 +7451,7 @@

    Edge Side Includes

    @@ -7494,7 +7494,7 @@

    Edge Side Includes

    @@ -7531,7 +7531,7 @@

    Edge Side Includes

    @@ -7579,7 +7579,7 @@

    Edge Side Includes

    @@ -7614,7 +7614,7 @@

    Edge Side Includes

    @@ -7667,7 +7667,7 @@

    Edge Side Includes

    @@ -7704,7 +7704,7 @@

    Edge Side Includes

    @@ -7732,7 +7732,7 @@

    Edge Side Includes

    @@ -7765,7 +7765,7 @@

    Edge Side Includes

    @@ -7800,7 +7800,7 @@

    Edge Side Includes

    @@ -7856,7 +7856,35 @@

    Edge Side Includes

    + + + + + +
    +
    +
    + +

    The End.

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -8735,6 +8763,12 @@

    Table of Contents

    + + The End. + 145 + + +
    From 077362ba61c784f3a7dd44c8cea3345e361ef7b1 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Sat, 4 Jan 2014 03:16:20 +0100 Subject: [PATCH 13/71] Publish slides (Sam 4 jan 2014 03:16:20 CET) --- extended.html | 8952 +++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 714 ++-- isima.html | 7603 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 16912 insertions(+), 357 deletions(-) create mode 100644 extended.html create mode 100644 isima.html diff --git a/extended.html b/extended.html new file mode 100644 index 0000000..8a9fc93 --- /dev/null +++ b/extended.html @@ -0,0 +1,8952 @@ + + + + + + + PHP Extended + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + 00:00:00 +
    +
    +
    +
    +
    + + +
    +
    +
    + +

    PHP Extended

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Let's Do Professional Development Now!

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Who Is Speaking?

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    William DURAND

    + + +

    PhD student at Michelin / LIMOS

    +

    Graduated from IUT and ISIMA

    +

    Worked at:

    + +

    Open-Source evangelist:

    + +

    + twitter.com/couac +  |  + github.com/willdurand +  |  + williamdurand.fr +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Agenda

    + + +
      +
    • Symfony
        +
      • Controllers
      • +
      • Templating
      • +
      • Dependency Injection
      • +
      • Command Line
      • +
      • Forms
      • +
      • Validation
      • +
      • Translation
      • +
      • HTTP Cache
      • +
      +
    • +
    • Stack PHP
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    A Framework To Simplify Developments

    + + +

    A framework helps you work better by structuring developments, +and faster by reusing generic modules.

    +

    A framework facilitates long-term maintenance and scalability by +complying with standard development rules.

    +

    Compliance with development standards also simplifies integrating and +interfacing the application with the rest of the information system.

    +

    In other words, it works as a tool to make the development process +easier and more productive.

    +

    Most of the time, a framework implements many kinds of design patterns.

    +
    +

    Read more: Symfony explained to a +Developer.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is Symfony2?

    + + +

    First of all:

    +
    +

    Symfony2 is a reusable set of standalone, decoupled, and cohesive PHP + components that solve common web development problems.

    +
    + +

    Then, based on these components:

    +
    +

    Symfony2 is also a full-stack web framework.

    +
    + +

    Fabien Potencier, +http://fabien.potencier.org/article/49/what-is-symfony2.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Is Symfony2 A MVC Framework?

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    NO!

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Why You Should Use Symfony2

    + + +

    Symfony2 is built on powerful concepts:

    +
      +
    • Separation of Concerns;
    • +
    • Pragmatism;
    • +
    • Best Practices.
    • +
    +

    +

    It has been written by ~900 developers.

    +

    Open Source, MIT licensed.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Symfony2 Components

    + + +

    The Components implement common features needed to develop websites.

    +

    They are the foundation of the Symfony full-stack framework, but they can +also be used standalone even if you don't use the framework as they don't +have any mandatory dependencies.

    +

    There are ~26 components, including:

    +
    BrowserKit              EventDispatcher     OptionsResolver     Translation
    +ClassLoader             ExpressionLanguage  Process             Yaml
    +Config                  Filesystem          PropertyAccess
    +Console                 Finder              Routing
    +CssSelector             Form                Security
    +Debug                   HttpFoundation      Serializer
    +DependencyInjection     HttpKernel          Stopwatch
    +DomCrawler              Intl                Templating
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Getting Ready With Components

    + + +

    Assuming you want to play with YAML files, start by requiring the symfony/yaml +component into your composer.json file:

    +
    {
    +    "require": {
    +        "symfony/yaml": "~2.4"
    +    }
    +}
    +
    + +

    Install it by running php composer.phar install, and use it:

    +
    require __DIR__ . '/vendor/autoload.php';
    +
    +use Symfony\Component\Yaml\Yaml;
    +
    +$yaml = Yaml::parse('/path/to/file.yml');
    +
    + +
    +

    http://symfony.com/doc/current/components/yaml/introduction.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Full-Stack Framework

    + + +

    The Symfony2 Framework accomplishes two distinct tasks:

    +
      +
    • Provides a selection of components;
    • +
    • Provides sensible configuration and a "glue" library that ties all of these + pieces together.
    • +
    +

    The goal of the framework is to integrate many independent tools in order to +provide a consistent experience for the developer. Even the framework itself is +a Symfony2 bundle (i.e. a plugin) that can be configured or replaced entirely.

    +

    Symfony2 provides a powerful set of tools for rapidly developing web +applications without imposing on your application.

    +
    +

    http://symfony.com/doc/current/book/index.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Overall Architecture

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Symfony2 Request

    + + +
    use Symfony\Component\HttpFoundation\Request;
    +
    +$request = Request::createFromGlobals();
    +
    +// the URI being requested (e.g. /about) minus any query parameters
    +$request->getPathInfo();
    +
    +// the HTTP verb
    +$request->getMethod();
    +
    +// GET variables
    +$request->query->get('foo');
    +
    +// POST variables
    +$request->request->get('bar');
    +
    +// SERVER variables
    +$request->server->get('HTTP_HOST');
    +
    +// retrieve an HTTP request header, with normalized, lowercase keys
    +$request->headers->get('host');
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Symfony2 Response

    + + +
    use Symfony\Component\HttpFoundation\Response;
    +
    +$response = new Response();
    +
    +$response->setContent(<<<HTML
    +<html>
    +    <body>
    +        <h1>Hello world!</h1>
    +    </body>
    +</html>
    +HTML
    +);
    +
    +$response->setStatusCode(200);
    +
    +$response->headers->set('Content-Type', 'text/html');
    +
    +// prints the HTTP headers followed by the content
    +$response->send();
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Simplest Front Controller Ever

    + + +
    // index.php
    +use Symfony\Component\HttpFoundation\Request;
    +use Symfony\Component\HttpFoundation\Response;
    +
    +$request = Request::createFromGlobals();
    +$path    = $request->getPathInfo();
    +
    +if (in_array($path, array('', '/'))) {
    +    $response = new Response('Welcome to the homepage.');
    +} elseif ('/hello' === $path) {
    +    $response = new Response('hello, World!');
    +} else {
    +    $response = new Response('Page not found.', 404);
    +}
    +
    +$response->send();
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Symfony Application Flow

    + + +

    It's all about transforming a Request into a Response: +

    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Routing Definition

    + + +

    The routing system determines which PHP function should be executed based on +information from the request and routing configuration you've created.

    +
    # app/config/routing.yml
    +hello:
    +    pattern:  /hello
    +    defaults: { _controller: AcmeDemoBundle:Main:hello }
    +
    + +

    The AcmeDemoBundle:Main:hello string is a short syntax that points to a +specific PHP method named helloAction() inside a class called +MainController.

    +
    +

    + This example uses YAML to define the routing configuration. + Routing configuration can also be written in other formats such as XML or PHP. +

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Your First Controller

    + + +

    In Symfony2, a method in a controller is called an action. The convention is +to suffix each method with Action.

    +

    Also, each controller should be suffixed with Controller.

    +
    // src/Acme/DemoBundle/Controller/MainController.php
    +namespace Acme\DemoBundle\Controller;
    +
    +use Symfony\Component\HttpFoundation\Response;
    +
    +class MainController
    +{
    +    public function helloAction()
    +    {
    +        return new Response('<h1>Hello, World!</h1>');
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    A Symfony2 Project

    + + +

    Recommended structure of a Symfony2 project:

    +
    path/to/project/
    +    app/
    +        cache/
    +        config/
    +        logs/
    +    src/
    +        ...
    +    vendor/
    +        ...
    +    web/
    +        app.php
    +        ...
    +
    + +
      +
    • app/ contains the application kernel, and the configuration;
    • +
    • src/ contains your bundles;
    • +
    • vendor/ contains your dependencies;
    • +
    • web/ contains your front controllers and your assets.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Application Kernel

    + + +

    This is the central part of your application:

    +
    // app/AppKernel.php
    +use Symfony\Component\HttpKernel\Kernel;
    +
    +class AppKernel extends Kernel
    +{
    +    public function registerBundles()
    +    {
    +        $bundles = array(
    +            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
    +            // ...
    +        );
    +
    +        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
    +            $bundles[] = // dev bundle;
    +        }
    +
    +        return $bundles;
    +    }
    +
    +    // ...
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Application Configuration

    + + +

    An application consists of a collection of "bundles" representing all of the +features and capabilities of your application.

    +

    Each "bundle" can be customized via configuration files written in YAML, XML +or PHP.

    +

    By default, the main configuration file lives in the app/config/ +directory and is called either config.yml, config.xml or config.php +depending on which format you prefer.

    +

    Symfony2 is all about configuring everything, and you can do pretty much +everything you want. That's why people agreed on some conventions, but then +again, a convention is just A way to do things, not THE way to do them.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    YAML Configuration

    + + +

    Example:

    +
    # app/config/config.yml
    +imports:
    +    - { resource: parameters.yml }
    +    - { resource: security.yml }
    +
    +framework:
    +    secret: "%secret%"
    +    router: { resource: "%kernel.root_dir%/config/routing.yml" }
    +    # ...
    +
    +# Twig Configuration
    +twig:
    +    debug:            "%kernel.debug%"
    +    strict_variables: "%kernel.debug%"
    +
    +# ...
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    XML Configuration

    + + +

    Example:

    +
    <!-- app/config/config.xml -->
    +<imports>
    +    <import resource="parameters.yml"/>
    +    <import resource="security.yml"/>
    +</imports>
    +
    +<framework:config secret="%secret%">
    +    <framework:router resource="%kernel.root_dir%/config/routing.xml"/>
    +    <!-- ... -->
    +</framework:config>
    +
    +<!-- Twig Configuration -->
    +<twig:config debug="%kernel.debug%" strict-variables="%kernel.debug%"/>
    +
    +<!-- ... -->
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    PHP Configuration

    + + +

    Example:

    +
    $this->import('parameters.yml');
    +$this->import('security.yml');
    +
    +$container->loadFromExtension('framework', array(
    +    'secret' => '%secret%',
    +    'router' => array(
    +        'resource' => '%kernel.root_dir%/config/routing.php'
    +    ),
    +    // ...
    +));
    +
    +// Twig Configuration
    +$container->loadFromExtension('twig', array(
    +    'debug'            => '%kernel.debug%',
    +    'strict_variables' => '%kernel.debug%',
    +));
    +
    +// ...
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Rules (Well... My Rules)

    + + +

    The main configuration MUST be written in YAML:

    +
    # app/config/config.yml
    +# ...
    +twig:
    +    debug:            "%kernel.debug%"
    +    strict_variables: "%kernel.debug%"
    +
    + +

    The routing definition MUST be written in YAML:

    +
    # app/config/routing.yml
    +hello:
    +    pattern:  /hello
    +    defaults: { _controller: AcmeDemoBundle:Main:hello }
    +
    + +

    The DI Container configuration MUST be written in XML:

    +
    <services>
    +    <service id="acme_demo.controllers.main"
    +        class="Acme\DemoBundle\MainController" />
    +</services>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Environments

    + + +

    An application can run in various environments. The different environments +share the same PHP code, but use different configuration.

    +

    A Symfony2 project generally uses three environments: dev, test and prod.

    +
    // web/app.php
    +
    +// ...
    +$kernel = new AppKernel('prod', false);
    +
    + +

    The AppKernel class is responsible for actually loading the configuration file +of your choice:

    +
    // app/AppKernel.php
    +public function registerContainerConfiguration(LoaderInterface $loader)
    +{
    +    $loader->load(
    +        __DIR__ . '/config/config_' . $this->getEnvironment() . '.yml'
    +    );
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is A Bundle?

    + + +

    A Bundle is a directory containing a set of files (PHP files, stylesheets, +JavaScripts, images, ...) that implement a single feature (a blog, a forum, +etc).

    +

    It should be reusable, so that you don't reinvent the wheel each time you +need a common feature. In Symfony2, (almost) everything lives inside a bundle.

    +

    In order to use a bundle in your application, you need to register it in the +AppKernel, using the registerBundles() method:

    +
    public function registerBundles()
    +{
    +    $bundles = array(
    +        // ...
    +
    +        new My\AwesomeBundle\MyAwesomeBundle(),
    +    );
    +
    +    // ...
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Bundle: Directory Structure

    + + +

    Recommended structure for a bundle:

    +
    XXX/...
    +    DemoBundle/
    +        DemoBundle.php
    +        Controller/
    +        Resources/
    +            meta/
    +                LICENSE
    +            config/
    +            doc/
    +                index.rst
    +            translations/
    +            views/
    +            public/
    +        Tests/
    +
    + +

    The DemoBundle class is mandatory, and both Resources/meta/LICENSE and +Resources/doc/index.rst files should be present.

    +

    The XXX directory(ies) reflects the namespace structure of the bundle.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Bundle: Where To Put Your Classes?

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeDirectory
    CommandsCommand/
    ControllersController/
    Service Container ExtensionsDependencyInjection/
    Event ListenersEventListener/
    ConfigurationResources/config/
    Web ResourcesResources/public/
    Translation filesResources/translations/
    TemplatesResources/views/
    Unit and Functional TestsTests/
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Creating a Bundle

    + + +

    A bundle has to extend the Symfony\Component\HttpKernel\Bundle\Bundle +class:

    +
    // src/Acme/MyFirstBundle/AcmeMyFirstBundle.php
    +namespace Acme\MyFirstBundle;
    +
    +use Symfony\Component\HttpKernel\Bundle\Bundle;
    +
    +class AcmeMyFirstBundle extends Bundle
    +{
    +}
    +
    + +

    Then, you can register your bundle:

    +
    // app/AppKernel.php
    +public function registerBundles()
    +{
    +    $bundles = array(
    +        new Acme\MyFirstBundle\AcmeMyFirstBundle(),
    +    );
    +
    +    return $bundles;
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Web Directory

    + + +

    The web root directory is the home of all public and static files including +images, stylesheets, and JavaScript files. It is also where each front +controller lives:

    +
    // web/app.php
    +require_once __DIR__.'/../app/bootstrap.php.cache';
    +require_once __DIR__.'/../app/AppKernel.php';
    +
    +use Symfony\Component\HttpFoundation\Request;
    +
    +$kernel   = new AppKernel('prod', false);
    +$request  = Request::createFromGlobals();
    +$response = $kernel->handle($request);
    +$response->send();
    +
    + +

    The front controller file (app.php in this example) is the actual PHP file +that's executed when using a Symfony2 application and its job is to use a +Kernel class, AppKernel, to bootstrap the application, for a given +environment.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Summary

    + + +

    Creating a page is a three-step process involving a route, a controller, and +(optionally) a template.

    +

    Each project contains just a few main directories: web/ (web assets and the +front controllers), app/ (configuration), src/ (your bundles), and vendor/ +(third-party code).

    +

    Each feature in Symfony2 (including the Symfony2 framework core) is organized +into a bundle, which is a structured set of files for that feature.

    +

    The configuration for each bundle lives in the Resources/config directory of the +bundle and can be specified in YAML, XML or PHP.

    +

    The global application configuration lives in the app/config/ directory.

    +

    Each environment is accessible via a different front controller (e.g. app.php +and app_dev.php) and loads a different configuration file.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Controllers

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Request, Controller, Response

    + + +

    A controller is a PHP function you create that takes information from the +HTTP request and constructs and returns an HTTP response.

    +

    Every request handled by a Symfony2 project goes through the same lifecycle:

    +
      +
    1. Each request is handled by a single front controller file (e.g. app.php or +app_dev.php) that bootstraps the application;
    2. +
    3. The Router reads information from the request (e.g. the URI), finds a route +that matches that information, and reads the _controller parameter from the +route;
    4. +
    5. The controller from the matched route is executed and the code inside the +controller creates and returns a Response object;
    6. +
    7. The HTTP headers and content of the Response object are sent back to the +client.
    8. +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Simplest Page Ever

    + + +

    Routing Definition

    +
    # app/config/routing.yml
    +homepage:
    +    pattern:  /
    +    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +
    + +

    Controller Implementation

    +
    // src/Acme/DemoBundle/Controller/HelloController.php
    +namespace Acme\DemoBundle\Controller;
    +
    +use Symfony\Component\HttpFoundation\Response;
    +
    +class HelloController
    +{
    +    public function indexAction()
    +    {
    +        return new Response('Home, Sweet Home!');
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Controller Naming Pattern

    + + +

    Every route must have a _controller parameter, which dictates which controller +should be executed when that route is matched.

    +

    This parameter uses a simple string pattern called the logical controller name. +The pattern has three parts, each separated by a colon:

    +
    bundle:controller:action
    +
    +

    For example, a _controller value of AcmeBlogBundle:Blog:show means:

    +
      +
    • Bundle: AcmeBlogBundle;
    • +
    • Controller Class: BlogController;
    • +
    • Method Name: showAction.
    • +
    +

    Notice that Symfony adds the string Controller to the class name (Blog => +BlogController) and Action to the method name (show => showAction).

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Route Params as Controller Args

    + + +

    Routing Definition

    +
    # src/Acme/DemoBundle/Resources/config/routing.yml
    +acme_demo.hello_hello:
    +    pattern:  /hello/{name}
    +    defaults: { _controller: AcmeDemoBundle:Hello:hello }
    +    requirements:
    +        _method: GET
    +
    + +

    Controller Implementation

    +
    // src/Acme/DemoBundle/Controller/HelloController.php
    +
    +class HelloController
    +{
    +    // ...
    +
    +    public function helloAction($name)
    +    {
    +        return new Response(sprintf('Home, Sweet %s!', $name));
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Request as a Controller Argument

    + + +

    For convenience, you can also have Symfony pass you the Request object as an +argument to your controller:

    +
    use Symfony\Component\HttpFoundation\Request;
    +
    +class HelloController
    +{
    +    // ...
    +
    +    public function updateAction(Request $request)
    +    {
    +        // do something useful with $request
    +    }
    +}
    +
    + +

    This is useful when you are working with forms.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Base Controller Class

    + + +

    Symfony2 comes with a base Controller class that assists with some of the most +common controller tasks and gives your controller class access to any resource +it might need:

    +
    use Symfony\Bundle\FrameworkBundle\Controller\Controller
    +
    +class HelloController extends Controller
    +{
    +    // ...
    +}
    +
    + +

    Redirecting

    +
    $this->redirect($this->generateUrl('homepage'));
    +
    + +

    Rendering Templates

    +
    return $this->render(
    +    'AcmeDemoBundle:Hello:hello.html.twig', array('name' => $name)
    +);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Response

    + + +

    The only requirement for a controller is to return a Response object.

    +

    Create a simple Response with a 200 status code:

    +
    use Symfony\Component\HttpFoundation\Response;
    +
    +$response = new Response('Hello, ' . $name, 200);
    +
    + +

    Create a JSON response with a 200 status code:

    +
    $response = new Response(json_encode(array('name' => $name)));
    +$response->headers->set('Content-Type', 'application/json');
    +
    + +

    Or:

    +
    use Symfony\Component\HttpFoundation\JsonResponse;
    +
    +$response = new JsonResponse(array('name' => $name));
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Routing

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Basic Route Configuration

    + + +

    The Symfony2 router lets you define URLs that you map to different areas of +your application.

    +

    A route is a map from a URL path to a controller. Each route is named, and +maps a pattern (or path as of Symfony2.2) to a _controller:

    +
    # app/config/routing.yml
    +homepage:
    +    pattern:  /
    +    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +
    + +

    This route matches the homepage (/) and maps it to the +AcmeDemoBundle:Hello:index controller.

    +
    +

    http://symfony.com/doc/master/book/routing.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Routing with Placeholders (1/2)

    + + +

    Required Placeholders

    +
    blog:
    +    path:      /blog/{page}
    +    defaults:  { _controller: AcmeBlogBundle:Blog:index }
    +
    + +

    The path will match anything that looks like /blog/*.

    +

    Even better, the value matching the {page} placeholder will be available +inside your controller.

    +

    /blog will not match.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Routing with Placeholders (2/2)

    + + +

    Optional Placeholders

    +
    blog:
    +    path:      /blog/{page}
    +    defaults:  { _controller: AcmeBlogBundle:Blog:index, page: 1 }
    +
    + +

    By adding page to the defaults key, {page} is no longer required.

    +

    /blog will match this route and the value of the page parameter will be +set to 1. /blog/2 will also match, giving the page parameter a value of 2.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Requirements

    + + +
    blog:
    +    path:      /blog/{page}
    +    defaults:  { _controller: AcmeBlogBundle:Blog:index, page: 1 }
    +    requirements:
    +        page:  \d+
    +
    + +

    The \d+ requirement is a regular expression that says that the value of +the {page} parameter must be a digit (i.e. a number).

    +

    HTTP Method Requirements

    +
    # src/Acme/DemoBundle/Resources/config/routing.yml
    +acme_demo.hello_hello:
    +    pattern:  /hello/{name}
    +    defaults: { _controller: AcmeDemoBundle:Hello:hello }
    +    methods:  [ GET ]
    +    # methods:  [ GET, POST ]
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Including External Routing Resources

    + + +

    All routes are loaded via a single configuration file, most of the time it will +be app/config/routing.yml.

    +

    In order to respect the "bundle" principle, the routing configuration should be +located in the bundle itself, and you should just require it:

    +
    # app/config/routing.yml
    +acme_demo:
    +    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
    +
    + +

    Prefixing Imported Routes

    +
    # app/config/routing.yml
    +acme_demo:
    +    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
    +    prefix: /demo
    +
    + +

    The string /demo now be prepended to the path of each route loaded from +the new routing resource.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Generating URLs

    + + +

    The Router is able to generate both relative and absolute URLs.

    +
    $router = $this->get('router');
    +
    + +

    Relative URLs

    +
    $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ]);
    +// /hello/will
    +
    + +

    Absolute URLs

    +
    $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ], true);
    +// http://example.com/hello/will
    +
    + +

    Query String

    +
    $router->generate('acme_demo.hello_hello', [
    +    'name' => 'will', 'some' => 'thing'
    +]);
    +// /hello/will?some=thing
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Templating

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Why Twig?

    + + +

    Fast, Secure, Flexible.

    +

    Before

    +
    <ul id="navigation">
    +    <?php foreach ($navigation as $item): ?>
    +        <li>
    +            <a href="<?php echo $item->getHref() ?>">
    +                <?php echo $item->getCaption() ?>
    +            </a>
    +        </li>
    +    <?php endforeach; ?>
    +</ul>
    +
    + +

    After

    +
    <ul id="navigation">
    +    {% for item in navigation %}
    +        <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
    +    {% endfor %}
    +</ul>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Getting Familiar With Twig

    + + +

    Delimiters

    +
      +
    • {{ ... }}: prints a variable or the result of an expression;
    • +
    • {% ... %}: controls the logic of the template; it is used to execute for + loops and if statements, for example;
    • +
    • {# ... #}: comments.
    • +
    +
    +

    http://twig.sensiolabs.org/

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Accessing Variables

    + + +
    {# array('name' => 'Fabien') #}
    +{{ name }}
    +
    +{# array('user' => array('name' => 'Fabien')) #}
    +{{ user.name }}
    +
    +{# force array lookup #}
    +{{ user['name'] }}
    +
    +{# array('user' => new User('Fabien')) #}
    +{{ user.name }}
    +{{ user.getName }}
    +
    +{# force method name lookup #}
    +{{ user.name() }}
    +{{ user.getName() }}
    +
    +{# pass arguments to a method #}
    +{{ user.date('Y-m-d') }}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Control Structure

    + + +

    Conditions

    +
    {% if user.isSuperAdmin() %}
    +    ...
    +{% elseif user.isMember() %}
    +    ...
    +{% else %}
    +    ...
    +{% endif %}
    +
    + +

    Loops

    +
    <ul>
    +    {% for user in users if user.active %}
    +        <li>{{ user.username }}</li>
    +    {% else %}
    +        <li>No users found</li>
    +    {% endfor %}
    +</ul>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Filters

    + + +

    Filters are used to modify Twig variables.

    +

    You can use inline filters by using the | symbol:

    +
    {{ 'hello'|upper }}
    +
    + +

    But you can also use the block syntax:

    +
    {% filter upper %}
    +    hello
    +{% endfilter %}
    +
    + +

    Filters can be parametrized:

    +
    {{ post.createdAt|date('Y-m-d') }}
    +
    + +
    +

    http://twig.sensiolabs.org/doc/filters/index.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Including Other Templates

    + + +

    The include tag is useful to include a template and return the rendered +content of that template into the current one:

    +
    {% include 'sidebar.html' %}
    +
    + +

    Example

    +

    Given the following template:

    +
    {% for user in users %}
    +    {% include "render_user.html" %}
    +{% endfor %}
    +
    + +

    with render_user.html:

    +
    <p>{{ user.username }}</p>
    +
    + +

    + +
    <p>William D.</p>
    +<p>Julien M.</p>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Template Inheritance (1/2)

    + + +

    Let's define a base template, base.html, which defines a simple HTML skeleton:

    +
    {# app/Resources/views/base.html.twig #}
    +<!DOCTYPE html>
    +<html>
    +    <head>
    +        <title>{% block title %}Test Application{% endblock %}</title>
    +    </head>
    +    <body>
    +        <div id="sidebar">
    +            {% block sidebar %}
    +            <ul>
    +                <li><a href="/">Home</a></li>
    +                <li><a href="/blog">Blog</a></li>
    +            </ul>
    +            {% endblock %}
    +        </div>
    +
    +        <div id="content">
    +            {% block body %}{% endblock %}
    +        </div>
    +    </body>
    +</html>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Template Inheritance (2/2)

    + + +

    The key to template inheritance is the {% extends %} tag.

    +

    A child template might look like this:

    +
    {# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
    +{% extends '::base.html.twig' %}
    +
    +{% block title %}My cool blog posts{% endblock %}
    +
    +{% block body %}
    +    {% for entry in blog_entries %}
    +        <h2>{{ entry.title }}</h2>
    +        <p>{{ entry.body }}</p>
    +    {% endfor %}
    +{% endblock %}
    +
    + +

    The parent template is identified by a special string syntax +(::base.html.twig) which indicates that the template lives in +app/Resources/views/.

    +

    If you need to get the content of a block from the parent template, you can +use the {{ parent() }} function.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Template Naming and Locations (1/2)

    + + +

    By default, templates can live in two different locations:

    +
      +
    • app/Resources/views/: The applications views directory can contain + application-wide base templates (i.e. your application's layouts) as well as + templates that override bundle templates;
    • +
    • path/to/bundle/Resources/views/: Each bundle houses its templates in its + Resources/views directory (and subdirectories).
    • +
    +

    Symfony2 uses a bundle:controller:template string syntax for templates.

    +

    You can skip the controller string: bundle::template. The template +file would live in Resources/views/.

    +

    You can also skip the bundle string. It refers to an application-wide base +template or layout. This means that the template is not located in any bundle, +but instead in the root app/Resources/views/ directory.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Template Naming and Locations (2/2)

    + + +

    Example

    +
    AcmeBlogBundle:Blog:index.html.twig
    +
    + +
      +
    • AcmeBlogBundle: (bundle) the template lives inside the AcmeBlogBundle (e.g. +src/Acme/BlogBundle);
    • +
    • Blog: (controller) indicates that the template lives inside the Blog +subdirectory of Resources/views;
    • +
    • index.html.twig: (template) the actual name of the file is index.html.twig.
    • +
    +

    Assuming that the AcmeBlogBundle lives at src/Acme/BlogBundle, the final +path to the layout would be:

    +
    src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Overriding Bundle Templates

    + + +

    Once you use a third-party bundle, you'll likely need to override and customize +one or more of its templates.

    +

    When the FooBarBundle:Bar:index.html.twig is rendered, Symfony2 actually +looks in two different locations for the template:

    +
      +
    • app/Resources/FooBarBundle/views/Bar/index.html.twig;
    • +
    • src/Foo/BarBundle/Resources/views/Bar/index.html.twig.
    • +
    +

    In order to override the bundle template, copy the index.html.twig template +from the bundle to: app/Resources/FooBarBundle/views/Bar/index.html.twig.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Overriding Core Templates

    + + +

    The core TwigBundle contains a number of different templates that can be +overridden by copying each from the Resources/views/ directory of the +TwigBundle to the app/Resources/TwigBundle/views/ directory.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Three-Level Approach

    + + +
      +
    1. +

      Create a app/Resources/views/base.html.twig file that contains the main +layout for your application (like in the previous example). Internally, this +template is called ::base.html.twig.

      +
    2. +
    3. +

      Create a template for each section of your site. The AcmeBlogBundle +would have a template called AcmeBlogBundle::layout.html.twig that contains +only blog section-specific elements.

      +
    4. +
    5. +

      Create individual templates for each page and make each extend the +appropriate section template. For example, the "index" page would be called +something close to AcmeBlogBundle:Blog:index.html.twig and list the actual +blog posts.

      +
    6. +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Twig Into Symfony2

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Rendering A Template

    + + +

    Using The Base Controller

    +
    public function listAction()
    +{
    +    // ...
    +
    +    return $this->render('AcmeBlogBundle:Blog:index.html.twig', array(
    +        'posts' => $posts,
    +    ));
    +}
    +
    + +

    Using the Templating Service

    +
    $engine  = $this->container->get('templating');
    +$content = $engine->render('AcmeBlogBundle:Blog:index.html.twig', array(
    +    'posts' => $posts,
    +));
    +
    +return new Response($content);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Linking to Pages

    + + +

    Assuming the following routing definition:

    +
    homepage:
    +    path:     /
    +    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +
    +acme_blog.post_show:
    +    path:     /posts/{slug}
    +    defaults: { _controller: AcmeBlogBundle:Post:show }
    +
    + +

    You can create a relative URL using path():

    +
    <a href="{{ path('homepage') }}">Home</a>
    +
    + +

    You can create an absolute URL using url():

    +
    <a href="{{ url('homepage') }}">Home</a>
    +
    + +

    The second argument is used to pass parameters:

    +
    <a href="{{ path('acme_blog.post_show', {'slug': 'my-super-slug'}) }}">
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Linking to Assets

    + + +
    <script src={{ asset('js/script.js') }}></script>
    +
    +<link href="{{ asset('css/style.css') }}" rel="stylesheet">
    +
    +<img src="{{ asset('images/logo.png') }}" alt="Symfony!" />
    +
    + +

    Cache Busting

    +

    Cache busting is the process of forcing browsers or proxy servers to +update their cache, for instance, JavaScript and CSS files or images.

    +
    # app/config/config.yml
    +framework:
    +    # ...
    +    templating: { engines: ['twig'], assets_version: v2 }
    +
    + +

    The asset_version parameter is used to bust the cache on assets by globally +adding a query parameter to all rendered asset paths:

    +
    /images/logo.png?v2
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Linking To Pages In JavaScript

    + + +

    The FOSJsRoutingBundle +allows you to expose your routing in your JavaScript code. That means you'll +be able to generate URL with given parameters like you can do with the Router +component provided by Symfony2.

    +
    # app/config/routing.yml
    +my_route_to_expose:
    +    pattern:  /foo/{id}/bar
    +    defaults: { _controller: FooBarBundle:Foo:bar }
    +    options:
    +        expose: true
    +
    + +

    According to the routing definition above, you can write the following +JavaScript code to generate URLs:

    +
    Routing.generate('my_route_to_expose', { id: 10 });
    +// /foo/10/bar
    +
    +Routing.generate('my_route_to_expose', { id: 10 }, true);
    +// http://example.org/foo/10/bar
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Global Template Variables

    + + +
      +
    • app.security: the security context;
    • +
    • app.user: the current user object;
    • +
    • app.request: the request object;
    • +
    • app.session: the session object;
    • +
    • app.environment: the current environment (dev, prod, etc);
    • +
    • app.debug: true if in debug mode. false otherwise.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Service Container

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is A Service?

    + + +

    A Service is a generic term for any PHP object that performs a specific task.

    +

    A service is usually used globally, such as a database connection object or an +object that delivers email messages.

    +

    In Symfony2, services are often configured and retrieved from the service +container.

    +

    An application that has many decoupled services is said to follow a +Service-Oriented Architecture (SOA).

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is A Service Container?

    + + +

    A Service Container, also known as a Dependency Injection Container +(DIC), is a special object that manages the instantiation of services inside +an application.

    +

    The service container takes care of lazily instantiating and injecting +dependent services.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Creating A Service

    + + +
    class Foo
    +{
    +    private $bar;
    +    private $debug;
    +
    +    public function __construct(Bar $bar = null, $debug = false)
    +    {
    +        $this->bar   = $bar;
    +        $this->debug = $debug;
    +    }
    +}
    +
    + +

    The service definition for the class described above is:

    +
    <services>
    +    <service id="foo" class="My\Bundle\Foo" />
    +</services>
    +
    + +

    This service is now available in the container, and you can access it by +asking the service from the container:

    +
    $foo = $this->container->get('foo');
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Service Parameters

    + + +

    The service definition described before is not flexible enough. For instance, +$debug argument is never configured.

    +

    Parameters make defining services more organized and flexible:

    +
    <parameters>
    +    <parameter key="my_bundle.foo.class">My\Bundle\Foo</parameter>
    +</parameters>
    +
    +<services>
    +    <service id="foo" class="%my_bundle.foo.class%">
    +        <argument></argument> <!-- null -->
    +        <argument>%kernel.debug%</argument>
    +    </service>
    +</services>
    +
    + +

    In the definition above, kernel.debug is a parameter defined by the framework +itself. The foo service is now parametrized.

    +

    Also, it becomes easy to change the implementation of this service by simply +overriding the my_bundle.foo.class parameter.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Injecting Services

    + + +

    As you may noticed, the Foo class takes an instance of Bar as first +argument. You can inject this instance in your foo service by +referencing the bar service:

    +
    <parameters>
    +    <parameter key="my_bundle.foo.class">My\Bundle\Foo</parameter>
    +    <parameter key="my_bundle.bar.class">My\Bundle\Bar</parameter>
    +</parameters>
    +
    +<services>
    +    <service id="bar" class="%my_bundle.bar.class%" />
    +
    +    <service id="foo" class="%my_bundle.foo.class%">
    +        <argument type="service" id="bar" />
    +        <argument>%kernel.debug%</argument>
    +    </service>
    +</services>
    +
    + +

    Optional Dependencies: Setter Injection

    +
    <call method="setBar">
    +    <argument type="service" id="bar" />
    +</call>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Importing Configuration Resources

    + + +

    The imports Way

    +
    # app/config/config.yml
    +imports:
    +    - { resource: "@AcmeDemoBundle/Resources/config/services.xml" }
    +
    + +

    Container Extensions

    +

    A service container extension is a PHP class to accomplish two things:

    +
      +
    • import all service container resources needed to configure the services for + the bundle;
    • +
    • provide semantic, straightforward configuration so that the bundle can + be configured without interacting with the flat parameters of the bundle's + service container configuration.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Creating an Extension Class

    + + +

    An extension class should live in the DependencyInjection directory of your +bundle and its name should be constructed by replacing the Bundle suffix of +the Bundle class name with Extension.

    +
    // Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php
    +namespace Acme\DemoBundle\DependencyInjection;
    +
    +use Symfony\Component\Config\FileLocator;
    +use Symfony\Component\DependencyInjection\ContainerBuilder;
    +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
    +use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    +
    +class AcmeDemoExtension extends Extension
    +{
    +    public function load(array $configs, ContainerBuilder $container)
    +    {
    +        $loader = new XmlFileLoader($container, new FileLocator(
    +            __DIR__ . '/../Resources/config'
    +        ));
    +        $loader->load('services.xml');
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Dealing With Configuration (1/2)

    + + +

    The presence of the previous class means that you can now define an +acme_demo configuration namespace in any configuration file:

    +
    # app/config/config.yml
    +acme_demo: ~
    +
    + +

    Take the following configuration:

    +
    acme_demo:
    +    foo: fooValue
    +    bar: barValue
    +
    + +

    The array passed to your load() method will look like this:

    +
    array(
    +    array(
    +        'foo' => 'fooValue',
    +        'bar' => 'barValue',
    +    )
    +)
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Dealing With Configuration (2/2)

    + + +

    The $configs argument is an array of arrays, not just a single flat array +of the configuration values.

    +

    It's your job to decide how these configurations should be merged together.

    +

    You might, for example, have later values override previous values or +somehow merge them together:

    +
    public function load(array $configs, ContainerBuilder $container)
    +{
    +    $config = array();
    +    foreach ($configs as $subConfig) {
    +        $config = array_merge($config, $subConfig);
    +    }
    +
    +    // ... now use the flat $config array
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Configuration Class (1/2)

    + + +

    Definition

    +
    // src/Acme/DemoBundle/DependencyInjection/Configuration.php
    +namespace Acme\DemoBundle\DependencyInjection;
    +
    +use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    +use Symfony\Component\Config\Definition\ConfigurationInterface;
    +
    +class Configuration implements ConfigurationInterface
    +{
    +    public function getConfigTreeBuilder()
    +    {
    +        $treeBuilder = new TreeBuilder();
    +        $rootNode    = $treeBuilder->root('acme_demo');
    +
    +        $rootNode
    +            ->children()
    +                ->scalarNode('my_type')->defaultValue('bar')->end()
    +            ->end();
    +
    +        return $treeBuilder;
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Configuration Class (2/2)

    + + +

    Usage

    +
    public function load(array $configs, ContainerBuilder $container)
    +{
    +    $configuration = new Configuration();
    +
    +    $config = $this->processConfiguration($configuration, $configs);
    +
    +    // ...
    +}
    +
    + +

    The processConfiguration() method uses the configuration tree you've defined +in the Configuration class to validate, normalize and merge all of +the configuration arrays together.

    +
    +

    Read more on How to expose a Semantic Configuration for a Bundle: +http://symfony.com/doc/master/cookbook/bundles/extension.html.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    More On The Service Container

    + + +

    Tags

    +

    In the service container, a tag implies that the service is meant to be used +for a specific purpose.

    +
    <service id="my_bundle.twig.foo" class="My\Bundle\Twig\FooExtension">
    +    <tag name="twig.extension" />
    +</service>
    +
    + +

    Twig finds all services tagged with twig.extension and automatically registers +them as extensions.

    +

    Debugging Services

    +
    $ php app/console container:debug
    +
    +$ php app/console container:debug foo
    +
    + +
    +

    http://symfony.com/doc/master/book/service_container.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Symfony2 Commands

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Built-in Commands (1/2)

    + + +
    $ php app/console
    +
    + +

    Global Options

    +

    You can get help information:

    +
    $ php app/console help cmd
    +$ php app/console cmd --help
    +$ php app/console cmd -h
    +
    + +

    You can get more verbose messages:

    +
    $ php app/console cmd --verbose
    +$ php app/console cmd -v [-vv] [-vvv]
    +
    + +

    You can suppress output:

    +
    $ php app/console cmd --quiet
    +$ php app/console cmd -q
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Built-in Commands (2/2)

    + + +
    assets
    +  assets:install          Installs bundles web assets under a public
    +                          web directory
    +cache
    +  cache:clear             Clears the cache
    +  cache:warmup            Warms up an empty cache
    +config
    +  config:dump-reference   Dumps default configuration for an extension
    +container
    +  container:debug         Displays current services for an application
    +init
    +  init:acl                Mounts ACL tables in the database
    +router
    +  router:debug            Displays current routes for an application
    +  router:dump-apache      Dumps all routes as Apache rewrite rules
    +  router:match            Helps debug routes by simulating a path info
    +                          match
    +server
    +  server:run              Runs PHP built-in web server
    +translation
    +  translation:update      Updates the translation file
    +twig
    +  twig:lint               Lints a template and outputs encountered
    +                          errors
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Creating Commands

    + + +

    Create a Command directory inside your bundle and create a php file suffixed +with Command.php for each command that you want to provide:

    +
    // src/Acme/DemoBundle/Command/GreetCommand.php
    +namespace Acme\DemoBundle\Command;
    +
    +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    +use Symfony\Component\Console\Input\InputInterface;
    +use Symfony\Component\Console\Output\OutputInterface;
    +
    +class GreetCommand extends ContainerAwareCommand
    +{
    +    protected function configure()
    +    {
    +        $this->setName('demo:greet');
    +    }
    +
    +    protected function execute(
    +        InputInterface $input,
    +        OutputInterface $output
    +    ) {
    +        // code ...
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Command Arguments

    + + +

    Arguments are the strings, separated by spaces, that come after the command +name itself. They are ordered, and can be optional or required.

    +
    protected function configure()
    +{
    +    $this
    +        // ...
    +        ->addArgument(
    +            'name',
    +            InputArgument::REQUIRED,
    +            'Who do you want to greet?'
    +        )
    +        ->addArgument(
    +            'last_name',
    +            InputArgument::OPTIONAL,
    +            'Your last name?'
    +        );
    +}
    +
    + +

    Usage

    +
    $input->getArgument('last_name');
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Command Options (1/2)

    + + +

    Unlike arguments, options are not ordered, always optional, and can be +setup to accept a value or simply as a boolean flag without a value.

    +
    protected function configure()
    +{
    +    $this
    +        // ...
    +        ->addOption(
    +            'yell',
    +            null,
    +            InputOption::VALUE_NONE,
    +            'If set, the task will yell in uppercase letters'
    +        );
    +}
    +
    + +

    Usage

    +
    // php app/console demo:greet --yell
    +
    +if ($input->getOption('yell')) {
    +    // ...
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Command Options (2/2)

    + + +
    protected function configure()
    +{
    +    $this
    +        // ...
    +        ->addOption(
    +            'iterations',
    +            null,
    +            InputOption::VALUE_REQUIRED,
    +            'How many times should the message be printed?',
    +            1
    +        );
    +}
    +
    + +

    Usage

    +
    // php app/console demo:greet --iterations=10
    +
    +for ($i = 0; $i < $input->getOption('iterations'); $i++) {
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    More On Commands

    + + +

    Getting Services from the Service Container

    +
    protected function execute(
    +    InputInterface $input,
    +    OutputInterface $output
    +) {
    +    $translator = $this->getContainer()->get('translator');
    +    // ...
    +}
    +
    + +

    Calling an existing Command

    +
    $command   = $this->getApplication()->find('demo:greet');
    +$arguments = array(
    +    'command' => 'demo:greet',
    +    'name'    => 'Fabien',
    +    'yell'    => true,
    +);
    +
    +$returnCode = $command->run(new ArrayInput($arguments), $output);
    +
    + +
    +

    http://symfony.com/doc/master/cookbook/console/index.html

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Forms

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Building Your First Form

    + + +
    public function newAction(Request $request)
    +{
    +    $form = $formFactory
    +        ->createFormBuilder()
    +        ->add('name')
    +        ->add('bio', 'textarea')
    +        ->add('birthday', 'date')
    +        ->getForm();
    +
    +    return $this->render('AcmeDemoBundle:Default:new.html.twig', [
    +        'form' => $form->createView(),
    +    ]);
    +}
    +
    + +

    In order to display the Form, you need to pass a special view object to the +View layer. It's achieved through the createView() method.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Rendering The Form

    + + +

    +

    +
    {# src/Acme/DemoBundle/Resources/views/Default/new.html.twig #}
    +<form action="{{ path('acme_demo.default_new') }}" method="post">
    +    {{ form_widget(form) }}
    +
    +    <input type="submit" />
    +</form>
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Handling Forms: The Right Way

    + + +
      +
    1. +

      When initially loading the page in a browser, the request method is GET +and the form is simply created and rendered;

      +
    2. +
    3. +

      When the user submits the form (i.e. the method is POST) with invalid +data, the form is bound and then rendered, this time displaying all +validation errors;

      +
    4. +
    5. +

      When the user submits the form with valid data, the form is bound and you have +the opportunity to perform some actions before redirecting the user to some +other page (e.g. a "success" page).

      +
    6. +
    +

    Redirecting a user after a successful form submission prevents the user from +being able to hit "refresh" and re-post the data.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Handling Form Submissions

    + + +
    public function newAction(Request $request)
    +{
    +    $form = $formFactory
    +        ->createFormBuilder()
    +        ->add('name')
    +        ->add('bio', 'textarea')
    +        ->add('birthday', 'date')
    +        ->getForm();
    +
    +    if ($request->isMethod('POST')) {
    +        $form->handleRequest($request);
    +
    +        if ($form->isValid()) {
    +            $data = $form->getData();
    +            // do something ...
    +
    +            return $this->redirect($this->generateUrl('success'));
    +        }
    +    }
    +
    +    // ...
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Built-in Form Types

    + + +

    Everything is a Type!

    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Creating A Custom Type (Form Class)

    + + +
    use Symfony\Component\Form\AbstractType;
    +use Symfony\Component\Form\FormBuilderInterface;
    +use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    +
    +class PersonType extends AbstractType
    +{
    +    public function buildForm(FormBuilderInterface $builder, array $options)
    +    {
    +        $builder
    +            ->add('name')
    +            ->add('bio', 'textarea')
    +            ->add('birthday', 'date');
    +    }
    +
    +    public function setDefaultOptions(OptionsResolverInterface $resolver)
    +    {
    +        $resolver->setDefaults([
    +            'data_class' => 'My\Person',
    +        ]);
    +    }
    +
    +    public function getName()
    +    {
    +        return 'person';
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Dealing With Objects

    + + +
    public function newAction(Request $request)
    +{
    +    $person = new Person();
    +    $form   = $this->createForm(new PersonType(), $person);
    +
    +    if ($request->isMethod('POST')) {
    +        $form->handleRequest($request);
    +
    +        if ($form->isValid()) {
    +            $person->save(); // insert a new `person`
    +
    +            return $this->redirect($this->generateUrl('success'));
    +        }
    +    }
    +
    +    // ...
    +}
    +
    + +

    Placing the form logic into its own class means that the form can be easily +reused elsewhere in your project.

    +

    This is the best way to create forms, but the choice is up to you!

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The processForm() Method (1/2)

    + + +

    Saving or updating an object is pretty much the same thing. In order to avoid +code duplication, you can use a processForm() method that can be used in both +the newAction() and the updateAction():

    +
    /**
    + * Create a new Person
    + */
    +public function newAction()
    +{
    +    return $this->processForm(new Person());
    +}
    +
    +/**
    + * Update an existing Person
    + */
    +public function updateAction($id)
    +{
    +    $person = ...; // get a `Person` by its $id
    +
    +    return $this->processForm($person);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The processForm() Method (2/2)

    + + +
    /**
    + * @param Person $person
    + *
    + * @return Response
    + */
    +private function processForm(Person $person)
    +{
    +    $form = $this->createForm(new PersonType(), $person);
    +
    +    if ($this->getRequest()->isMethod('POST')) {
    +        $form->handleRequest($this->getRequest());
    +
    +        if ($form->isValid()) {
    +            $person->save();
    +
    +            return $this->redirect($this->generateUrl('success'));
    +        }
    +    }
    +
    +    return $this->render('AcmeDemoBundle:Default:new.html.twig', [
    +        'form' => $form->createView(),
    +    ]);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Cross-Site Request Forgery Protection

    + + +

    CSRF is a method by which a malicious user attempts to make your legitimate +users unknowingly submit data that they don't intend to submit. Fortunately, +CSRF attacks can be prevented by using a CSRF token inside your forms.

    +

    CSRF protection works by adding a hidden field to your form, called _token +by default that contains a value that only you and your user knows.

    +

    This ensures that the user is submitting the given data. Symfony automatically +validates the presence and accuracy of this token.

    +

    The _token field is a hidden field and will be automatically rendered if you +include the form_rest() function in your template, which ensures that all +un-rendered fields are output.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Rendering a Form in a Template (1/2)

    + + +
    <form action="" method="post" {{ form_enctype(form) }}>
    +    {{ form_errors(form) }}
    +
    +    {{ form_row(form.name) }}
    +
    +    {{ form_row(form.bio) }}
    +
    +    {{ form_row(form.birthday) }}
    +
    +    {{ form_rest(form) }}
    +
    +    <input type="submit" />
    +</form>
    +
    + +
    +

    Read more: +http://symfony.com/doc/master/book/forms.html#rendering-a-form-in-a-template.

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Rendering a Form in a Template (2/2)

    + + +
      +
    • +

      form_enctype(form): if at least one field is a file upload field, this renders + the obligatory enctype="multipart/form-data";

      +
    • +
    • +

      form_errors(form): renders any errors global to the whole form (field-specific + errors are displayed next to each field);

      +
    • +
    • +

      form_row(form.name): renders the label, any errors, and the HTML form widget + for the given field inside, by default, a div element;

      +
    • +
    • +

      form_rest(form): renders any fields that have not yet been rendered. It's + usually a good idea to place a call to this helper at the bottom of each form + This helper is also useful for taking advantage of the automatic CSRF Protection.

      +
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Validation

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    About Form Validation

    + + +

    In the previous section, you learned how a form can be submitted with valid or +invalid data. In Symfony2, validation is applied to the underlying object.

    +

    In other words, the question isn't whether the "form" is valid, but whether or +not the object is valid after the form has applied the submitted data to it.

    +

    Calling $form->isValid() is a shortcut that asks the object whether or not +it has valid data.

    +

    Validation is done by adding a set of rules (called constraints) to a class.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Validator Component

    + + +

    This component is based on the JSR303 Bean Validation +specification.

    +

    Example

    +

    Given the following class:

    +
    namespace Acme\DemoBundle\Entity;
    +
    +class Author
    +{
    +    public $name;
    +}
    +
    + +

    You can configure a set of constraints on this class:

    +
    # src/Acme/DemoBundle/Resources/config/validation.yml
    +Acme\DemoBundle\Entity\Author:
    +    properties:
    +        name:
    +            - NotBlank: ~
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Using the validator Service

    + + +
    $author = new Author();
    +// ... do something to the $author object
    +
    +$validator = $this->get('validator');
    +$errors    = $validator->validate($author);
    +
    +if (count($errors) > 0) {
    +    // Ooops, errors!
    +} else {
    +    // Everything is ok :-)
    +}
    +
    + +

    If the $name property is empty, you will see the following error message:

    +
    Acme\DemoBundle\Author.name:
    +    This value should not be blank
    +
    + +

    Most of the time, you won't interact directly with the validator service or need +to worry about printing out the errors. Most of the time, you will use +validation indirectly when handling submitted form data.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    + +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Constraint Targets (1/2)

    + + +

    Constraints can be applied to a class property or a public getter method +(e.g. getFullName()). The first is the most common and easy to use, but the +second allows you to specify more complex validation rules.

    +

    Properties

    +

    Validating class properties is the most basic validation technique. Symfony2 +allows you to validate private, protected or public properties.

    +
    # src/Acme/DemoBundle/Resources/config/validation.yml
    +Acme\DemoBundle\Entity\Author:
    +    properties:
    +        firstName:
    +            - NotBlank: ~
    +
    + +

    Classes

    +

    Some constraints apply to the entire class being validated. For example, the +Callback constraint is a generic constraint that's applied to the clas +itself.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Constraint Targets (2/2)

    + + +

    Getters

    +

    Constraints can also be applied to the return value of a method. Symfony2 +allows you to add a constraint to any public method whose name starts with +get or is.

    +
    # src/Acme/DemoBundle/Resources/config/validation.yml
    +Acme\DemoBundle\Entity\Author:
    +    getters:
    +        passwordLegal:
    +            - "False":
    +                message: "The password cannot match your first name"
    +
    + +

    With the following code in the Author class:

    +
    public function isPasswordLegal()
    +{
    +    return ($this->firstName !== $this->password);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Validation Groups (1/2)

    + + +

    In some cases, you will need to validate an object against only some of the +constraints on that class.

    +

    You can organize each constraint into one or more validation groups, and +then apply validation against just one group of constraints.

    +

    Example

    +
    # src/Acme/DemoBundle/Resources/config/validation.yml
    +Acme\DemoBundle\Entity\User:
    +    properties:
    +        email:
    +            - Email:    { groups: [ registration ] }
    +        password:
    +            - NotBlank: { groups: [ registration ] }
    +            - Length:   { groups: [ registration ], min: 7 }
    +        city:
    +            - Length:
    +                min: 2
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Validation Groups (2/2)

    + + +

    With the configuration seen before, there are two validation groups:

    +
      +
    • Default: contains the constraints not assigned to any other group;
    • +
    • registration: contains the constraints on the email and password fields only.
    • +
    +

    To tell the validator to use a specific group, pass one or more group names as +the second argument to the validate() method:

    +
    $errors = $validator->validate($author, [ 'registration' ]);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Using Validation Groups In Forms

    + + +

    If your object takes advantage of validation groups, you'll need to specify +which validation group(s) your form should use:

    +
    $form = $this
    +    ->createFormBuilder($users, [
    +        'validation_groups' => [ 'registration' ],
    +    ])
    +    ->add(...);
    +
    + +

    If you're creating form classes, then you'll need to add the following to +the setDefaultOptions() method:

    +
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    +
    +public function setDefaultOptions(OptionsResolverInterface $resolver)
    +{
    +    $resolver->setDefaults([
    +        'validation_groups' => [ 'registration' ],
    +    ]);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Validating Values and Arrays

    + + +
    use Symfony\Component\Validator\Constraints\Email;
    +
    +$emailConstraint = new Email();
    +$emailConstraint->message = 'Invalid email address';
    +
    +$errorList = $this->get('validator')->validateValue(
    +    $email, $emailConstraint
    +);
    +
    +if (0 !== count($errorList)) {
    +    // this is *not* a valid email address
    +    $errorMessage = $errorList[0]->getMessage();
    +}
    +
    + +

    By calling validateValue() on the validator, you can pass in a raw value and +the constraint object that you want to validate that value against.

    +

    The validateValue() method returns a ConstraintViolationList object, which +acts just like an array of errors.

    +

    Each error in the collection is a ConstraintViolation object, which holds the +error message on its getMessage() method.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Translations

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Definitions

    + + +

    Internationalization

    +

    The term internationalization (often abbreviated i18n) refers to the +process of abstracting strings and other locale-specific pieces out of your +application and into a layer where they can be translated and converted +based on the user's locale (i.e. language and country).

    +

    Localization

    +

    The act of creating translation files is an important part of localization +(often abbreviated l10n). It is the process of adapting a product or +service to a particular language, culture, and desired local +look-and-feel.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Using the translator Service

    + + +
    # messages.fr.yml
    +Symfony2 is great: J'aime Symfony2
    +'Hello %name%': Bonjour %name%
    +
    + +

    When the following code is executed, Symfony2 will attempt to translate the +message Symfony2 is great based on the locale of the user:

    +
    echo $this->get('translator')->trans('Symfony2 is great');
    +
    + +

    Now, if the language of the user's locale is French (e.g. fr_FR or fr_BE), +the message will be translated into J'aime Symfony2.

    +

    Message Placeholders

    +
    echo $this->get('translator')->trans('Hello %name%', [
    +    '%name%' => 'Will'
    +]);
    +
    +// French:  Bonjour Will
    +// Default: Hello Will
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Translation Process

    + + +

    To translate the message, Symfony2 uses a simple process:

    +
      +
    1. +

      The locale of the current user, which is stored on the request (or stored as +_locale on the session), is determined;

      +
    2. +
    3. +

      A catalog of translated messages is loaded from translation resources defined +for the locale (e.g. fr_FR). Messages from the fallback locale are also loaded +and added to the catalog if they don't already exist. The end result is a large +"dictionary" of translations;

      +
    4. +
    5. +

      If the message is located in the catalog, the translation is returned. If not, +the translator returns the original message.

      +
    6. +
    +

    When using the trans() method, Symfony2 looks for the exact string inside the +appropriate message catalog and returns it (if it exists).

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Locations and Naming Conventions

    + + +

    Symfony2 looks for message files (i.e. translations) in the following locations:

    +
      +
    • the <kernel root directory>/Resources/translations directory;
    • +
    • the <kernel root directory>/Resources/<bundle name>/translations directory;
    • +
    • the Resources/translations/ directory of the bundle.
    • +
    +

    The filename of the translations is also important as Symfony2 uses a convention +to determine details about the translations. Each message file must be named +according to the following path: domain.locale.loader:

    +
      +
    • domain: an optional way to organize messages into groups;
    • +
    • locale: the locale that the translations are for (en_GB, en, etc);
    • +
    • loader: how Symfony2 should load and parse the file (xliff, php or yml).
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Pluralization

    + + +

    When a translation has different forms due to pluralization, you can provide all +the forms as a string separated by a pipe (|):

    +
    'There is one apple|There are %count% apples'
    +
    + +

    To translate pluralized messages, use the transChoice() method:

    +
    $t = $this->get('translator')->transChoice(
    +    'There is one apple|There are %count% apples',
    +    10,
    +    array('%count%' => 10)
    +);
    +
    + +

    The second argument (10 in this example), is the number of objects being +described and is used to determine which translation to use and also to +populate the %count% placeholder.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Explicit Interval Pluralization

    + + +

    Sometimes, you'll need more control or want a different translation for specific +cases (for 0, or when the count is negative, for example). For such cases, you +can use explicit math intervals:

    +
    '{0} There are no apples|{1} There is one apple|]1,19] There are
    +%count% apples|[20,Inf] There are many apples'
    +
    + +

    The intervals follow the ISO 31-11 +notation.

    +

    An Interval can represent a finite set of numbers:

    +
    {1,2,3,4}
    +
    + +

    Or numbers between two other numbers:

    +
    [1, +Inf[
    +]-1,2[
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    BazingaJsTranslationBundle

    + + +
    # app/Resources/translations/Hello.fr.yml
    +ba:
    +    bar:      Bonjour.
    +place.holder: Bonjour %username%!
    +plural:       Il y a %count% pomme|Il y a %count% pommes
    +
    + +

    + +
    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'Hello' }) }}">
    +</script>
    +
    + +

    A Translator object is now available in your JavaScript:

    +
    Translator.trans('ba.bar', {}, 'Hello', 'fr');
    +// "Bonjour."
    +
    +Translator.trans('place.holder', { "username" : "Will" }, 'Hello');
    +// "Bonjour Will!"
    +
    +Translator.transChoice('plural', 1, { "count": 1 }, 'Hello');
    +// "Il y a 1 pomme"
    +
    +Translator.transChoice('plural', 10, { "count": 10 }, 'Hello');
    +// "Il y a 10 pommes"
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    HTTP Cache

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    HTTP Cache

    + + +

    The nature of rich web applications means that they're dynamic. No matter how +efficient your application, each request will always contain more overhead +than serving a static file.

    +

    But as your site grows, that overhead can become a problem. The processing +that's normally performed on every request should be done only once.

    +

    This is exactly what caching aims to accomplish!

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Terminology (1/2)

    + + +

    Gateway Cache

    +

    A gateway cache, or reverse proxy, is an independent layer that sits in +front of your application.

    +

    The reverse proxy caches responses as they are returned from your application +and answers requests with cached responses before they hit your application.

    +

    Symfony2 provides its own reverse proxy, but any reverse proxy can be used.

    +

    HTTP Cache

    +

    HTTP cache headers are used to communicate with the gateway cache and any +other caches between your application and the client.

    +

    Symfony2 provides sensible defaults and a powerful interface for interacting +with the cache headers.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Terminology (2/2)

    + + +

    HTTP Expiration

    +

    HTTP expiration and validation are the two models used for determining +whether cached content is fresh (can be reused from the cache) or stale (should +be regenerated by the application).

    +

    Edge Side Includes

    +

    Edge Side Includes (ESI) allow HTTP cache to be used to cache page +fragments (even nested fragments) independently. With ESI, you can even cache +an entire page for 60 minutes, but an embedded sidebar for only 5 minutes.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Caching with a Gateway Cache

    + + +

    When caching with HTTP, the cache is separated from your application entirely +and sits between your application and the client making the request.

    +

    The job of the cache is to accept requests from the client and pass them back +to your application.

    +

    The cache will also receive responses back from your application and forward +them on to the client. The cache is the middle-man of the request-response +communication between the client and your application.

    +

    Along the way, the cache will store each response that is deemed cacheable. +If the same resource is requested again, the cache sends the cached response to +the client, ignoring your application entirely.

    +

    This type of cache is known as a HTTP gateway cache and many exist such as +Varnish, Squid in reverse proxy mode, and the Symfony2 reverse +proxy.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Types of Caches

    + + +

    The HTTP cache headers sent by your application are consumed and interpreted by +up to three different types of caches:

    +
      +
    • Browser Caches: every browser comes with its own local cache that is mainly +useful for when you hit "back" or for images and other assets. The browser cache +is a private cache as cached resources aren't shared with anyone else;
    • +
    • Proxy Caches: a proxy is a shared cache as many people can be behind a +single one. It's usually installed by large corporations and ISPs to reduce +latency and network traffic;
    • +
    • Gateway Caches: like a proxy, it's also a shared cache but on the +server side. Installed by network administrators, it makes websites more +scalable, reliable and performant.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    HTTP Caching

    + + +

    HTTP specifies four response cache headers that are looked at here:

    +
      +
    • Cache-Control
    • +
    • Expires
    • +
    • ETag
    • +
    • Last-Modified
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Public vs Private Responses

    + + +

    Both gateway and proxy caches are considered shared caches as the cached +content is shared by more than one user.

    +

    If a user-specific response were ever mistakenly stored by a shared cache, it +might be returned later to any number of different users. Imagine if your +account information were cached and then returned to every subsequent user who +asked for their account page!

    +

    To handle this situation, every response may be set to be public or private:

    +
      +
    • public: indicates that the response may be cached by both private and +shared caches;
    • +
    • private: indicates that all or part of the response message is intended for +a single user and must not be cached by a shared cache.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Safe Methods

    + + +

    HTTP caching only works for safe HTTP methods (like GET and HEAD). Being +safe means that you never change the application's state on the server when +serving the request.

    +

    This has two very reasonable consequences:

    +
      +
    • You should never change the state of your application when responding to a +GET or HEAD request. Even if you don't use a gateway cache, the presence +of proxy caches mean that any GET or HEAD request may or may not actually +hit your server;
    • +
    • Don't expect PUT, POST or DELETE methods to cache. These methods are +meant to be used when mutating the state of your application. Caching them +would prevent certain requests from hitting and mutating your application.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Expiration

    + + +

    The expiration model is the more efficient and straightforward of the two +caching models and should be used whenever possible.

    +

    When a response is cached with an expiration, the cache will store the response +and return it directly without hitting the application until it expires.

    +

    The expiration model can be accomplished using one of two HTTP headers:

    +
      +
    • Cache-Control
    • +
    • Expires
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Cache-Control Header (1/2)

    + + +

    The Cache-Control header is unique in that it contains not one, but +various pieces of information about the cacheability of a response.

    +

    Each piece of information is separated by a comma:

    +
    Cache-Control: private, max-age=0, must-revalidate
    +Cache-Control: max-age=3600, must-revalidate
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Cache-Control Header (2/2)

    + + +

    Symfony provides an abstraction around the Cache-Control header:

    +
    use Symfony\Component\HttpFoundation\Response;
    +
    +$response = new Response();
    +
    +// mark the response as either public or private
    +$response->setPublic();
    +$response->setPrivate();
    +
    +// set the private or shared max age
    +$response->setMaxAge(600);
    +$response->setSharedMaxAge(600);
    +
    +// set a custom Cache-Control directive
    +$response->headers->addCacheControlDirective('must-revalidate', true);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Expires Header

    + + +

    The Expires header can be set with the setExpires() Response method. It takes +a DateTime instance as an argument:

    +
    $date = new DateTime();
    +$date->modify('+600 seconds');
    +
    +$response->setExpires($date);
    +
    + +

    The resulting HTTP header will look like this:

    +
    Expires: Thu, 01 Mar 2013 10:00:00 GMT
    +
    + +

    The setExpires() method automatically converts the date to the GMT timezone as +required by the specification.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Validation

    + + +

    With the expiration model, the application won't be asked to return the updated +response until the cache finally becomes stale. It is not good!

    +

    The validation model addresses this issue.

    +

    Under this model, the cache continues to store responses. The difference is +that, for each request, the cache asks the application whether or not the +cached response is still valid.

    +

    If the cache is still valid, your application should return a 304 status code +and no content. This tells the cache that it's ok to return the cached response.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The ETag Header

    + + +

    The ETag header is a string header called entity-tag that uniquely +identifies one representation of the target resource. It's entirely +generated and set by your application.

    +

    An ETag is like a fingerprint and is used to quickly compare if two +unique across all representations of the same resource.

    +
    public function indexAction()
    +{
    +    $response = $this->render('MyBundle:Main:index.html.twig');
    +    $response->setETag(md5($response->getContent()));
    +    $response->setPublic(); // make sure the response is public/cacheable
    +    $response->isNotModified($this->getRequest());
    +
    +    return $response;
    +}
    +
    + +

    The isNotModified() method compares the ETag sent with the Request with +the one set on the Response. If the two match, the method automatically sets +the Response status code to 304 Not Modified.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Last-Modified Header (1/2)

    + + +

    According to the HTTP specification, the Last-Modified header field indicates +the date and time at which the origin server believes the representation was +last modified.

    +

    In other words, the application decides whether or not the cached content has +been updated based on whether or not it's been updated since the response was +cached.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Last-Modified Header (2/2)

    + + +
    public function showAction($articleSlug)
    +{
    +    // ...
    +
    +    $articleDate = new \DateTime($article->getUpdatedAt());
    +    $authorDate  = new \DateTime($author->getUpdatedAt());
    +
    +    $date = $authorDate > $articleDate ? $authorDate : $articleDate;
    +
    +    $response->setLastModified($date);
    +    // Set response as public. Otherwise it will be private by default
    +    $response->setPublic();
    +
    +    if ($response->isNotModified($this->getRequest())) {
    +        return $response;
    +    }
    +
    +    // ... do more work to populate the response
    +    // with the full content
    +
    +    return $response;
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Edge Side Includes (ESI)

    + + +

    Edge Side Includes or ESI is a small markup language for dynamic +web content assembly at the reverse proxy level. The reverse proxy analyses the +HTML code, parses ESI specific markup and assembles the final result before +flushing it to the client.

    +

    +
    <esi:include src="user.php" />
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Stack PHP

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    HttpKernel

    + + +


    +
    +

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    What Is Stack?

    + + +

    A convention for composing HttpKernelInterface middlewares:

    +

    +
    +

    http://stackphp.com/

    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Implementation

    + + +
    use Symfony\Component\HttpFoundation\Request;
    +use Symfony\Component\HttpKernel\HttpKernelInterface;
    +
    +class MyStackMiddleware implements HttpKernelInterface
    +{
    +    private $app;
    +
    +    public function __construct(HttpKernelInterface $app)
    +    {
    +        $this->app = $app;
    +    }
    +
    +    /**
    +     * {@inheritDoc}
    +     */
    +    public function handle(
    +        Request $request,
    +        $type = HttpKernelInterface::MASTER_REQUEST,
    +        $catch = true
    +    ) {
    +        // do something awesome
    +
    +        return $this->app->handle($request, $type, $catch);
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The End.

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + +
    +
    + + + + + + + Fork me on GitHub + + \ No newline at end of file diff --git a/index.html b/index.html index 2a463e8..0476953 100644 --- a/index.html +++ b/index.html @@ -1571,7 +1571,7 @@
    - +
    @@ -1589,7 +1589,7 @@
    - +
    @@ -1617,7 +1617,7 @@
    - +
    @@ -1668,7 +1668,7 @@
    - +
    @@ -1696,7 +1696,7 @@
    - +
    @@ -1735,7 +1735,7 @@

    Week #4

    - +
    @@ -1763,7 +1763,7 @@

    Week #4

    - +
    @@ -1798,7 +1798,7 @@

    Week #4

    - +
    @@ -1834,7 +1834,7 @@

    Week #4

    - +
    @@ -1870,7 +1870,7 @@

    Week #4

    - +
    @@ -1904,7 +1904,7 @@

    Week #4

    - +
    @@ -1939,7 +1939,7 @@

    Week #4

    - +
    @@ -1967,7 +1967,7 @@

    Week #4

    - +
    @@ -1995,7 +1995,7 @@

    Week #4

    - +
    @@ -2033,7 +2033,7 @@

    Week #4

    - +
    @@ -2082,7 +2082,7 @@

    Week #4

    - +
    @@ -2133,7 +2133,7 @@

    Week #4

    - +
    @@ -2176,7 +2176,7 @@

    Abstract class definition

    - +
    @@ -2228,7 +2228,7 @@

    Abstract class definition

    - +
    @@ -2267,7 +2267,7 @@

    The Rules

    - +
    @@ -2320,7 +2320,7 @@

    The Rules

    - +
    @@ -2369,7 +2369,7 @@

    Type Hinting

    - +
    @@ -2413,7 +2413,7 @@

    Usage

    - +
    @@ -2461,7 +2461,7 @@

    Usage

    - +
    @@ -2507,7 +2507,7 @@

    Usage

    - +
    @@ -2551,7 +2551,7 @@

    Usage

    - +
    @@ -2600,7 +2600,7 @@

    Usage

    - +
    @@ -2648,7 +2648,7 @@

    PSR-0

    - +
    @@ -2695,7 +2695,7 @@

    PSR-0

    - +
    @@ -2747,7 +2747,7 @@

    PSR-0

    - +
    @@ -2790,7 +2790,7 @@

    PSR-0

    - +
    @@ -2836,7 +2836,7 @@

    PSR-0

    - +
    @@ -2879,7 +2879,7 @@

    PSR-0

    - +
    @@ -2919,7 +2919,7 @@

    PSR-0

    - +
    @@ -2947,7 +2947,7 @@

    PSR-0

    - +
    @@ -2999,7 +2999,7 @@

    PSR-0

    - +
    @@ -3047,7 +3047,7 @@

    PSR-0

    - +
    @@ -3099,7 +3099,7 @@

    PSR-0

    - +
    @@ -3127,7 +3127,7 @@

    PSR-0

    - +
    @@ -3167,7 +3167,7 @@

    PSR-0

    - +
    @@ -3211,7 +3211,7 @@

    Collections

    - +
    @@ -3256,7 +3256,7 @@

    Collections

    - +
    @@ -3306,7 +3306,7 @@

    Collections

    - +
    @@ -3346,7 +3346,7 @@

    Collections

    - +
    @@ -3389,7 +3389,7 @@

    Collections

    - +
    @@ -3439,7 +3439,7 @@

    Collections

    - +
    @@ -3480,7 +3480,7 @@

    Collections

    - +
    @@ -3512,7 +3512,7 @@

    Collections

    - +
    @@ -3540,7 +3540,7 @@

    Collections

    - +
    @@ -3592,7 +3592,7 @@

    Hyper Media Types

    - +
    @@ -3644,7 +3644,7 @@

    Hyper Media Types

    - +
    @@ -3696,7 +3696,7 @@

    Hyper Media Types

    - +
    @@ -3724,7 +3724,7 @@

    Hyper Media Types

    - +
    @@ -3773,7 +3773,7 @@

    Hyper Media Types

    - +
    @@ -3823,7 +3823,7 @@

    Hyper Media Types

    - +
    @@ -3870,7 +3870,7 @@

    Hyper Media Types

    - +
    @@ -3919,7 +3919,7 @@

    Hyper Media Types

    - +
    @@ -3958,7 +3958,7 @@

    spl_autoload_functions()

    - +
    @@ -4007,7 +4007,7 @@

    spl_autoload_unregister()

    - +
    @@ -4062,7 +4062,7 @@

    spl_autoload_unregister()

    - +
    @@ -4090,7 +4090,7 @@

    spl_autoload_unregister()

    - +
    @@ -4135,7 +4135,7 @@

    Traversable

    - +
    @@ -4186,7 +4186,7 @@

    Traversable

    - +
    @@ -4237,7 +4237,7 @@

    Traversable

    - +
    @@ -4278,7 +4278,7 @@

    SPL Functions

    - +
    @@ -4331,7 +4331,7 @@

    SPL Functions

    - +
    @@ -4380,7 +4380,7 @@

    SPL Functions

    - +
    @@ -4429,7 +4429,7 @@

    SPL Functions

    - +
    @@ -4469,7 +4469,7 @@

    SPL Functions

    - +
    @@ -4520,7 +4520,7 @@

    SPL Functions

    - +
    @@ -4562,7 +4562,7 @@

    SPL Functions

    - +
    @@ -4590,7 +4590,7 @@

    SPL Functions

    - +
    @@ -4634,7 +4634,7 @@

    SPL Functions

    - +
    @@ -4684,7 +4684,7 @@

    SPL Functions

    - +
    @@ -4727,7 +4727,7 @@

    SPL Functions

    - +
    @@ -4775,7 +4775,7 @@

    SPL Functions

    - +
    @@ -4825,7 +4825,7 @@

    SPL Functions

    - +
    @@ -4872,7 +4872,7 @@

    Execution

    - +
    @@ -4925,7 +4925,7 @@

    Usage

    - +
    @@ -4953,7 +4953,7 @@

    Usage

    - +
    @@ -4996,7 +4996,7 @@

    Usage

    - +
    @@ -5039,7 +5039,7 @@

    Usage

    - +
    @@ -5092,7 +5092,7 @@

    Usage

    - +
    @@ -5139,7 +5139,7 @@

    Usage

    - +
    @@ -5188,7 +5188,7 @@

    Usage

    - +
    @@ -5240,7 +5240,7 @@

    Usage

    - +
    @@ -5283,7 +5283,7 @@

    Centralized declaration

    - +
    @@ -5316,7 +5316,7 @@

    Centralized declaration

    - +
    @@ -5357,7 +5357,7 @@

    Centralized declaration

    - +
    @@ -5385,7 +5385,7 @@

    Centralized declaration

    - +
    @@ -5420,7 +5420,7 @@

    Centralized declaration

    - +
    @@ -5455,7 +5455,7 @@

    Centralized declaration

    - +
    @@ -5496,7 +5496,7 @@

    Centralized declaration

    - +
    @@ -5524,7 +5524,7 @@

    Centralized declaration

    - +
    @@ -5578,7 +5578,7 @@

    Centralized declaration

    - +
    @@ -5624,7 +5624,7 @@

    Centralized declaration

    - +
    @@ -5671,7 +5671,7 @@

    Centralized declaration

    - +
    @@ -5699,7 +5699,7 @@

    Centralized declaration

    - +
    @@ -5747,7 +5747,7 @@

    CRUD

    - +
    @@ -5794,7 +5794,7 @@

    CRUD

    - +
    @@ -5842,7 +5842,7 @@

    CRUD

    - +
    @@ -5894,7 +5894,7 @@

    CRUD

    - +
    @@ -5939,7 +5939,7 @@

    CRUD

    - +
    @@ -5986,7 +5986,7 @@

    CRUD

    - +
    @@ -6014,7 +6014,7 @@

    CRUD

    - +
    @@ -6061,7 +6061,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6116,7 +6116,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6144,7 +6144,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6197,7 +6197,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6246,7 +6246,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6274,7 +6274,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6321,7 +6321,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6349,7 +6349,7 @@

    Active Record = Row Data Gateway + Domain Logic

    - +
    @@ -6392,7 +6392,7 @@

    PHP Data Object (PDO)

    - +
    @@ -6441,7 +6441,7 @@

    Usage

    - +
    @@ -6495,7 +6495,7 @@

    Usage

    - +
    @@ -6542,7 +6542,7 @@

    Usage

    - +
    @@ -6570,7 +6570,7 @@

    Usage

    - +
    @@ -6607,7 +6607,7 @@

    Usage

    - +
    @@ -6643,7 +6643,7 @@

    Code Snippet

    - +
    @@ -6679,7 +6679,7 @@

    Code Snippet

    - +
    @@ -6721,7 +6721,7 @@

    Code Snippet

    - +
    @@ -6761,7 +6761,7 @@

    Doctrine2 ORM

    - +
    @@ -6789,7 +6789,7 @@

    Doctrine2 ORM

    - +
    @@ -6831,7 +6831,7 @@

    A few use cases:

    - +
    @@ -6880,7 +6880,7 @@

    A few use cases:

    - +
    @@ -6921,7 +6921,7 @@

    Workarounds

    - +
    @@ -6949,7 +6949,7 @@

    Workarounds

    - +
    @@ -6980,7 +6980,7 @@

    Workarounds

    - +
    @@ -7010,7 +7010,7 @@

    Workarounds

    - +
    @@ -7051,7 +7051,7 @@

    Event Dispatcher

    - +
    @@ -7099,7 +7099,7 @@

    Event Dispatcher

    - +
    @@ -7151,7 +7151,7 @@

    Event Dispatcher

    - +
    @@ -7195,7 +7195,7 @@

    Event Dispatcher

    - +
    @@ -7235,7 +7235,7 @@

    Event Dispatcher

    - +
    @@ -7292,7 +7292,7 @@

    Event Dispatcher

    - +
    @@ -7322,7 +7322,7 @@

    Event Dispatcher

    - +
    @@ -7375,7 +7375,7 @@

    Event Dispatcher

    - +
    @@ -7411,7 +7411,7 @@

    WSSE Username Token

    - +
    @@ -7455,7 +7455,7 @@

    WSSE Username Token

    - +
    @@ -7483,7 +7483,7 @@

    WSSE Username Token

    - +
    @@ -7520,7 +7520,7 @@

    WSSE Username Token

    - +
    @@ -7577,7 +7577,7 @@

    WSSE Username Token

    - +
    @@ -7621,7 +7621,7 @@

    Usage

    - +
    @@ -7666,7 +7666,7 @@

    Usage

    - +
    @@ -7703,7 +7703,7 @@

    Usage

    - +
    @@ -7746,7 +7746,7 @@

    Usage

    - +
    @@ -7788,7 +7788,7 @@

    Usage

    - +
    @@ -7830,7 +7830,7 @@

    Usage

    - +
    @@ -7879,7 +7879,7 @@

    Usage

    - +
    @@ -7928,7 +7928,7 @@

    Usage

    - +
    @@ -7971,7 +7971,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8013,7 +8013,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8054,7 +8054,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8100,7 +8100,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8128,7 +8128,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8162,7 +8162,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8190,7 +8190,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8236,7 +8236,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8284,7 +8284,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8323,7 +8323,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8373,7 +8373,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8401,7 +8401,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8438,7 +8438,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8466,7 +8466,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8509,7 +8509,7 @@

    StoryBDD

    - +
    @@ -8555,7 +8555,7 @@

    StoryBDD

    - +
    @@ -8603,7 +8603,7 @@

    StoryBDD

    - +
    @@ -8656,7 +8656,7 @@

    StoryBDD

    - +
    @@ -8684,7 +8684,7 @@

    StoryBDD

    - +
    @@ -8716,7 +8716,7 @@

    StoryBDD

    - +
    @@ -8744,7 +8744,7 @@

    StoryBDD

    - +
    @@ -8772,7 +8772,7 @@

    StoryBDD

    - +
    @@ -8800,7 +8800,7 @@

    StoryBDD

    - +
    @@ -8828,7 +8828,7 @@

    StoryBDD

    - +
    @@ -8868,7 +8868,7 @@

    StoryBDD

    - +
    @@ -8896,7 +8896,7 @@

    StoryBDD

    - +
    -

    Well... Maybe Not.
    PHP Extended

    +

    Well... Maybe Not.
    PHP Extended

    @@ -8924,7 +8924,7 @@

    StoryBDD

    @@ -1621,7 +1621,7 @@
    @@ -1672,7 +1672,7 @@
    @@ -1700,7 +1700,7 @@
    @@ -1715,7 +1715,8 @@

    Week #1

    -

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server

    +

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, +Client/Server, REST

    Week #2

    Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View Controller

    @@ -1739,7 +1740,7 @@

    Week #4

    @@ -1767,7 +1768,7 @@

    Week #4

    @@ -1802,7 +1803,7 @@

    Week #4

    @@ -1838,7 +1839,7 @@

    Week #4

    @@ -1874,7 +1875,7 @@

    Week #4

    @@ -1908,7 +1909,7 @@

    Week #4

    @@ -1943,7 +1944,7 @@

    Week #4

    @@ -1971,7 +1972,7 @@

    Week #4

    @@ -1999,7 +2000,7 @@

    Week #4

    @@ -2037,7 +2038,7 @@

    Week #4

    @@ -2086,7 +2087,7 @@

    Week #4

    @@ -2137,7 +2138,7 @@

    Week #4

    @@ -2180,7 +2181,7 @@

    Abstract class definition

    @@ -2232,7 +2233,7 @@

    Abstract class definition

    @@ -2271,7 +2272,7 @@

    The Rules

    @@ -2324,7 +2325,7 @@

    The Rules

    @@ -2373,7 +2374,7 @@

    Type Hinting

    @@ -2417,7 +2418,7 @@

    Usage

    @@ -2465,7 +2466,7 @@

    Usage

    @@ -2511,7 +2512,7 @@

    Usage

    @@ -2555,7 +2556,7 @@

    Usage

    @@ -2604,7 +2605,7 @@

    Usage

    @@ -2652,7 +2653,7 @@

    PSR-0

    @@ -2699,7 +2700,7 @@

    PSR-0

    @@ -2751,7 +2752,7 @@

    PSR-0

    @@ -2794,7 +2795,7 @@

    PSR-0

    @@ -2840,7 +2841,7 @@

    PSR-0

    @@ -2883,7 +2884,7 @@

    PSR-0

    @@ -2923,7 +2924,7 @@

    PSR-0

    @@ -2951,7 +2952,7 @@

    PSR-0

    @@ -3003,7 +3004,7 @@

    PSR-0

    @@ -3051,7 +3052,7 @@

    PSR-0

    @@ -3103,7 +3104,7 @@

    PSR-0

    @@ -3131,7 +3132,7 @@

    PSR-0

    @@ -3171,7 +3172,7 @@

    PSR-0

    @@ -3215,7 +3216,7 @@

    Collections

    @@ -3260,7 +3261,7 @@

    Collections

    @@ -3310,7 +3311,7 @@

    Collections

    @@ -3350,7 +3351,7 @@

    Collections

    @@ -3393,7 +3394,7 @@

    Collections

    @@ -3443,7 +3444,7 @@

    Collections

    @@ -3454,7 +3455,35 @@

    Collections

    -

    REST (REpresentational State Transfer)

    +

    REST

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    REpresentational State Transfer

    REST is the underlying architectural principle of the web, formalized as a set @@ -3484,7 +3513,7 @@

    Collections

    @@ -3516,7 +3545,7 @@

    Collections

    @@ -3544,7 +3573,7 @@

    Collections

    @@ -3596,7 +3625,7 @@

    Hyper Media Types

    @@ -3648,7 +3677,7 @@

    Hyper Media Types

    @@ -3700,7 +3729,7 @@

    Hyper Media Types

    @@ -3728,7 +3757,7 @@

    Hyper Media Types

    @@ -3777,7 +3806,7 @@

    Hyper Media Types

    @@ -3827,7 +3856,7 @@

    Hyper Media Types

    @@ -3874,7 +3903,7 @@

    Hyper Media Types

    @@ -3923,7 +3952,7 @@

    Hyper Media Types

    @@ -3962,7 +3991,7 @@

    spl_autoload_functions()

    @@ -4011,7 +4040,7 @@

    spl_autoload_unregister()

    @@ -4066,7 +4095,7 @@

    spl_autoload_unregister()

    @@ -4094,7 +4123,7 @@

    spl_autoload_unregister()

    @@ -4139,7 +4168,7 @@

    Traversable

    @@ -4190,7 +4219,7 @@

    Traversable

    @@ -4241,7 +4270,7 @@

    Traversable

    @@ -4282,7 +4311,7 @@

    SPL Functions

    @@ -4335,7 +4364,7 @@

    SPL Functions

    @@ -4384,7 +4413,7 @@

    SPL Functions

    @@ -4433,7 +4462,7 @@

    SPL Functions

    @@ -4473,7 +4502,7 @@

    SPL Functions

    @@ -4524,7 +4553,7 @@

    SPL Functions

    @@ -4566,7 +4595,7 @@

    SPL Functions

    @@ -4594,7 +4623,7 @@

    SPL Functions

    @@ -4638,7 +4667,7 @@

    SPL Functions

    @@ -4688,7 +4717,7 @@

    SPL Functions

    @@ -4731,7 +4760,7 @@

    SPL Functions

    @@ -4779,7 +4808,7 @@

    SPL Functions

    @@ -4829,7 +4858,7 @@

    SPL Functions

    @@ -4876,7 +4905,7 @@

    Execution

    @@ -4929,7 +4958,7 @@

    Usage

    @@ -4957,7 +4986,7 @@

    Usage

    @@ -5000,7 +5029,7 @@

    Usage

    @@ -5043,7 +5072,7 @@

    Usage

    @@ -5096,7 +5125,7 @@

    Usage

    @@ -5143,7 +5172,7 @@

    Usage

    @@ -5192,7 +5221,7 @@

    Usage

    @@ -5244,7 +5273,7 @@

    Usage

    @@ -5287,7 +5316,7 @@

    Centralized declaration

    @@ -5320,7 +5349,7 @@

    Centralized declaration

    @@ -5361,7 +5390,7 @@

    Centralized declaration

    @@ -5389,7 +5418,7 @@

    Centralized declaration

    @@ -5424,7 +5453,7 @@

    Centralized declaration

    @@ -5459,7 +5488,7 @@

    Centralized declaration

    @@ -5500,7 +5529,7 @@

    Centralized declaration

    @@ -5528,7 +5557,7 @@

    Centralized declaration

    @@ -5582,7 +5611,7 @@

    Centralized declaration

    @@ -5628,7 +5657,7 @@

    Centralized declaration

    @@ -5675,7 +5704,7 @@

    Centralized declaration

    @@ -5703,7 +5732,7 @@

    Centralized declaration

    @@ -5751,7 +5780,7 @@

    CRUD

    @@ -5798,7 +5827,7 @@

    CRUD

    @@ -5846,7 +5875,7 @@

    CRUD

    @@ -5898,7 +5927,7 @@

    CRUD

    @@ -5943,7 +5972,7 @@

    CRUD

    @@ -5990,7 +6019,7 @@

    CRUD

    @@ -6018,7 +6047,7 @@

    CRUD

    @@ -6065,7 +6094,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6120,7 +6149,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6148,7 +6177,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6201,7 +6230,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6250,7 +6279,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6278,7 +6307,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6325,7 +6354,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6353,7 +6382,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6396,7 +6425,7 @@

    PHP Data Object (PDO)

    @@ -6445,7 +6474,7 @@

    Usage

    @@ -6499,7 +6528,7 @@

    Usage

    @@ -6546,7 +6575,7 @@

    Usage

    @@ -6574,7 +6603,7 @@

    Usage

    @@ -6611,7 +6640,7 @@

    Usage

    @@ -6647,7 +6676,7 @@

    Code Snippet

    @@ -6683,7 +6712,7 @@

    Code Snippet

    @@ -6725,7 +6754,7 @@

    Code Snippet

    @@ -6765,7 +6794,7 @@

    Doctrine2 ORM

    @@ -6793,7 +6822,7 @@

    Doctrine2 ORM

    @@ -6835,7 +6864,7 @@

    A few use cases:

    @@ -6884,7 +6913,7 @@

    A few use cases:

    @@ -6925,7 +6954,7 @@

    Workarounds

    @@ -6953,7 +6982,7 @@

    Workarounds

    @@ -6984,7 +7013,7 @@

    Workarounds

    @@ -7014,7 +7043,7 @@

    Workarounds

    @@ -7055,7 +7084,7 @@

    Event Dispatcher

    @@ -7103,7 +7132,7 @@

    Event Dispatcher

    @@ -7155,7 +7184,7 @@

    Event Dispatcher

    @@ -7199,7 +7228,7 @@

    Event Dispatcher

    @@ -7239,7 +7268,7 @@

    Event Dispatcher

    @@ -7296,7 +7325,7 @@

    Event Dispatcher

    @@ -7326,7 +7355,7 @@

    Event Dispatcher

    @@ -7379,7 +7408,7 @@

    Event Dispatcher

    @@ -7415,7 +7444,7 @@

    WSSE Username Token

    @@ -7459,7 +7488,7 @@

    WSSE Username Token

    @@ -7487,7 +7516,7 @@

    WSSE Username Token

    @@ -7524,7 +7553,7 @@

    WSSE Username Token

    @@ -7581,7 +7610,7 @@

    WSSE Username Token

    @@ -7625,7 +7654,7 @@

    Usage

    @@ -7670,7 +7699,7 @@

    Usage

    @@ -7707,7 +7736,7 @@

    Usage

    @@ -7750,7 +7779,7 @@

    Usage

    @@ -7792,7 +7821,7 @@

    Usage

    @@ -7834,7 +7863,7 @@

    Usage

    @@ -7883,7 +7912,7 @@

    Usage

    @@ -7932,7 +7961,7 @@

    Usage

    @@ -7975,7 +8004,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8017,7 +8046,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8058,7 +8087,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8104,7 +8133,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8132,7 +8161,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8166,7 +8195,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8194,7 +8223,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8240,7 +8269,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8288,7 +8317,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8327,7 +8356,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8377,7 +8406,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8405,7 +8434,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8442,7 +8471,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8470,7 +8499,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8513,7 +8542,7 @@

    StoryBDD

    @@ -8559,7 +8588,7 @@

    StoryBDD

    @@ -8607,7 +8636,7 @@

    StoryBDD

    @@ -8660,7 +8689,7 @@

    StoryBDD

    @@ -8688,7 +8717,7 @@

    StoryBDD

    @@ -8720,7 +8749,7 @@

    StoryBDD

    @@ -8748,7 +8777,7 @@

    StoryBDD

    @@ -8776,7 +8805,7 @@

    StoryBDD

    @@ -8804,7 +8833,7 @@

    StoryBDD

    @@ -8832,7 +8861,7 @@

    StoryBDD

    @@ -8872,7 +8901,7 @@

    StoryBDD

    @@ -8900,7 +8929,7 @@

    StoryBDD

    @@ -8928,7 +8957,7 @@

    StoryBDD

    @@ -9214,223 +9243,223 @@

    Table of Contents

    - REST (REpresentational State Transfer) + REST 46 - Richardson Maturity Model + REpresentational State Transfer 47 - Level 3 = Content Negotiation + HATEOAS + Richardson Maturity Model 48 - Media Types + Level 3 = Content Negotiation + HATEOAS 49 - Content Type Negotiation + Media Types 50 - HATEOAS + Content Type Negotiation 51 - PHP Autoloading + HATEOAS 52 - Why Is It Necessary? + PHP Autoloading 53 - The require() Way + Why Is It Necessary? 54 - The require_once() Way + The require() Way 55 - Working With Multiple Files + The require_once() Way 56 - Rethinking The Way You Load Classes + Working With Multiple Files 57 - Examples + Rethinking The Way You Load Classes 58 - Under The Hood + Examples 59 - Leveraging PHP APIs + Under The Hood 60 - Built-in Interfaces + Leveraging PHP APIs 61 - The Reflection API (1/2) + Built-in Interfaces 62 - The Reflection API (2/2) + The Reflection API (1/2) 63 - The Standard PHP Library (SPL) + The Reflection API (2/2) 64 - Observer/Observable (1/2) + The Standard PHP Library (SPL) 65 - Observer/Observable (2/2) + Observer/Observable (1/2) 66 - Exceptions (1/2) + Observer/Observable (2/2) 67 - Exceptions (2/2) + Exceptions (1/2) 68 - Password Hashing + Exceptions (2/2) 69 - PHP Archive (PHAR) + Password Hashing 70 - Dependency Management in PHP + PHP Archive (PHAR) 71 - Composer + Dependency Management in PHP 72 - composer install + Composer 73 - Composer Autoloader + composer install 74 - Example + Composer Autoloader 75 - The Symfony2 Console Component + Example 76 - A Basic Command (1/2) + The Symfony2 Console Component 77 - A Basic Command (2/2) + A Basic Command (1/2) 78 - Model View Controller + A Basic Command (2/2) 79 - MVC Overview + Model View Controller 80 - The Model + MVC Overview 81 - The View + The Model 82 @@ -9448,61 +9477,61 @@

    Table of Contents

    - The Controller + The View 85 - Routing + The Controller 86 - Front Controller Pattern + Routing 87 - Interact With Multiple Services + Front Controller Pattern 88 - Databases + Interact With Multiple Services 89 - Agenda + Databases 90 - Quick note + Agenda 91 - Database Design Patterns + Quick note 92 - Row Data Gateway + Database Design Patterns 93 - Row Data Gateway + Row Data Gateway 94 @@ -9520,13 +9549,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 97 - Table Data Gateway + Table Data Gateway 98 @@ -9562,13 +9591,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 104 - Active Record + Active Record 105 @@ -9580,13 +9609,13 @@

    Table of Contents

    - Data Mapper + Active Record 107 - Data Mapper + Data Mapper 108 @@ -9598,31 +9627,31 @@

    Table of Contents

    - Identity Map + Data Mapper 110 - Identity Map + Identity Map 111 - Data Access Layer + Identity Map 112 - Data Access Layer / Data Source Name + Data Access Layer 113 - Data Access Layer + Data Access Layer / Data Source Name 114 @@ -9640,181 +9669,181 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 117 - Object Relational Mapping (1/4) + Object Relational Mapping 118 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 119 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 120 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 121 - Existing Components + Object Relational Mapping (4/4) 122 - Sessions + Existing Components 123 - Overview + Sessions 124 - Code Please + Overview 125 - Security Concerns + Code Please 126 - Authentication + Security Concerns 127 - What You Have Right Now + Authentication 128 - The Big Picture + What You Have Right Now 129 - The Interceptor Pattern + The Big Picture 130 - Introducing the Event Dispatcher + The Interceptor Pattern 131 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 132 - The Firewall (1/2) + Using the EventDispatcherTrait 133 - The Firewall (2/2) + The Firewall (1/2) 134 - Implementing The Firewall + The Firewall (2/2) 135 - Authentication Mechanism + Implementing The Firewall 136 - Adding New Routes + Authentication Mechanism 137 - Stateless Authentication + Adding New Routes 138 - Basic Security Thinking + Stateless Authentication 139 - Writing Better Code + Basic Security Thinking 140 - Agenda + Writing Better Code 141 - Coding Standards + Agenda 142 - PHP Coding Standards Fixer + Coding Standards 143 - Programming To The Interface + PHP Coding Standards Fixer 144 - Component Driven Development + Programming To The Interface 145 - Dependency Injection + Component Driven Development 146 @@ -9838,7 +9867,7 @@

    Table of Contents

    - PHP Implementations + Dependency Injection 150 @@ -9850,37 +9879,37 @@

    Table of Contents

    - From STUPID to SOLID code! (1/2) + PHP Implementations 152 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 153 - Object Calisthenics + From STUPID to SOLID code! (2/2) 154 - Testing + Object Calisthenics 155 - Agenda + Testing 156 - Unit Testing + Agenda 157 @@ -9892,25 +9921,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 159 - PHPUnit — Assertions + PHPUnit — The Rules 160 - Running PHPUnit + PHPUnit — Assertions 161 - Functional Testing + Running PHPUnit 162 @@ -9922,7 +9951,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 164 @@ -9934,77 +9963,83 @@

    Table of Contents

    - Behat + Behavior Driven Development 166 - Using Behat (1/2) + Behat 167 - Using Behat (2/2) + Using Behat (1/2) 168 - Awesome Projects + Using Behat (2/2) 169 -
    + Awesome Projects 170 - Embracing Open Source +
    171 - + Embracing Open Source 172 - + 173 - + 174 - Golden Rules + 175 - The End. + Golden Rules 176 - Well... Maybe Not.
    PHP Extended + The End. 177 + + Well... Maybe Not.
    PHP Extended + 178 + + +
    diff --git a/isima.html b/isima.html index 8effb5e..e7a439a 100644 --- a/isima.html +++ b/isima.html @@ -1593,7 +1593,7 @@
    @@ -1621,7 +1621,7 @@
    @@ -1672,7 +1672,7 @@
    @@ -1700,7 +1700,7 @@ @@ -1715,7 +1715,8 @@

    Week #1

    -

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server

    +

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, +Client/Server, REST

    Week #2

    Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View Controller

    @@ -1738,7 +1739,7 @@

    Week #4

    @@ -1766,7 +1767,7 @@

    Week #4

    @@ -1801,7 +1802,7 @@

    Week #4

    @@ -1837,7 +1838,7 @@

    Week #4

    @@ -1873,7 +1874,7 @@

    Week #4

    @@ -1907,7 +1908,7 @@

    Week #4

    @@ -1942,7 +1943,7 @@

    Week #4

    @@ -1970,7 +1971,7 @@

    Week #4

    @@ -1998,7 +1999,7 @@

    Week #4

    @@ -2036,7 +2037,7 @@

    Week #4

    @@ -2085,7 +2086,7 @@

    Week #4

    @@ -2136,7 +2137,7 @@

    Week #4

    @@ -2179,7 +2180,7 @@

    Abstract class definition

    @@ -2231,7 +2232,7 @@

    Abstract class definition

    @@ -2270,7 +2271,7 @@

    The Rules

    @@ -2323,7 +2324,7 @@

    The Rules

    @@ -2372,7 +2373,7 @@

    Type Hinting

    @@ -2416,7 +2417,7 @@

    Usage

    @@ -2464,7 +2465,7 @@

    Usage

    @@ -2510,7 +2511,7 @@

    Usage

    @@ -2554,7 +2555,7 @@

    Usage

    @@ -2603,7 +2604,7 @@

    Usage

    @@ -2651,7 +2652,7 @@

    PSR-0

    @@ -2698,7 +2699,7 @@

    PSR-0

    @@ -2750,7 +2751,7 @@

    PSR-0

    @@ -2793,7 +2794,7 @@

    PSR-0

    @@ -2839,7 +2840,7 @@

    PSR-0

    @@ -2882,7 +2883,7 @@

    PSR-0

    @@ -2922,7 +2923,7 @@

    PSR-0

    @@ -2950,7 +2951,7 @@

    PSR-0

    @@ -3002,7 +3003,7 @@

    PSR-0

    @@ -3050,7 +3051,7 @@

    PSR-0

    @@ -3102,7 +3103,7 @@

    PSR-0

    @@ -3130,7 +3131,7 @@

    PSR-0

    @@ -3170,7 +3171,7 @@

    PSR-0

    @@ -3214,7 +3215,7 @@

    Collections

    @@ -3259,7 +3260,7 @@

    Collections

    @@ -3309,7 +3310,7 @@

    Collections

    @@ -3349,7 +3350,7 @@

    Collections

    @@ -3392,7 +3393,7 @@

    Collections

    @@ -3442,7 +3443,7 @@

    Collections

    @@ -3453,7 +3454,35 @@

    Collections

    -

    REST (REpresentational State Transfer)

    +

    REST

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    REpresentational State Transfer

    REST is the underlying architectural principle of the web, formalized as a set @@ -3483,7 +3512,7 @@

    Collections

    @@ -3515,7 +3544,7 @@

    Collections

    @@ -3543,7 +3572,7 @@

    Collections

    @@ -3595,7 +3624,7 @@

    Hyper Media Types

    @@ -3647,7 +3676,7 @@

    Hyper Media Types

    @@ -3699,7 +3728,7 @@

    Hyper Media Types

    @@ -3727,7 +3756,7 @@

    Hyper Media Types

    @@ -3776,7 +3805,7 @@

    Hyper Media Types

    @@ -3826,7 +3855,7 @@

    Hyper Media Types

    @@ -3873,7 +3902,7 @@

    Hyper Media Types

    @@ -3922,7 +3951,7 @@

    Hyper Media Types

    @@ -3961,7 +3990,7 @@

    spl_autoload_functions()

    @@ -4010,7 +4039,7 @@

    spl_autoload_unregister()

    @@ -4065,7 +4094,7 @@

    spl_autoload_unregister()

    @@ -4093,7 +4122,7 @@

    spl_autoload_unregister()

    @@ -4138,7 +4167,7 @@

    Traversable

    @@ -4189,7 +4218,7 @@

    Traversable

    @@ -4240,7 +4269,7 @@

    Traversable

    @@ -4281,7 +4310,7 @@

    SPL Functions

    @@ -4334,7 +4363,7 @@

    SPL Functions

    @@ -4383,7 +4412,7 @@

    SPL Functions

    @@ -4432,7 +4461,7 @@

    SPL Functions

    @@ -4472,7 +4501,7 @@

    SPL Functions

    @@ -4523,7 +4552,7 @@

    SPL Functions

    @@ -4565,7 +4594,7 @@

    SPL Functions

    @@ -4593,7 +4622,7 @@

    SPL Functions

    @@ -4637,7 +4666,7 @@

    SPL Functions

    @@ -4687,7 +4716,7 @@

    SPL Functions

    @@ -4730,7 +4759,7 @@

    SPL Functions

    @@ -4778,7 +4807,7 @@

    SPL Functions

    @@ -4828,7 +4857,7 @@

    SPL Functions

    @@ -4875,7 +4904,7 @@

    Execution

    @@ -4928,7 +4957,7 @@

    Usage

    @@ -4956,7 +4985,7 @@

    Usage

    @@ -4999,7 +5028,7 @@

    Usage

    @@ -5042,7 +5071,7 @@

    Usage

    @@ -5095,7 +5124,7 @@

    Usage

    @@ -5142,7 +5171,7 @@

    Usage

    @@ -5191,7 +5220,7 @@

    Usage

    @@ -5243,7 +5272,7 @@

    Usage

    @@ -5286,7 +5315,7 @@

    Centralized declaration

    @@ -5319,7 +5348,7 @@

    Centralized declaration

    @@ -5360,7 +5389,7 @@

    Centralized declaration

    @@ -5388,7 +5417,7 @@

    Centralized declaration

    @@ -5423,7 +5452,7 @@

    Centralized declaration

    @@ -5458,7 +5487,7 @@

    Centralized declaration

    @@ -5499,7 +5528,7 @@

    Centralized declaration

    @@ -5527,7 +5556,7 @@

    Centralized declaration

    @@ -5581,7 +5610,7 @@

    Centralized declaration

    @@ -5627,7 +5656,7 @@

    Centralized declaration

    @@ -5674,7 +5703,7 @@

    Centralized declaration

    @@ -5702,7 +5731,7 @@

    Centralized declaration

    @@ -5750,7 +5779,7 @@

    CRUD

    @@ -5797,7 +5826,7 @@

    CRUD

    @@ -5845,7 +5874,7 @@

    CRUD

    @@ -5897,7 +5926,7 @@

    CRUD

    @@ -5942,7 +5971,7 @@

    CRUD

    @@ -5989,7 +6018,7 @@

    CRUD

    @@ -6017,7 +6046,7 @@

    CRUD

    @@ -6064,7 +6093,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6119,7 +6148,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6147,7 +6176,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6200,7 +6229,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6249,7 +6278,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6277,7 +6306,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6324,7 +6353,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6352,7 +6381,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6395,7 +6424,7 @@

    PHP Data Object (PDO)

    @@ -6444,7 +6473,7 @@

    Usage

    @@ -6498,7 +6527,7 @@

    Usage

    @@ -6545,7 +6574,7 @@

    Usage

    @@ -6573,7 +6602,7 @@

    Usage

    @@ -6610,7 +6639,7 @@

    Usage

    @@ -6646,7 +6675,7 @@

    Code Snippet

    @@ -6682,7 +6711,7 @@

    Code Snippet

    @@ -6724,7 +6753,7 @@

    Code Snippet

    @@ -6764,7 +6793,7 @@

    Doctrine2 ORM

    @@ -6792,7 +6821,7 @@

    Doctrine2 ORM

    @@ -7078,223 +7107,223 @@

    Table of Contents

    - REST (REpresentational State Transfer) + REST 46 - Richardson Maturity Model + REpresentational State Transfer 47 - Level 3 = Content Negotiation + HATEOAS + Richardson Maturity Model 48 - Media Types + Level 3 = Content Negotiation + HATEOAS 49 - Content Type Negotiation + Media Types 50 - HATEOAS + Content Type Negotiation 51 - PHP Autoloading + HATEOAS 52 - Why Is It Necessary? + PHP Autoloading 53 - The require() Way + Why Is It Necessary? 54 - The require_once() Way + The require() Way 55 - Working With Multiple Files + The require_once() Way 56 - Rethinking The Way You Load Classes + Working With Multiple Files 57 - Examples + Rethinking The Way You Load Classes 58 - Under The Hood + Examples 59 - Leveraging PHP APIs + Under The Hood 60 - Built-in Interfaces + Leveraging PHP APIs 61 - The Reflection API (1/2) + Built-in Interfaces 62 - The Reflection API (2/2) + The Reflection API (1/2) 63 - The Standard PHP Library (SPL) + The Reflection API (2/2) 64 - Observer/Observable (1/2) + The Standard PHP Library (SPL) 65 - Observer/Observable (2/2) + Observer/Observable (1/2) 66 - Exceptions (1/2) + Observer/Observable (2/2) 67 - Exceptions (2/2) + Exceptions (1/2) 68 - Password Hashing + Exceptions (2/2) 69 - PHP Archive (PHAR) + Password Hashing 70 - Dependency Management in PHP + PHP Archive (PHAR) 71 - Composer + Dependency Management in PHP 72 - composer install + Composer 73 - Composer Autoloader + composer install 74 - Example + Composer Autoloader 75 - The Symfony2 Console Component + Example 76 - A Basic Command (1/2) + The Symfony2 Console Component 77 - A Basic Command (2/2) + A Basic Command (1/2) 78 - Model View Controller + A Basic Command (2/2) 79 - MVC Overview + Model View Controller 80 - The Model + MVC Overview 81 - The View + The Model 82 @@ -7312,61 +7341,61 @@

    Table of Contents

    - The Controller + The View 85 - Routing + The Controller 86 - Front Controller Pattern + Routing 87 - Interact With Multiple Services + Front Controller Pattern 88 - Databases + Interact With Multiple Services 89 - Agenda + Databases 90 - Quick note + Agenda 91 - Database Design Patterns + Quick note 92 - Row Data Gateway + Database Design Patterns 93 - Row Data Gateway + Row Data Gateway 94 @@ -7384,13 +7413,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 97 - Table Data Gateway + Table Data Gateway 98 @@ -7426,13 +7455,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 104 - Active Record + Active Record 105 @@ -7444,13 +7473,13 @@

    Table of Contents

    - Data Mapper + Active Record 107 - Data Mapper + Data Mapper 108 @@ -7462,31 +7491,31 @@

    Table of Contents

    - Identity Map + Data Mapper 110 - Identity Map + Identity Map 111 - Data Access Layer + Identity Map 112 - Data Access Layer / Data Source Name + Data Access Layer 113 - Data Access Layer + Data Access Layer / Data Source Name 114 @@ -7504,47 +7533,53 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 117 - Object Relational Mapping (1/4) + Object Relational Mapping 118 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 119 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 120 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 121 - Existing Components + Object Relational Mapping (4/4) 122 - The End. + Existing Components 123 + + The End. + 124 + + + From 2e87854391406d16598e4bb81ce8a1c13b86dce2 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 6 Jan 2014 11:36:12 +0100 Subject: [PATCH 16/71] Publish slides (Lun 6 jan 2014 11:36:12 CET) --- extended.html | 778 +++++++++++++++++++++++++------------------------- index.html | 778 +++++++++++++++++++++++++------------------------- isima.html | 778 +++++++++++++++++++++++++------------------------- 3 files changed, 1179 insertions(+), 1155 deletions(-) diff --git a/extended.html b/extended.html index 8a9fc93..f61e5ea 100644 --- a/extended.html +++ b/extended.html @@ -26,7 +26,7 @@ PHP Extended - + - - - - - - - + +
    @@ -8943,6 +8561,396 @@

    Help

    + + + + - - - + +
    @@ -10089,6 +9707,396 @@

    Help

    + + + + - - - + +
    @@ -7629,6 +7247,396 @@

    Help

    + + + + -
    @@ -8563,7 +8560,22 @@

    Help

    Fork me on GitHub diff --git a/index.html b/index.html index 6cbd3e9..56325a8 100644 --- a/index.html +++ b/index.html @@ -1174,9 +1174,6 @@ - - -
    @@ -9709,7 +9706,22 @@

    Help

    Fork me on GitHub diff --git a/isima.html b/isima.html index 3ed7868..d8c2db5 100644 --- a/isima.html +++ b/isima.html @@ -1174,9 +1174,6 @@ - - -
    @@ -7249,7 +7246,22 @@

    Help

    Fork me on GitHub From f76a1ee9ab75f2f12c64636258ff122315547fc0 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 7 Jan 2014 12:28:02 +0100 Subject: [PATCH 19/71] Publish slides (Mar 7 jan 2014 12:28:02 CET) --- index.html | 6 +++--- isima.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 56325a8..94045bd 100644 --- a/index.html +++ b/index.html @@ -2148,7 +2148,7 @@

    Usage

    $foo::$value = 123; // accessing the attribute directly from the class -echo Foo::value; +echo Foo::$value; => 123 @@ -2894,7 +2894,7 @@

    Collections

    • Some headers to describe the content;
    • The response's status code;
    • -
    • The content of the request;
    • +
    • The content of the response;

    Here is an example:

    HTTP/1.1 200 OK
    @@ -3306,7 +3306,7 @@ 

    Hyper Media Types

    HATEOAS

    -

    HATEOAS stands for Hypertext As The Engine Of +

    HATEOAS stands for Hypermedia As The Engine Of Application State. It means that hypertext should be used to find your way through the API.

    It is all about state transitions. Your application is just a big state diff --git a/isima.html b/isima.html index d8c2db5..bee563d 100644 --- a/isima.html +++ b/isima.html @@ -2147,7 +2147,7 @@

    Usage

    $foo::$value = 123; // accessing the attribute directly from the class -echo Foo::value; +echo Foo::$value; => 123
    @@ -2893,7 +2893,7 @@

    Collections

    • Some headers to describe the content;
    • The response's status code;
    • -
    • The content of the request;
    • +
    • The content of the response;

    Here is an example:

    HTTP/1.1 200 OK
    @@ -3305,7 +3305,7 @@ 

    Hyper Media Types

    HATEOAS

    -

    HATEOAS stands for Hypertext As The Engine Of +

    HATEOAS stands for Hypermedia As The Engine Of Application State. It means that hypertext should be used to find your way through the API.

    It is all about state transitions. Your application is just a big state From 764f92822cf0fbb35e77d73f625bc2f88e0d4d49 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 7 Jan 2014 14:05:04 +0100 Subject: [PATCH 20/71] Publish slides (Mar 7 jan 2014 14:05:04 CET) --- index.html | 9 +++++---- isima.html | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 94045bd..333690a 100644 --- a/index.html +++ b/index.html @@ -1963,7 +1963,7 @@

    The Rules

    Type Hinting

    -

    Works with objects, interfaces, arrays or callable. You can't use +

    Works with classes, interfaces, arrays or callable. You can't use scalar types such as int or string:

    public function doSomething(Foo $foo);
     
    @@ -2003,9 +2003,10 @@ 

    Type Hinting

    Methods (2/3)

    -

    The -> sign is used to call methods on objects.

    +

    The -> operator is used to call methods on objects.

    Usage

    -
    $foo->doSomething();
    +
    $foo = new Foo();
    +$foo->doSomething();
     
     // >= PHP 5.4
     (new Foo())->doSomething();
    @@ -2015,7 +2016,7 @@ 

    Usage

    $foo->$method(); $foo->{$method . 'Else'}(); -// will call 'doSomethingElse()' +// will call 'doSomethingElse()'; curly braces are required.
    diff --git a/isima.html b/isima.html index bee563d..70ceaee 100644 --- a/isima.html +++ b/isima.html @@ -1962,7 +1962,7 @@

    The Rules

    Type Hinting

    -

    Works with objects, interfaces, arrays or callable. You can't use +

    Works with classes, interfaces, arrays or callable. You can't use scalar types such as int or string:

    public function doSomething(Foo $foo);
     
    @@ -2002,9 +2002,10 @@ 

    Type Hinting

    Methods (2/3)

    -

    The -> sign is used to call methods on objects.

    +

    The -> operator is used to call methods on objects.

    Usage

    -
    $foo->doSomething();
    +
    $foo = new Foo();
    +$foo->doSomething();
     
     // >= PHP 5.4
     (new Foo())->doSomething();
    @@ -2014,7 +2015,7 @@ 

    Usage

    $foo->$method(); $foo->{$method . 'Else'}(); -// will call 'doSomethingElse()' +// will call 'doSomethingElse()'; curly braces are required.
    From 9bd6eba01a31f422f0694f3ea945df2d87a6e672 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 7 Jan 2014 14:17:26 +0100 Subject: [PATCH 21/71] Publish slides (Mar 7 jan 2014 14:17:26 CET) --- index.html | 7 +++++-- isima.html | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 333690a..1ef2443 100644 --- a/index.html +++ b/index.html @@ -2197,13 +2197,16 @@

    Usage

    Inheritance

    -
    interface MyTraversable extends Traversable
    +
    // Interface may extend several other interfaces.
    +// This is not possible with class though!
    +interface MyTraversable extends Traversable, Countable
     {
     }
     

    Usage

    -
    class Foo implements Fooable, MyTraversable {}
    +
    // a class may implement several interfaces, but may extend only one class!
    +class Foo implements Fooable, MyTraversable {}
     
    diff --git a/isima.html b/isima.html index 70ceaee..0cc3ce0 100644 --- a/isima.html +++ b/isima.html @@ -2196,13 +2196,16 @@

    Usage

    Inheritance

    -
    interface MyTraversable extends Traversable
    +
    // Interface may extend several other interfaces.
    +// This is not possible with class though!
    +interface MyTraversable extends Traversable, Countable
     {
     }
     

    Usage

    -
    class Foo implements Fooable, MyTraversable {}
    +
    // a class may implement several interfaces, but may extend only one class!
    +class Foo implements Fooable, MyTraversable {}
     
    From 63f59127b9181f4a5a40deaf9714435544952d1e Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 7 Jan 2014 14:38:35 +0100 Subject: [PATCH 22/71] Publish slides (Mar 7 jan 2014 14:38:35 CET) --- index.html | 6 +++--- isima.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 1ef2443..cb5b9f4 100644 --- a/index.html +++ b/index.html @@ -2860,7 +2860,7 @@

    Collections

    GET /my/simple/uri?with-query-string HTTP/1.1
     Host: example.org
     Content-Type: text/plain; charset=utf-8
    -Content-Length: length
    +Content-Length: 17
     
     This is a content
     
    @@ -2903,7 +2903,7 @@

    Collections

    Here is an example:

    HTTP/1.1 200 OK
     Content-Type: text/html; charset=utf-8
    -Content-Length: length
    +Content-Length: 76
     
     <!DOCTYPE HTML>
     <html>
    @@ -3030,7 +3030,7 @@ 

    Collections

    GET /my/simple/uri?a=1&id=2 HTTP/1.1
     Host: example.org
     Content-Type: text/plain; charset=utf-8
    -Content-Length: length
    +Content-Length: 14
     
     b=3&city=paris
     
    diff --git a/isima.html b/isima.html index 0cc3ce0..e1d474b 100644 --- a/isima.html +++ b/isima.html @@ -2859,7 +2859,7 @@

    Collections

    GET /my/simple/uri?with-query-string HTTP/1.1
     Host: example.org
     Content-Type: text/plain; charset=utf-8
    -Content-Length: length
    +Content-Length: 17
     
     This is a content
     
    @@ -2902,7 +2902,7 @@

    Collections

    Here is an example:

    HTTP/1.1 200 OK
     Content-Type: text/html; charset=utf-8
    -Content-Length: length
    +Content-Length: 76
     
     <!DOCTYPE HTML>
     <html>
    @@ -3029,7 +3029,7 @@ 

    Collections

    GET /my/simple/uri?a=1&id=2 HTTP/1.1
     Host: example.org
     Content-Type: text/plain; charset=utf-8
    -Content-Length: length
    +Content-Length: 14
     
     b=3&city=paris
     
    From 4b79152a3e204910cfc9bd6352ae6454bc6b3446 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 8 Jan 2014 17:36:24 +0100 Subject: [PATCH 23/71] Publish slides (Mer 8 jan 2014 17:36:24 CET) --- extended.html | 2 +- index.html | 676 ++++++++++++++++++++++++++++++++------------------ isima.html | 287 +++++++++++---------- 3 files changed, 600 insertions(+), 365 deletions(-) diff --git a/extended.html b/extended.html index aaea34f..1e04a29 100644 --- a/extended.html +++ b/extended.html @@ -6624,7 +6624,7 @@

    Message Placeholders

    cases (for 0, or when the count is negative, for example). For such cases, you can use explicit math intervals:

    '{0} There are no apples|{1} There is one apple|]1,19] There are
    -%count% apples|[20,Inf] There are many apples'
    +%count% apples|[20,Inf[ There are many apples'
     

    The intervals follow the ISO 31-11 diff --git a/index.html b/index.html index cb5b9f4..d6a6d85 100644 --- a/index.html +++ b/index.html @@ -1208,7 +1208,7 @@

    @@ -1236,7 +1236,7 @@
    @@ -1287,7 +1287,7 @@
    @@ -1315,7 +1315,7 @@
    @@ -1355,7 +1355,7 @@

    Week #4

    @@ -1383,7 +1383,7 @@

    Week #4

    @@ -1418,7 +1418,7 @@

    Week #4

    @@ -1454,7 +1454,7 @@

    Week #4

    @@ -1490,7 +1490,7 @@

    Week #4

    @@ -1524,7 +1524,7 @@

    Week #4

    @@ -1559,7 +1559,7 @@

    Week #4

    @@ -1587,7 +1587,7 @@

    Week #4

    @@ -1615,7 +1615,7 @@

    Week #4

    @@ -1653,7 +1653,7 @@

    Week #4

    @@ -1702,7 +1702,7 @@

    Week #4

    @@ -1753,7 +1753,7 @@

    Week #4

    @@ -1796,7 +1796,7 @@

    Abstract class definition

    @@ -1848,7 +1848,7 @@

    Abstract class definition

    @@ -1887,7 +1887,7 @@

    The Rules

    @@ -1940,7 +1940,7 @@

    The Rules

    @@ -1989,7 +1989,7 @@

    Type Hinting

    @@ -2034,7 +2034,7 @@

    Usage

    @@ -2082,7 +2082,7 @@

    Usage

    @@ -2128,7 +2128,7 @@

    Usage

    @@ -2172,7 +2172,7 @@

    Usage

    @@ -2224,7 +2224,7 @@

    Usage

    @@ -2272,7 +2272,7 @@

    PSR-0

    @@ -2319,7 +2319,7 @@

    PSR-0

    @@ -2371,7 +2371,7 @@

    PSR-0

    @@ -2414,7 +2414,7 @@

    PSR-0

    @@ -2460,7 +2460,7 @@

    PSR-0

    @@ -2503,7 +2503,7 @@

    PSR-0

    @@ -2525,7 +2525,8 @@

    PSR-0

    @@ -2543,7 +2544,7 @@

    PSR-0

    @@ -2571,7 +2572,7 @@

    PSR-0

    @@ -2623,7 +2624,7 @@

    PSR-0

    @@ -2671,7 +2672,7 @@

    PSR-0

    @@ -2723,7 +2724,7 @@

    PSR-0

    @@ -2751,7 +2752,7 @@

    PSR-0

    @@ -2791,7 +2792,7 @@

    PSR-0

    @@ -2835,7 +2836,7 @@

    Collections

    @@ -2880,7 +2881,7 @@

    Collections

    @@ -2930,7 +2931,7 @@

    Collections

    @@ -2970,7 +2971,7 @@

    Collections

    @@ -3013,7 +3014,7 @@

    Collections

    @@ -3063,7 +3064,7 @@

    Collections

    @@ -3091,7 +3092,7 @@

    Collections

    @@ -3132,7 +3133,7 @@

    Collections

    @@ -3164,7 +3165,7 @@

    Collections

    @@ -3192,7 +3193,7 @@

    Collections

    @@ -3244,7 +3245,7 @@

    Hyper Media Types

    @@ -3296,7 +3297,7 @@

    Hyper Media Types

    @@ -3348,7 +3349,7 @@

    Hyper Media Types

    @@ -3376,7 +3377,7 @@

    Hyper Media Types

    @@ -3425,7 +3426,7 @@

    Hyper Media Types

    @@ -3475,7 +3476,7 @@

    Hyper Media Types

    @@ -3522,7 +3523,7 @@

    Hyper Media Types

    @@ -3571,7 +3572,7 @@

    Hyper Media Types

    @@ -3610,7 +3611,7 @@

    spl_autoload_functions()

    @@ -3659,7 +3660,7 @@

    spl_autoload_unregister()

    @@ -3714,7 +3715,7 @@

    spl_autoload_unregister()

    @@ -3742,7 +3743,7 @@

    spl_autoload_unregister()

    @@ -3787,7 +3788,7 @@

    Traversable

    @@ -3838,7 +3839,7 @@

    Traversable

    @@ -3889,7 +3890,7 @@

    Traversable

    @@ -3930,7 +3931,7 @@

    SPL Functions

    @@ -3983,7 +3984,7 @@

    SPL Functions

    @@ -4032,7 +4033,7 @@

    SPL Functions

    @@ -4081,7 +4082,7 @@

    SPL Functions

    @@ -4121,7 +4122,7 @@

    SPL Functions

    @@ -4172,7 +4173,7 @@

    SPL Functions

    @@ -4214,7 +4215,7 @@

    SPL Functions

    @@ -4242,7 +4243,7 @@

    SPL Functions

    @@ -4286,7 +4287,7 @@

    SPL Functions

    @@ -4336,7 +4337,7 @@

    SPL Functions

    @@ -4379,7 +4380,7 @@

    SPL Functions

    @@ -4427,7 +4428,7 @@

    SPL Functions

    @@ -4477,7 +4478,7 @@

    SPL Functions

    @@ -4524,7 +4525,7 @@

    Execution

    @@ -4577,7 +4578,7 @@

    Usage

    @@ -4605,7 +4606,7 @@

    Usage

    @@ -4648,7 +4649,7 @@

    Usage

    @@ -4691,7 +4692,7 @@

    Usage

    @@ -4744,7 +4745,7 @@

    Usage

    @@ -4791,7 +4792,7 @@

    Usage

    @@ -4840,7 +4841,7 @@

    Usage

    @@ -4892,7 +4893,7 @@

    Usage

    @@ -4935,7 +4936,7 @@

    Centralized declaration

    @@ -4968,7 +4969,7 @@

    Centralized declaration

    @@ -5009,7 +5010,7 @@

    Centralized declaration

    @@ -5037,7 +5038,7 @@

    Centralized declaration

    @@ -5072,7 +5073,7 @@

    Centralized declaration

    @@ -5107,7 +5108,7 @@

    Centralized declaration

    @@ -5148,7 +5149,7 @@

    Centralized declaration

    @@ -5176,7 +5177,7 @@

    Centralized declaration

    @@ -5230,7 +5231,7 @@

    Centralized declaration

    @@ -5276,7 +5277,7 @@

    Centralized declaration

    @@ -5323,7 +5324,7 @@

    Centralized declaration

    @@ -5351,7 +5352,7 @@

    Centralized declaration

    @@ -5399,7 +5400,7 @@

    CRUD

    @@ -5446,7 +5447,7 @@

    CRUD

    @@ -5494,7 +5495,7 @@

    CRUD

    @@ -5546,7 +5547,7 @@

    CRUD

    @@ -5591,7 +5592,7 @@

    CRUD

    @@ -5638,7 +5639,7 @@

    CRUD

    @@ -5666,7 +5667,7 @@

    CRUD

    @@ -5713,7 +5714,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5768,7 +5769,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5796,7 +5797,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5849,7 +5850,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5898,7 +5899,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5926,7 +5927,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5973,7 +5974,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6001,7 +6002,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6044,7 +6045,7 @@

    PHP Data Object (PDO)

    @@ -6093,7 +6094,7 @@

    Usage

    @@ -6147,7 +6148,7 @@

    Usage

    @@ -6194,7 +6195,7 @@

    Usage

    @@ -6222,7 +6223,7 @@

    Usage

    @@ -6259,7 +6260,7 @@

    Usage

    @@ -6295,7 +6296,7 @@

    Code Snippet

    @@ -6331,7 +6332,7 @@

    Code Snippet

    @@ -6373,7 +6374,7 @@

    Code Snippet

    @@ -6413,7 +6414,7 @@

    Doctrine2 ORM

    @@ -6441,7 +6442,7 @@

    Doctrine2 ORM

    @@ -6483,7 +6484,7 @@

    A few use cases:

    @@ -6532,7 +6533,7 @@

    A few use cases:

    @@ -6573,7 +6574,7 @@

    Workarounds

    @@ -6601,7 +6602,7 @@

    Workarounds

    @@ -6632,7 +6633,7 @@

    Workarounds

    @@ -6662,7 +6663,7 @@

    Workarounds

    @@ -6703,7 +6704,7 @@

    Event Dispatcher

    @@ -6751,7 +6752,7 @@

    Event Dispatcher

    @@ -6803,7 +6804,7 @@

    Event Dispatcher

    @@ -6847,7 +6848,7 @@

    Event Dispatcher

    @@ -6887,7 +6888,7 @@

    Event Dispatcher

    @@ -6944,7 +6945,7 @@

    Event Dispatcher

    @@ -6974,7 +6975,7 @@

    Event Dispatcher

    @@ -7027,7 +7028,7 @@

    Event Dispatcher

    @@ -7063,7 +7064,7 @@

    WSSE Username Token

    @@ -7107,7 +7108,7 @@

    WSSE Username Token

    @@ -7135,7 +7136,7 @@

    WSSE Username Token

    @@ -7152,8 +7153,11 @@

    WSSE Username Token

    • Coding Standards
    • Programming To The Interface
    • +
    • Dependency Inversion Principle (DIP)
    • +
    • Dependency Injection (DI)
    • +
    • Inversion of Control (IoC)
    • +
    • Dependency Injection Container (DIC)
    • Component Driven Development
    • -
    • Dependency Injection
    • From STUPID to SOLID code!
    • Object Calisthenics
    @@ -7172,7 +7176,7 @@

    WSSE Username Token

    @@ -7229,7 +7233,7 @@

    WSSE Username Token

    @@ -7273,7 +7277,7 @@

    Usage

    @@ -7318,7 +7322,7 @@

    Usage

    @@ -7329,17 +7333,18 @@

    Usage

    -

    Component Driven Development

    +

    Dependency Inversion Principle (DIP)

    -

    It’s all about Separation of Concerns (SoC).

    -

    You design components with their own logic, each component does one thing -well, and only one thing.

    -

    How to manage these components in your application?

    -
    -

    Read more: Component Driven Development: it's like -Lego!

    -
    +

    The Dependency Inversion Principle has two parts:

    +
      +
    • High-level modules should not depend on low-level modules. Both should depend + on abstractions;
    • +
    • Abstractions should not depend upon details. Details should depend upon + abstractions.
    • +
    +

    DIP is about the level of the abstraction in the messages sent from your code to +the thing it is calling.

    @@ -7355,7 +7360,7 @@

    Usage

    @@ -7366,21 +7371,28 @@

    Usage

    -

    Dependency Injection

    +

    Dependency Injection (DI)

    -

    Design Pattern that allows a choice of component to be made at runtime -rather than compile time.

    -

    Most of the time, you rely on configuration files to describe your classes -and their dependencies.

    -

    A class in this context is also known as a service, and all services live -in a service container or dependency injection container.

    -

    You ask this container to retrieve a service, and it is lazy loaded and dynamically -built:

    -
    // It's an instance of TemplateEngineInterface, but you don't know
    -// anything about its internal implementation.
    -// Is it the raw PHP implementation or Twig?
    -$engine = $container->get('template_engine');
    +            

    Dependency Injection is about how one object acquires a dependency.

    +
    class Foo
    +{
    +    private $bar;
    +
    +    // **NOT** DI
    +    public function __construct()
    +    {
    +        $this->bar = new Bar();
    +    }
    +}
    +
    + +

    When a dependency is provided externally, then the system is using DI:

    +
    // DI!
    +public function __construct(Bar $bar)
    +{
    +    $this->bar = $bar;
    +}
     
    @@ -7398,7 +7410,7 @@

    Usage

    @@ -7409,7 +7421,58 @@

    Usage

    -

    Dependency Injection

    +

    Dependency Injection (Anti) Pattern

    + + +

    ServiceLocator

    +

    The basic idea behind a service locator is to have an object that knows how to +get hold of all of the services that an application might need.

    +
    class ServiceLocator
    +{
    +    public static function getBar()
    +    {
    +        return new Bar();
    +    }
    +}
    +
    +class Foo
    +{
    +    private $bar;
    +
    +    public function __construct()
    +    {
    +        $this->bar = ServiceLocator::getBar();
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Dependency Injection Patterns

    Constructor Injection

    @@ -7440,7 +7503,7 @@

    Usage

    @@ -7451,7 +7514,7 @@

    Usage

    -

    Dependency Injection

    +

    Dependency Injection Patterns

    Setter Injection

    @@ -7482,7 +7545,7 @@

    Usage

    @@ -7493,7 +7556,7 @@

    Usage

    -

    Dependency Injection

    +

    Dependency Injection Patterns

    Interface Injection

    @@ -7531,7 +7594,83 @@

    Usage

    + +
    +
    + + +
    +
    +
    + +

    Inversion of Control (IoC)

    + + +

    Inversion of Control is about who initiates the call. If your code +initiates a call, it is not IoC, if the container/system/library calls back +into code that you provided it, is it IoC.

    +

    Hollywood Principle: Don't call us, we'll call you.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Dependency Injection Container (DIC)

    + + +

    A framework or library for building graphs of objects by passing in (injecting) +each object's dependencies. Object lifetimes are handled by the container +instead of by the consuming object.

    +

    Most of the time, you rely on configuration files to describe your classes +and their dependencies. A class in this context is also known as a +service.

    +

    You ask this container to retrieve a service, and it is lazy loaded and +dynamically built:

    +
    // It's an instance of TemplateEngineInterface, but you don't know
    +// anything about its internal implementation.
    +// Is it the raw PHP implementation or Twig?
    +$engine = $container->get('template_engine');
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7580,7 +7719,7 @@

    Usage

    @@ -7623,7 +7762,44 @@

    The Symfony2 DependencyInjection Component

    + +
    +
    + + +
    +
    +
    + +

    Component Driven Development

    + + +

    It’s all about Separation of Concerns (SoC).

    +

    You design components with their own logic, each component does one thing +well, and only one thing.

    +

    How to manage these components in your application?

    +
    +

    Read more: Component Driven Development: it's like +Lego!

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7665,7 +7841,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7706,7 +7882,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7752,7 +7928,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7780,7 +7956,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7814,7 +7990,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7842,7 +8018,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7888,7 +8064,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7936,7 +8112,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7975,7 +8151,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8025,7 +8201,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8053,7 +8229,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8090,7 +8266,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8118,7 +8294,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8161,7 +8337,7 @@

    StoryBDD

    @@ -8207,7 +8383,7 @@

    StoryBDD

    @@ -8255,7 +8431,7 @@

    StoryBDD

    @@ -8308,7 +8484,7 @@

    StoryBDD

    @@ -8336,7 +8512,7 @@

    StoryBDD

    @@ -8368,7 +8544,7 @@

    StoryBDD

    @@ -8396,7 +8572,7 @@

    StoryBDD

    @@ -8424,7 +8600,7 @@

    StoryBDD

    @@ -8452,7 +8628,7 @@

    StoryBDD

    @@ -8480,7 +8656,7 @@

    StoryBDD

    @@ -8520,7 +8696,7 @@

    StoryBDD

    @@ -8548,7 +8724,7 @@

    StoryBDD

    @@ -8576,7 +8752,7 @@

    StoryBDD

    @@ -9462,203 +9638,227 @@

    Table of Contents

    - Component Driven Development + Dependency Inversion Principle (DIP) 146 - Dependency Injection + Dependency Injection (DI) 147 - Dependency Injection + Dependency Injection (Anti) Pattern 148 - Dependency Injection + Dependency Injection Patterns 149 - Dependency Injection + Dependency Injection Patterns 150 - PHP Implementations + Dependency Injection Patterns 151 - PHP Implementations + Inversion of Control (IoC) 152 - From STUPID to SOLID code! (1/2) + Dependency Injection Container (DIC) 153 - From STUPID to SOLID code! (2/2) + PHP Implementations 154 - Object Calisthenics + PHP Implementations 155 - Testing + Component Driven Development 156 - Agenda + From STUPID to SOLID code! (1/2) 157 - Unit Testing + From STUPID to SOLID code! (2/2) 158 - Unit Testing + Object Calisthenics 159 - PHPUnit — The Rules + Testing 160 - PHPUnit — Assertions + Agenda 161 - Running PHPUnit + Unit Testing 162 - Functional Testing + Unit Testing 163 - Functional Testing + PHPUnit — The Rules 164 - Behavior Driven Development + PHPUnit — Assertions 165 - Behavior Driven Development + Running PHPUnit 166 - Behat + Functional Testing 167 - Using Behat (1/2) + Functional Testing 168 - Using Behat (2/2) + Behavior Driven Development 169 - Awesome Projects + Behavior Driven Development 170 -
    + Behat 171 - Embracing Open Source + Using Behat (1/2) 172 - + Using Behat (2/2) 173 - + Awesome Projects 174 - +
    175 - Golden Rules + Embracing Open Source 176 - The End. + 177 - Well... Maybe Not.
    PHP Extended + 178 + + + 179 + + + + + Golden Rules + 180 + + + + + The End. + 181 + + + + + Well... Maybe Not.
    PHP Extended + 182 + + + diff --git a/isima.html b/isima.html index e1d474b..1342b11 100644 --- a/isima.html +++ b/isima.html @@ -1208,7 +1208,7 @@ @@ -1236,7 +1236,7 @@ @@ -1287,7 +1287,7 @@ @@ -1315,7 +1315,7 @@ @@ -1354,7 +1354,7 @@

    Week #4

    @@ -1382,7 +1382,7 @@

    Week #4

    @@ -1417,7 +1417,7 @@

    Week #4

    @@ -1453,7 +1453,7 @@

    Week #4

    @@ -1489,7 +1489,7 @@

    Week #4

    @@ -1523,7 +1523,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1586,7 +1586,7 @@

    Week #4

    @@ -1614,7 +1614,7 @@

    Week #4

    @@ -1652,7 +1652,7 @@

    Week #4

    @@ -1701,7 +1701,7 @@

    Week #4

    @@ -1752,7 +1752,7 @@

    Week #4

    @@ -1795,7 +1795,7 @@

    Abstract class definition

    @@ -1847,7 +1847,7 @@

    Abstract class definition

    @@ -1886,7 +1886,7 @@

    The Rules

    @@ -1939,7 +1939,7 @@

    The Rules

    @@ -1988,7 +1988,7 @@

    Type Hinting

    @@ -2033,7 +2033,7 @@

    Usage

    @@ -2081,7 +2081,7 @@

    Usage

    @@ -2127,7 +2127,7 @@

    Usage

    @@ -2171,7 +2171,7 @@

    Usage

    @@ -2223,7 +2223,7 @@

    Usage

    @@ -2271,7 +2271,7 @@

    PSR-0

    @@ -2318,7 +2318,7 @@

    PSR-0

    @@ -2370,7 +2370,7 @@

    PSR-0

    @@ -2413,7 +2413,7 @@

    PSR-0

    @@ -2459,7 +2459,7 @@

    PSR-0

    @@ -2502,7 +2502,7 @@

    PSR-0

    @@ -2524,7 +2524,8 @@

    PSR-0

    @@ -2542,7 +2543,7 @@

    PSR-0

    @@ -2570,7 +2571,7 @@

    PSR-0

    @@ -2622,7 +2623,7 @@

    PSR-0

    @@ -2670,7 +2671,7 @@

    PSR-0

    @@ -2722,7 +2723,7 @@

    PSR-0

    @@ -2750,7 +2751,7 @@

    PSR-0

    @@ -2790,7 +2791,7 @@

    PSR-0

    @@ -2834,7 +2835,7 @@

    Collections

    @@ -2879,7 +2880,7 @@

    Collections

    @@ -2929,7 +2930,7 @@

    Collections

    @@ -2969,7 +2970,7 @@

    Collections

    @@ -3012,7 +3013,7 @@

    Collections

    @@ -3062,7 +3063,7 @@

    Collections

    @@ -3090,7 +3091,7 @@

    Collections

    @@ -3131,7 +3132,7 @@

    Collections

    @@ -3163,7 +3164,7 @@

    Collections

    @@ -3191,7 +3192,7 @@

    Collections

    @@ -3243,7 +3244,7 @@

    Hyper Media Types

    @@ -3295,7 +3296,7 @@

    Hyper Media Types

    @@ -3347,7 +3348,7 @@

    Hyper Media Types

    @@ -3375,7 +3376,7 @@

    Hyper Media Types

    @@ -3424,7 +3425,7 @@

    Hyper Media Types

    @@ -3474,7 +3475,7 @@

    Hyper Media Types

    @@ -3521,7 +3522,7 @@

    Hyper Media Types

    @@ -3570,7 +3571,7 @@

    Hyper Media Types

    @@ -3609,7 +3610,7 @@

    spl_autoload_functions()

    @@ -3658,7 +3659,7 @@

    spl_autoload_unregister()

    @@ -3713,7 +3714,7 @@

    spl_autoload_unregister()

    @@ -3741,7 +3742,7 @@

    spl_autoload_unregister()

    @@ -3786,7 +3787,7 @@

    Traversable

    @@ -3837,7 +3838,7 @@

    Traversable

    @@ -3888,7 +3889,7 @@

    Traversable

    @@ -3929,7 +3930,7 @@

    SPL Functions

    @@ -3982,7 +3983,7 @@

    SPL Functions

    @@ -4031,7 +4032,7 @@

    SPL Functions

    @@ -4080,7 +4081,7 @@

    SPL Functions

    @@ -4120,7 +4121,7 @@

    SPL Functions

    @@ -4171,7 +4172,7 @@

    SPL Functions

    @@ -4213,7 +4214,7 @@

    SPL Functions

    @@ -4241,7 +4242,7 @@

    SPL Functions

    @@ -4285,7 +4286,7 @@

    SPL Functions

    @@ -4335,7 +4336,7 @@

    SPL Functions

    @@ -4378,7 +4379,7 @@

    SPL Functions

    @@ -4426,7 +4427,7 @@

    SPL Functions

    @@ -4476,7 +4477,7 @@

    SPL Functions

    @@ -4523,7 +4524,7 @@

    Execution

    @@ -4576,7 +4577,7 @@

    Usage

    @@ -4604,7 +4605,7 @@

    Usage

    @@ -4647,7 +4648,7 @@

    Usage

    @@ -4690,7 +4691,7 @@

    Usage

    @@ -4743,7 +4744,7 @@

    Usage

    @@ -4790,7 +4791,7 @@

    Usage

    @@ -4839,7 +4840,7 @@

    Usage

    @@ -4891,7 +4892,7 @@

    Usage

    @@ -4934,7 +4935,7 @@

    Centralized declaration

    @@ -4967,7 +4968,7 @@

    Centralized declaration

    @@ -5008,7 +5009,7 @@

    Centralized declaration

    @@ -5036,7 +5037,7 @@

    Centralized declaration

    @@ -5071,7 +5072,7 @@

    Centralized declaration

    @@ -5106,7 +5107,7 @@

    Centralized declaration

    @@ -5147,7 +5148,7 @@

    Centralized declaration

    @@ -5175,7 +5176,7 @@

    Centralized declaration

    @@ -5229,7 +5230,7 @@

    Centralized declaration

    @@ -5275,7 +5276,7 @@

    Centralized declaration

    @@ -5322,7 +5323,7 @@

    Centralized declaration

    @@ -5350,7 +5351,7 @@

    Centralized declaration

    @@ -5398,7 +5399,7 @@

    CRUD

    @@ -5445,7 +5446,7 @@

    CRUD

    @@ -5493,7 +5494,7 @@

    CRUD

    @@ -5545,7 +5546,7 @@

    CRUD

    @@ -5590,7 +5591,7 @@

    CRUD

    @@ -5637,7 +5638,7 @@

    CRUD

    @@ -5665,7 +5666,7 @@

    CRUD

    @@ -5712,7 +5713,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5767,7 +5768,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5795,7 +5796,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5848,7 +5849,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5897,7 +5898,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5925,7 +5926,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5972,7 +5973,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6000,7 +6001,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6043,7 +6044,7 @@

    PHP Data Object (PDO)

    @@ -6092,7 +6093,7 @@

    Usage

    @@ -6146,7 +6147,7 @@

    Usage

    @@ -6193,7 +6194,7 @@

    Usage

    @@ -6221,7 +6222,7 @@

    Usage

    @@ -6258,7 +6259,7 @@

    Usage

    @@ -6294,7 +6295,7 @@

    Code Snippet

    @@ -6330,7 +6331,7 @@

    Code Snippet

    @@ -6372,7 +6373,7 @@

    Code Snippet

    @@ -6412,7 +6413,35 @@

    Doctrine2 ORM

    + + + + + +
    +
    +
    + +

    Next Week: Web Security 101

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6440,7 +6469,7 @@

    Doctrine2 ORM

    @@ -7194,11 +7223,17 @@

    Table of Contents

    - The End. + Next Week: Web Security 101 124 + + The End. + 125 + + + From e776ab12b0c7cd282fcd8e8460865a5cd91020eb Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 14 Jan 2014 00:48:37 +0100 Subject: [PATCH 24/71] Publish slides (Mar 14 jan 2014 00:48:37 CET) --- index.html | 5 +++-- isima.html | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index d6a6d85..842e480 100644 --- a/index.html +++ b/index.html @@ -3853,7 +3853,7 @@

    Traversable

    The Reflection API (2/2)

    -

    It is even possible to invoke protected methods!

    +

    It is even possible to invoke protected/private methods!

    class MyClass
     {
         public function hello() { printf("Hello %s", $this->getName()); }
    @@ -3906,7 +3906,8 @@ 

    Traversable

    Provides a collection of classes and interfaces:

    Datastructures

    -

    SplStack, SplQueue, SplObjectStorage, etc.

    +

    SplStack, SplQueue, +SplObjectStorage, etc.

    Named Exceptions

    LogicException, InvalidArgumentException, OutOfRangeException, RuntimeException, etc.

    diff --git a/isima.html b/isima.html index 1342b11..413f183 100644 --- a/isima.html +++ b/isima.html @@ -3852,7 +3852,7 @@

    Traversable

    The Reflection API (2/2)

    -

    It is even possible to invoke protected methods!

    +

    It is even possible to invoke protected/private methods!

    class MyClass
     {
         public function hello() { printf("Hello %s", $this->getName()); }
    @@ -3905,7 +3905,8 @@ 

    Traversable

    Provides a collection of classes and interfaces:

    Datastructures

    -

    SplStack, SplQueue, SplObjectStorage, etc.

    +

    SplStack, SplQueue, +SplObjectStorage, etc.

    Named Exceptions

    LogicException, InvalidArgumentException, OutOfRangeException, RuntimeException, etc.

    From 68000919941be9852c719e55c24565bec5cdde79 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 14 Jan 2014 10:02:55 +0100 Subject: [PATCH 25/71] Publish slides (Mar 14 jan 2014 10:02:55 CET) --- index.html | 36 ++++++++++++++++++------------------ isima.html | 36 ++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index 842e480..4432edd 100644 --- a/index.html +++ b/index.html @@ -3853,7 +3853,7 @@

    Traversable

    The Reflection API (2/2)

    -

    It is even possible to invoke protected/private methods!

    +

    It is even possible to invoke private methods!

    class MyClass
     {
         public function hello() { printf("Hello %s", $this->getName()); }
    @@ -3943,7 +3943,7 @@ 

    SPL Functions

    -

    Observer/Observable (1/2)

    +

    Observer Pattern (1/2)

    The SplObserver interface is used alongside SplSubject to implement the @@ -3996,11 +3996,11 @@

    SPL Functions

    -

    Observer/Observable (2/2)

    +

    Observer Pattern (2/2)

    -

    Those interfaces are never used as default channel has to be specified for the -notify() method.

    +

    Those interfaces are never used as there is only one default channel for +the notify() method.

    Symfony2 EventDispatcher component to the rescue!

    use Symfony\Component\EventDispatcher\EventDispatcher;
    @@ -4910,17 +4910,17 @@ 

    Usage

    Routing is the process of binding URIs to controllers.

    Folder organization

    -

    The simplest kind of routing, but also the hardest to maintain:

    +

    The simplest kind of routing, but also the hardest one to maintain:

    web/
     ├ trees/
     │ └ pineapple.php
     └ tree.php
     
    -

    Centralized declaration

    -

    Modern frameworks all provide a routing component such as Symfony2 Routing -component allowing to define all routes in a centralized place and easing -URI generation.

    +

    Centralized Declaration

    +

    Modern frameworks provide a routing component such as the Symfony2 Routing +component allowing to define routes in a centralized place, and easing URI +generation.

    This require a single entry point: the Frontend Controller.

    @@ -4987,13 +4987,13 @@

    Centralized declaration

    Web applications become more and more complex and interact with multiple services such as:

      -
    • Relational database to store consistent data;
    • -
    • Search engine to index and retrieve documents;
    • +
    • Relational databases to store consistent data;
    • +
    • Search engines to index and retrieve documents;
    • Message queues to postpone executions or as event brokers;
    • -
    • External APIs (geocoding, payment, social, ...);
    • -
    • Mail server to send or receive emails;
    • -
    • Text message gateway;
    • -
    • HTTP cache server to reduce resources needs and speed up responses;
    • +
    • External APIs (geocoding, payment, social);
    • +
    • Mail servers to send or receive emails;
    • +
    • Text message gateways;
    • +
    • HTTP cache servers to reduce resources needs and speed up responses;
    • and much much more.
    @@ -9159,13 +9159,13 @@

    Table of Contents

    - Observer/Observable (1/2) + Observer Pattern (1/2) 66 - Observer/Observable (2/2) + Observer Pattern (2/2) 67 diff --git a/isima.html b/isima.html index 413f183..07c2e52 100644 --- a/isima.html +++ b/isima.html @@ -3852,7 +3852,7 @@

    Traversable

    The Reflection API (2/2)

    -

    It is even possible to invoke protected/private methods!

    +

    It is even possible to invoke private methods!

    class MyClass
     {
         public function hello() { printf("Hello %s", $this->getName()); }
    @@ -3942,7 +3942,7 @@ 

    SPL Functions

    -

    Observer/Observable (1/2)

    +

    Observer Pattern (1/2)

    The SplObserver interface is used alongside SplSubject to implement the @@ -3995,11 +3995,11 @@

    SPL Functions

    -

    Observer/Observable (2/2)

    +

    Observer Pattern (2/2)

    -

    Those interfaces are never used as default channel has to be specified for the -notify() method.

    +

    Those interfaces are never used as there is only one default channel for +the notify() method.

    Symfony2 EventDispatcher component to the rescue!

    use Symfony\Component\EventDispatcher\EventDispatcher;
    @@ -4909,17 +4909,17 @@ 

    Usage

    Routing is the process of binding URIs to controllers.

    Folder organization

    -

    The simplest kind of routing, but also the hardest to maintain:

    +

    The simplest kind of routing, but also the hardest one to maintain:

    web/
     ├ trees/
     │ └ pineapple.php
     └ tree.php
     
    -

    Centralized declaration

    -

    Modern frameworks all provide a routing component such as Symfony2 Routing -component allowing to define all routes in a centralized place and easing -URI generation.

    +

    Centralized Declaration

    +

    Modern frameworks provide a routing component such as the Symfony2 Routing +component allowing to define routes in a centralized place, and easing URI +generation.

    This require a single entry point: the Frontend Controller.

    @@ -4986,13 +4986,13 @@

    Centralized declaration

    Web applications become more and more complex and interact with multiple services such as:

      -
    • Relational database to store consistent data;
    • -
    • Search engine to index and retrieve documents;
    • +
    • Relational databases to store consistent data;
    • +
    • Search engines to index and retrieve documents;
    • Message queues to postpone executions or as event brokers;
    • -
    • External APIs (geocoding, payment, social, ...);
    • -
    • Mail server to send or receive emails;
    • -
    • Text message gateway;
    • -
    • HTTP cache server to reduce resources needs and speed up responses;
    • +
    • External APIs (geocoding, payment, social);
    • +
    • Mail servers to send or receive emails;
    • +
    • Text message gateways;
    • +
    • HTTP cache servers to reduce resources needs and speed up responses;
    • and much much more.
    @@ -6876,13 +6876,13 @@

    Table of Contents

    - Observer/Observable (1/2) + Observer Pattern (1/2) 66 - Observer/Observable (2/2) + Observer Pattern (2/2) 67 From 545939a45b0453641f6ef0f8875bce9a2256ac7d Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 20 Jan 2014 23:27:04 +0100 Subject: [PATCH 26/71] Publish slides (Lun 20 jan 2014 23:27:04 CET) --- index.html | 924 +++++++++++++++++++++++++++++++++++++++-------------- isima.html | 696 ++++++++++++++++++++++++++++++++-------- 2 files changed, 1248 insertions(+), 372 deletions(-) diff --git a/index.html b/index.html index 4432edd..8159850 100644 --- a/index.html +++ b/index.html @@ -1208,7 +1208,7 @@
    @@ -1236,7 +1236,7 @@
    @@ -1287,7 +1287,7 @@
    @@ -1315,7 +1315,7 @@
    @@ -1355,7 +1355,7 @@

    Week #4

    @@ -1383,7 +1383,7 @@

    Week #4

    @@ -1418,7 +1418,7 @@

    Week #4

    @@ -1454,7 +1454,7 @@

    Week #4

    @@ -1490,7 +1490,7 @@

    Week #4

    @@ -1524,7 +1524,7 @@

    Week #4

    @@ -1559,7 +1559,7 @@

    Week #4

    @@ -1587,7 +1587,7 @@

    Week #4

    @@ -1615,7 +1615,7 @@

    Week #4

    @@ -1653,7 +1653,7 @@

    Week #4

    @@ -1702,7 +1702,7 @@

    Week #4

    @@ -1753,7 +1753,7 @@

    Week #4

    @@ -1796,7 +1796,7 @@

    Abstract class definition

    @@ -1848,7 +1848,7 @@

    Abstract class definition

    @@ -1887,7 +1887,7 @@

    The Rules

    @@ -1940,7 +1940,7 @@

    The Rules

    @@ -1989,7 +1989,7 @@

    Type Hinting

    @@ -2034,7 +2034,7 @@

    Usage

    @@ -2082,7 +2082,7 @@

    Usage

    @@ -2128,7 +2128,7 @@

    Usage

    @@ -2172,7 +2172,7 @@

    Usage

    @@ -2224,7 +2224,7 @@

    Usage

    @@ -2272,7 +2272,7 @@

    PSR-0

    @@ -2319,7 +2319,7 @@

    PSR-0

    @@ -2371,7 +2371,7 @@

    PSR-0

    @@ -2414,7 +2414,7 @@

    PSR-0

    @@ -2460,7 +2460,7 @@

    PSR-0

    @@ -2503,7 +2503,7 @@

    PSR-0

    @@ -2544,7 +2544,7 @@

    PSR-0

    @@ -2572,7 +2572,7 @@

    PSR-0

    @@ -2624,7 +2624,7 @@

    PSR-0

    @@ -2672,7 +2672,7 @@

    PSR-0

    @@ -2724,7 +2724,7 @@

    PSR-0

    @@ -2752,7 +2752,7 @@

    PSR-0

    @@ -2792,7 +2792,7 @@

    PSR-0

    @@ -2836,7 +2836,7 @@

    Collections

    @@ -2881,7 +2881,7 @@

    Collections

    @@ -2931,7 +2931,7 @@

    Collections

    @@ -2971,7 +2971,7 @@

    Collections

    @@ -3014,7 +3014,7 @@

    Collections

    @@ -3064,7 +3064,7 @@

    Collections

    @@ -3092,7 +3092,7 @@

    Collections

    @@ -3133,7 +3133,7 @@

    Collections

    @@ -3165,7 +3165,7 @@

    Collections

    @@ -3193,7 +3193,7 @@

    Collections

    @@ -3245,7 +3245,7 @@

    Hyper Media Types

    @@ -3297,7 +3297,7 @@

    Hyper Media Types

    @@ -3349,7 +3349,7 @@

    Hyper Media Types

    @@ -3377,7 +3377,7 @@

    Hyper Media Types

    @@ -3426,7 +3426,7 @@

    Hyper Media Types

    @@ -3476,7 +3476,7 @@

    Hyper Media Types

    @@ -3523,7 +3523,7 @@

    Hyper Media Types

    @@ -3572,7 +3572,7 @@

    Hyper Media Types

    @@ -3611,7 +3611,7 @@

    spl_autoload_functions()

    @@ -3660,7 +3660,7 @@

    spl_autoload_unregister()

    @@ -3715,7 +3715,7 @@

    spl_autoload_unregister()

    @@ -3743,7 +3743,7 @@

    spl_autoload_unregister()

    @@ -3788,7 +3788,7 @@

    Traversable

    @@ -3839,7 +3839,7 @@

    Traversable

    @@ -3890,7 +3890,7 @@

    Traversable

    @@ -3932,7 +3932,7 @@

    SPL Functions

    @@ -3985,7 +3985,7 @@

    SPL Functions

    @@ -4034,7 +4034,7 @@

    SPL Functions

    @@ -4083,7 +4083,7 @@

    SPL Functions

    @@ -4123,7 +4123,7 @@

    SPL Functions

    @@ -4174,7 +4174,7 @@

    SPL Functions

    @@ -4216,7 +4216,7 @@

    SPL Functions

    @@ -4244,7 +4244,7 @@

    SPL Functions

    @@ -4288,7 +4288,7 @@

    SPL Functions

    @@ -4338,7 +4338,7 @@

    SPL Functions

    @@ -4381,7 +4381,7 @@

    SPL Functions

    @@ -4429,7 +4429,7 @@

    SPL Functions

    @@ -4479,7 +4479,7 @@

    SPL Functions

    @@ -4526,7 +4526,7 @@

    Execution

    @@ -4579,7 +4579,7 @@

    Usage

    @@ -4607,7 +4607,7 @@

    Usage

    @@ -4650,7 +4650,7 @@

    Usage

    @@ -4693,7 +4693,7 @@

    Usage

    @@ -4746,7 +4746,7 @@

    Usage

    @@ -4793,7 +4793,7 @@

    Usage

    @@ -4842,7 +4842,7 @@

    Usage

    @@ -4894,7 +4894,7 @@

    Usage

    @@ -4937,7 +4937,7 @@

    Centralized Declaration

    @@ -4970,7 +4970,7 @@

    Centralized Declaration

    @@ -5011,7 +5011,7 @@

    Centralized Declaration

    @@ -5039,7 +5039,7 @@

    Centralized Declaration

    @@ -5058,6 +5058,7 @@

    Centralized Declaration

  • Data Access Layer
  • Object Relational Mapping
  • Existing Components
  • +
  • A Note About Domain-Driven Design
  • @@ -5074,7 +5075,7 @@

    Centralized Declaration

    @@ -5109,7 +5110,7 @@

    Centralized Declaration

    @@ -5150,7 +5151,7 @@

    Centralized Declaration

    @@ -5178,7 +5179,7 @@

    Centralized Declaration

    @@ -5232,7 +5233,7 @@

    Centralized Declaration

    @@ -5278,7 +5279,7 @@

    Centralized Declaration

    @@ -5296,7 +5297,7 @@

    Centralized Declaration

    public function insert(Connection $con)
     {
         // Prepared statement
    -    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
    +    $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)');
     
         $stmt->bindValue(':name', $name);
     
    @@ -5325,7 +5326,7 @@ 

    Centralized Declaration

    @@ -5353,7 +5354,7 @@

    Centralized Declaration

    @@ -5401,7 +5402,7 @@

    CRUD

    @@ -5448,7 +5449,7 @@

    CRUD

    @@ -5471,7 +5472,7 @@

    CRUD

    public function insert($name) { // Prepared statement - $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)'); + $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)'); $stmt->bindValue(':name', $name); @@ -5496,7 +5497,7 @@

    CRUD

    @@ -5548,7 +5549,7 @@

    CRUD

    @@ -5593,7 +5594,7 @@

    CRUD

    @@ -5640,7 +5641,7 @@

    CRUD

    @@ -5668,7 +5669,7 @@

    CRUD

    @@ -5715,7 +5716,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5770,7 +5771,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5798,7 +5799,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5851,7 +5852,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5900,7 +5901,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5928,7 +5929,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5975,7 +5976,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6003,7 +6004,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6046,7 +6047,7 @@

    PHP Data Object (PDO)

    @@ -6095,7 +6096,7 @@

    Usage

    @@ -6149,7 +6150,7 @@

    Usage

    @@ -6196,7 +6197,7 @@

    Usage

    @@ -6224,7 +6225,7 @@

    Usage

    @@ -6261,7 +6262,7 @@

    Usage

    @@ -6297,7 +6298,7 @@

    Code Snippet

    @@ -6333,7 +6334,7 @@

    Code Snippet

    @@ -6375,7 +6376,7 @@

    Code Snippet

    @@ -6415,7 +6416,390 @@

    Doctrine2 ORM

    + + + + + +
    +
    +
    + +

    A Note About
    Domain-Driven Design

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Entities

    + + +

    An object defined primarily by its identity is called an entity:

    +
    class Customer
    +{
    +    private $id;
    +
    +    private $name;
    +
    +    public function __construct($id, Name $name)
    +    {
    +        $this->id   = $id;
    +        $this->name = $name;
    +    }
    +
    +    public function getId()
    +    {
    +        return $this->id;
    +    }
    +
    +    public function getName()
    +    {
    +        return $this->name;
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Value Objects

    + + +

    An object that represents a descriptive aspect of the domain with no conceptual +identity is called a Value Object:

    +
    class Name
    +{
    +    private $firstName;
    +
    +    private $lastName;
    +
    +    public function __construct($firstName, $lastName)
    +    {
    +        $this->firstName = $firstName;
    +        $this->lastName  = $lastName;
    +    }
    +
    +    public function getFirstName()
    +    {
    +        return $this->firstName;
    +    }
    +
    +    public function getLastName()
    +    {
    +        return $this->lastName;
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +

    A Repository mediates between the domain and data mapping layers, acting +like an in-memory domain object collection.

    +
    interface CustomerRepository
    +{
    +    /**
    +     * @return Customer
    +     */
    +    public function find($customerId);
    +
    +    /**
    +     * @return Customer[]
    +     */
    +    public function findAll();
    +
    +    public function add(Customer $user);
    +
    +    public function remove(Customer $user);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +

    Client objects construct query specifications declaratively and submit them +to Repository for satisfaction.

    +

    Objects can be added to and removed from the Repository, as they can from +a simple collection of objects, and the mapping code encapsulated by the +Repository will carry out the appropriate operations behind the scenes.

    +

    Conceptually, a Repository encapsulates the set of objects persisted in a data +store and the operations performed over them, providing a more object-oriented +view of the persistence layer.

    +

    Repository also supports the objective of achieving a clean separation and +one-way dependency between the domain and data mapping layers.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Specification Pattern

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Specification Pattern

    + + +

    The Specification pattern is a way to model business rules as individual +objects. The idea is that a question about an object, is answered by a +isSatisfiedBy() method:

    +
    interface CustomerSpecification
    +{
    +    /**
    +     * @return boolean
    +     */
    +    public function isSatisfiedBy(Customer $customer);
    +}
    +
    + +

    + +
    class CustomerIsPremium implements CustomerSpecification
    +{
    +    /**
    +     * {@inheritDoc}
    +     */
    +    public function isSatisfiedBy(Customer $customer)
    +    {
    +        // figure out if the customer is indeed premium,
    +        // and return true or false.
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +

    A findSatisfying() method can be added to the CustomerRepository:

    +
    interface CustomerRepository
    +{
    +    ...
    +
    +    /**
    +     * @return Customer[]
    +     */
    +    public function findSatisfying(CustomerSpecification $specification);
    +}
    +
    + +

    Usage

    +
    $specification = new CustomerIsPremium();
    +$customers     = $repository->findSatisfying($specification);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6443,7 +6827,7 @@

    Doctrine2 ORM

    @@ -6485,7 +6869,7 @@

    A few use cases:

    @@ -6534,7 +6918,7 @@

    A few use cases:

    @@ -6575,7 +6959,7 @@

    Workarounds

    @@ -6603,7 +6987,7 @@

    Workarounds

    @@ -6634,7 +7018,7 @@

    Workarounds

    @@ -6664,7 +7048,7 @@

    Workarounds

    @@ -6705,7 +7089,7 @@

    Event Dispatcher

    @@ -6753,7 +7137,7 @@

    Event Dispatcher

    @@ -6805,7 +7189,7 @@

    Event Dispatcher

    @@ -6849,7 +7233,7 @@

    Event Dispatcher

    @@ -6889,7 +7273,7 @@

    Event Dispatcher

    @@ -6946,7 +7330,7 @@

    Event Dispatcher

    @@ -6976,7 +7360,7 @@

    Event Dispatcher

    @@ -7029,7 +7413,7 @@

    Event Dispatcher

    @@ -7065,7 +7449,7 @@

    WSSE Username Token

    @@ -7109,7 +7493,7 @@

    WSSE Username Token

    @@ -7137,7 +7521,7 @@

    WSSE Username Token

    @@ -7177,7 +7561,7 @@

    WSSE Username Token

    @@ -7234,7 +7618,7 @@

    WSSE Username Token

    @@ -7278,7 +7662,7 @@

    Usage

    @@ -7323,7 +7707,7 @@

    Usage

    @@ -7361,7 +7745,7 @@

    Usage

    @@ -7411,7 +7795,7 @@

    Usage

    @@ -7462,7 +7846,7 @@

    Usage

    @@ -7504,7 +7888,7 @@

    Usage

    @@ -7546,7 +7930,7 @@

    Usage

    @@ -7595,7 +7979,7 @@

    Usage

    @@ -7628,7 +8012,7 @@

    Usage

    @@ -7671,7 +8055,7 @@

    Usage

    @@ -7720,7 +8104,7 @@

    Usage

    @@ -7763,7 +8147,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7800,7 +8184,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7842,7 +8226,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7883,7 +8267,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7929,7 +8313,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7957,7 +8341,7 @@

    The Symfony2 DependencyInjection Component

    @@ -7991,7 +8375,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8019,7 +8403,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8065,7 +8449,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8113,7 +8497,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8152,7 +8536,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8202,7 +8586,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8230,7 +8614,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8267,7 +8651,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8295,7 +8679,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8338,7 +8722,7 @@

    StoryBDD

    @@ -8384,7 +8768,7 @@

    StoryBDD

    @@ -8432,7 +8816,7 @@

    StoryBDD

    @@ -8485,7 +8869,7 @@

    StoryBDD

    @@ -8513,7 +8897,7 @@

    StoryBDD

    @@ -8545,7 +8929,7 @@

    StoryBDD

    @@ -8573,7 +8957,7 @@

    StoryBDD

    @@ -8601,7 +8985,7 @@

    StoryBDD

    @@ -8629,7 +9013,7 @@

    StoryBDD

    @@ -8657,7 +9041,7 @@

    StoryBDD

    @@ -8697,7 +9081,7 @@

    StoryBDD

    @@ -8725,7 +9109,7 @@

    StoryBDD

    @@ -8753,7 +9137,7 @@

    StoryBDD

    @@ -9507,359 +9891,413 @@

    Table of Contents

    - Sessions + A Note About
    Domain-Driven Design
    124 - Overview + Entities 125 - Code Please + Value Objects 126 - Security Concerns + The Repository Pattern 127 - Authentication + The Repository Pattern 128 - What You Have Right Now + The Repository Pattern 129 - The Big Picture + The Specification Pattern 130 - The Interceptor Pattern + The Specification Pattern 131 - Introducing the Event Dispatcher + Combine Them! 132 - Using the EventDispatcherTrait + Sessions 133 - The Firewall (1/2) + Overview 134 - The Firewall (2/2) + Code Please 135 - Implementing The Firewall + Security Concerns 136 - Authentication Mechanism + Authentication 137 - Adding New Routes + What You Have Right Now 138 - Stateless Authentication + The Big Picture 139 - Basic Security Thinking + The Interceptor Pattern 140 - Writing Better Code + Introducing the Event Dispatcher 141 - Agenda + Using the EventDispatcherTrait 142 - Coding Standards + The Firewall (1/2) 143 - PHP Coding Standards Fixer + The Firewall (2/2) 144 - Programming To The Interface + Implementing The Firewall 145 - Dependency Inversion Principle (DIP) + Authentication Mechanism 146 - Dependency Injection (DI) + Adding New Routes 147 - Dependency Injection (Anti) Pattern + Stateless Authentication 148 - Dependency Injection Patterns + Basic Security Thinking 149 - Dependency Injection Patterns + Writing Better Code 150 - Dependency Injection Patterns + Agenda 151 - Inversion of Control (IoC) + Coding Standards 152 - Dependency Injection Container (DIC) + PHP Coding Standards Fixer 153 - PHP Implementations + Programming To The Interface 154 - PHP Implementations + Dependency Inversion Principle (DIP) 155 - Component Driven Development + Dependency Injection (DI) 156 - From STUPID to SOLID code! (1/2) + Dependency Injection (Anti) Pattern 157 - From STUPID to SOLID code! (2/2) + Dependency Injection Patterns 158 - Object Calisthenics + Dependency Injection Patterns 159 - Testing + Dependency Injection Patterns 160 - Agenda + Inversion of Control (IoC) 161 - Unit Testing + Dependency Injection Container (DIC) 162 - Unit Testing + PHP Implementations 163 - PHPUnit — The Rules + PHP Implementations 164 - PHPUnit — Assertions + Component Driven Development 165 - Running PHPUnit + From STUPID to SOLID code! (1/2) 166 - Functional Testing + From STUPID to SOLID code! (2/2) 167 - Functional Testing + Object Calisthenics 168 - Behavior Driven Development + Testing 169 - Behavior Driven Development + Agenda 170 - Behat + Unit Testing 171 - Using Behat (1/2) + Unit Testing 172 - Using Behat (2/2) + PHPUnit — The Rules 173 - Awesome Projects + PHPUnit — Assertions 174 -
    + Running PHPUnit 175 - Embracing Open Source + Functional Testing 176 - + Functional Testing 177 - + Behavior Driven Development 178 - + Behavior Driven Development 179 - Golden Rules + Behat 180 - The End. + Using Behat (1/2) 181 - Well... Maybe Not.
    PHP Extended + Using Behat (2/2) 182 + + Awesome Projects + 183 + + + + +
    + 184 + + + + + Embracing Open Source + 185 + + + + + + 186 + + + + + + 187 + + + + + + 188 + + + + + Golden Rules + 189 + + + + + The End. + 190 + + + + + Well... Maybe Not.
    PHP Extended + 191 + + + diff --git a/isima.html b/isima.html index 07c2e52..738ead1 100644 --- a/isima.html +++ b/isima.html @@ -1208,7 +1208,7 @@ @@ -1236,7 +1236,7 @@ @@ -1287,7 +1287,7 @@ @@ -1315,7 +1315,7 @@ @@ -1354,7 +1354,7 @@

    Week #4

    @@ -1382,7 +1382,7 @@

    Week #4

    @@ -1417,7 +1417,7 @@

    Week #4

    @@ -1453,7 +1453,7 @@

    Week #4

    @@ -1489,7 +1489,7 @@

    Week #4

    @@ -1523,7 +1523,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1586,7 +1586,7 @@

    Week #4

    @@ -1614,7 +1614,7 @@

    Week #4

    @@ -1652,7 +1652,7 @@

    Week #4

    @@ -1701,7 +1701,7 @@

    Week #4

    @@ -1752,7 +1752,7 @@

    Week #4

    @@ -1795,7 +1795,7 @@

    Abstract class definition

    @@ -1847,7 +1847,7 @@

    Abstract class definition

    @@ -1886,7 +1886,7 @@

    The Rules

    @@ -1939,7 +1939,7 @@

    The Rules

    @@ -1988,7 +1988,7 @@

    Type Hinting

    @@ -2033,7 +2033,7 @@

    Usage

    @@ -2081,7 +2081,7 @@

    Usage

    @@ -2127,7 +2127,7 @@

    Usage

    @@ -2171,7 +2171,7 @@

    Usage

    @@ -2223,7 +2223,7 @@

    Usage

    @@ -2271,7 +2271,7 @@

    PSR-0

    @@ -2318,7 +2318,7 @@

    PSR-0

    @@ -2370,7 +2370,7 @@

    PSR-0

    @@ -2413,7 +2413,7 @@

    PSR-0

    @@ -2459,7 +2459,7 @@

    PSR-0

    @@ -2502,7 +2502,7 @@

    PSR-0

    @@ -2543,7 +2543,7 @@

    PSR-0

    @@ -2571,7 +2571,7 @@

    PSR-0

    @@ -2623,7 +2623,7 @@

    PSR-0

    @@ -2671,7 +2671,7 @@

    PSR-0

    @@ -2723,7 +2723,7 @@

    PSR-0

    @@ -2751,7 +2751,7 @@

    PSR-0

    @@ -2791,7 +2791,7 @@

    PSR-0

    @@ -2835,7 +2835,7 @@

    Collections

    @@ -2880,7 +2880,7 @@

    Collections

    @@ -2930,7 +2930,7 @@

    Collections

    @@ -2970,7 +2970,7 @@

    Collections

    @@ -3013,7 +3013,7 @@

    Collections

    @@ -3063,7 +3063,7 @@

    Collections

    @@ -3091,7 +3091,7 @@

    Collections

    @@ -3132,7 +3132,7 @@

    Collections

    @@ -3164,7 +3164,7 @@

    Collections

    @@ -3192,7 +3192,7 @@

    Collections

    @@ -3244,7 +3244,7 @@

    Hyper Media Types

    @@ -3296,7 +3296,7 @@

    Hyper Media Types

    @@ -3348,7 +3348,7 @@

    Hyper Media Types

    @@ -3376,7 +3376,7 @@

    Hyper Media Types

    @@ -3425,7 +3425,7 @@

    Hyper Media Types

    @@ -3475,7 +3475,7 @@

    Hyper Media Types

    @@ -3522,7 +3522,7 @@

    Hyper Media Types

    @@ -3571,7 +3571,7 @@

    Hyper Media Types

    @@ -3610,7 +3610,7 @@

    spl_autoload_functions()

    @@ -3659,7 +3659,7 @@

    spl_autoload_unregister()

    @@ -3714,7 +3714,7 @@

    spl_autoload_unregister()

    @@ -3742,7 +3742,7 @@

    spl_autoload_unregister()

    @@ -3787,7 +3787,7 @@

    Traversable

    @@ -3838,7 +3838,7 @@

    Traversable

    @@ -3889,7 +3889,7 @@

    Traversable

    @@ -3931,7 +3931,7 @@

    SPL Functions

    @@ -3984,7 +3984,7 @@

    SPL Functions

    @@ -4033,7 +4033,7 @@

    SPL Functions

    @@ -4082,7 +4082,7 @@

    SPL Functions

    @@ -4122,7 +4122,7 @@

    SPL Functions

    @@ -4173,7 +4173,7 @@

    SPL Functions

    @@ -4215,7 +4215,7 @@

    SPL Functions

    @@ -4243,7 +4243,7 @@

    SPL Functions

    @@ -4287,7 +4287,7 @@

    SPL Functions

    @@ -4337,7 +4337,7 @@

    SPL Functions

    @@ -4380,7 +4380,7 @@

    SPL Functions

    @@ -4428,7 +4428,7 @@

    SPL Functions

    @@ -4478,7 +4478,7 @@

    SPL Functions

    @@ -4525,7 +4525,7 @@

    Execution

    @@ -4578,7 +4578,7 @@

    Usage

    @@ -4606,7 +4606,7 @@

    Usage

    @@ -4649,7 +4649,7 @@

    Usage

    @@ -4692,7 +4692,7 @@

    Usage

    @@ -4745,7 +4745,7 @@

    Usage

    @@ -4792,7 +4792,7 @@

    Usage

    @@ -4841,7 +4841,7 @@

    Usage

    @@ -4893,7 +4893,7 @@

    Usage

    @@ -4936,7 +4936,7 @@

    Centralized Declaration

    @@ -4969,7 +4969,7 @@

    Centralized Declaration

    @@ -5010,7 +5010,7 @@

    Centralized Declaration

    @@ -5038,7 +5038,7 @@

    Centralized Declaration

    @@ -5057,6 +5057,7 @@

    Centralized Declaration

  • Data Access Layer
  • Object Relational Mapping
  • Existing Components
  • +
  • A Note About Domain-Driven Design
  • @@ -5073,7 +5074,7 @@

    Centralized Declaration

    @@ -5108,7 +5109,7 @@

    Centralized Declaration

    @@ -5149,7 +5150,7 @@

    Centralized Declaration

    @@ -5177,7 +5178,7 @@

    Centralized Declaration

    @@ -5231,7 +5232,7 @@

    Centralized Declaration

    @@ -5277,7 +5278,7 @@

    Centralized Declaration

    @@ -5295,7 +5296,7 @@

    Centralized Declaration

    public function insert(Connection $con)
     {
         // Prepared statement
    -    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
    +    $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)');
     
         $stmt->bindValue(':name', $name);
     
    @@ -5324,7 +5325,7 @@ 

    Centralized Declaration

    @@ -5352,7 +5353,7 @@

    Centralized Declaration

    @@ -5400,7 +5401,7 @@

    CRUD

    @@ -5447,7 +5448,7 @@

    CRUD

    @@ -5470,7 +5471,7 @@

    CRUD

    public function insert($name) { // Prepared statement - $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)'); + $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)'); $stmt->bindValue(':name', $name); @@ -5495,7 +5496,7 @@

    CRUD

    @@ -5547,7 +5548,7 @@

    CRUD

    @@ -5592,7 +5593,7 @@

    CRUD

    @@ -5639,7 +5640,7 @@

    CRUD

    @@ -5667,7 +5668,7 @@

    CRUD

    @@ -5714,7 +5715,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5769,7 +5770,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5797,7 +5798,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5850,7 +5851,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5899,7 +5900,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5927,7 +5928,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5974,7 +5975,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6002,7 +6003,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6045,7 +6046,7 @@

    PHP Data Object (PDO)

    @@ -6094,7 +6095,7 @@

    Usage

    @@ -6148,7 +6149,7 @@

    Usage

    @@ -6195,7 +6196,7 @@

    Usage

    @@ -6223,7 +6224,7 @@

    Usage

    @@ -6260,7 +6261,7 @@

    Usage

    @@ -6296,7 +6297,7 @@

    Code Snippet

    @@ -6332,7 +6333,7 @@

    Code Snippet

    @@ -6374,7 +6375,7 @@

    Code Snippet

    @@ -6414,7 +6415,390 @@

    Doctrine2 ORM

    + + + + + +
    +
    +
    + +

    A Note About
    Domain-Driven Design

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Entities

    + + +

    An object defined primarily by its identity is called an entity:

    +
    class Customer
    +{
    +    private $id;
    +
    +    private $name;
    +
    +    public function __construct($id, Name $name)
    +    {
    +        $this->id   = $id;
    +        $this->name = $name;
    +    }
    +
    +    public function getId()
    +    {
    +        return $this->id;
    +    }
    +
    +    public function getName()
    +    {
    +        return $this->name;
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Value Objects

    + + +

    An object that represents a descriptive aspect of the domain with no conceptual +identity is called a Value Object:

    +
    class Name
    +{
    +    private $firstName;
    +
    +    private $lastName;
    +
    +    public function __construct($firstName, $lastName)
    +    {
    +        $this->firstName = $firstName;
    +        $this->lastName  = $lastName;
    +    }
    +
    +    public function getFirstName()
    +    {
    +        return $this->firstName;
    +    }
    +
    +    public function getLastName()
    +    {
    +        return $this->lastName;
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +

    A Repository mediates between the domain and data mapping layers, acting +like an in-memory domain object collection.

    +
    interface CustomerRepository
    +{
    +    /**
    +     * @return Customer
    +     */
    +    public function find($customerId);
    +
    +    /**
    +     * @return Customer[]
    +     */
    +    public function findAll();
    +
    +    public function add(Customer $user);
    +
    +    public function remove(Customer $user);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Repository Pattern

    + + +

    Client objects construct query specifications declaratively and submit them +to Repository for satisfaction.

    +

    Objects can be added to and removed from the Repository, as they can from +a simple collection of objects, and the mapping code encapsulated by the +Repository will carry out the appropriate operations behind the scenes.

    +

    Conceptually, a Repository encapsulates the set of objects persisted in a data +store and the operations performed over them, providing a more object-oriented +view of the persistence layer.

    +

    Repository also supports the objective of achieving a clean separation and +one-way dependency between the domain and data mapping layers.

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Specification Pattern

    + + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    The Specification Pattern

    + + +

    The Specification pattern is a way to model business rules as individual +objects. The idea is that a question about an object, is answered by a +isSatisfiedBy() method:

    +
    interface CustomerSpecification
    +{
    +    /**
    +     * @return boolean
    +     */
    +    public function isSatisfiedBy(Customer $customer);
    +}
    +
    + +

    + +
    class CustomerIsPremium implements CustomerSpecification
    +{
    +    /**
    +     * {@inheritDoc}
    +     */
    +    public function isSatisfiedBy(Customer $customer)
    +    {
    +        // figure out if the customer is indeed premium,
    +        // and return true or false.
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +

    A findSatisfying() method can be added to the CustomerRepository:

    +
    interface CustomerRepository
    +{
    +    ...
    +
    +    /**
    +     * @return Customer[]
    +     */
    +    public function findSatisfying(CustomerSpecification $specification);
    +}
    +
    + +

    Usage

    +
    $specification = new CustomerIsPremium();
    +$customers     = $repository->findSatisfying($specification);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6442,7 +6826,7 @@

    Doctrine2 ORM

    @@ -6470,7 +6854,7 @@

    Doctrine2 ORM

    @@ -7224,17 +7608,71 @@

    Table of Contents

    - Next Week: Web Security 101 + A Note About
    Domain-Driven Design
    124 - The End. + Entities 125 + + Value Objects + 126 + + + + + The Repository Pattern + 127 + + + + + The Repository Pattern + 128 + + + + + The Repository Pattern + 129 + + + + + The Specification Pattern + 130 + + + + + The Specification Pattern + 131 + + + + + Combine Them! + 132 + + + + + Next Week: Web Security 101 + 133 + + + + + The End. + 134 + + + From 37779f214f0b629ae3a5780edbb966608f719e62 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 21 Jan 2014 13:15:50 +0100 Subject: [PATCH 27/71] Publish slides (Mar 21 jan 2014 13:15:50 CET) --- index.html | 633 ++++++++++++++++++++++++++++++++--------------------- isima.html | 407 ++++++++++++++++++++++------------ 2 files changed, 645 insertions(+), 395 deletions(-) diff --git a/index.html b/index.html index 8159850..334c0b8 100644 --- a/index.html +++ b/index.html @@ -1208,7 +1208,7 @@ @@ -1236,7 +1236,7 @@ @@ -1287,7 +1287,7 @@ @@ -1315,7 +1315,7 @@ @@ -1355,7 +1355,7 @@

    Week #4

    @@ -1383,7 +1383,7 @@

    Week #4

    @@ -1418,7 +1418,7 @@

    Week #4

    @@ -1454,7 +1454,7 @@

    Week #4

    @@ -1490,7 +1490,7 @@

    Week #4

    @@ -1524,7 +1524,7 @@

    Week #4

    @@ -1559,7 +1559,7 @@

    Week #4

    @@ -1587,7 +1587,7 @@

    Week #4

    @@ -1615,7 +1615,7 @@

    Week #4

    @@ -1653,7 +1653,7 @@

    Week #4

    @@ -1702,7 +1702,7 @@

    Week #4

    @@ -1753,7 +1753,7 @@

    Week #4

    @@ -1796,7 +1796,7 @@

    Abstract class definition

    @@ -1848,7 +1848,7 @@

    Abstract class definition

    @@ -1887,7 +1887,7 @@

    The Rules

    @@ -1940,7 +1940,7 @@

    The Rules

    @@ -1989,7 +1989,7 @@

    Type Hinting

    @@ -2034,7 +2034,7 @@

    Usage

    @@ -2082,7 +2082,7 @@

    Usage

    @@ -2128,7 +2128,7 @@

    Usage

    @@ -2172,7 +2172,7 @@

    Usage

    @@ -2224,7 +2224,7 @@

    Usage

    @@ -2272,7 +2272,7 @@

    PSR-0

    @@ -2319,7 +2319,7 @@

    PSR-0

    @@ -2371,7 +2371,7 @@

    PSR-0

    @@ -2414,7 +2414,7 @@

    PSR-0

    @@ -2460,7 +2460,7 @@

    PSR-0

    @@ -2503,7 +2503,7 @@

    PSR-0

    @@ -2544,7 +2544,7 @@

    PSR-0

    @@ -2572,7 +2572,7 @@

    PSR-0

    @@ -2624,7 +2624,7 @@

    PSR-0

    @@ -2672,7 +2672,7 @@

    PSR-0

    @@ -2724,7 +2724,7 @@

    PSR-0

    @@ -2752,7 +2752,7 @@

    PSR-0

    @@ -2792,7 +2792,7 @@

    PSR-0

    @@ -2836,7 +2836,7 @@

    Collections

    @@ -2881,7 +2881,7 @@

    Collections

    @@ -2931,7 +2931,7 @@

    Collections

    @@ -2971,7 +2971,7 @@

    Collections

    @@ -3014,7 +3014,7 @@

    Collections

    @@ -3064,7 +3064,7 @@

    Collections

    @@ -3092,7 +3092,7 @@

    Collections

    @@ -3133,7 +3133,7 @@

    Collections

    @@ -3165,7 +3165,7 @@

    Collections

    @@ -3193,7 +3193,7 @@

    Collections

    @@ -3245,7 +3245,7 @@

    Hyper Media Types

    @@ -3297,7 +3297,7 @@

    Hyper Media Types

    @@ -3349,7 +3349,7 @@

    Hyper Media Types

    @@ -3377,7 +3377,7 @@

    Hyper Media Types

    @@ -3426,7 +3426,7 @@

    Hyper Media Types

    @@ -3476,7 +3476,7 @@

    Hyper Media Types

    @@ -3523,7 +3523,7 @@

    Hyper Media Types

    @@ -3572,7 +3572,7 @@

    Hyper Media Types

    @@ -3611,7 +3611,7 @@

    spl_autoload_functions()

    @@ -3660,7 +3660,7 @@

    spl_autoload_unregister()

    @@ -3715,7 +3715,7 @@

    spl_autoload_unregister()

    @@ -3743,7 +3743,7 @@

    spl_autoload_unregister()

    @@ -3788,7 +3788,7 @@

    Traversable

    @@ -3839,7 +3839,7 @@

    Traversable

    @@ -3890,7 +3890,7 @@

    Traversable

    @@ -3932,7 +3932,7 @@

    SPL Functions

    @@ -3985,7 +3985,7 @@

    SPL Functions

    @@ -4034,7 +4034,7 @@

    SPL Functions

    @@ -4083,7 +4083,7 @@

    SPL Functions

    @@ -4123,7 +4123,7 @@

    SPL Functions

    @@ -4174,7 +4174,7 @@

    SPL Functions

    @@ -4216,7 +4216,7 @@

    SPL Functions

    @@ -4244,7 +4244,7 @@

    SPL Functions

    @@ -4288,7 +4288,7 @@

    SPL Functions

    @@ -4338,7 +4338,7 @@

    SPL Functions

    @@ -4381,7 +4381,7 @@

    SPL Functions

    @@ -4429,7 +4429,7 @@

    SPL Functions

    @@ -4479,7 +4479,7 @@

    SPL Functions

    @@ -4526,7 +4526,7 @@

    Execution

    @@ -4579,7 +4579,7 @@

    Usage

    @@ -4607,7 +4607,7 @@

    Usage

    @@ -4650,7 +4650,7 @@

    Usage

    @@ -4693,7 +4693,7 @@

    Usage

    @@ -4746,7 +4746,7 @@

    Usage

    @@ -4793,7 +4793,7 @@

    Usage

    @@ -4842,7 +4842,7 @@

    Usage

    @@ -4894,7 +4894,7 @@

    Usage

    @@ -4937,7 +4937,7 @@

    Centralized Declaration

    @@ -4970,7 +4970,7 @@

    Centralized Declaration

    @@ -5011,7 +5011,7 @@

    Centralized Declaration

    @@ -5039,7 +5039,7 @@

    Centralized Declaration

    @@ -5075,7 +5075,7 @@

    Centralized Declaration

    @@ -5110,7 +5110,7 @@

    Centralized Declaration

    @@ -5151,7 +5151,7 @@

    Centralized Declaration

    @@ -5179,7 +5179,7 @@

    Centralized Declaration

    @@ -5233,7 +5233,7 @@

    Centralized Declaration

    @@ -5279,7 +5279,7 @@

    Centralized Declaration

    @@ -5297,7 +5297,7 @@

    Centralized Declaration

    public function insert(Connection $con)
     {
         // Prepared statement
    -    $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)');
    +    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
     
         $stmt->bindValue(':name', $name);
     
    @@ -5326,7 +5326,7 @@ 

    Centralized Declaration

    @@ -5354,7 +5354,7 @@

    Centralized Declaration

    @@ -5402,7 +5402,7 @@

    CRUD

    @@ -5449,7 +5449,7 @@

    CRUD

    @@ -5472,7 +5472,7 @@

    CRUD

    public function insert($name) { // Prepared statement - $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)'); + $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)'); $stmt->bindValue(':name', $name); @@ -5497,7 +5497,7 @@

    CRUD

    @@ -5549,7 +5549,7 @@

    CRUD

    @@ -5594,7 +5594,7 @@

    CRUD

    @@ -5641,7 +5641,7 @@

    CRUD

    @@ -5669,7 +5669,7 @@

    CRUD

    @@ -5716,7 +5716,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5771,7 +5771,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5799,7 +5799,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5852,7 +5852,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5901,7 +5901,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5929,7 +5929,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5949,7 +5949,7 @@

    Active Record = Row Data Gateway + Domain Logic

    { private $identityMap = []; - public function findOneById($id) + public function find($id) { if (!isset($this->identityMap[$id])) { // fetch the object for the given id @@ -5976,7 +5976,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6004,7 +6004,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6047,7 +6047,7 @@

    PHP Data Object (PDO)

    @@ -6096,7 +6096,7 @@

    Usage

    @@ -6150,7 +6150,7 @@

    Usage

    @@ -6197,7 +6197,7 @@

    Usage

    @@ -6225,7 +6225,7 @@

    Usage

    @@ -6262,7 +6262,7 @@

    Usage

    @@ -6298,7 +6298,7 @@

    Code Snippet

    @@ -6334,7 +6334,7 @@

    Code Snippet

    @@ -6376,7 +6376,7 @@

    Code Snippet

    @@ -6416,7 +6416,7 @@

    Doctrine2 ORM

    @@ -6444,7 +6444,7 @@

    Doctrine2 ORM

    @@ -6498,7 +6498,7 @@

    Doctrine2 ORM

    @@ -6553,7 +6553,7 @@

    Doctrine2 ORM

    @@ -6581,7 +6581,7 @@

    Doctrine2 ORM

    @@ -6630,7 +6630,7 @@

    Doctrine2 ORM

    @@ -6669,7 +6669,7 @@

    Doctrine2 ORM

    @@ -6697,7 +6697,7 @@

    Doctrine2 ORM

    @@ -6753,7 +6753,7 @@

    Doctrine2 ORM

    @@ -6764,7 +6764,7 @@

    Doctrine2 ORM

    -

    Combine Them!

    +

    Repository ♥ Specification

    A findSatisfying() method can be added to the CustomerRepository:

    @@ -6799,7 +6799,120 @@

    Usage

    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +
    class OrSpecification implements CustomerSpecification
    +{
    +    public function __construct(
    +        CustomerSpecification $s1,
    +        CustomerSpecification $s2
    +    ) {
    +        $this->s1 = $s1;
    +        $this->s2 = $s2;
    +    }
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return $this->s1->isSatisfiedBy($c) || $this->s2->isSatisfiedBy($c);
    +    }
    +}
    +
    + +

    + +
    class AndSpecification implements CustomerSpecification
    +{
    +    ...
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return $this->s1->isSatisfiedBy($c) && $this->s2->isSatisfiedBy($c);
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +
    class NotSpecification implements CustomerSpecification
    +{
    +    public function __construct(CustomerSpecification $s)
    +    {
    +        $this->s = $s;
    +    }
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return !$this->s->isSatisfiedBy($c);
    +    }
    +}
    +
    + +

    Usage

    +
    $specification = new AndSpecification(
    +    new CustomerHasOrderedThreeTimes(),
    +    new NotSpecification(
    +        new CustomerIsPremium()
    +    )
    +);
    +
    +$customers = $repository->findSatisfying($specification);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6827,7 +6940,7 @@

    Usage

    @@ -6869,7 +6982,7 @@

    A few use cases:

    @@ -6918,7 +7031,7 @@

    A few use cases:

    @@ -6959,7 +7072,7 @@

    Workarounds

    @@ -6987,7 +7100,7 @@

    Workarounds

    @@ -7018,7 +7131,7 @@

    Workarounds

    @@ -7048,7 +7161,7 @@

    Workarounds

    @@ -7089,7 +7202,7 @@

    Event Dispatcher

    @@ -7137,7 +7250,7 @@

    Event Dispatcher

    @@ -7189,7 +7302,7 @@

    Event Dispatcher

    @@ -7233,7 +7346,7 @@

    Event Dispatcher

    @@ -7273,7 +7386,7 @@

    Event Dispatcher

    @@ -7330,7 +7443,7 @@

    Event Dispatcher

    @@ -7360,7 +7473,7 @@

    Event Dispatcher

    @@ -7413,7 +7526,7 @@

    Event Dispatcher

    @@ -7449,7 +7562,7 @@

    WSSE Username Token

    @@ -7493,7 +7606,7 @@

    WSSE Username Token

    @@ -7521,7 +7634,7 @@

    WSSE Username Token

    @@ -7561,7 +7674,7 @@

    WSSE Username Token

    @@ -7618,7 +7731,7 @@

    WSSE Username Token

    @@ -7662,7 +7775,7 @@

    Usage

    @@ -7707,7 +7820,7 @@

    Usage

    @@ -7745,7 +7858,7 @@

    Usage

    @@ -7795,7 +7908,7 @@

    Usage

    @@ -7846,7 +7959,7 @@

    Usage

    @@ -7888,7 +8001,7 @@

    Usage

    @@ -7930,7 +8043,7 @@

    Usage

    @@ -7979,7 +8092,7 @@

    Usage

    @@ -8012,7 +8125,7 @@

    Usage

    @@ -8055,7 +8168,7 @@

    Usage

    @@ -8104,7 +8217,7 @@

    Usage

    @@ -8147,7 +8260,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8184,7 +8297,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8226,7 +8339,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8267,7 +8380,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8313,7 +8426,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8341,7 +8454,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8375,7 +8488,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8403,7 +8516,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8449,7 +8562,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8497,7 +8610,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8536,7 +8649,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8586,7 +8699,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8614,7 +8727,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8651,7 +8764,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8679,7 +8792,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8722,7 +8835,7 @@

    StoryBDD

    @@ -8768,7 +8881,7 @@

    StoryBDD

    @@ -8816,7 +8929,7 @@

    StoryBDD

    @@ -8869,7 +8982,7 @@

    StoryBDD

    @@ -8897,7 +9010,7 @@

    StoryBDD

    @@ -8929,7 +9042,7 @@

    StoryBDD

    @@ -8957,7 +9070,7 @@

    StoryBDD

    @@ -8985,7 +9098,7 @@

    StoryBDD

    @@ -9013,7 +9126,7 @@

    StoryBDD

    @@ -9041,7 +9154,7 @@

    StoryBDD

    @@ -9081,7 +9194,7 @@

    StoryBDD

    @@ -9109,7 +9222,7 @@

    StoryBDD

    @@ -9137,7 +9250,7 @@

    StoryBDD

    @@ -9939,169 +10052,169 @@

    Table of Contents

    - Combine Them! + Repository ♥ Specification 132 - Sessions + Combine Them! 133 - Overview + Combine Them! 134 - Code Please + Sessions 135 - Security Concerns + Overview 136 - Authentication + Code Please 137 - What You Have Right Now + Security Concerns 138 - The Big Picture + Authentication 139 - The Interceptor Pattern + What You Have Right Now 140 - Introducing the Event Dispatcher + The Big Picture 141 - Using the EventDispatcherTrait + The Interceptor Pattern 142 - The Firewall (1/2) + Introducing the Event Dispatcher 143 - The Firewall (2/2) + Using the EventDispatcherTrait 144 - Implementing The Firewall + The Firewall (1/2) 145 - Authentication Mechanism + The Firewall (2/2) 146 - Adding New Routes + Implementing The Firewall 147 - Stateless Authentication + Authentication Mechanism 148 - Basic Security Thinking + Adding New Routes 149 - Writing Better Code + Stateless Authentication 150 - Agenda + Basic Security Thinking 151 - Coding Standards + Writing Better Code 152 - PHP Coding Standards Fixer + Agenda 153 - Programming To The Interface + Coding Standards 154 - Dependency Inversion Principle (DIP) + PHP Coding Standards Fixer 155 - Dependency Injection (DI) + Programming To The Interface 156 - Dependency Injection (Anti) Pattern + Dependency Inversion Principle (DIP) 157 - Dependency Injection Patterns + Dependency Injection (DI) 158 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 159 @@ -10113,191 +10226,203 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 161 - Dependency Injection Container (DIC) + Dependency Injection Patterns 162 - PHP Implementations + Inversion of Control (IoC) 163 - PHP Implementations + Dependency Injection Container (DIC) 164 - Component Driven Development + PHP Implementations 165 - From STUPID to SOLID code! (1/2) + PHP Implementations 166 - From STUPID to SOLID code! (2/2) + Component Driven Development 167 - Object Calisthenics + From STUPID to SOLID code! (1/2) 168 - Testing + From STUPID to SOLID code! (2/2) 169 - Agenda + Object Calisthenics 170 - Unit Testing + Testing 171 - Unit Testing + Agenda 172 - PHPUnit — The Rules + Unit Testing 173 - PHPUnit — Assertions + Unit Testing 174 - Running PHPUnit + PHPUnit — The Rules 175 - Functional Testing + PHPUnit — Assertions 176 - Functional Testing + Running PHPUnit 177 - Behavior Driven Development + Functional Testing 178 - Behavior Driven Development + Functional Testing 179 - Behat + Behavior Driven Development 180 - Using Behat (1/2) + Behavior Driven Development 181 - Using Behat (2/2) + Behat 182 - Awesome Projects + Using Behat (1/2) 183 -
    + Using Behat (2/2) 184 - Embracing Open Source + Awesome Projects 185 - +
    186 - + Embracing Open Source 187 - + 188 - Golden Rules + 189 - The End. + 190 - Well... Maybe Not.
    PHP Extended + Golden Rules 191 + + The End. + 192 + + + + + Well... Maybe Not.
    PHP Extended + 193 + + + diff --git a/isima.html b/isima.html index 738ead1..e3a2866 100644 --- a/isima.html +++ b/isima.html @@ -1208,7 +1208,7 @@ @@ -1236,7 +1236,7 @@ @@ -1287,7 +1287,7 @@ @@ -1315,7 +1315,7 @@ @@ -1354,7 +1354,7 @@

    Week #4

    @@ -1382,7 +1382,7 @@

    Week #4

    @@ -1417,7 +1417,7 @@

    Week #4

    @@ -1453,7 +1453,7 @@

    Week #4

    @@ -1489,7 +1489,7 @@

    Week #4

    @@ -1523,7 +1523,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1586,7 +1586,7 @@

    Week #4

    @@ -1614,7 +1614,7 @@

    Week #4

    @@ -1652,7 +1652,7 @@

    Week #4

    @@ -1701,7 +1701,7 @@

    Week #4

    @@ -1752,7 +1752,7 @@

    Week #4

    @@ -1795,7 +1795,7 @@

    Abstract class definition

    @@ -1847,7 +1847,7 @@

    Abstract class definition

    @@ -1886,7 +1886,7 @@

    The Rules

    @@ -1939,7 +1939,7 @@

    The Rules

    @@ -1988,7 +1988,7 @@

    Type Hinting

    @@ -2033,7 +2033,7 @@

    Usage

    @@ -2081,7 +2081,7 @@

    Usage

    @@ -2127,7 +2127,7 @@

    Usage

    @@ -2171,7 +2171,7 @@

    Usage

    @@ -2223,7 +2223,7 @@

    Usage

    @@ -2271,7 +2271,7 @@

    PSR-0

    @@ -2318,7 +2318,7 @@

    PSR-0

    @@ -2370,7 +2370,7 @@

    PSR-0

    @@ -2413,7 +2413,7 @@

    PSR-0

    @@ -2459,7 +2459,7 @@

    PSR-0

    @@ -2502,7 +2502,7 @@

    PSR-0

    @@ -2543,7 +2543,7 @@

    PSR-0

    @@ -2571,7 +2571,7 @@

    PSR-0

    @@ -2623,7 +2623,7 @@

    PSR-0

    @@ -2671,7 +2671,7 @@

    PSR-0

    @@ -2723,7 +2723,7 @@

    PSR-0

    @@ -2751,7 +2751,7 @@

    PSR-0

    @@ -2791,7 +2791,7 @@

    PSR-0

    @@ -2835,7 +2835,7 @@

    Collections

    @@ -2880,7 +2880,7 @@

    Collections

    @@ -2930,7 +2930,7 @@

    Collections

    @@ -2970,7 +2970,7 @@

    Collections

    @@ -3013,7 +3013,7 @@

    Collections

    @@ -3063,7 +3063,7 @@

    Collections

    @@ -3091,7 +3091,7 @@

    Collections

    @@ -3132,7 +3132,7 @@

    Collections

    @@ -3164,7 +3164,7 @@

    Collections

    @@ -3192,7 +3192,7 @@

    Collections

    @@ -3244,7 +3244,7 @@

    Hyper Media Types

    @@ -3296,7 +3296,7 @@

    Hyper Media Types

    @@ -3348,7 +3348,7 @@

    Hyper Media Types

    @@ -3376,7 +3376,7 @@

    Hyper Media Types

    @@ -3425,7 +3425,7 @@

    Hyper Media Types

    @@ -3475,7 +3475,7 @@

    Hyper Media Types

    @@ -3522,7 +3522,7 @@

    Hyper Media Types

    @@ -3571,7 +3571,7 @@

    Hyper Media Types

    @@ -3610,7 +3610,7 @@

    spl_autoload_functions()

    @@ -3659,7 +3659,7 @@

    spl_autoload_unregister()

    @@ -3714,7 +3714,7 @@

    spl_autoload_unregister()

    @@ -3742,7 +3742,7 @@

    spl_autoload_unregister()

    @@ -3787,7 +3787,7 @@

    Traversable

    @@ -3838,7 +3838,7 @@

    Traversable

    @@ -3889,7 +3889,7 @@

    Traversable

    @@ -3931,7 +3931,7 @@

    SPL Functions

    @@ -3984,7 +3984,7 @@

    SPL Functions

    @@ -4033,7 +4033,7 @@

    SPL Functions

    @@ -4082,7 +4082,7 @@

    SPL Functions

    @@ -4122,7 +4122,7 @@

    SPL Functions

    @@ -4173,7 +4173,7 @@

    SPL Functions

    @@ -4215,7 +4215,7 @@

    SPL Functions

    @@ -4243,7 +4243,7 @@

    SPL Functions

    @@ -4287,7 +4287,7 @@

    SPL Functions

    @@ -4337,7 +4337,7 @@

    SPL Functions

    @@ -4380,7 +4380,7 @@

    SPL Functions

    @@ -4428,7 +4428,7 @@

    SPL Functions

    @@ -4478,7 +4478,7 @@

    SPL Functions

    @@ -4525,7 +4525,7 @@

    Execution

    @@ -4578,7 +4578,7 @@

    Usage

    @@ -4606,7 +4606,7 @@

    Usage

    @@ -4649,7 +4649,7 @@

    Usage

    @@ -4692,7 +4692,7 @@

    Usage

    @@ -4745,7 +4745,7 @@

    Usage

    @@ -4792,7 +4792,7 @@

    Usage

    @@ -4841,7 +4841,7 @@

    Usage

    @@ -4893,7 +4893,7 @@

    Usage

    @@ -4936,7 +4936,7 @@

    Centralized Declaration

    @@ -4969,7 +4969,7 @@

    Centralized Declaration

    @@ -5010,7 +5010,7 @@

    Centralized Declaration

    @@ -5038,7 +5038,7 @@

    Centralized Declaration

    @@ -5074,7 +5074,7 @@

    Centralized Declaration

    @@ -5109,7 +5109,7 @@

    Centralized Declaration

    @@ -5150,7 +5150,7 @@

    Centralized Declaration

    @@ -5178,7 +5178,7 @@

    Centralized Declaration

    @@ -5232,7 +5232,7 @@

    Centralized Declaration

    @@ -5278,7 +5278,7 @@

    Centralized Declaration

    @@ -5296,7 +5296,7 @@

    Centralized Declaration

    public function insert(Connection $con)
     {
         // Prepared statement
    -    $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)');
    +    $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)');
     
         $stmt->bindValue(':name', $name);
     
    @@ -5325,7 +5325,7 @@ 

    Centralized Declaration

    @@ -5353,7 +5353,7 @@

    Centralized Declaration

    @@ -5401,7 +5401,7 @@

    CRUD

    @@ -5448,7 +5448,7 @@

    CRUD

    @@ -5471,7 +5471,7 @@

    CRUD

    public function insert($name) { // Prepared statement - $stmt = $this->con->prepare('INSERT INTO bananas ValueS (:name)'); + $stmt = $this->con->prepare('INSERT INTO bananas VALUES (:name)'); $stmt->bindValue(':name', $name); @@ -5496,7 +5496,7 @@

    CRUD

    @@ -5548,7 +5548,7 @@

    CRUD

    @@ -5593,7 +5593,7 @@

    CRUD

    @@ -5640,7 +5640,7 @@

    CRUD

    @@ -5668,7 +5668,7 @@

    CRUD

    @@ -5715,7 +5715,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5770,7 +5770,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5798,7 +5798,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5851,7 +5851,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5900,7 +5900,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5928,7 +5928,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5948,7 +5948,7 @@

    Active Record = Row Data Gateway + Domain Logic

    { private $identityMap = []; - public function findOneById($id) + public function find($id) { if (!isset($this->identityMap[$id])) { // fetch the object for the given id @@ -5975,7 +5975,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6003,7 +6003,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6046,7 +6046,7 @@

    PHP Data Object (PDO)

    @@ -6095,7 +6095,7 @@

    Usage

    @@ -6149,7 +6149,7 @@

    Usage

    @@ -6196,7 +6196,7 @@

    Usage

    @@ -6224,7 +6224,7 @@

    Usage

    @@ -6261,7 +6261,7 @@

    Usage

    @@ -6297,7 +6297,7 @@

    Code Snippet

    @@ -6333,7 +6333,7 @@

    Code Snippet

    @@ -6375,7 +6375,7 @@

    Code Snippet

    @@ -6415,7 +6415,7 @@

    Doctrine2 ORM

    @@ -6443,7 +6443,7 @@

    Doctrine2 ORM

    @@ -6497,7 +6497,7 @@

    Doctrine2 ORM

    @@ -6552,7 +6552,7 @@

    Doctrine2 ORM

    @@ -6580,7 +6580,7 @@

    Doctrine2 ORM

    @@ -6629,7 +6629,7 @@

    Doctrine2 ORM

    @@ -6668,7 +6668,7 @@

    Doctrine2 ORM

    @@ -6696,7 +6696,7 @@

    Doctrine2 ORM

    @@ -6752,7 +6752,7 @@

    Doctrine2 ORM

    @@ -6763,7 +6763,7 @@

    Doctrine2 ORM

    -

    Combine Them!

    +

    Repository ♥ Specification

    A findSatisfying() method can be added to the CustomerRepository:

    @@ -6798,7 +6798,120 @@

    Usage

    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +
    class OrSpecification implements CustomerSpecification
    +{
    +    public function __construct(
    +        CustomerSpecification $s1,
    +        CustomerSpecification $s2
    +    ) {
    +        $this->s1 = $s1;
    +        $this->s2 = $s2;
    +    }
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return $this->s1->isSatisfiedBy($c) || $this->s2->isSatisfiedBy($c);
    +    }
    +}
    +
    + +

    + +
    class AndSpecification implements CustomerSpecification
    +{
    +    ...
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return $this->s1->isSatisfiedBy($c) && $this->s2->isSatisfiedBy($c);
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Combine Them!

    + + +
    class NotSpecification implements CustomerSpecification
    +{
    +    public function __construct(CustomerSpecification $s)
    +    {
    +        $this->s = $s;
    +    }
    +
    +    public function isSatisfiedBy(Customer $c)
    +    {
    +        return !$this->s->isSatisfiedBy($c);
    +    }
    +}
    +
    + +

    Usage

    +
    $specification = new AndSpecification(
    +    new CustomerHasOrderedThreeTimes(),
    +    new NotSpecification(
    +        new CustomerIsPremium()
    +    )
    +);
    +
    +$customers = $repository->findSatisfying($specification);
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -6826,7 +6939,7 @@

    Usage

    @@ -6854,7 +6967,7 @@

    Usage

    @@ -7656,23 +7769,35 @@

    Table of Contents

    - Combine Them! + Repository ♥ Specification 132 - Next Week: Web Security 101 + Combine Them! 133 - The End. + Combine Them! 134 + + Next Week: Web Security 101 + 135 + + + + + The End. + 136 + + + From a1c828661d089f6ce637a02b81cc7e667e04accd Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 29 Jan 2014 00:39:49 +0100 Subject: [PATCH 28/71] Publish slides (Mer 29 jan 2014 00:39:49 CET) --- index.html | 4 ++-- isima.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 334c0b8..f0b9c02 100644 --- a/index.html +++ b/index.html @@ -1898,7 +1898,7 @@

    The Rules

    -

    Attributes

    +

    Properties

    class Foo
    @@ -9380,7 +9380,7 @@ 

    Table of Contents

    - Attributes + Properties 20 diff --git a/isima.html b/isima.html index e3a2866..2449976 100644 --- a/isima.html +++ b/isima.html @@ -1897,7 +1897,7 @@

    The Rules

    -

    Attributes

    +

    Properties

    class Foo
    @@ -7097,7 +7097,7 @@ 

    Table of Contents

    - Attributes + Properties 20 From 38f8ca6d962e1366976435ec2350a4d502b46d62 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 29 Jan 2014 01:29:25 +0100 Subject: [PATCH 29/71] Publish slides (Mer 29 jan 2014 01:29:25 CET) --- index.html | 759 +++++++++++++++++++++++++++++------------------------ isima.html | 543 +++++++++++++++++++++----------------- 2 files changed, 718 insertions(+), 584 deletions(-) diff --git a/index.html b/index.html index f0b9c02..8055aa8 100644 --- a/index.html +++ b/index.html @@ -1208,7 +1208,7 @@
    @@ -1236,7 +1236,7 @@
    @@ -1287,7 +1287,7 @@
    @@ -1315,7 +1315,7 @@
    @@ -1355,7 +1355,7 @@

    Week #4

    @@ -1383,7 +1383,7 @@

    Week #4

    @@ -1418,7 +1418,7 @@

    Week #4

    @@ -1454,7 +1454,7 @@

    Week #4

    @@ -1490,7 +1490,7 @@

    Week #4

    @@ -1524,7 +1524,7 @@

    Week #4

    @@ -1559,7 +1559,7 @@

    Week #4

    @@ -1587,7 +1587,7 @@

    Week #4

    @@ -1615,7 +1615,7 @@

    Week #4

    @@ -1653,7 +1653,7 @@

    Week #4

    @@ -1702,7 +1702,7 @@

    Week #4

    @@ -1753,7 +1753,7 @@

    Week #4

    @@ -1796,7 +1796,7 @@

    Abstract class definition

    @@ -1848,7 +1848,7 @@

    Abstract class definition

    @@ -1887,7 +1887,7 @@

    The Rules

    @@ -1940,7 +1940,7 @@

    The Rules

    @@ -1989,7 +1989,7 @@

    Type Hinting

    @@ -2034,7 +2034,7 @@

    Usage

    @@ -2082,7 +2082,7 @@

    Usage

    @@ -2093,7 +2093,7 @@

    Usage

    -

    Static Keyword (1/2)

    +

    Static Keyword

    Attributes/Methods can be defined as static:

    @@ -2110,8 +2110,10 @@

    Usage

    }
    -

    Warning: the static keyword can also be used to -define static variables and for late static bindings. +

    Warning: the static keyword can also be used to define static +variables +and for late static +bindings. This is different!

    @@ -2128,7 +2130,7 @@

    Usage

    @@ -2139,7 +2141,66 @@

    Usage

    -

    Static Keyword (2/2)

    +

    Late State Bindings

    + + +
    class A
    +{
    +    public static function who() { echo __CLASS__; }
    +
    +    public static function testSelf()
    +    {
    +        self::who();
    +    }
    +
    +    public static function testStatic()
    +    {
    +        static::who();
    +    }
    +}
    +
    +class B extends A
    +{
    +    public static function who() { echo __CLASS__; }
    +}
    +
    + +

    + +
    B::testSelf();
    +// A
    +
    +B::testStatic();
    +// B
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    Static Keyword

    Usage

    @@ -2172,7 +2233,7 @@

    Usage

    @@ -2224,7 +2285,7 @@

    Usage

    @@ -2272,7 +2333,7 @@

    PSR-0

    @@ -2319,7 +2380,7 @@

    PSR-0

    @@ -2371,7 +2432,7 @@

    PSR-0

    @@ -2414,7 +2475,7 @@

    PSR-0

    @@ -2460,7 +2521,7 @@

    PSR-0

    @@ -2503,7 +2564,7 @@

    PSR-0

    @@ -2544,7 +2605,7 @@

    PSR-0

    @@ -2572,7 +2633,7 @@

    PSR-0

    @@ -2624,7 +2685,7 @@

    PSR-0

    @@ -2672,7 +2733,7 @@

    PSR-0

    @@ -2724,7 +2785,7 @@

    PSR-0

    @@ -2752,7 +2813,7 @@

    PSR-0

    @@ -2792,7 +2853,7 @@

    PSR-0

    @@ -2836,7 +2897,7 @@

    Collections

    @@ -2881,7 +2942,7 @@

    Collections

    @@ -2931,7 +2992,7 @@

    Collections

    @@ -2971,7 +3032,7 @@

    Collections

    @@ -3014,7 +3075,7 @@

    Collections

    @@ -3064,7 +3125,7 @@

    Collections

    @@ -3092,7 +3153,7 @@

    Collections

    @@ -3133,7 +3194,7 @@

    Collections

    @@ -3165,7 +3226,7 @@

    Collections

    @@ -3193,7 +3254,7 @@

    Collections

    @@ -3245,7 +3306,7 @@

    Hyper Media Types

    @@ -3297,7 +3358,7 @@

    Hyper Media Types

    @@ -3349,7 +3410,7 @@

    Hyper Media Types

    @@ -3377,7 +3438,7 @@

    Hyper Media Types

    @@ -3426,7 +3487,7 @@

    Hyper Media Types

    @@ -3476,7 +3537,7 @@

    Hyper Media Types

    @@ -3523,7 +3584,7 @@

    Hyper Media Types

    @@ -3572,7 +3633,7 @@

    Hyper Media Types

    @@ -3611,7 +3672,7 @@

    spl_autoload_functions()

    @@ -3660,7 +3721,7 @@

    spl_autoload_unregister()

    @@ -3715,7 +3776,7 @@

    spl_autoload_unregister()

    @@ -3743,7 +3804,7 @@

    spl_autoload_unregister()

    @@ -3788,7 +3849,7 @@

    Traversable

    @@ -3839,7 +3900,7 @@

    Traversable

    @@ -3890,7 +3951,7 @@

    Traversable

    @@ -3932,7 +3993,7 @@

    SPL Functions

    @@ -3985,7 +4046,7 @@

    SPL Functions

    @@ -4034,7 +4095,7 @@

    SPL Functions

    @@ -4083,7 +4144,7 @@

    SPL Functions

    @@ -4123,7 +4184,7 @@

    SPL Functions

    @@ -4174,7 +4235,7 @@

    SPL Functions

    @@ -4216,7 +4277,7 @@

    SPL Functions

    @@ -4244,7 +4305,7 @@

    SPL Functions

    @@ -4288,7 +4349,7 @@

    SPL Functions

    @@ -4338,7 +4399,7 @@

    SPL Functions

    @@ -4381,7 +4442,7 @@

    SPL Functions

    @@ -4429,7 +4490,7 @@

    SPL Functions

    @@ -4479,7 +4540,7 @@

    SPL Functions

    @@ -4526,7 +4587,7 @@

    Execution

    @@ -4579,7 +4640,7 @@

    Usage

    @@ -4607,7 +4668,7 @@

    Usage

    @@ -4650,7 +4711,7 @@

    Usage

    @@ -4693,7 +4754,7 @@

    Usage

    @@ -4746,7 +4807,7 @@

    Usage

    @@ -4793,7 +4854,7 @@

    Usage

    @@ -4842,7 +4903,7 @@

    Usage

    @@ -4894,7 +4955,7 @@

    Usage

    @@ -4937,7 +4998,7 @@

    Centralized Declaration

    @@ -4970,7 +5031,7 @@

    Centralized Declaration

    @@ -5011,7 +5072,7 @@

    Centralized Declaration

    @@ -5039,7 +5100,7 @@

    Centralized Declaration

    @@ -5075,7 +5136,7 @@

    Centralized Declaration

    @@ -5110,7 +5171,7 @@

    Centralized Declaration

    @@ -5151,7 +5212,7 @@

    Centralized Declaration

    @@ -5179,7 +5240,7 @@

    Centralized Declaration

    @@ -5233,7 +5294,7 @@

    Centralized Declaration

    @@ -5279,7 +5340,7 @@

    Centralized Declaration

    @@ -5326,7 +5387,7 @@

    Centralized Declaration

    @@ -5354,7 +5415,7 @@

    Centralized Declaration

    @@ -5402,7 +5463,7 @@

    CRUD

    @@ -5449,7 +5510,7 @@

    CRUD

    @@ -5497,7 +5558,7 @@

    CRUD

    @@ -5549,7 +5610,7 @@

    CRUD

    @@ -5594,7 +5655,7 @@

    CRUD

    @@ -5641,7 +5702,7 @@

    CRUD

    @@ -5669,7 +5730,7 @@

    CRUD

    @@ -5716,7 +5777,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5771,7 +5832,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5799,7 +5860,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5852,7 +5913,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5901,7 +5962,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5929,7 +5990,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5976,7 +6037,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6004,7 +6065,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6047,7 +6108,7 @@

    PHP Data Object (PDO)

    @@ -6096,7 +6157,7 @@

    Usage

    @@ -6150,7 +6211,7 @@

    Usage

    @@ -6197,7 +6258,7 @@

    Usage

    @@ -6225,7 +6286,7 @@

    Usage

    @@ -6262,7 +6323,7 @@

    Usage

    @@ -6298,7 +6359,7 @@

    Code Snippet

    @@ -6334,7 +6395,7 @@

    Code Snippet

    @@ -6376,7 +6437,7 @@

    Code Snippet

    @@ -6416,7 +6477,7 @@

    Doctrine2 ORM

    @@ -6444,7 +6505,7 @@

    Doctrine2 ORM

    @@ -6498,7 +6559,7 @@

    Doctrine2 ORM

    @@ -6553,7 +6614,7 @@

    Doctrine2 ORM

    @@ -6581,7 +6642,7 @@

    Doctrine2 ORM

    @@ -6630,7 +6691,7 @@

    Doctrine2 ORM

    @@ -6669,7 +6730,7 @@

    Doctrine2 ORM

    @@ -6697,7 +6758,7 @@

    Doctrine2 ORM

    @@ -6753,7 +6814,7 @@

    Doctrine2 ORM

    @@ -6799,7 +6860,7 @@

    Usage

    @@ -6858,7 +6919,7 @@

    Usage

    @@ -6912,7 +6973,7 @@

    Usage

    @@ -6940,7 +7001,7 @@

    Usage

    @@ -6982,7 +7043,7 @@

    A few use cases:

    @@ -7031,7 +7092,7 @@

    A few use cases:

    @@ -7072,7 +7133,7 @@

    Workarounds

    @@ -7100,7 +7161,7 @@

    Workarounds

    @@ -7131,7 +7192,7 @@

    Workarounds

    @@ -7161,7 +7222,7 @@

    Workarounds

    @@ -7202,7 +7263,7 @@

    Event Dispatcher

    @@ -7250,7 +7311,7 @@

    Event Dispatcher

    @@ -7302,7 +7363,7 @@

    Event Dispatcher

    @@ -7346,7 +7407,7 @@

    Event Dispatcher

    @@ -7386,7 +7447,7 @@

    Event Dispatcher

    @@ -7443,7 +7504,7 @@

    Event Dispatcher

    @@ -7473,7 +7534,7 @@

    Event Dispatcher

    @@ -7526,7 +7587,7 @@

    Event Dispatcher

    @@ -7562,7 +7623,7 @@

    WSSE Username Token

    @@ -7606,7 +7667,7 @@

    WSSE Username Token

    @@ -7634,7 +7695,7 @@

    WSSE Username Token

    @@ -7674,7 +7735,7 @@

    WSSE Username Token

    @@ -7731,7 +7792,7 @@

    WSSE Username Token

    @@ -7775,7 +7836,7 @@

    Usage

    @@ -7820,7 +7881,7 @@

    Usage

    @@ -7858,7 +7919,7 @@

    Usage

    @@ -7908,7 +7969,7 @@

    Usage

    @@ -7959,7 +8020,7 @@

    Usage

    @@ -8001,7 +8062,7 @@

    Usage

    @@ -8043,7 +8104,7 @@

    Usage

    @@ -8092,7 +8153,7 @@

    Usage

    @@ -8125,7 +8186,7 @@

    Usage

    @@ -8168,7 +8229,7 @@

    Usage

    @@ -8217,7 +8278,7 @@

    Usage

    @@ -8260,7 +8321,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8297,7 +8358,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8339,7 +8400,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8380,7 +8441,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8426,7 +8487,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8454,7 +8515,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8488,7 +8549,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8516,7 +8577,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8562,7 +8623,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8610,7 +8671,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8649,7 +8710,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8699,7 +8760,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8727,7 +8788,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8764,7 +8825,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8792,7 +8853,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8835,7 +8896,7 @@

    StoryBDD

    @@ -8881,7 +8942,7 @@

    StoryBDD

    @@ -8929,7 +8990,7 @@

    StoryBDD

    @@ -8982,7 +9043,7 @@

    StoryBDD

    @@ -9010,7 +9071,7 @@

    StoryBDD

    @@ -9042,7 +9103,7 @@

    StoryBDD

    @@ -9070,7 +9131,7 @@

    StoryBDD

    @@ -9098,7 +9159,7 @@

    StoryBDD

    @@ -9126,7 +9187,7 @@

    StoryBDD

    @@ -9154,7 +9215,7 @@

    StoryBDD

    @@ -9194,7 +9255,7 @@

    StoryBDD

    @@ -9222,7 +9283,7 @@

    StoryBDD

    @@ -9250,7 +9311,7 @@

    StoryBDD

    @@ -9404,361 +9465,361 @@

    Table of Contents

    - Static Keyword (1/2) + Static Keyword 24 - Static Keyword (2/2) + Late State Bindings 25 - Interfaces + Static Keyword 26 - Namespaces + Interfaces 27 - The class Keyword + Namespaces 28 - Traits + The class Keyword 29 - Anonymous Functions + Traits 30 - Closures + Anonymous Functions 31 - Magic Methods + Closures 32 - Generators + Magic Methods 33 - The PHP Command Line + Generators 34 - The PHP Command Line (1/2) + The PHP Command Line 35 - The PHP Command Line (2/2) + The PHP Command Line (1/2) 36 - Writing a CLI program + The PHP Command Line (2/2) 37 - Client/Server + Writing a CLI program 38 - Client/Server Basics + Client/Server 39 - Unified Resource Identifier (URI) + Client/Server Basics 40 - HTTP Request + Unified Resource Identifier (URI) 41 - HTTP Response + HTTP Request 42 - HTTP Verbs + HTTP Response 43 - HTTP Parameters (1/2) + HTTP Verbs 44 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 45 - REST + HTTP Parameters (2/2) 46 - REpresentational State Transfer + REST 47 - Richardson Maturity Model + REpresentational State Transfer 48 - Level 3 = Content Negotiation + HATEOAS + Richardson Maturity Model 49 - Media Types + Level 3 = Content Negotiation + HATEOAS 50 - Content Type Negotiation + Media Types 51 - HATEOAS + Content Type Negotiation 52 - PHP Autoloading + HATEOAS 53 - Why Is It Necessary? + PHP Autoloading 54 - The require() Way + Why Is It Necessary? 55 - The require_once() Way + The require() Way 56 - Working With Multiple Files + The require_once() Way 57 - Rethinking The Way You Load Classes + Working With Multiple Files 58 - Examples + Rethinking The Way You Load Classes 59 - Under The Hood + Examples 60 - Leveraging PHP APIs + Under The Hood 61 - Built-in Interfaces + Leveraging PHP APIs 62 - The Reflection API (1/2) + Built-in Interfaces 63 - The Reflection API (2/2) + The Reflection API (1/2) 64 - The Standard PHP Library (SPL) + The Reflection API (2/2) 65 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 66 - Observer Pattern (2/2) + Observer Pattern (1/2) 67 - Exceptions (1/2) + Observer Pattern (2/2) 68 - Exceptions (2/2) + Exceptions (1/2) 69 - Password Hashing + Exceptions (2/2) 70 - PHP Archive (PHAR) + Password Hashing 71 - Dependency Management in PHP + PHP Archive (PHAR) 72 - Composer + Dependency Management in PHP 73 - composer install + Composer 74 - Composer Autoloader + composer install 75 - Example + Composer Autoloader 76 - The Symfony2 Console Component + Example 77 - A Basic Command (1/2) + The Symfony2 Console Component 78 - A Basic Command (2/2) + A Basic Command (1/2) 79 - Model View Controller + A Basic Command (2/2) 80 - MVC Overview + Model View Controller 81 - The Model + MVC Overview 82 - The View + The Model 83 @@ -9776,61 +9837,61 @@

    Table of Contents

    - The Controller + The View 86 - Routing + The Controller 87 - Front Controller Pattern + Routing 88 - Interact With Multiple Services + Front Controller Pattern 89 - Databases + Interact With Multiple Services 90 - Agenda + Databases 91 - Quick note + Agenda 92 - Database Design Patterns + Quick note 93 - Row Data Gateway + Database Design Patterns 94 - Row Data Gateway + Row Data Gateway 95 @@ -9848,13 +9909,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 98 - Table Data Gateway + Table Data Gateway 99 @@ -9890,13 +9951,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 105 - Active Record + Active Record 106 @@ -9908,13 +9969,13 @@

    Table of Contents

    - Data Mapper + Active Record 108 - Data Mapper + Data Mapper 109 @@ -9926,31 +9987,31 @@

    Table of Contents

    - Identity Map + Data Mapper 111 - Identity Map + Identity Map 112 - Data Access Layer + Identity Map 113 - Data Access Layer / Data Source Name + Data Access Layer 114 - Data Access Layer + Data Access Layer / Data Source Name 115 @@ -9968,67 +10029,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 118 - Object Relational Mapping (1/4) + Object Relational Mapping 119 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 120 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 121 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 122 - Existing Components + Object Relational Mapping (4/4) 123 - A Note About
    Domain-Driven Design
    + Existing Components 124 - Entities + A Note About
    Domain-Driven Design
    125 - Value Objects + Entities 126 - The Repository Pattern + Value Objects 127 - The Repository Pattern + The Repository Pattern 128 @@ -10040,25 +10101,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 130 - The Specification Pattern + The Specification Pattern 131 - Repository ♥ Specification + The Specification Pattern 132 - Combine Them! + Repository ♥ Specification 133 @@ -10070,157 +10131,157 @@

    Table of Contents

    - Sessions + Combine Them! 135 - Overview + Sessions 136 - Code Please + Overview 137 - Security Concerns + Code Please 138 - Authentication + Security Concerns 139 - What You Have Right Now + Authentication 140 - The Big Picture + What You Have Right Now 141 - The Interceptor Pattern + The Big Picture 142 - Introducing the Event Dispatcher + The Interceptor Pattern 143 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 144 - The Firewall (1/2) + Using the EventDispatcherTrait 145 - The Firewall (2/2) + The Firewall (1/2) 146 - Implementing The Firewall + The Firewall (2/2) 147 - Authentication Mechanism + Implementing The Firewall 148 - Adding New Routes + Authentication Mechanism 149 - Stateless Authentication + Adding New Routes 150 - Basic Security Thinking + Stateless Authentication 151 - Writing Better Code + Basic Security Thinking 152 - Agenda + Writing Better Code 153 - Coding Standards + Agenda 154 - PHP Coding Standards Fixer + Coding Standards 155 - Programming To The Interface + PHP Coding Standards Fixer 156 - Dependency Inversion Principle (DIP) + Programming To The Interface 157 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 158 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 159 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 160 @@ -10238,19 +10299,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 163 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 164 - PHP Implementations + Dependency Injection Container (DIC) 165 @@ -10262,43 +10323,43 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 167 - From STUPID to SOLID code! (1/2) + Component Driven Development 168 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 169 - Object Calisthenics + From STUPID to SOLID code! (2/2) 170 - Testing + Object Calisthenics 171 - Agenda + Testing 172 - Unit Testing + Agenda 173 @@ -10310,25 +10371,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 175 - PHPUnit — Assertions + PHPUnit — The Rules 176 - Running PHPUnit + PHPUnit — Assertions 177 - Functional Testing + Running PHPUnit 178 @@ -10340,7 +10401,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 180 @@ -10352,77 +10413,83 @@

    Table of Contents

    - Behat + Behavior Driven Development 182 - Using Behat (1/2) + Behat 183 - Using Behat (2/2) + Using Behat (1/2) 184 - Awesome Projects + Using Behat (2/2) 185 -
    + Awesome Projects 186 - Embracing Open Source +
    187 - + Embracing Open Source 188 - + 189 - + 190 - Golden Rules + 191 - The End. + Golden Rules 192 - Well... Maybe Not.
    PHP Extended + The End. 193 + + Well... Maybe Not.
    PHP Extended + 194 + + + diff --git a/isima.html b/isima.html index 2449976..71f1a02 100644 --- a/isima.html +++ b/isima.html @@ -1208,7 +1208,7 @@ @@ -1236,7 +1236,7 @@ @@ -1287,7 +1287,7 @@ @@ -1315,7 +1315,7 @@ @@ -1354,7 +1354,7 @@

    Week #4

    @@ -1382,7 +1382,7 @@

    Week #4

    @@ -1417,7 +1417,7 @@

    Week #4

    @@ -1453,7 +1453,7 @@

    Week #4

    @@ -1489,7 +1489,7 @@

    Week #4

    @@ -1523,7 +1523,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1586,7 +1586,7 @@

    Week #4

    @@ -1614,7 +1614,7 @@

    Week #4

    @@ -1652,7 +1652,7 @@

    Week #4

    @@ -1701,7 +1701,7 @@

    Week #4

    @@ -1752,7 +1752,7 @@

    Week #4

    @@ -1795,7 +1795,7 @@

    Abstract class definition

    @@ -1847,7 +1847,7 @@

    Abstract class definition

    @@ -1886,7 +1886,7 @@

    The Rules

    @@ -1939,7 +1939,7 @@

    The Rules

    @@ -1988,7 +1988,7 @@

    Type Hinting

    @@ -2033,7 +2033,7 @@

    Usage

    @@ -2081,7 +2081,7 @@

    Usage

    @@ -2092,7 +2092,7 @@

    Usage

    -

    Static Keyword (1/2)

    +

    Static Keyword

    Attributes/Methods can be defined as static:

    @@ -2109,8 +2109,10 @@

    Usage

    }
    -

    Warning: the static keyword can also be used to -define static variables and for late static bindings. +

    Warning: the static keyword can also be used to define static +variables +and for late static +bindings. This is different!

    @@ -2127,7 +2129,7 @@

    Usage

    @@ -2138,7 +2140,66 @@

    Usage

    -

    Static Keyword (2/2)

    +

    Late State Bindings

    + + +
    class A
    +{
    +    public static function who() { echo __CLASS__; }
    +
    +    public static function testSelf()
    +    {
    +        self::who();
    +    }
    +
    +    public static function testStatic()
    +    {
    +        static::who();
    +    }
    +}
    +
    +class B extends A
    +{
    +    public static function who() { echo __CLASS__; }
    +}
    +
    + +

    + +
    B::testSelf();
    +// A
    +
    +B::testStatic();
    +// B
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    + + + +
    +
    +
    + +

    Static Keyword

    Usage

    @@ -2171,7 +2232,7 @@

    Usage

    @@ -2223,7 +2284,7 @@

    Usage

    @@ -2271,7 +2332,7 @@

    PSR-0

    @@ -2318,7 +2379,7 @@

    PSR-0

    @@ -2370,7 +2431,7 @@

    PSR-0

    @@ -2413,7 +2474,7 @@

    PSR-0

    @@ -2459,7 +2520,7 @@

    PSR-0

    @@ -2502,7 +2563,7 @@

    PSR-0

    @@ -2543,7 +2604,7 @@

    PSR-0

    @@ -2571,7 +2632,7 @@

    PSR-0

    @@ -2623,7 +2684,7 @@

    PSR-0

    @@ -2671,7 +2732,7 @@

    PSR-0

    @@ -2723,7 +2784,7 @@

    PSR-0

    @@ -2751,7 +2812,7 @@

    PSR-0

    @@ -2791,7 +2852,7 @@

    PSR-0

    @@ -2835,7 +2896,7 @@

    Collections

    @@ -2880,7 +2941,7 @@

    Collections

    @@ -2930,7 +2991,7 @@

    Collections

    @@ -2970,7 +3031,7 @@

    Collections

    @@ -3013,7 +3074,7 @@

    Collections

    @@ -3063,7 +3124,7 @@

    Collections

    @@ -3091,7 +3152,7 @@

    Collections

    @@ -3132,7 +3193,7 @@

    Collections

    @@ -3164,7 +3225,7 @@

    Collections

    @@ -3192,7 +3253,7 @@

    Collections

    @@ -3244,7 +3305,7 @@

    Hyper Media Types

    @@ -3296,7 +3357,7 @@

    Hyper Media Types

    @@ -3348,7 +3409,7 @@

    Hyper Media Types

    @@ -3376,7 +3437,7 @@

    Hyper Media Types

    @@ -3425,7 +3486,7 @@

    Hyper Media Types

    @@ -3475,7 +3536,7 @@

    Hyper Media Types

    @@ -3522,7 +3583,7 @@

    Hyper Media Types

    @@ -3571,7 +3632,7 @@

    Hyper Media Types

    @@ -3610,7 +3671,7 @@

    spl_autoload_functions()

    @@ -3659,7 +3720,7 @@

    spl_autoload_unregister()

    @@ -3714,7 +3775,7 @@

    spl_autoload_unregister()

    @@ -3742,7 +3803,7 @@

    spl_autoload_unregister()

    @@ -3787,7 +3848,7 @@

    Traversable

    @@ -3838,7 +3899,7 @@

    Traversable

    @@ -3889,7 +3950,7 @@

    Traversable

    @@ -3931,7 +3992,7 @@

    SPL Functions

    @@ -3984,7 +4045,7 @@

    SPL Functions

    @@ -4033,7 +4094,7 @@

    SPL Functions

    @@ -4082,7 +4143,7 @@

    SPL Functions

    @@ -4122,7 +4183,7 @@

    SPL Functions

    @@ -4173,7 +4234,7 @@

    SPL Functions

    @@ -4215,7 +4276,7 @@

    SPL Functions

    @@ -4243,7 +4304,7 @@

    SPL Functions

    @@ -4287,7 +4348,7 @@

    SPL Functions

    @@ -4337,7 +4398,7 @@

    SPL Functions

    @@ -4380,7 +4441,7 @@

    SPL Functions

    @@ -4428,7 +4489,7 @@

    SPL Functions

    @@ -4478,7 +4539,7 @@

    SPL Functions

    @@ -4525,7 +4586,7 @@

    Execution

    @@ -4578,7 +4639,7 @@

    Usage

    @@ -4606,7 +4667,7 @@

    Usage

    @@ -4649,7 +4710,7 @@

    Usage

    @@ -4692,7 +4753,7 @@

    Usage

    @@ -4745,7 +4806,7 @@

    Usage

    @@ -4792,7 +4853,7 @@

    Usage

    @@ -4841,7 +4902,7 @@

    Usage

    @@ -4893,7 +4954,7 @@

    Usage

    @@ -4936,7 +4997,7 @@

    Centralized Declaration

    @@ -4969,7 +5030,7 @@

    Centralized Declaration

    @@ -5010,7 +5071,7 @@

    Centralized Declaration

    @@ -5038,7 +5099,7 @@

    Centralized Declaration

    @@ -5074,7 +5135,7 @@

    Centralized Declaration

    @@ -5109,7 +5170,7 @@

    Centralized Declaration

    @@ -5150,7 +5211,7 @@

    Centralized Declaration

    @@ -5178,7 +5239,7 @@

    Centralized Declaration

    @@ -5232,7 +5293,7 @@

    Centralized Declaration

    @@ -5278,7 +5339,7 @@

    Centralized Declaration

    @@ -5325,7 +5386,7 @@

    Centralized Declaration

    @@ -5353,7 +5414,7 @@

    Centralized Declaration

    @@ -5401,7 +5462,7 @@

    CRUD

    @@ -5448,7 +5509,7 @@

    CRUD

    @@ -5496,7 +5557,7 @@

    CRUD

    @@ -5548,7 +5609,7 @@

    CRUD

    @@ -5593,7 +5654,7 @@

    CRUD

    @@ -5640,7 +5701,7 @@

    CRUD

    @@ -5668,7 +5729,7 @@

    CRUD

    @@ -5715,7 +5776,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5770,7 +5831,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5798,7 +5859,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5851,7 +5912,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5900,7 +5961,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5928,7 +5989,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5975,7 +6036,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6003,7 +6064,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6046,7 +6107,7 @@

    PHP Data Object (PDO)

    @@ -6095,7 +6156,7 @@

    Usage

    @@ -6149,7 +6210,7 @@

    Usage

    @@ -6196,7 +6257,7 @@

    Usage

    @@ -6224,7 +6285,7 @@

    Usage

    @@ -6261,7 +6322,7 @@

    Usage

    @@ -6297,7 +6358,7 @@

    Code Snippet

    @@ -6333,7 +6394,7 @@

    Code Snippet

    @@ -6375,7 +6436,7 @@

    Code Snippet

    @@ -6415,7 +6476,7 @@

    Doctrine2 ORM

    @@ -6443,7 +6504,7 @@

    Doctrine2 ORM

    @@ -6497,7 +6558,7 @@

    Doctrine2 ORM

    @@ -6552,7 +6613,7 @@

    Doctrine2 ORM

    @@ -6580,7 +6641,7 @@

    Doctrine2 ORM

    @@ -6629,7 +6690,7 @@

    Doctrine2 ORM

    @@ -6668,7 +6729,7 @@

    Doctrine2 ORM

    @@ -6696,7 +6757,7 @@

    Doctrine2 ORM

    @@ -6752,7 +6813,7 @@

    Doctrine2 ORM

    @@ -6798,7 +6859,7 @@

    Usage

    @@ -6857,7 +6918,7 @@

    Usage

    @@ -6911,7 +6972,7 @@

    Usage

    @@ -6939,7 +7000,7 @@

    Usage

    @@ -6967,7 +7028,7 @@

    Usage

    @@ -7121,361 +7182,361 @@

    Table of Contents

    - Static Keyword (1/2) + Static Keyword 24 - Static Keyword (2/2) + Late State Bindings 25 - Interfaces + Static Keyword 26 - Namespaces + Interfaces 27 - The class Keyword + Namespaces 28 - Traits + The class Keyword 29 - Anonymous Functions + Traits 30 - Closures + Anonymous Functions 31 - Magic Methods + Closures 32 - Generators + Magic Methods 33 - The PHP Command Line + Generators 34 - The PHP Command Line (1/2) + The PHP Command Line 35 - The PHP Command Line (2/2) + The PHP Command Line (1/2) 36 - Writing a CLI program + The PHP Command Line (2/2) 37 - Client/Server + Writing a CLI program 38 - Client/Server Basics + Client/Server 39 - Unified Resource Identifier (URI) + Client/Server Basics 40 - HTTP Request + Unified Resource Identifier (URI) 41 - HTTP Response + HTTP Request 42 - HTTP Verbs + HTTP Response 43 - HTTP Parameters (1/2) + HTTP Verbs 44 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 45 - REST + HTTP Parameters (2/2) 46 - REpresentational State Transfer + REST 47 - Richardson Maturity Model + REpresentational State Transfer 48 - Level 3 = Content Negotiation + HATEOAS + Richardson Maturity Model 49 - Media Types + Level 3 = Content Negotiation + HATEOAS 50 - Content Type Negotiation + Media Types 51 - HATEOAS + Content Type Negotiation 52 - PHP Autoloading + HATEOAS 53 - Why Is It Necessary? + PHP Autoloading 54 - The require() Way + Why Is It Necessary? 55 - The require_once() Way + The require() Way 56 - Working With Multiple Files + The require_once() Way 57 - Rethinking The Way You Load Classes + Working With Multiple Files 58 - Examples + Rethinking The Way You Load Classes 59 - Under The Hood + Examples 60 - Leveraging PHP APIs + Under The Hood 61 - Built-in Interfaces + Leveraging PHP APIs 62 - The Reflection API (1/2) + Built-in Interfaces 63 - The Reflection API (2/2) + The Reflection API (1/2) 64 - The Standard PHP Library (SPL) + The Reflection API (2/2) 65 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 66 - Observer Pattern (2/2) + Observer Pattern (1/2) 67 - Exceptions (1/2) + Observer Pattern (2/2) 68 - Exceptions (2/2) + Exceptions (1/2) 69 - Password Hashing + Exceptions (2/2) 70 - PHP Archive (PHAR) + Password Hashing 71 - Dependency Management in PHP + PHP Archive (PHAR) 72 - Composer + Dependency Management in PHP 73 - composer install + Composer 74 - Composer Autoloader + composer install 75 - Example + Composer Autoloader 76 - The Symfony2 Console Component + Example 77 - A Basic Command (1/2) + The Symfony2 Console Component 78 - A Basic Command (2/2) + A Basic Command (1/2) 79 - Model View Controller + A Basic Command (2/2) 80 - MVC Overview + Model View Controller 81 - The Model + MVC Overview 82 - The View + The Model 83 @@ -7493,61 +7554,61 @@

    Table of Contents

    - The Controller + The View 86 - Routing + The Controller 87 - Front Controller Pattern + Routing 88 - Interact With Multiple Services + Front Controller Pattern 89 - Databases + Interact With Multiple Services 90 - Agenda + Databases 91 - Quick note + Agenda 92 - Database Design Patterns + Quick note 93 - Row Data Gateway + Database Design Patterns 94 - Row Data Gateway + Row Data Gateway 95 @@ -7565,13 +7626,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 98 - Table Data Gateway + Table Data Gateway 99 @@ -7607,13 +7668,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 105 - Active Record + Active Record 106 @@ -7625,13 +7686,13 @@

    Table of Contents

    - Data Mapper + Active Record 108 - Data Mapper + Data Mapper 109 @@ -7643,31 +7704,31 @@

    Table of Contents

    - Identity Map + Data Mapper 111 - Identity Map + Identity Map 112 - Data Access Layer + Identity Map 113 - Data Access Layer / Data Source Name + Data Access Layer 114 - Data Access Layer + Data Access Layer / Data Source Name 115 @@ -7685,67 +7746,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 118 - Object Relational Mapping (1/4) + Object Relational Mapping 119 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 120 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 121 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 122 - Existing Components + Object Relational Mapping (4/4) 123 - A Note About
    Domain-Driven Design
    + Existing Components 124 - Entities + A Note About
    Domain-Driven Design
    125 - Value Objects + Entities 126 - The Repository Pattern + Value Objects 127 - The Repository Pattern + The Repository Pattern 128 @@ -7757,25 +7818,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 130 - The Specification Pattern + The Specification Pattern 131 - Repository ♥ Specification + The Specification Pattern 132 - Combine Them! + Repository ♥ Specification 133 @@ -7787,17 +7848,23 @@

    Table of Contents

    - Next Week: Web Security 101 + Combine Them! 135 - The End. + Next Week: Web Security 101 136 + + The End. + 137 + + + From 9691afc0fa27df2302d4dbfcf901f541e362fd5c Mon Sep 17 00:00:00 2001 From: William DURAND Date: Wed, 29 Jan 2014 01:44:19 +0100 Subject: [PATCH 30/71] Publish slides (Mer 29 jan 2014 01:44:19 CET) --- isima.html | 644 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 373 insertions(+), 271 deletions(-) diff --git a/isima.html b/isima.html index 71f1a02..d9c6079 100644 --- a/isima.html +++ b/isima.html @@ -25,7 +25,7 @@ - PHP + Advanced OOP @@ -1174,6 +1232,19 @@ + + + +
    From 3f085049eca0f2e74d8730640a84fcf914ad1139 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Sun, 2 Feb 2014 00:37:09 +0100 Subject: [PATCH 33/71] =?UTF-8?q?Publish=20slides=20(Dim=20=202=20f=C3=A9v?= =?UTF-8?q?=202014=2000:37:09=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extended.html | 8 +- index.html | 1296 ++++++++++++++--------- isima.html | 2816 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 3105 insertions(+), 1015 deletions(-) diff --git a/extended.html b/extended.html index 1e04a29..4f2f064 100644 --- a/extended.html +++ b/extended.html @@ -1007,8 +1007,8 @@ font-weight: bold; } -div.slide h3 { - margin: 0; +div.slide h1 { + margin: auto; } .slide.future { @@ -1171,6 +1171,10 @@ margin-bottom: 3%; } +.more-on-this-later { + display: none; +} + diff --git a/index.html b/index.html index 5ef9f6a..c60bdc0 100644 --- a/index.html +++ b/index.html @@ -1007,8 +1007,8 @@ font-weight: bold; } -div.slide h3 { - margin: 0; +div.slide h1 { + margin: auto; } .slide.future { @@ -1171,6 +1171,10 @@ margin-bottom: 3%; } +.more-on-this-later { + display: none; +} + @@ -1208,7 +1212,7 @@ @@ -1236,7 +1240,7 @@ @@ -1287,7 +1291,7 @@ @@ -1315,7 +1319,7 @@ @@ -1333,8 +1337,7 @@

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server, REST

    Week #2

    -

    Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View -Controller

    +

    Autoloading, Leveraging PHP APIs, Dependency Management, Model View Controller

    Week #3

    Databases

    Week #4

    @@ -1355,7 +1358,7 @@

    Week #4

    @@ -1383,7 +1386,7 @@

    Week #4

    @@ -1418,7 +1421,7 @@

    Week #4

    @@ -1454,7 +1457,7 @@

    Week #4

    @@ -1490,7 +1493,7 @@

    Week #4

    @@ -1524,7 +1527,7 @@

    Week #4

    @@ -1559,7 +1562,7 @@

    Week #4

    @@ -1587,7 +1590,7 @@

    Week #4

    @@ -1615,7 +1618,7 @@

    Week #4

    @@ -1653,7 +1656,7 @@

    Week #4

    @@ -1702,7 +1705,7 @@

    Week #4

    @@ -1753,7 +1756,7 @@

    Week #4

    @@ -1796,7 +1799,7 @@

    Abstract class definition

    @@ -1848,7 +1851,7 @@

    Abstract class definition

    @@ -1887,7 +1890,7 @@

    The Rules

    @@ -1940,7 +1943,7 @@

    The Rules

    @@ -1991,7 +1994,7 @@

    Type Hinting

    @@ -2036,7 +2039,7 @@

    Usage

    @@ -2084,7 +2087,7 @@

    Usage

    @@ -2132,7 +2135,7 @@

    Usage

    @@ -2191,7 +2194,7 @@

    Usage

    @@ -2235,7 +2238,7 @@

    Usage

    @@ -2287,7 +2290,7 @@

    Usage

    @@ -2335,7 +2338,7 @@

    PSR-0

    @@ -2382,7 +2385,7 @@

    PSR-0

    @@ -2434,7 +2437,7 @@

    PSR-0

    @@ -2477,7 +2480,7 @@

    PSR-0

    @@ -2523,7 +2526,7 @@

    PSR-0

    @@ -2566,7 +2569,7 @@

    PSR-0

    @@ -2607,7 +2610,7 @@

    PSR-0

    @@ -2635,7 +2638,7 @@

    PSR-0

    @@ -2687,7 +2690,7 @@

    PSR-0

    @@ -2735,7 +2738,7 @@

    PSR-0

    @@ -2787,7 +2790,7 @@

    PSR-0

    @@ -2815,7 +2818,7 @@

    PSR-0

    @@ -2855,7 +2858,7 @@

    PSR-0

    @@ -2899,7 +2902,7 @@

    Collections

    @@ -2921,10 +2924,10 @@

    Collections

  • A request body to send data.
  • Here is an example:

    -
    GET /my/simple/uri?with-query-string HTTP/1.1
    -Host: example.org
    -Content-Type: text/plain; charset=utf-8
    -Content-Length: 17
    +
    GET /my/simple/uri?with-query-string HTTP/1.1
    +Host: example.org
    +Content-Type: text/plain; charset=utf-8
    +Content-Length: 17
     
     This is a content
     
    @@ -2944,7 +2947,47 @@

    Collections

    + +
    + + + +
    +
    +
    + +

    HTTP Verbs

    + + +

    An HTTP verb is an action to perform on a resource located at a given +URI:

    +
      +
    • GET: retrieve a resource or a collection of resources;
    • +
    • POST: create a new resource;
    • +
    • PUT: update an existing resource or create a new resource at a + given URI;
    • +
    • DELETE: delete a given resource;
    • +
    • PATCH: partial update of a given resource.
    • +
    +

    Important: this list is not exhaustive.

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -2965,9 +3008,9 @@

    Collections

  • The content of the response;
  • Here is an example:

    -
    HTTP/1.1 200 OK
    -Content-Type: text/html; charset=utf-8
    -Content-Length: 76
    +
    HTTP/1.1 200 OK
    +Content-Type: text/html; charset=utf-8
    +Content-Length: 76
     
     <!DOCTYPE HTML>
     <html>
    @@ -2994,7 +3037,7 @@ 

    Collections

    @@ -3005,20 +3048,66 @@

    Collections

    -

    HTTP Verbs

    +

    Status Codes (1/2)

    -

    An HTTP verb is an action to perform on a resource located at a given -URI:

    +

    1xx Informational

    +

    2xx Successful

      -
    • GET: retrieve a resource or a collection of resources;
    • -
    • POST: create a new resource;
    • -
    • PUT: update an existing resource or create a new resource at a - given URI;
    • -
    • DELETE: delete a given resource;
    • -
    • PATCH: partial update of a given resource.
    • +
    • 200 OK
    • +
    • 201 Created
    • +
    • 204 Not Content
    -

    Important: this list is not exhaustive.

    +

    3xx Redirections

    +
      +
    • 301 Moved Permanently
    • +
    • 302 Found
    • +
    • 304 Not Modified
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Status Codes (2/2)

    + + +

    4xx Client Error

    +
      +
    • 400 Bad Request
    • +
    • 401 Unauthorized
    • +
    • 403 Forbidden
    • +
    • 404 Not Found
    • +
    • 405 Method Not Allowed
    • +
    • 406 Not Acceptable
    • +
    • 409 Conflict
    • +
    • 415 Unsupported Media Type
    • +
    +

    5xx Server Error

    +
      +
    • 500 Internal Server Error
    • +
    @@ -3034,7 +3123,7 @@

    Collections

    @@ -3077,7 +3166,7 @@

    Collections

    @@ -3091,12 +3180,12 @@

    Collections

    HTTP Parameters (2/2)

    -
    GET /my/simple/uri?a=1&id=2 HTTP/1.1
    -Host: example.org
    -Content-Type: text/plain; charset=utf-8
    -Content-Length: 14
    +            
    GET /my/simple/uri?a=1&id=2 HTTP/1.1
    +Host: example.org
    +Content-Type: text/plain; charset=utf-8
    +Content-Length: 14
     
    -b=3&city=paris
    +b=3&city=paris
     

    Will result in:

    @@ -3127,7 +3216,7 @@

    Collections

    @@ -3155,7 +3244,7 @@

    Collections

    @@ -3196,7 +3285,7 @@

    Collections

    @@ -3228,7 +3317,118 @@

    Collections

    + + + + + +
    +
    +
    + +

    Level 0 - The Swamp of POX

    + + +

    In A Nutshell

    +
      +
    • HTTP as a tunneling mechanism;
    • +
    • RPC style system (SOAP, XML-RPC).
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Level 1 - Resources

    + + +

    In A Nutshell

    +
      +
    • Individual resources (URIs);
    • +
    • Notion of object identity.
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Level 2 - HTTP Verbs

    + + +

    In A Nutshell

    +
      +
    • Client uses specific HTTP verbs;
    • +
    • Server uses HTTP status codes.
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3256,7 +3456,7 @@

    Collections

    @@ -3308,7 +3508,7 @@

    Hyper Media Types

    @@ -3360,7 +3560,7 @@

    Hyper Media Types

    @@ -3412,7 +3612,7 @@

    Hyper Media Types

    @@ -3440,7 +3640,7 @@

    Hyper Media Types

    @@ -3489,7 +3689,7 @@

    Hyper Media Types

    @@ -3539,7 +3739,7 @@

    Hyper Media Types

    @@ -3586,7 +3786,7 @@

    Hyper Media Types

    @@ -3635,7 +3835,7 @@

    Hyper Media Types

    @@ -3674,7 +3874,7 @@

    spl_autoload_functions()

    @@ -3723,7 +3923,7 @@

    spl_autoload_unregister()

    @@ -3778,7 +3978,7 @@

    spl_autoload_unregister()

    @@ -3806,7 +4006,7 @@

    spl_autoload_unregister()

    @@ -3851,7 +4051,7 @@

    Traversable

    @@ -3902,7 +4102,7 @@

    Traversable

    @@ -3953,7 +4153,7 @@

    Traversable

    @@ -3995,7 +4195,7 @@

    SPL Functions

    @@ -4048,7 +4248,7 @@

    SPL Functions

    @@ -4097,7 +4297,7 @@

    SPL Functions

    @@ -4146,7 +4346,7 @@

    SPL Functions

    @@ -4186,7 +4386,7 @@

    SPL Functions

    @@ -4237,7 +4437,7 @@

    SPL Functions

    @@ -4279,7 +4479,7 @@

    SPL Functions

    @@ -4290,7 +4490,7 @@

    SPL Functions

    -

    Dependency Management in PHP

    +

    Dependency Management

    @@ -4307,7 +4507,7 @@

    SPL Functions

    @@ -4351,7 +4551,7 @@

    SPL Functions

    @@ -4401,7 +4601,7 @@

    SPL Functions

    @@ -4444,13 +4644,13 @@

    SPL Functions

    - +
    @@ -4488,17 +4688,17 @@

    SPL Functions

    - +
    @@ -4538,17 +4738,17 @@

    SPL Functions

    - +
    @@ -4585,17 +4785,17 @@

    Execution

    - +
    @@ -4638,11 +4838,11 @@

    Usage

    @@ -4670,7 +4870,7 @@

    Usage

    @@ -4713,7 +4913,7 @@

    Usage

    @@ -4737,9 +4937,14 @@

    Usage

  • API calls;
  • etc.
  • -
    +

    More on this next week!

    +
    + +
    + +

    More on this in a few minutes!

    @@ -4756,7 +4961,7 @@

    Usage

    @@ -4809,7 +5014,7 @@

    Usage

    @@ -4856,7 +5061,7 @@

    Usage

    @@ -4905,7 +5110,7 @@

    Usage

    @@ -4957,7 +5162,7 @@

    Usage

    @@ -5000,7 +5205,7 @@

    Centralized Declaration

    @@ -5033,48 +5238,7 @@

    Centralized Declaration

    - - - - - -
    -
    -
    - -

    Interact With Multiple Services

    - - -

    Web applications become more and more complex and interact with -multiple services such as:

    -
      -
    • Relational databases to store consistent data;
    • -
    • Search engines to index and retrieve documents;
    • -
    • Message queues to postpone executions or as event brokers;
    • -
    • External APIs (geocoding, payment, social);
    • -
    • Mail servers to send or receive emails;
    • -
    • Text message gateways;
    • -
    • HTTP cache servers to reduce resources needs and speed up responses;
    • -
    • and much much more.
    • -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    @@ -5102,7 +5266,7 @@

    Centralized Declaration

    @@ -5138,7 +5302,7 @@

    Centralized Declaration

    @@ -5173,7 +5337,7 @@

    Centralized Declaration

    @@ -5214,7 +5378,7 @@

    Centralized Declaration

    @@ -5242,7 +5406,7 @@

    Centralized Declaration

    @@ -5296,7 +5460,7 @@

    Centralized Declaration

    @@ -5342,7 +5506,7 @@

    Centralized Declaration

    @@ -5389,7 +5553,7 @@

    Centralized Declaration

    @@ -5417,7 +5581,7 @@

    Centralized Declaration

    @@ -5465,7 +5629,7 @@

    CRUD

    @@ -5512,7 +5676,7 @@

    CRUD

    @@ -5560,7 +5724,7 @@

    CRUD

    @@ -5612,7 +5776,7 @@

    CRUD

    @@ -5657,7 +5821,7 @@

    CRUD

    @@ -5704,7 +5868,7 @@

    CRUD

    @@ -5732,7 +5896,7 @@

    CRUD

    @@ -5779,7 +5943,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5834,7 +5998,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5862,7 +6026,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5915,7 +6079,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5964,7 +6128,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5992,7 +6156,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6039,7 +6203,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6067,7 +6231,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6110,7 +6274,7 @@

    PHP Data Object (PDO)

    @@ -6159,7 +6323,7 @@

    Usage

    @@ -6213,7 +6377,7 @@

    Usage

    @@ -6260,7 +6424,7 @@

    Usage

    @@ -6288,7 +6452,7 @@

    Usage

    @@ -6325,7 +6489,7 @@

    Usage

    @@ -6361,7 +6525,7 @@

    Code Snippet

    @@ -6397,7 +6561,7 @@

    Code Snippet

    @@ -6439,7 +6603,7 @@

    Code Snippet

    @@ -6479,7 +6643,7 @@

    Doctrine2 ORM

    @@ -6507,7 +6671,7 @@

    Doctrine2 ORM

    @@ -6561,7 +6725,7 @@

    Doctrine2 ORM

    @@ -6616,7 +6780,7 @@

    Doctrine2 ORM

    @@ -6644,7 +6808,7 @@

    Doctrine2 ORM

    @@ -6693,7 +6857,7 @@

    Doctrine2 ORM

    @@ -6732,7 +6896,7 @@

    Doctrine2 ORM

    @@ -6760,7 +6924,7 @@

    Doctrine2 ORM

    @@ -6816,7 +6980,7 @@

    Doctrine2 ORM

    @@ -6862,7 +7026,7 @@

    Usage

    @@ -6921,7 +7085,7 @@

    Usage

    @@ -6950,7 +7114,9 @@

    Usage

    Usage

    -
    $specification = new AndSpecification(
    +
    // Find customers who have ordered exactly three times,
    +// but who are not premium customers (yet?)
    +$specification = new AndSpecification(
         new CustomerHasOrderedThreeTimes(),
         new NotSpecification(
             new CustomerIsPremium()
    @@ -6975,13 +7141,61 @@ 

    Usage

    + +
    +
    + + +
    +
    +
    + +

    Specification For Business Rules

    + + +

    Reuse your specifications in your business layer:

    +
    class AwesomeOfferSender
    +{
    +    private $specification;
    +
    +    public function __construct(CustomerIsPremium $specification)
    +    {
    +        $this->specification = $specification;
    +    }
    +
    +    public function sendOffersTo(Customer $customer)
    +    {
    +        if ($this->specification->isSatisfiedBy($customer)) {
    +            // send offers
    +        }
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    - +
    @@ -6999,17 +7213,17 @@

    Usage

    - +
    @@ -7017,18 +7231,19 @@

    Usage

    Overview

    -

    A way to persist browsing data accross client calls:

    +

    Sessions are a way to preserve certain data across subsequent accesses.

    +

    In A Nutshell

      -
    • unique identifier;
    • -
    • stored server side;
    • -
    • easy to use;
    • -
    • built-in.
    • +
    • Unique identifier (session id);
    • +
    • Server side;
    • +
    • Easy to use;
    • +
    • Built-in.

    A few use cases:

      -
    • Keep user authentication and roles;
    • -
    • Store cart;
    • -
    • Store a flash message between redirections.
    • +
    • Keeping user authentication and roles;
    • +
    • Storing items into a cart;
    • +
    • Storing a flash message between redirections.
    @@ -7041,17 +7256,17 @@

    A few use cases:

    - +
    @@ -7059,19 +7274,19 @@

    A few use cases:

    Code Please

    -
    // initalize session
    +            
    // Initalize session
     session_start();
     
    -// regenerate identifier
    +// Regenerate identifier
     session_regenerate_id();
     
    -// affect "key"
    +// Assign "key" to `$value`
     $_SESSION['key'] = $value;
     
    -// retrieve key
    +// Retrieve "key"
     $_SESSION['key'];
     
    -// terminate session
    +// Terminate session
     session_destroy();
     
    @@ -7090,17 +7305,17 @@

    A few use cases:

    - +
    @@ -7109,11 +7324,12 @@

    A few use cases:

      -
    • Cookie hijacking/XSS;
    • -
    • Man in the Middle;
    • +
    • Session fixation;
    • +
    • Session hijacking;
    • +
    • Man in the Middle (capture);
    • Predicatable session token.
    -

    Workarounds

    +

    Workarounds

    - +
    @@ -7159,17 +7375,17 @@

    Workarounds

    - +
    @@ -7190,17 +7406,17 @@

    Workarounds

    - +
    @@ -7220,17 +7436,17 @@

    Workarounds

    - +
    @@ -7261,17 +7477,17 @@

    Event Dispatcher

    - +
    @@ -7309,17 +7525,17 @@

    Event Dispatcher

    - +
    @@ -7361,17 +7577,17 @@

    Event Dispatcher

    - +
    @@ -7405,17 +7621,17 @@

    Event Dispatcher

    - +
    @@ -7445,17 +7661,17 @@

    Event Dispatcher

    - +
    @@ -7502,17 +7718,17 @@

    Event Dispatcher

    - +
    @@ -7532,17 +7748,17 @@

    Event Dispatcher

    - +
    @@ -7585,17 +7801,17 @@

    Event Dispatcher

    - +
    @@ -7621,17 +7837,17 @@

    WSSE Username Token

    - +
    @@ -7665,17 +7881,17 @@

    WSSE Username Token

    - +
    @@ -7693,17 +7909,17 @@

    WSSE Username Token

    - +
    @@ -7733,17 +7949,17 @@

    WSSE Username Token

    - +
    @@ -7790,17 +8006,17 @@

    WSSE Username Token

    - +
    @@ -7834,17 +8050,17 @@

    Usage

    - +
    @@ -7879,17 +8095,17 @@

    Usage

    - +
    @@ -7917,17 +8133,17 @@

    Usage

    - +
    @@ -7967,17 +8183,17 @@

    Usage

    - +
    @@ -8018,17 +8234,17 @@

    Usage

    - +
    @@ -8060,17 +8276,17 @@

    Usage

    - +
    @@ -8102,17 +8318,17 @@

    Usage

    - +
    @@ -8151,17 +8367,17 @@

    Usage

    - +
    @@ -8184,17 +8400,17 @@

    Usage

    - +
    @@ -8227,17 +8443,17 @@

    Usage

    - +
    @@ -8276,17 +8492,17 @@

    Usage

    - +
    @@ -8319,17 +8535,17 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8356,17 +8572,17 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8398,17 +8614,17 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8439,17 +8655,17 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -8485,11 +8701,39 @@

    The Symfony2 DependencyInjection Component

    +
    +
    + + +
    +
    +
    + + +



    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -8517,7 +8761,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8551,7 +8795,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8579,7 +8823,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8625,7 +8869,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8673,7 +8917,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8712,7 +8956,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8762,7 +9006,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8790,7 +9034,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8827,7 +9071,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8855,7 +9099,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8898,7 +9142,7 @@

    StoryBDD

    @@ -8944,7 +9188,7 @@

    StoryBDD

    @@ -8992,7 +9236,7 @@

    StoryBDD

    @@ -9045,7 +9289,7 @@

    StoryBDD

    @@ -9073,7 +9317,7 @@

    StoryBDD

    @@ -9105,7 +9349,7 @@

    StoryBDD

    @@ -9133,7 +9377,7 @@

    StoryBDD

    @@ -9161,7 +9405,7 @@

    StoryBDD

    @@ -9189,7 +9433,7 @@

    StoryBDD

    @@ -9217,7 +9461,7 @@

    StoryBDD

    @@ -9257,7 +9501,7 @@

    StoryBDD

    @@ -9285,7 +9529,7 @@

    StoryBDD

    @@ -9313,7 +9557,7 @@

    StoryBDD

    @@ -9581,367 +9825,367 @@

    Table of Contents

    - HTTP Response + HTTP Verbs 43 - HTTP Verbs + HTTP Response 44 - HTTP Parameters (1/2) + Status Codes (1/2) 45 - HTTP Parameters (2/2) + Status Codes (2/2) 46 - REST + HTTP Parameters (1/2) 47 - REpresentational State Transfer + HTTP Parameters (2/2) 48 - Richardson Maturity Model + REST 49 - Level 3 = Content Negotiation + HATEOAS + REpresentational State Transfer 50 - Media Types + Richardson Maturity Model 51 - Content Type Negotiation + Level 0 - The Swamp of POX 52 - HATEOAS + Level 1 - Resources 53 - PHP Autoloading + Level 2 - HTTP Verbs 54 - Why Is It Necessary? + Level 3 = Content Negotiation + HATEOAS 55 - The require() Way + Media Types 56 - The require_once() Way + Content Type Negotiation 57 - Working With Multiple Files + HATEOAS 58 - Rethinking The Way You Load Classes + PHP Autoloading 59 - Examples + Why Is It Necessary? 60 - Under The Hood + The require() Way 61 - Leveraging PHP APIs + The require_once() Way 62 - Built-in Interfaces + Working With Multiple Files 63 - The Reflection API (1/2) + Rethinking The Way You Load Classes 64 - The Reflection API (2/2) + Examples 65 - The Standard PHP Library (SPL) + Under The Hood 66 - Observer Pattern (1/2) + Leveraging PHP APIs 67 - Observer Pattern (2/2) + Built-in Interfaces 68 - Exceptions (1/2) + The Reflection API (1/2) 69 - Exceptions (2/2) + The Reflection API (2/2) 70 - Password Hashing + The Standard PHP Library (SPL) 71 - PHP Archive (PHAR) + Observer Pattern (1/2) 72 - Dependency Management in PHP + Observer Pattern (2/2) 73 - Composer + Exceptions (1/2) 74 - composer install + Exceptions (2/2) 75 - Composer Autoloader + Password Hashing 76 - Example + PHP Archive (PHAR) 77 - The Symfony2 Console Component + Dependency Management 78 - A Basic Command (1/2) + Composer 79 - A Basic Command (2/2) + composer install 80 - Model View Controller + Composer Autoloader 81 - MVC Overview + Example 82 - The Model + The Symfony2 Console Component 83 - The View + A Basic Command (1/2) 84 - The View + A Basic Command (2/2) 85 - The View + Model View Controller 86 - The Controller + MVC Overview 87 - Routing + The Model 88 - Front Controller Pattern + The View 89 - Interact With Multiple Services + The View 90 - Databases + The View 91 - Agenda + The Controller 92 - Quick note + Routing 93 - Database Design Patterns + Front Controller Pattern 94 - Row Data Gateway + Databases 95 - Row Data Gateway + Agenda 96 - Row Data Gateway + Quick note 97 - Row Data Gateway + Database Design Patterns 98 - Table Data Gateway + Row Data Gateway 99 - Table Data Gateway + Row Data Gateway 100 - Table Data Gateway + Row Data Gateway 101 - Table Data Gateway + Row Data Gateway 102 - Table Data Gateway + Table Data Gateway 103 @@ -9959,73 +10203,73 @@

    Table of Contents

    - Active Record + Table Data Gateway 106 - Active Record + Table Data Gateway 107 - Active Record + Table Data Gateway 108 - Data Mapper + Table Data Gateway 109 - Data Mapper + Active Record 110 - Data Mapper + Active Record 111 - Identity Map + Active Record 112 - Identity Map + Data Mapper 113 - Data Access Layer + Data Mapper 114 - Data Access Layer / Data Source Name + Data Mapper 115 - Data Access Layer + Identity Map 116 - Data Access Layer + Identity Map 117 @@ -10037,461 +10281,497 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer / Data Source Name 119 - Object Relational Mapping (1/4) + Data Access Layer 120 - Object Relational Mapping (2/4) + Data Access Layer 121 - Object Relational Mapping (3/4) + Data Access Layer 122 - Object Relational Mapping (4/4) + Object Relational Mapping 123 - Existing Components + Object Relational Mapping (1/4) 124 - A Note About
    Domain-Driven Design
    + Object Relational Mapping (2/4) 125 - Entities + Object Relational Mapping (3/4) 126 - Value Objects + Object Relational Mapping (4/4) 127 - The Repository Pattern + Existing Components 128 - The Repository Pattern + A Note About
    Domain-Driven Design
    129 - The Repository Pattern + Entities 130 - The Specification Pattern + Value Objects 131 - The Specification Pattern + The Repository Pattern 132 - Repository ♥ Specification + The Repository Pattern 133 - Combine Them! + The Repository Pattern 134 - Combine Them! + The Specification Pattern 135 - Sessions + The Specification Pattern 136 - Overview + Repository ♥ Specification 137 - Code Please + Combine Them! 138 - Security Concerns + Combine Them! 139 - Authentication + Specification For Business Rules 140 - What You Have Right Now + Sessions 141 - The Big Picture + Overview 142 - The Interceptor Pattern + Code Please 143 - Introducing the Event Dispatcher + Security Concerns 144 - Using the EventDispatcherTrait + Authentication 145 - The Firewall (1/2) + What You Have Right Now 146 - The Firewall (2/2) + The Big Picture 147 - Implementing The Firewall + The Interceptor Pattern 148 - Authentication Mechanism + Introducing the Event Dispatcher 149 - Adding New Routes + Using the EventDispatcherTrait 150 - Stateless Authentication + The Firewall (1/2) 151 - Basic Security Thinking + The Firewall (2/2) 152 - Writing Better Code + Implementing The Firewall 153 - Agenda + Authentication Mechanism 154 - Coding Standards + Adding New Routes 155 - PHP Coding Standards Fixer + Stateless Authentication 156 - Programming To The Interface + Basic Security Thinking 157 - Dependency Inversion Principle (DIP) + Writing Better Code 158 - Dependency Injection (DI) + Agenda 159 - Dependency Injection (Anti) Pattern + Coding Standards 160 - Dependency Injection Patterns + PHP Coding Standards Fixer 161 - Dependency Injection Patterns + Programming To The Interface 162 - Dependency Injection Patterns + Dependency Inversion Principle (DIP) 163 - Inversion of Control (IoC) + Dependency Injection (DI) 164 - Dependency Injection Container (DIC) + Dependency Injection (Anti) Pattern 165 - PHP Implementations + Dependency Injection Patterns 166 - PHP Implementations + Dependency Injection Patterns 167 - Component Driven Development + Dependency Injection Patterns 168 - From STUPID to SOLID code! (1/2) + Inversion of Control (IoC) 169 - From STUPID to SOLID code! (2/2) + Dependency Injection Container (DIC) 170 - Object Calisthenics + PHP Implementations 171 - Testing + PHP Implementations 172 - Agenda + Component Driven Development 173 - Unit Testing + From STUPID to SOLID code! (1/2) 174 - Unit Testing + From STUPID to SOLID code! (2/2) 175 - PHPUnit — The Rules + Object Calisthenics 176 - PHPUnit — Assertions + - 177 - Running PHPUnit + Testing 178 - Functional Testing + Agenda 179 - Functional Testing + Unit Testing 180 - Behavior Driven Development + Unit Testing 181 - Behavior Driven Development + PHPUnit — The Rules 182 - Behat + PHPUnit — Assertions 183 - Using Behat (1/2) + Running PHPUnit 184 - Using Behat (2/2) + Functional Testing 185 - Awesome Projects + Functional Testing 186 -
    + Behavior Driven Development 187 - Embracing Open Source + Behavior Driven Development 188 - + Behat 189 - + Using Behat (1/2) 190 - + Using Behat (2/2) 191 - Golden Rules + Awesome Projects 192 - The End. +
    193 - Well... Maybe Not.
    PHP Extended + Embracing Open Source 194 + + + 195 + + + + + + 196 + + + + + + 197 + + + + + Golden Rules + 198 + + + + + The End. + 199 + + + + + Well... Maybe Not.
    PHP Extended + 200 + + +
    diff --git a/isima.html b/isima.html index 091ce0f..f4ee6ab 100644 --- a/isima.html +++ b/isima.html @@ -1065,8 +1065,8 @@ font-weight: bold; } -div.slide h3 { - margin: 0; +div.slide h1 { + margin: auto; } .slide.future { @@ -1229,6 +1229,10 @@ margin-bottom: 3%; } +.more-on-this-later { + display: none; +} + @@ -1242,6 +1246,23 @@ color: #000; } +div.slide h1, +div.slide h2, +div.slide h3, +div.slide h4, +div.slide h5, +div.slide h6 { + color: #fff; +} + +.more-on-this-next-week { + display: none; +} + +.more-on-this-later { + display: block; +} + @@ -1279,7 +1300,7 @@
    @@ -1307,7 +1328,7 @@
    @@ -1335,7 +1356,7 @@
    @@ -1363,7 +1384,7 @@
    @@ -1391,7 +1412,7 @@
    @@ -1442,7 +1463,7 @@
    @@ -1470,7 +1491,7 @@
    @@ -1484,15 +1505,15 @@

    Agenda

    -

    Week #1

    +

    Week #1

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server, REST

    -

    Week #2

    -

    Autoloading, Leveraging PHP APIs, Dependency Management in PHP, Model View -Controller

    -

    Week #3

    -

    Databases

    -

    Week #4

    +

    Week #2

    +

    Autoloading, Leveraging PHP APIs, Dependency Management, Model View Controller, +Databases

    +

    Week #3

    +

    A Note About Domain-Driven Design, Sessions, Authentication, Writing Better Code

    +

    Week #4

    Security 101

    @@ -1509,7 +1530,7 @@

    Week #4

    @@ -1537,7 +1558,7 @@

    Week #4

    @@ -1572,7 +1593,7 @@

    Week #4

    @@ -1608,7 +1629,7 @@

    Week #4

    @@ -1644,7 +1665,7 @@

    Week #4

    @@ -1678,7 +1699,7 @@

    Week #4

    @@ -1713,7 +1734,7 @@

    Week #4

    @@ -1741,7 +1762,7 @@

    Week #4

    @@ -1769,7 +1790,7 @@

    Week #4

    @@ -1807,7 +1828,7 @@

    Week #4

    @@ -1856,7 +1877,7 @@

    Week #4

    @@ -1907,7 +1928,7 @@

    Week #4

    @@ -1950,7 +1971,7 @@

    Abstract class definition

    @@ -2002,7 +2023,7 @@

    Abstract class definition

    @@ -2041,7 +2062,7 @@

    The Rules

    @@ -2094,7 +2115,7 @@

    The Rules

    @@ -2145,7 +2166,7 @@

    Type Hinting

    @@ -2190,7 +2211,7 @@

    Usage

    @@ -2238,7 +2259,7 @@

    Usage

    @@ -2286,7 +2307,7 @@

    Usage

    @@ -2345,7 +2366,7 @@

    Usage

    @@ -2389,7 +2410,7 @@

    Usage

    @@ -2441,7 +2462,7 @@

    Usage

    @@ -2489,7 +2510,7 @@

    PSR-0

    @@ -2536,7 +2557,7 @@

    PSR-0

    @@ -2588,7 +2609,7 @@

    PSR-0

    @@ -2631,7 +2652,7 @@

    PSR-0

    @@ -2677,7 +2698,7 @@

    PSR-0

    @@ -2720,7 +2741,7 @@

    PSR-0

    @@ -2761,7 +2782,7 @@

    PSR-0

    @@ -2789,7 +2810,7 @@

    PSR-0

    @@ -2841,7 +2862,7 @@

    PSR-0

    @@ -2889,7 +2910,7 @@

    PSR-0

    @@ -2941,7 +2962,7 @@

    PSR-0

    @@ -2969,7 +2990,7 @@

    PSR-0

    @@ -3009,7 +3030,7 @@

    PSR-0

    @@ -3053,7 +3074,7 @@

    Collections

    @@ -3075,10 +3096,10 @@

    Collections

  • A request body to send data.
  • Here is an example:

    -
    GET /my/simple/uri?with-query-string HTTP/1.1
    -Host: example.org
    -Content-Type: text/plain; charset=utf-8
    -Content-Length: 17
    +
    GET /my/simple/uri?with-query-string HTTP/1.1
    +Host: example.org
    +Content-Type: text/plain; charset=utf-8
    +Content-Length: 17
     
     This is a content
     
    @@ -3098,7 +3119,47 @@

    Collections

    + +
    + + + +
    +
    +
    + +

    HTTP Verbs

    + + +

    An HTTP verb is an action to perform on a resource located at a given +URI:

    +
      +
    • GET: retrieve a resource or a collection of resources;
    • +
    • POST: create a new resource;
    • +
    • PUT: update an existing resource or create a new resource at a + given URI;
    • +
    • DELETE: delete a given resource;
    • +
    • PATCH: partial update of a given resource.
    • +
    +

    Important: this list is not exhaustive.

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3119,9 +3180,9 @@

    Collections

  • The content of the response;
  • Here is an example:

    -
    HTTP/1.1 200 OK
    -Content-Type: text/html; charset=utf-8
    -Content-Length: 76
    +
    HTTP/1.1 200 OK
    +Content-Type: text/html; charset=utf-8
    +Content-Length: 76
     
     <!DOCTYPE HTML>
     <html>
    @@ -3148,7 +3209,7 @@ 

    Collections

    @@ -3159,20 +3220,66 @@

    Collections

    -

    HTTP Verbs

    +

    Status Codes (1/2)

    -

    An HTTP verb is an action to perform on a resource located at a given -URI:

    +

    1xx Informational

    +

    2xx Successful

      -
    • GET: retrieve a resource or a collection of resources;
    • -
    • POST: create a new resource;
    • -
    • PUT: update an existing resource or create a new resource at a - given URI;
    • -
    • DELETE: delete a given resource;
    • -
    • PATCH: partial update of a given resource.
    • +
    • 200 OK
    • +
    • 201 Created
    • +
    • 204 Not Content
    -

    Important: this list is not exhaustive.

    +

    3xx Redirections

    +
      +
    • 301 Moved Permanently
    • +
    • 302 Found
    • +
    • 304 Not Modified
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Status Codes (2/2)

    + + +

    4xx Client Error

    +
      +
    • 400 Bad Request
    • +
    • 401 Unauthorized
    • +
    • 403 Forbidden
    • +
    • 404 Not Found
    • +
    • 405 Method Not Allowed
    • +
    • 406 Not Acceptable
    • +
    • 409 Conflict
    • +
    • 415 Unsupported Media Type
    • +
    +

    5xx Server Error

    +
      +
    • 500 Internal Server Error
    • +
    @@ -3188,7 +3295,7 @@

    Collections

    @@ -3231,7 +3338,7 @@

    Collections

    @@ -3245,12 +3352,12 @@

    Collections

    HTTP Parameters (2/2)

    -
    GET /my/simple/uri?a=1&id=2 HTTP/1.1
    -Host: example.org
    -Content-Type: text/plain; charset=utf-8
    -Content-Length: 14
    +            
    GET /my/simple/uri?a=1&id=2 HTTP/1.1
    +Host: example.org
    +Content-Type: text/plain; charset=utf-8
    +Content-Length: 14
     
    -b=3&city=paris
    +b=3&city=paris
     

    Will result in:

    @@ -3281,7 +3388,7 @@

    Collections

    @@ -3309,7 +3416,7 @@

    Collections

    @@ -3350,7 +3457,7 @@

    Collections

    @@ -3382,7 +3489,118 @@

    Collections

    + + + + + +
    +
    +
    + +

    Level 0 - The Swamp of POX

    + + +

    In A Nutshell

    +
      +
    • HTTP as a tunneling mechanism;
    • +
    • RPC style system (SOAP, XML-RPC).
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Level 1 - Resources

    + + +

    In A Nutshell

    +
      +
    • Individual resources (URIs);
    • +
    • Notion of object identity.
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Level 2 - HTTP Verbs

    + + +

    In A Nutshell

    +
      +
    • Client uses specific HTTP verbs;
    • +
    • Server uses HTTP status codes.
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3410,7 +3628,7 @@

    Collections

    @@ -3462,7 +3680,7 @@

    Hyper Media Types

    @@ -3514,7 +3732,7 @@

    Hyper Media Types

    @@ -3566,7 +3784,7 @@

    Hyper Media Types

    @@ -3594,7 +3812,7 @@

    Hyper Media Types

    @@ -3643,7 +3861,7 @@

    Hyper Media Types

    @@ -3693,7 +3911,7 @@

    Hyper Media Types

    @@ -3740,7 +3958,7 @@

    Hyper Media Types

    @@ -3789,7 +4007,7 @@

    Hyper Media Types

    @@ -3828,7 +4046,7 @@

    spl_autoload_functions()

    @@ -3877,7 +4095,7 @@

    spl_autoload_unregister()

    @@ -3932,7 +4150,7 @@

    spl_autoload_unregister()

    @@ -3960,7 +4178,7 @@

    spl_autoload_unregister()

    @@ -4005,7 +4223,7 @@

    Traversable

    @@ -4056,7 +4274,7 @@

    Traversable

    @@ -4107,7 +4325,7 @@

    Traversable

    @@ -4149,7 +4367,7 @@

    SPL Functions

    @@ -4202,7 +4420,7 @@

    SPL Functions

    @@ -4251,7 +4469,7 @@

    SPL Functions

    @@ -4300,7 +4518,7 @@

    SPL Functions

    @@ -4340,7 +4558,7 @@

    SPL Functions

    @@ -4391,7 +4609,7 @@

    SPL Functions

    @@ -4433,7 +4651,7 @@

    SPL Functions

    @@ -4444,7 +4662,7 @@

    SPL Functions

    -

    Dependency Management in PHP

    +

    Dependency Management

    @@ -4461,7 +4679,7 @@

    SPL Functions

    @@ -4505,7 +4723,7 @@

    SPL Functions

    @@ -4555,7 +4773,7 @@

    SPL Functions

    @@ -4598,39 +4816,19 @@

    SPL Functions

    - +
    -
    +
    -

    Example

    - +

    Model View Controller

    -

    Instead of writing a console application by hand, let's use an existing library: -the Symfony2 Console component:

    -
    {
    -    "require": {
    -        "symfony/console": "~2.4"
    -    }
    -}
    -
    - -

    The structure of your application should look like:

    -
    console-app
    -├── app
    -│   └── console
    -├── composer.json
    -├── src
    -├── tests
    -└── vendor
    -
    -
    @@ -4642,44 +4840,26 @@

    SPL Functions

    - +
    -
    +
    -

    The Symfony2 Console Component

    +

    MVC Overview

    -

    The easiest way to write strong console applications:

    -
      -
    • Create a set of commands;
    • -
    • Add them to a console application.
    • -
    -

    Your Commands should extend the Command class:

    -
    class GreetCommand extends Command
    -{
    -    protected function configure()
    -    {
    -        // configure the name, arguments, options, etc.
    -    }
    -
    -    protected function execute(
    -        InputInterface $input,
    -        OutputInterface $output
    -    ) {
    -    }
    -}
    -
    +

    Typical client request process in MVC architecture:

    +

    @@ -4687,198 +4867,38 @@

    SPL Functions

    Notes

    +
      +
    1. Client makes a request
    2. +
    3. Controller handles request:
        +
      • interactions with model
      • +
      • data preparation
      • +
      • send data to view
      • +
      +
    4. +
    5. View format data
    6. +
    +
    - +
    -
    +
    -

    A Basic Command (1/2)

    - - -

    Configuration

    -
    $this
    -    ->setName('demo:greet')
    -    ->addArgument(
    -        'name',
    -        InputArgument::OPTIONAL,
    -        'Who do you want to greet?'
    -    );
    -
    - -

    Execution

    -
    if (null === $name = $input->getArgument('name')) {
    -    $name = 'World';
    -}
    -
    -$output->writeln('Hello, ' . $name);
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    - -
    -
    - - -
    -
    -
    - -

    A Basic Command (2/2)

    - - -

    The Console Application

    -
    #!/usr/bin/env php
    -# app/console
    -<?php
    -
    -// require the Composer autoloader
    -require __DIR__ . '/../vendor/autoload.php';
    -
    -$application = new Application();
    -$application->add(new GreetCommand());
    -$application->run();
    -
    - -

    Usage

    -
    $ app/console demo:greet
    -Hello, World
    -$ app/console demo:greet William
    -Hello, William
    -
    - -
    -

    Read more: -http://symfony.com/doc/current/components/console/.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    - -
    -
    - - -
    -
    -
    - -

    Model View Controller

    - - -
    -
    -

    Notes

    -
    - -
    -
    - -
    -
    - - -
    -
    -
    - -

    MVC Overview

    - - -

    Typical client request process in MVC architecture:

    -

    -
    - -
    -
    -

    Notes

    -
    - -
      -
    1. Client makes a request
    2. -
    3. Controller handles request:
        -
      • interactions with model
      • -
      • data preparation
      • -
      • send data to view
      • -
      -
    4. -
    5. View format data
    6. -
    - -
    -
    - -
    -
    - - -
    -
    -
    - -

    The Model

    +

    The Model

    Model is the layer in charge of data interaction.

    @@ -4891,9 +4911,14 @@

    Usage

  • API calls;
  • etc.
  • -
    +

    More on this next week!

    +
    + +
    + +

    More on this in a few minutes!

    @@ -4910,7 +4935,7 @@

    Usage

    @@ -4963,7 +4988,7 @@

    Usage

    @@ -5010,7 +5035,7 @@

    Usage

    @@ -5059,7 +5084,7 @@

    Usage

    @@ -5111,7 +5136,7 @@

    Usage

    @@ -5154,7 +5179,7 @@

    Centralized Declaration

    @@ -5187,48 +5212,7 @@

    Centralized Declaration

    - - - - - -
    -
    -
    - -

    Interact With Multiple Services

    - - -

    Web applications become more and more complex and interact with -multiple services such as:

    -
      -
    • Relational databases to store consistent data;
    • -
    • Search engines to index and retrieve documents;
    • -
    • Message queues to postpone executions or as event brokers;
    • -
    • External APIs (geocoding, payment, social);
    • -
    • Mail servers to send or receive emails;
    • -
    • Text message gateways;
    • -
    • HTTP cache servers to reduce resources needs and speed up responses;
    • -
    • and much much more.
    • -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    @@ -5256,7 +5240,7 @@

    Centralized Declaration

    @@ -5292,7 +5276,7 @@

    Centralized Declaration

    @@ -5327,7 +5311,7 @@

    Centralized Declaration

    @@ -5368,7 +5352,7 @@

    Centralized Declaration

    @@ -5396,7 +5380,7 @@

    Centralized Declaration

    @@ -5450,7 +5434,7 @@

    Centralized Declaration

    @@ -5496,7 +5480,7 @@

    Centralized Declaration

    @@ -5543,7 +5527,7 @@

    Centralized Declaration

    @@ -5571,7 +5555,7 @@

    Centralized Declaration

    @@ -5619,7 +5603,7 @@

    CRUD

    @@ -5666,7 +5650,7 @@

    CRUD

    @@ -5714,7 +5698,7 @@

    CRUD

    @@ -5766,7 +5750,7 @@

    CRUD

    @@ -5811,7 +5795,7 @@

    CRUD

    @@ -5858,7 +5842,7 @@

    CRUD

    @@ -5886,7 +5870,7 @@

    CRUD

    @@ -5933,7 +5917,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5988,7 +5972,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6016,7 +6000,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6069,7 +6053,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6118,7 +6102,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6146,7 +6130,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6193,7 +6177,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6221,7 +6205,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6264,7 +6248,7 @@

    PHP Data Object (PDO)

    @@ -6313,7 +6297,7 @@

    Usage

    @@ -6367,7 +6351,7 @@

    Usage

    @@ -6414,7 +6398,7 @@

    Usage

    @@ -6442,7 +6426,7 @@

    Usage

    @@ -6479,7 +6463,7 @@

    Usage

    @@ -6515,7 +6499,7 @@

    Code Snippet

    @@ -6551,7 +6535,7 @@

    Code Snippet

    @@ -6593,7 +6577,7 @@

    Code Snippet

    @@ -6633,7 +6617,7 @@

    Doctrine2 ORM

    @@ -6661,7 +6645,7 @@

    Doctrine2 ORM

    @@ -6715,7 +6699,7 @@

    Doctrine2 ORM

    @@ -6770,7 +6754,7 @@

    Doctrine2 ORM

    @@ -6798,7 +6782,7 @@

    Doctrine2 ORM

    @@ -6847,7 +6831,7 @@

    Doctrine2 ORM

    @@ -6886,7 +6870,7 @@

    Doctrine2 ORM

    @@ -6914,7 +6898,7 @@

    Doctrine2 ORM

    @@ -6970,7 +6954,7 @@

    Doctrine2 ORM

    @@ -7016,7 +7000,7 @@

    Usage

    @@ -7075,7 +7059,7 @@

    Usage

    @@ -7104,7 +7088,9 @@

    Usage

    Usage

    -
    $specification = new AndSpecification(
    +
    // Find customers who have ordered exactly three times,
    +// but who are not premium customers (yet?)
    +$specification = new AndSpecification(
         new CustomerHasOrderedThreeTimes(),
         new NotSpecification(
             new CustomerIsPremium()
    @@ -7129,18 +7115,66 @@ 

    Usage

    + +
    +
    + + +
    +
    +
    + +

    Specification For Business Rules

    + + +

    Reuse your specifications in your business layer:

    +
    class AwesomeOfferSender
    +{
    +    private $specification;
    +
    +    public function __construct(CustomerIsPremium $specification)
    +    {
    +        $this->specification = $specification;
    +    }
    +
    +    public function sendOffersTo(Customer $customer)
    +    {
    +        if ($this->specification->isSatisfiedBy($customer)) {
    +            // send offers
    +        }
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    - +
    -

    Next Week: Web Security 101

    +

    Sessions

    @@ -7153,23 +7187,38 @@

    Usage

    - +
    -

    The End.

    +

    Overview

    + +

    Sessions are a way to preserve certain data across subsequent accesses.

    +

    In A Nutshell

    +
      +
    • Unique identifier (session id);
    • +
    • Server side;
    • +
    • Easy to use;
    • +
    • Built-in.
    • +
    +

    A few use cases:

    +
      +
    • Keeping user authentication and roles;
    • +
    • Storing items into a cart;
    • +
    • Storing a flash message between redirections.
    • +
    @@ -7181,36 +7230,1565 @@

    Usage

    -
    - + +
    +
    +
    + +

    Code Please

    + + +
    // Initalize session
    +session_start();
     
    -  
    -  
       
    
    From e8d7cb7ace8f68a35cae341a99d4f4ed29d7b67b Mon Sep 17 00:00:00 2001
    From: William DURAND 
    Date: Sun, 2 Feb 2014 00:54:51 +0100
    Subject: [PATCH 34/71] =?UTF-8?q?Publish=20slides=20(Dim=20=202=20f=C3=A9v?=
     =?UTF-8?q?=202014=2000:54:51=20CET)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     index.html | 7 +++++--
     isima.html | 7 +++++--
     2 files changed, 10 insertions(+), 4 deletions(-)
    
    diff --git a/index.html b/index.html
    index c60bdc0..ae8ec0f 100644
    --- a/index.html
    +++ b/index.html
    @@ -5222,7 +5222,7 @@ 

    Centralized Declaration

    A controller that handles all requests for a web application:

    This controller dispatches the request to the specialized controllers.

    -

    It is usually tied to URL rewriting.

    +

    It is usually tied to URL rewriting.

    @@ -8211,8 +8211,11 @@

    Usage

    return new Bar(); } } +
    -class Foo +

    + +
    class Foo
     {
         private $bar;
     
    diff --git a/isima.html b/isima.html
    index f4ee6ab..55ec1b1 100644
    --- a/isima.html
    +++ b/isima.html
    @@ -5196,7 +5196,7 @@ 

    Centralized Declaration

    A controller that handles all requests for a web application:

    This controller dispatches the request to the specialized controllers.

    -

    It is usually tied to URL rewriting.

    +

    It is usually tied to URL rewriting.

    @@ -8185,8 +8185,11 @@

    Usage

    return new Bar(); } } +
    -class Foo +

    + +
    class Foo
     {
         private $bar;
     
    
    From c0b615175ae68eee47408c32566fc3413d7f3c7f Mon Sep 17 00:00:00 2001
    From: William DURAND 
    Date: Mon, 3 Feb 2014 09:47:32 +0100
    Subject: [PATCH 35/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?=
     =?UTF-8?q?=202014=2009:47:32=20CET)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     index.html | 1139 +++++++++++++++++++++++++++++++++++++++-------------
     isima.html |  530 +++++++++++++-----------
     2 files changed, 1166 insertions(+), 503 deletions(-)
    
    diff --git a/index.html b/index.html
    index ae8ec0f..db9b580 100644
    --- a/index.html
    +++ b/index.html
    @@ -1212,7 +1212,7 @@
                 
                 
                 
               
             
    @@ -1240,7 +1240,7 @@
    @@ -1291,7 +1291,7 @@
    @@ -1319,7 +1319,7 @@ @@ -1358,7 +1358,7 @@

    Week #4

    @@ -1386,7 +1386,7 @@

    Week #4

    @@ -1421,7 +1421,7 @@

    Week #4

    @@ -1457,7 +1457,7 @@

    Week #4

    @@ -1493,7 +1493,7 @@

    Week #4

    @@ -1527,7 +1527,7 @@

    Week #4

    @@ -1562,7 +1562,7 @@

    Week #4

    @@ -1590,7 +1590,7 @@

    Week #4

    @@ -1618,7 +1618,7 @@

    Week #4

    @@ -1656,7 +1656,7 @@

    Week #4

    @@ -1705,7 +1705,7 @@

    Week #4

    @@ -1756,7 +1756,7 @@

    Week #4

    @@ -1799,7 +1799,7 @@

    Abstract class definition

    @@ -1851,7 +1851,7 @@

    Abstract class definition

    @@ -1890,7 +1890,7 @@

    The Rules

    @@ -1943,7 +1943,7 @@

    The Rules

    @@ -1994,7 +1994,7 @@

    Type Hinting

    @@ -2039,7 +2039,7 @@

    Usage

    @@ -2087,7 +2087,7 @@

    Usage

    @@ -2135,7 +2135,7 @@

    Usage

    @@ -2194,7 +2194,7 @@

    Usage

    @@ -2238,7 +2238,7 @@

    Usage

    @@ -2290,7 +2290,7 @@

    Usage

    @@ -2338,7 +2338,7 @@

    PSR-0

    @@ -2385,7 +2385,7 @@

    PSR-0

    @@ -2437,7 +2437,7 @@

    PSR-0

    @@ -2480,7 +2480,7 @@

    PSR-0

    @@ -2526,7 +2526,7 @@

    PSR-0

    @@ -2569,7 +2569,7 @@

    PSR-0

    @@ -2610,7 +2610,7 @@

    PSR-0

    @@ -2638,7 +2638,7 @@

    PSR-0

    @@ -2690,7 +2690,7 @@

    PSR-0

    @@ -2738,7 +2738,7 @@

    PSR-0

    @@ -2790,7 +2790,7 @@

    PSR-0

    @@ -2818,7 +2818,7 @@

    PSR-0

    @@ -2858,7 +2858,7 @@

    PSR-0

    @@ -2902,7 +2902,7 @@

    Collections

    @@ -2947,7 +2947,7 @@

    Collections

    @@ -2987,7 +2987,7 @@

    Collections

    @@ -3037,7 +3037,7 @@

    Collections

    @@ -3079,7 +3079,7 @@

    3xx Redirections

    @@ -3123,7 +3123,7 @@

    5xx Server Error

    @@ -3166,7 +3166,7 @@

    5xx Server Error

    @@ -3216,7 +3216,7 @@

    5xx Server Error

    @@ -3244,7 +3244,7 @@

    5xx Server Error

    @@ -3285,7 +3285,7 @@

    5xx Server Error

    @@ -3317,7 +3317,7 @@

    5xx Server Error

    @@ -3354,7 +3354,7 @@

    5xx Server Error

    @@ -3391,7 +3391,7 @@

    5xx Server Error

    @@ -3428,7 +3428,7 @@

    5xx Server Error

    @@ -3456,7 +3456,7 @@

    5xx Server Error

    @@ -3508,7 +3508,7 @@

    Hyper Media Types

    @@ -3560,7 +3560,7 @@

    Hyper Media Types

    @@ -3612,7 +3612,7 @@

    Hyper Media Types

    @@ -3640,7 +3640,7 @@

    Hyper Media Types

    @@ -3689,7 +3689,7 @@

    Hyper Media Types

    @@ -3739,7 +3739,7 @@

    Hyper Media Types

    @@ -3786,7 +3786,7 @@

    Hyper Media Types

    @@ -3808,13 +3808,13 @@

    Hyper Media Types

    * lib/Model/Location.php */ require_once __DIR__ . '/../../common.php'; -require_once DOCROOT . '/lib/Model/ModelInterface.php'; +require_once DOCROOT . '/lib/Model/ModelRepresentation.php'; require_once DOCROOT . '/lib/Model/User.php'; require_once DOCROOT . '/lib/Validator/Email.php'; require_once DOCROOT . '/lib/Validator/Username.php'; require_once DOCROOT . '/lib/Validator/Url.php'; -class Location implements ModelInterface +class Location implements ModelRepresentation { /* ... */ } @@ -3835,7 +3835,7 @@

    Hyper Media Types

    @@ -3874,7 +3874,7 @@

    spl_autoload_functions()

    @@ -3923,7 +3923,7 @@

    spl_autoload_unregister()

    @@ -3978,7 +3978,7 @@

    spl_autoload_unregister()

    @@ -4006,7 +4006,7 @@

    spl_autoload_unregister()

    @@ -4051,7 +4051,7 @@

    Traversable

    @@ -4102,7 +4102,7 @@

    Traversable

    @@ -4153,7 +4153,7 @@

    Traversable

    @@ -4195,7 +4195,7 @@

    SPL Functions

    @@ -4248,7 +4248,7 @@

    SPL Functions

    @@ -4297,7 +4297,7 @@

    SPL Functions

    @@ -4346,7 +4346,7 @@

    SPL Functions

    @@ -4386,7 +4386,7 @@

    SPL Functions

    @@ -4437,7 +4437,7 @@

    SPL Functions

    @@ -4479,7 +4479,7 @@

    SPL Functions

    @@ -4507,7 +4507,7 @@

    SPL Functions

    @@ -4551,7 +4551,7 @@

    SPL Functions

    @@ -4601,7 +4601,7 @@

    SPL Functions

    @@ -4644,7 +4644,7 @@

    SPL Functions

    @@ -4692,7 +4692,7 @@

    SPL Functions

    @@ -4742,7 +4742,7 @@

    SPL Functions

    @@ -4789,7 +4789,7 @@

    Execution

    @@ -4842,7 +4842,7 @@

    Usage

    @@ -4870,7 +4870,7 @@

    Usage

    @@ -4913,7 +4913,7 @@

    Usage

    @@ -4961,7 +4961,7 @@

    Usage

    @@ -4978,7 +4978,7 @@

    Usage

    PHP is a templating language per se.

    Never, ever, ever mix HTML and PHP codes or kittens will die: you have to separate the presentation from the business logic.

    -
    class TemplateEngine
    +
    class PhpTemplateEngine implements TemplateEngine
     {
         private $templateDir;
     
    @@ -5014,7 +5014,7 @@ 

    Usage

    @@ -5038,7 +5038,7 @@

    Usage

    Usage

    -
    $engine = new TemplateEngine('/path/to/templates');
    +
    $engine = new PhpTemplateEngine('/path/to/templates');
     
     echo $engine->render('my_template.html', [
         'name' => 'World',
    @@ -5061,7 +5061,7 @@ 

    Usage

    @@ -5110,7 +5110,7 @@

    Usage

    @@ -5130,7 +5130,7 @@

    Usage

    { public function __construct( BananaMapper $mapper, - TemplateEngineInterface $engine + TemplateEngine $engine ) { $this->mapper = $mapper; $this->engine = $engine; @@ -5162,7 +5162,7 @@

    Usage

    @@ -5205,7 +5205,7 @@

    Centralized Declaration

    @@ -5238,7 +5238,7 @@

    Centralized Declaration

    @@ -5266,7 +5266,7 @@

    Centralized Declaration

    @@ -5302,7 +5302,7 @@

    Centralized Declaration

    @@ -5337,7 +5337,7 @@

    Centralized Declaration

    @@ -5378,7 +5378,7 @@

    Centralized Declaration

    @@ -5406,7 +5406,7 @@

    Centralized Declaration

    @@ -5460,7 +5460,7 @@

    Centralized Declaration

    @@ -5506,7 +5506,7 @@

    Centralized Declaration

    @@ -5553,7 +5553,7 @@

    Centralized Declaration

    @@ -5581,7 +5581,7 @@

    Centralized Declaration

    @@ -5629,7 +5629,7 @@

    CRUD

    @@ -5676,7 +5676,7 @@

    CRUD

    @@ -5724,7 +5724,7 @@

    CRUD

    @@ -5776,7 +5776,7 @@

    CRUD

    @@ -5821,7 +5821,7 @@

    CRUD

    @@ -5868,7 +5868,7 @@

    CRUD

    @@ -5896,7 +5896,7 @@

    CRUD

    @@ -5943,7 +5943,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5998,7 +5998,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6026,7 +6026,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6079,7 +6079,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6128,7 +6128,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6156,7 +6156,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6203,7 +6203,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6231,7 +6231,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6274,7 +6274,7 @@

    PHP Data Object (PDO)

    @@ -6323,7 +6323,7 @@

    Usage

    @@ -6377,7 +6377,7 @@

    Usage

    @@ -6424,7 +6424,7 @@

    Usage

    @@ -6452,7 +6452,7 @@

    Usage

    @@ -6489,7 +6489,7 @@

    Usage

    @@ -6525,7 +6525,7 @@

    Code Snippet

    @@ -6561,7 +6561,7 @@

    Code Snippet

    @@ -6603,7 +6603,7 @@

    Code Snippet

    @@ -6643,7 +6643,7 @@

    Doctrine2 ORM

    @@ -6671,7 +6671,7 @@

    Doctrine2 ORM

    @@ -6725,7 +6725,7 @@

    Doctrine2 ORM

    @@ -6780,7 +6780,7 @@

    Doctrine2 ORM

    @@ -6808,7 +6808,7 @@

    Doctrine2 ORM

    @@ -6857,7 +6857,7 @@

    Doctrine2 ORM

    @@ -6896,7 +6896,7 @@

    Doctrine2 ORM

    @@ -6924,7 +6924,7 @@

    Doctrine2 ORM

    @@ -6980,7 +6980,7 @@

    Doctrine2 ORM

    @@ -7026,7 +7026,7 @@

    Usage

    @@ -7085,7 +7085,7 @@

    Usage

    @@ -7141,7 +7141,7 @@

    Usage

    @@ -7189,7 +7189,7 @@

    Usage

    @@ -7217,7 +7217,7 @@

    Usage

    @@ -7260,7 +7260,7 @@

    A few use cases:

    @@ -7309,7 +7309,7 @@

    A few use cases:

    @@ -7324,16 +7324,18 @@

    A few use cases:

      -
    • Session fixation;
    • -
    • Session hijacking;
    • -
    • Man in the Middle (capture);
    • -
    • Predicatable session token.
    • +
    • Prediction (guessing a valid session identifier);
    • +
    • Man in the Middle (capturing a valid session identifier);
    • +
    • Session Fixation (attacker chooses the session identifier);
    • +
    • Session Hijacking (all attacks that attempt to gain access to another user's + session).

    Workarounds

    • Regenerate ids when authentication changes;
    • -
    • Validate client informations (user agent);
    • -
    • Maximum lifetime;
    • +
    • Bind sessions to IP addresses;
    • +
    • Define expiration/timeout;
    • +
    • Don't rely on the default settings;
    • Use HTTPS.
    @@ -7351,7 +7353,59 @@

    Workarounds

    + + + + + +
    +
    +
    + +

    Session Configuration

    + + +

    An example of PHP session configuration that is more secure:

    +
    ; Helps mitigate XSS by telling the browser not to expose the cookie to
    +; client side scripting such as JavaScrip
    +session.cookie_httponly = 1
    +
    +; Prevents session fixation by making sure that PHP only uses cookies for
    +; sessions and disallow session ID passing as a GET parameter
    +session.session.use_only_cookies = 1
    +
    +; Better entropy source
    +; Evades insufficient entropy vulnerabilities
    +session.entropy_file = "/dev/urandom"
    +; `session.entropy_length` might help too!
    +
    +; Smaller exploitation window for XSS/CSRF/Clickjacking...
    +session.cookie_lifetime = 0
    +
    +; Ensures session cookies are only sent over secure connections (it requires
    +; a valid SSL certificate)
    +; Related to OWASP 2013-A6-Sensitive Data Exposure
    +session.cookie_secure = 1
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7379,7 +7433,7 @@

    Workarounds

    @@ -7393,8 +7447,10 @@

    Workarounds

    What You Have Right Now

    -

    No Authentication/Security Layer, anyone can access everything:

    -

    +

    No Authentication/Security Layer, anyone can access everything.

    +


    +
    +

    @@ -7410,7 +7466,7 @@

    Workarounds

    @@ -7424,7 +7480,8 @@

    Workarounds

    The Big Picture

    -

    +


    +

    @@ -7440,7 +7497,7 @@

    Workarounds

    @@ -7481,7 +7538,7 @@

    Event Dispatcher

    @@ -7495,7 +7552,7 @@

    Event Dispatcher

    Introducing the Event Dispatcher

    -

    Using a trait:

    +

    Simple event dispatcher using a trait:

    trait EventDispatcherTrait
     {
         private $events = [];
    @@ -7529,7 +7586,7 @@ 

    Event Dispatcher

    @@ -7581,7 +7638,7 @@

    Event Dispatcher

    @@ -7625,7 +7682,7 @@

    Event Dispatcher

    @@ -7665,7 +7722,7 @@

    Event Dispatcher

    @@ -7722,7 +7779,7 @@

    Event Dispatcher

    @@ -7736,7 +7793,8 @@

    Event Dispatcher

    Authentication Mechanism

    -

    +


    +

    @@ -7752,7 +7810,7 @@

    Event Dispatcher

    @@ -7789,7 +7847,11 @@

    Event Dispatcher

    return $app->redirect('/'); }); -
    + +
    +

    UI Terminology: Logon vs +Login.

    +
    @@ -7805,7 +7867,7 @@

    Event Dispatcher

    @@ -7820,7 +7882,7 @@

    Event Dispatcher

    Useful for API authentication.

    -

    OpenID

    +

    OpenID (in stateless mode)

    http://openid.net/

    Basic and Digest Access Authentication

    http://pretty-rfc.herokuapp.com/RFC2617

    @@ -7841,7 +7903,7 @@

    WSSE Username Token

    @@ -7885,7 +7947,7 @@

    WSSE Username Token

    @@ -7913,7 +7975,7 @@

    WSSE Username Token

    @@ -7953,7 +8015,7 @@

    WSSE Username Token

    @@ -8010,7 +8072,7 @@

    WSSE Username Token

    @@ -8054,7 +8116,7 @@

    Usage

    @@ -8070,8 +8132,8 @@

    Usage

    Reduces dependency on implementation specifics and makes code more reusable.

    The BananaController can use either Twig or the raw PHP implementation -as template engine thanks to the TemplateEngineInterface:

    -
    interface TemplateEngineInterface
    +as template engine thanks to the TemplateEngine interface:

    +
    interface TemplateEngine
     {
         /**
          * @param string $template
    @@ -8099,7 +8161,7 @@ 

    Usage

    @@ -8137,7 +8199,7 @@

    Usage

    @@ -8187,7 +8249,7 @@

    Usage

    @@ -8241,7 +8303,7 @@

    Usage

    @@ -8283,7 +8345,7 @@

    Usage

    @@ -8325,7 +8387,7 @@

    Usage

    @@ -8374,7 +8436,7 @@

    Usage

    @@ -8407,7 +8469,7 @@

    Usage

    @@ -8429,7 +8491,7 @@

    Usage

    service.

    You ask this container to retrieve a service, and it is lazy loaded and dynamically built:

    -
    // It's an instance of TemplateEngineInterface, but you don't know
    +
    // It's an instance of `TemplateEngine`, but you don't know
     // anything about its internal implementation.
     // Is it the raw PHP implementation or Twig?
     $engine = $container->get('template_engine');
    @@ -8450,7 +8512,7 @@ 

    Usage

    @@ -8499,7 +8561,7 @@

    Usage

    @@ -8542,7 +8604,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8579,7 +8641,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8621,7 +8683,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8662,7 +8724,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8708,7 +8770,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8736,7 +8798,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8764,7 +8826,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8798,7 +8860,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8826,7 +8888,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8872,7 +8934,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8920,7 +8982,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8959,7 +9021,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9009,7 +9071,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9037,7 +9099,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9074,7 +9136,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9102,7 +9164,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9145,7 +9207,7 @@

    StoryBDD

    @@ -9191,7 +9253,7 @@

    StoryBDD

    @@ -9239,7 +9301,7 @@

    StoryBDD

    @@ -9292,7 +9354,7 @@

    StoryBDD

    @@ -9320,7 +9382,389 @@

    StoryBDD

    + + + + + +
    +
    +
    + +

    Assert

    + + +

    Assertions and guard methods for input validation (not filtering!) in +business-model, libraries and application low-level code.

    +
    use Assert\Assertion;
    +use Assert\AssertionFailedException;
    +
    +try {
    +    \Assert\that($identifier)->notEmpty()->integer();
    +    Assertion::notEmpty($message, 'Message is not specified');
    +} catch(AssertionFailedException $e) {
    +    $e->getValue();         // the value that caused the failure
    +    $e->getConstraints();   // the additional constraints of the assertion
    +}
    +
    + +
    + +

    beberlei/assert

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Carbon

    + + +

    A simple API extension for DateTime.

    +
    $tomorrow            = Carbon::now()->addDay();
    +$lastWeek            = (new Carbon())->subWeek();
    +$noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London');
    +
    +if (Carbon::now()->isWeekend()) {
    +    echo 'Party!';
    +}
    +
    +Carbon::now()->subDays(5)->diffForHumans();    // 5 days ago
    +
    + +

    Freezing time:

    +
    Carbon::setTestNow(Carbon::create(2001, 5, 21, 12));
    +
    +echo Carbon::now();   // 2001-05-21 12:00:00
    +                      // test, test, test!
    +
    +Carbon::setTestNow(); // clear the mock
    +echo Carbon::now();   // 2014-02-02 21:00:00
    +
    + +
    + +

    briannesbitt/Carbon

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Faker

    + + +

    Fake data generator.

    +
    // use the factory to create a `Faker\Generator` instance
    +$faker = Faker\Factory::create();
    +
    +// generate data by accessing properties
    +echo $faker->name;
    +// 'Lucy Cechtelar';
    +echo $faker->address;
    +// "426 Jordy Lodge
    +// Cartwrightshire, SC 88120-6700"
    +echo $faker->text;
    +// Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam
    +// beatae sint laudantium consequatur. Magni occaecati itaque sint et sit
    +// tempore. Nesciunt amet quidem. Iusto deleniti cum autem ad quia aperiam.
    +echo $faker->email;
    +// 'tkshlerin@collins.com'
    +echo $faker->ipv4;
    +// '109.133.32.252'
    +echo $faker->creditCardNumber;
    +// '4485480221084675'
    +
    + +
    + +

    fzaninotto/Faker

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Flysystem

    + + +

    Filesystem abstraction layer.

    +
    use League\Flysystem\Filesystem;
    +use League\Flysystem\Adapter\Local as LocalAdapter;
    +
    +// Adapters: Local, Amazon Web Services - S3, Rackspace Cloud Files,
    +//           Dropbox, Ftp, Sftp, Zip, WebDAV
    +$filesystem = new Filesystem(new LocalAdapter(__DIR__ . '/path/to/root'));
    +
    +// Create a file
    +$filesystem->write('path/to/file.txt', 'contents');
    +
    +// Update a file
    +$filesystem->update('file/to/update.ext', 'new contents');
    +
    +// Write or update a file
    +$filesystem->put('filename.txt', 'contents');
    +
    +// Delete a file
    +$filesyste->delete('delete/this/file.md');
    +
    +// Check if a file exists
    +$exists = $filesystem->has('filename.txt');
    +
    + +
    + +

    thephpleague/flysystem

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Mockery

    + + +
    // The PHPUnit Way
    +$mock = $this->getMock('SomeClass');
    +$mock->expects($this->once())
    +    ->method('getName')
    +    ->will($this->returnValue('John Doe'));
    +
    +$mock2 = $this->getMock('AnotherClass');
    +$mock2->expects($this->any())
    +    ->method('getNumber')
    +    ->with(2)
    +    ->will($this->returnValue(2));
    +$mock2->expects($this->any())
    +    ->method('getNumber')
    +    ->with(3)
    +    ->will($this->returnValue(3));
    +
    +// The Mockery Way
    +$mock = \Mockery::mock('SomeClass');
    +$mock->shouldReceive('getName')->once()->andReturn('John Doe');
    +
    +$mock2 = \Mockery::mock('AnotherClass');
    +$mock2->shouldReceive('getNumber')->with(2)->andReturn(2);
    +$mock2->shouldReceive('getNumber')->with(3)->andReturn(3);
    +
    + +
    + +

    padraic/mockery

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Option Type for PHP

    + + +
    use PhpOption\Option;
    +
    +class MyRepository
    +{
    +    public function findSomeEntity($criteria)
    +    {
    +        return Option::fromValue($this->em->find(...));
    +    }
    +}
    +
    + +

    You always Require an Entity in Calling Code

    +
    // returns entity, or throws exception
    +$entity = $repository->findSomeEntity(...)->get();
    +
    + +

    Fallback to Default Value If Not Available

    +
    $entity = $repository->findSomeEntity(...)->getOrElse(new Entity());
    +
    + +
    + +

    schmittjoh/phpoption

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    PHP-Parser

    + + +

    A PHP parser written in PHP, producing Abstract Syntax Trees (AST).

    +
    <?php
    +
    +echo 'Hi', 'World';
    +
    + +

    + +
    array(
    +    0: Stmt_Echo(
    +        exprs: array(
    +            0: Scalar_String(
    +                value: Hi
    +            )
    +            1:
    +            Scalar_String(
    +                value:
    +                World
    +            )
    +        )
    +    )
    +)
    +
    + +
    + +

    nikic/PHP-Parser

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -9331,7 +9775,7 @@

    StoryBDD

    -


    +


    React

    Event-driven, non-blocking I/O with PHP: @@ -9352,7 +9796,98 @@

    StoryBDD

    + +
    +
    + + +
    +
    +
    + +

    Swiftmailer

    + + +

    Comprehensive mailing tools for PHP.

    +
    // Create the message
    +$message = Swift_Message::newInstance()
    +    // Give the message a subject
    +    ->setSubject('Your subject')
    +    // Set the From address with an associative array
    +    ->setFrom([ 'john@doe.com' => 'John Doe' ])
    +    // Set the To addresses with an associative array
    +    ->setTo([ 'receiver@domain.org', 'other@domain.org' => 'A name' ])
    +    // Give it a body
    +    ->setBody('Here is the message itself')
    +    ;
    +
    +// Create the Transport
    +$transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25);
    +
    +// Create the Mailer using your created Transport
    +$mailer = Swift_Mailer::newInstance($transport);
    +
    +// Send the message
    +$result = $mailer->send($message);
    +
    + +
    + +

    swiftmailer/swiftmailer

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +

    Whoops

    + + +

    PHP errors for cool kids.

    +

    +
    + +

    filp/whoops

    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -9380,7 +9915,7 @@

    StoryBDD

    @@ -9408,7 +9943,7 @@

    StoryBDD

    @@ -9436,7 +9971,7 @@

    StoryBDD

    @@ -9464,7 +9999,7 @@

    StoryBDD

    @@ -9504,7 +10039,7 @@

    StoryBDD

    @@ -9532,7 +10067,7 @@

    StoryBDD

    @@ -9560,7 +10095,7 @@

    StoryBDD

    @@ -10440,133 +10975,133 @@

    Table of Contents

    - Authentication + Session Configuration 145 - What You Have Right Now + Authentication 146 - The Big Picture + What You Have Right Now 147 - The Interceptor Pattern + The Big Picture 148 - Introducing the Event Dispatcher + The Interceptor Pattern 149 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 150 - The Firewall (1/2) + Using the EventDispatcherTrait 151 - The Firewall (2/2) + The Firewall (1/2) 152 - Implementing The Firewall + The Firewall (2/2) 153 - Authentication Mechanism + Implementing The Firewall 154 - Adding New Routes + Authentication Mechanism 155 - Stateless Authentication + Adding New Routes 156 - Basic Security Thinking + Stateless Authentication 157 - Writing Better Code + Basic Security Thinking 158 - Agenda + Writing Better Code 159 - Coding Standards + Agenda 160 - PHP Coding Standards Fixer + Coding Standards 161 - Programming To The Interface + PHP Coding Standards Fixer 162 - Dependency Inversion Principle (DIP) + Programming To The Interface 163 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 164 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 165 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 166 @@ -10584,19 +11119,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 169 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 170 - PHP Implementations + Dependency Injection Container (DIC) 171 @@ -10608,49 +11143,49 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 173 - From STUPID to SOLID code! (1/2) + Component Driven Development 174 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 175 - Object Calisthenics + From STUPID to SOLID code! (2/2) 176 - - + Object Calisthenics 177 - Testing + - 178 - Agenda + Testing 179 - Unit Testing + Agenda 180 @@ -10662,25 +11197,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 182 - PHPUnit — Assertions + PHPUnit — The Rules 183 - Running PHPUnit + PHPUnit — Assertions 184 - Functional Testing + Running PHPUnit 185 @@ -10692,7 +11227,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 187 @@ -10704,77 +11239,137 @@

    Table of Contents

    - Behat + Behavior Driven Development 189 - Using Behat (1/2) + Behat 190 - Using Behat (2/2) + Using Behat (1/2) 191 - Awesome Projects + Using Behat (2/2) 192 -
    + Awesome Projects 193 - Embracing Open Source + Assert 194 - + Carbon 195 - + Faker 196 - + Flysystem 197 - Golden Rules + Mockery 198 - The End. + Option Type for PHP 199 - Well... Maybe Not.
    PHP Extended + PHP-Parser 200 + +
    React
    + 201 + + + + + Swiftmailer + 202 + + + + + Whoops + 203 + + + + + Embracing Open Source + 204 + + + + + + 205 + + + + + + 206 + + + + + + 207 + + + + + Golden Rules + 208 + + + + + The End. + 209 + + + + + Well... Maybe Not.
    PHP Extended + 210 + + + diff --git a/isima.html b/isima.html index 55ec1b1..b2b8791 100644 --- a/isima.html +++ b/isima.html @@ -1300,7 +1300,7 @@ @@ -1328,7 +1328,7 @@ @@ -1356,7 +1356,7 @@ @@ -1384,7 +1384,7 @@ @@ -1412,7 +1412,7 @@ @@ -1463,7 +1463,7 @@ @@ -1491,7 +1491,7 @@ @@ -1530,7 +1530,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1593,7 +1593,7 @@

    Week #4

    @@ -1629,7 +1629,7 @@

    Week #4

    @@ -1665,7 +1665,7 @@

    Week #4

    @@ -1699,7 +1699,7 @@

    Week #4

    @@ -1734,7 +1734,7 @@

    Week #4

    @@ -1762,7 +1762,7 @@

    Week #4

    @@ -1790,7 +1790,7 @@

    Week #4

    @@ -1828,7 +1828,7 @@

    Week #4

    @@ -1877,7 +1877,7 @@

    Week #4

    @@ -1928,7 +1928,7 @@

    Week #4

    @@ -1971,7 +1971,7 @@

    Abstract class definition

    @@ -2023,7 +2023,7 @@

    Abstract class definition

    @@ -2062,7 +2062,7 @@

    The Rules

    @@ -2115,7 +2115,7 @@

    The Rules

    @@ -2166,7 +2166,7 @@

    Type Hinting

    @@ -2211,7 +2211,7 @@

    Usage

    @@ -2259,7 +2259,7 @@

    Usage

    @@ -2307,7 +2307,7 @@

    Usage

    @@ -2366,7 +2366,7 @@

    Usage

    @@ -2410,7 +2410,7 @@

    Usage

    @@ -2462,7 +2462,7 @@

    Usage

    @@ -2510,7 +2510,7 @@

    PSR-0

    @@ -2557,7 +2557,7 @@

    PSR-0

    @@ -2609,7 +2609,7 @@

    PSR-0

    @@ -2652,7 +2652,7 @@

    PSR-0

    @@ -2698,7 +2698,7 @@

    PSR-0

    @@ -2741,7 +2741,7 @@

    PSR-0

    @@ -2782,7 +2782,7 @@

    PSR-0

    @@ -2810,7 +2810,7 @@

    PSR-0

    @@ -2862,7 +2862,7 @@

    PSR-0

    @@ -2910,7 +2910,7 @@

    PSR-0

    @@ -2962,7 +2962,7 @@

    PSR-0

    @@ -2990,7 +2990,7 @@

    PSR-0

    @@ -3030,7 +3030,7 @@

    PSR-0

    @@ -3074,7 +3074,7 @@

    Collections

    @@ -3119,7 +3119,7 @@

    Collections

    @@ -3159,7 +3159,7 @@

    Collections

    @@ -3209,7 +3209,7 @@

    Collections

    @@ -3251,7 +3251,7 @@

    3xx Redirections

    @@ -3295,7 +3295,7 @@

    5xx Server Error

    @@ -3338,7 +3338,7 @@

    5xx Server Error

    @@ -3388,7 +3388,7 @@

    5xx Server Error

    @@ -3416,7 +3416,7 @@

    5xx Server Error

    @@ -3457,7 +3457,7 @@

    5xx Server Error

    @@ -3489,7 +3489,7 @@

    5xx Server Error

    @@ -3526,7 +3526,7 @@

    5xx Server Error

    @@ -3563,7 +3563,7 @@

    5xx Server Error

    @@ -3600,7 +3600,7 @@

    5xx Server Error

    @@ -3628,7 +3628,7 @@

    5xx Server Error

    @@ -3680,7 +3680,7 @@

    Hyper Media Types

    @@ -3732,7 +3732,7 @@

    Hyper Media Types

    @@ -3784,7 +3784,7 @@

    Hyper Media Types

    @@ -3812,7 +3812,7 @@

    Hyper Media Types

    @@ -3861,7 +3861,7 @@

    Hyper Media Types

    @@ -3911,7 +3911,7 @@

    Hyper Media Types

    @@ -3958,7 +3958,7 @@

    Hyper Media Types

    @@ -3980,13 +3980,13 @@

    Hyper Media Types

    * lib/Model/Location.php */ require_once __DIR__ . '/../../common.php'; -require_once DOCROOT . '/lib/Model/ModelInterface.php'; +require_once DOCROOT . '/lib/Model/ModelRepresentation.php'; require_once DOCROOT . '/lib/Model/User.php'; require_once DOCROOT . '/lib/Validator/Email.php'; require_once DOCROOT . '/lib/Validator/Username.php'; require_once DOCROOT . '/lib/Validator/Url.php'; -class Location implements ModelInterface +class Location implements ModelRepresentation { /* ... */ } @@ -4007,7 +4007,7 @@

    Hyper Media Types

    @@ -4046,7 +4046,7 @@

    spl_autoload_functions()

    @@ -4095,7 +4095,7 @@

    spl_autoload_unregister()

    @@ -4150,7 +4150,7 @@

    spl_autoload_unregister()

    @@ -4178,7 +4178,7 @@

    spl_autoload_unregister()

    @@ -4223,7 +4223,7 @@

    Traversable

    @@ -4274,7 +4274,7 @@

    Traversable

    @@ -4325,7 +4325,7 @@

    Traversable

    @@ -4367,7 +4367,7 @@

    SPL Functions

    @@ -4420,7 +4420,7 @@

    SPL Functions

    @@ -4469,7 +4469,7 @@

    SPL Functions

    @@ -4518,7 +4518,7 @@

    SPL Functions

    @@ -4558,7 +4558,7 @@

    SPL Functions

    @@ -4609,7 +4609,7 @@

    SPL Functions

    @@ -4651,7 +4651,7 @@

    SPL Functions

    @@ -4679,7 +4679,7 @@

    SPL Functions

    @@ -4723,7 +4723,7 @@

    SPL Functions

    @@ -4773,7 +4773,7 @@

    SPL Functions

    @@ -4816,7 +4816,7 @@

    SPL Functions

    @@ -4844,7 +4844,7 @@

    SPL Functions

    @@ -4887,7 +4887,7 @@

    SPL Functions

    @@ -4935,7 +4935,7 @@

    SPL Functions

    @@ -4952,7 +4952,7 @@

    SPL Functions

    PHP is a templating language per se.

    Never, ever, ever mix HTML and PHP codes or kittens will die: you have to separate the presentation from the business logic.

    -
    class TemplateEngine
    +
    class PhpTemplateEngine implements TemplateEngine
     {
         private $templateDir;
     
    @@ -4988,7 +4988,7 @@ 

    SPL Functions

    @@ -5012,7 +5012,7 @@

    SPL Functions

    Usage

    -
    $engine = new TemplateEngine('/path/to/templates');
    +
    $engine = new PhpTemplateEngine('/path/to/templates');
     
     echo $engine->render('my_template.html', [
         'name' => 'World',
    @@ -5035,7 +5035,7 @@ 

    Usage

    @@ -5084,7 +5084,7 @@

    Usage

    @@ -5104,7 +5104,7 @@

    Usage

    { public function __construct( BananaMapper $mapper, - TemplateEngineInterface $engine + TemplateEngine $engine ) { $this->mapper = $mapper; $this->engine = $engine; @@ -5136,7 +5136,7 @@

    Usage

    @@ -5179,7 +5179,7 @@

    Centralized Declaration

    @@ -5212,7 +5212,7 @@

    Centralized Declaration

    @@ -5240,7 +5240,7 @@

    Centralized Declaration

    @@ -5276,7 +5276,7 @@

    Centralized Declaration

    @@ -5311,7 +5311,7 @@

    Centralized Declaration

    @@ -5352,7 +5352,7 @@

    Centralized Declaration

    @@ -5380,7 +5380,7 @@

    Centralized Declaration

    @@ -5434,7 +5434,7 @@

    Centralized Declaration

    @@ -5480,7 +5480,7 @@

    Centralized Declaration

    @@ -5527,7 +5527,7 @@

    Centralized Declaration

    @@ -5555,7 +5555,7 @@

    Centralized Declaration

    @@ -5603,7 +5603,7 @@

    CRUD

    @@ -5650,7 +5650,7 @@

    CRUD

    @@ -5698,7 +5698,7 @@

    CRUD

    @@ -5750,7 +5750,7 @@

    CRUD

    @@ -5795,7 +5795,7 @@

    CRUD

    @@ -5842,7 +5842,7 @@

    CRUD

    @@ -5870,7 +5870,7 @@

    CRUD

    @@ -5917,7 +5917,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5972,7 +5972,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6000,7 +6000,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6053,7 +6053,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6102,7 +6102,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6130,7 +6130,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6177,7 +6177,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6205,7 +6205,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6248,7 +6248,7 @@

    PHP Data Object (PDO)

    @@ -6297,7 +6297,7 @@

    Usage

    @@ -6351,7 +6351,7 @@

    Usage

    @@ -6398,7 +6398,7 @@

    Usage

    @@ -6426,7 +6426,7 @@

    Usage

    @@ -6463,7 +6463,7 @@

    Usage

    @@ -6499,7 +6499,7 @@

    Code Snippet

    @@ -6535,7 +6535,7 @@

    Code Snippet

    @@ -6577,7 +6577,7 @@

    Code Snippet

    @@ -6617,7 +6617,7 @@

    Doctrine2 ORM

    @@ -6645,7 +6645,7 @@

    Doctrine2 ORM

    @@ -6699,7 +6699,7 @@

    Doctrine2 ORM

    @@ -6754,7 +6754,7 @@

    Doctrine2 ORM

    @@ -6782,7 +6782,7 @@

    Doctrine2 ORM

    @@ -6831,7 +6831,7 @@

    Doctrine2 ORM

    @@ -6870,7 +6870,7 @@

    Doctrine2 ORM

    @@ -6898,7 +6898,7 @@

    Doctrine2 ORM

    @@ -6954,7 +6954,7 @@

    Doctrine2 ORM

    @@ -7000,7 +7000,7 @@

    Usage

    @@ -7059,7 +7059,7 @@

    Usage

    @@ -7115,7 +7115,7 @@

    Usage

    @@ -7163,7 +7163,7 @@

    Usage

    @@ -7191,7 +7191,7 @@

    Usage

    @@ -7234,7 +7234,7 @@

    A few use cases:

    @@ -7283,7 +7283,7 @@

    A few use cases:

    @@ -7298,16 +7298,18 @@

    A few use cases:

      -
    • Session fixation;
    • -
    • Session hijacking;
    • -
    • Man in the Middle (capture);
    • -
    • Predicatable session token.
    • +
    • Prediction (guessing a valid session identifier);
    • +
    • Man in the Middle (capturing a valid session identifier);
    • +
    • Session Fixation (attacker chooses the session identifier);
    • +
    • Session Hijacking (all attacks that attempt to gain access to another user's + session).

    Workarounds

    • Regenerate ids when authentication changes;
    • -
    • Validate client informations (user agent);
    • -
    • Maximum lifetime;
    • +
    • Bind sessions to IP addresses;
    • +
    • Define expiration/timeout;
    • +
    • Don't rely on the default settings;
    • Use HTTPS.
    @@ -7325,7 +7327,59 @@

    Workarounds

    + + + + + +
    +
    +
    + +

    Session Configuration

    + + +

    An example of PHP session configuration that is more secure:

    +
    ; Helps mitigate XSS by telling the browser not to expose the cookie to
    +; client side scripting such as JavaScrip
    +session.cookie_httponly = 1
    +
    +; Prevents session fixation by making sure that PHP only uses cookies for
    +; sessions and disallow session ID passing as a GET parameter
    +session.session.use_only_cookies = 1
    +
    +; Better entropy source
    +; Evades insufficient entropy vulnerabilities
    +session.entropy_file = "/dev/urandom"
    +; `session.entropy_length` might help too!
    +
    +; Smaller exploitation window for XSS/CSRF/Clickjacking...
    +session.cookie_lifetime = 0
    +
    +; Ensures session cookies are only sent over secure connections (it requires
    +; a valid SSL certificate)
    +; Related to OWASP 2013-A6-Sensitive Data Exposure
    +session.cookie_secure = 1
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -7353,7 +7407,7 @@

    Workarounds

    @@ -7367,8 +7421,10 @@

    Workarounds

    What You Have Right Now

    -

    No Authentication/Security Layer, anyone can access everything:

    -

    +

    No Authentication/Security Layer, anyone can access everything.

    +


    +
    +

    @@ -7384,7 +7440,7 @@

    Workarounds

    @@ -7398,7 +7454,8 @@

    Workarounds

    The Big Picture

    -

    +


    +

    @@ -7414,7 +7471,7 @@

    Workarounds

    @@ -7455,7 +7512,7 @@

    Event Dispatcher

    @@ -7469,7 +7526,7 @@

    Event Dispatcher

    Introducing the Event Dispatcher

    -

    Using a trait:

    +

    Simple event dispatcher using a trait:

    trait EventDispatcherTrait
     {
         private $events = [];
    @@ -7503,7 +7560,7 @@ 

    Event Dispatcher

    @@ -7555,7 +7612,7 @@

    Event Dispatcher

    @@ -7599,7 +7656,7 @@

    Event Dispatcher

    @@ -7639,7 +7696,7 @@

    Event Dispatcher

    @@ -7696,7 +7753,7 @@

    Event Dispatcher

    @@ -7710,7 +7767,8 @@

    Event Dispatcher

    Authentication Mechanism

    -

    +


    +

    @@ -7726,7 +7784,7 @@

    Event Dispatcher

    @@ -7763,7 +7821,11 @@

    Event Dispatcher

    return $app->redirect('/'); }); -
    + +
    +

    UI Terminology: Logon vs +Login.

    +
    @@ -7779,7 +7841,7 @@

    Event Dispatcher

    @@ -7794,7 +7856,7 @@

    Event Dispatcher

    Useful for API authentication.

    -

    OpenID

    +

    OpenID (in stateless mode)

    http://openid.net/

    Basic and Digest Access Authentication

    http://pretty-rfc.herokuapp.com/RFC2617

    @@ -7815,7 +7877,7 @@

    WSSE Username Token

    @@ -7859,7 +7921,7 @@

    WSSE Username Token

    @@ -7887,7 +7949,7 @@

    WSSE Username Token

    @@ -7927,7 +7989,7 @@

    WSSE Username Token

    @@ -7984,7 +8046,7 @@

    WSSE Username Token

    @@ -8028,7 +8090,7 @@

    Usage

    @@ -8044,8 +8106,8 @@

    Usage

    Reduces dependency on implementation specifics and makes code more reusable.

    The BananaController can use either Twig or the raw PHP implementation -as template engine thanks to the TemplateEngineInterface:

    -
    interface TemplateEngineInterface
    +as template engine thanks to the TemplateEngine interface:

    +
    interface TemplateEngine
     {
         /**
          * @param string $template
    @@ -8073,7 +8135,7 @@ 

    Usage

    @@ -8111,7 +8173,7 @@

    Usage

    @@ -8161,7 +8223,7 @@

    Usage

    @@ -8215,7 +8277,7 @@

    Usage

    @@ -8257,7 +8319,7 @@

    Usage

    @@ -8299,7 +8361,7 @@

    Usage

    @@ -8348,7 +8410,7 @@

    Usage

    @@ -8381,7 +8443,7 @@

    Usage

    @@ -8403,7 +8465,7 @@

    Usage

    service.

    You ask this container to retrieve a service, and it is lazy loaded and dynamically built:

    -
    // It's an instance of TemplateEngineInterface, but you don't know
    +
    // It's an instance of `TemplateEngine`, but you don't know
     // anything about its internal implementation.
     // Is it the raw PHP implementation or Twig?
     $engine = $container->get('template_engine');
    @@ -8424,7 +8486,7 @@ 

    Usage

    @@ -8473,7 +8535,7 @@

    Usage

    @@ -8516,7 +8578,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8553,7 +8615,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8595,7 +8657,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8636,7 +8698,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8682,7 +8744,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8710,7 +8772,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8738,7 +8800,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8766,7 +8828,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9640,133 +9702,133 @@

    Table of Contents

    - Authentication + Session Configuration 144 - What You Have Right Now + Authentication 145 - The Big Picture + What You Have Right Now 146 - The Interceptor Pattern + The Big Picture 147 - Introducing the Event Dispatcher + The Interceptor Pattern 148 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 149 - The Firewall (1/2) + Using the EventDispatcherTrait 150 - The Firewall (2/2) + The Firewall (1/2) 151 - Implementing The Firewall + The Firewall (2/2) 152 - Authentication Mechanism + Implementing The Firewall 153 - Adding New Routes + Authentication Mechanism 154 - Stateless Authentication + Adding New Routes 155 - Basic Security Thinking + Stateless Authentication 156 - Writing Better Code + Basic Security Thinking 157 - Agenda + Writing Better Code 158 - Coding Standards + Agenda 159 - PHP Coding Standards Fixer + Coding Standards 160 - Programming To The Interface + PHP Coding Standards Fixer 161 - Dependency Inversion Principle (DIP) + Programming To The Interface 162 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 163 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 164 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 165 @@ -9784,19 +9846,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 168 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 169 - PHP Implementations + Dependency Injection Container (DIC) 170 @@ -9808,47 +9870,53 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 172 - From STUPID to SOLID code! (1/2) + Component Driven Development 173 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 174 - Object Calisthenics + From STUPID to SOLID code! (2/2) 175 - - + Object Calisthenics 176 - Next Week:
    Web Security 101
    + - 177 - The End. + Next Week:
    Web Security 101
    178 + + The End. + 179 + + + From e2ddcf776b15669519b77c50b08242c16cbce05f Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 3 Feb 2014 09:58:25 +0100 Subject: [PATCH 36/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?= =?UTF-8?q?=202014=2009:58:25=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 733 ++++++++++++++++++++++++++++------------------------- isima.html | 615 +++++++++++++++++++++++--------------------- 2 files changed, 717 insertions(+), 631 deletions(-) diff --git a/index.html b/index.html index db9b580..8bcf264 100644 --- a/index.html +++ b/index.html @@ -1212,7 +1212,7 @@ @@ -1240,7 +1240,7 @@ @@ -1291,7 +1291,7 @@ @@ -1319,7 +1319,7 @@ @@ -1358,7 +1358,7 @@

    Week #4

    @@ -1386,7 +1386,7 @@

    Week #4

    @@ -1421,7 +1421,7 @@

    Week #4

    @@ -1457,7 +1457,7 @@

    Week #4

    @@ -1493,7 +1493,7 @@

    Week #4

    @@ -1527,7 +1527,7 @@

    Week #4

    @@ -1562,7 +1562,7 @@

    Week #4

    @@ -1590,7 +1590,7 @@

    Week #4

    @@ -1618,7 +1618,7 @@

    Week #4

    @@ -1656,7 +1656,7 @@

    Week #4

    @@ -1705,7 +1705,7 @@

    Week #4

    @@ -1756,7 +1756,7 @@

    Week #4

    @@ -1799,7 +1799,7 @@

    Abstract class definition

    @@ -1851,7 +1851,7 @@

    Abstract class definition

    @@ -1890,7 +1890,7 @@

    The Rules

    @@ -1943,7 +1943,7 @@

    The Rules

    @@ -1994,7 +1994,7 @@

    Type Hinting

    @@ -2039,7 +2039,7 @@

    Usage

    @@ -2087,7 +2087,7 @@

    Usage

    @@ -2135,7 +2135,7 @@

    Usage

    @@ -2194,7 +2194,7 @@

    Usage

    @@ -2238,7 +2238,7 @@

    Usage

    @@ -2290,7 +2290,7 @@

    Usage

    @@ -2338,7 +2338,7 @@

    PSR-0

    @@ -2385,7 +2385,7 @@

    PSR-0

    @@ -2437,7 +2437,7 @@

    PSR-0

    @@ -2480,7 +2480,7 @@

    PSR-0

    @@ -2526,7 +2526,7 @@

    PSR-0

    @@ -2569,7 +2569,7 @@

    PSR-0

    @@ -2610,7 +2610,7 @@

    PSR-0

    @@ -2638,7 +2638,7 @@

    PSR-0

    @@ -2690,7 +2690,7 @@

    PSR-0

    @@ -2738,7 +2738,7 @@

    PSR-0

    @@ -2790,7 +2790,7 @@

    PSR-0

    @@ -2818,7 +2818,7 @@

    PSR-0

    @@ -2858,7 +2858,7 @@

    PSR-0

    @@ -2902,7 +2902,7 @@

    Collections

    @@ -2947,7 +2947,7 @@

    Collections

    @@ -2987,7 +2987,7 @@

    Collections

    @@ -3037,7 +3037,7 @@

    Collections

    @@ -3079,7 +3079,7 @@

    3xx Redirections

    @@ -3123,7 +3123,7 @@

    5xx Server Error

    @@ -3166,7 +3166,7 @@

    5xx Server Error

    @@ -3216,7 +3216,7 @@

    5xx Server Error

    @@ -3244,7 +3244,7 @@

    5xx Server Error

    @@ -3285,7 +3285,7 @@

    5xx Server Error

    @@ -3317,7 +3317,7 @@

    5xx Server Error

    @@ -3354,7 +3354,7 @@

    5xx Server Error

    @@ -3391,7 +3391,7 @@

    5xx Server Error

    @@ -3428,7 +3428,44 @@

    5xx Server Error

    + + + + + +
    +
    +
    + +

    Level 3 - Hypermedia Controls

    + + +

    In A Nutshell

    +
      +
    • Service discovery via link relations
    • +
    • Hypermedia formats
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3456,7 +3493,7 @@

    5xx Server Error

    @@ -3508,7 +3545,7 @@

    Hyper Media Types

    @@ -3560,7 +3597,7 @@

    Hyper Media Types

    @@ -3612,7 +3649,7 @@

    Hyper Media Types

    @@ -3640,7 +3677,7 @@

    Hyper Media Types

    @@ -3689,7 +3726,7 @@

    Hyper Media Types

    @@ -3739,7 +3776,7 @@

    Hyper Media Types

    @@ -3786,7 +3823,7 @@

    Hyper Media Types

    @@ -3835,7 +3872,7 @@

    Hyper Media Types

    @@ -3874,7 +3911,7 @@

    spl_autoload_functions()

    @@ -3923,7 +3960,7 @@

    spl_autoload_unregister()

    @@ -3978,7 +4015,7 @@

    spl_autoload_unregister()

    @@ -4006,7 +4043,7 @@

    spl_autoload_unregister()

    @@ -4051,7 +4088,7 @@

    Traversable

    @@ -4102,7 +4139,7 @@

    Traversable

    @@ -4153,7 +4190,7 @@

    Traversable

    @@ -4195,7 +4232,7 @@

    SPL Functions

    @@ -4248,7 +4285,7 @@

    SPL Functions

    @@ -4297,7 +4334,7 @@

    SPL Functions

    @@ -4346,7 +4383,7 @@

    SPL Functions

    @@ -4386,7 +4423,7 @@

    SPL Functions

    @@ -4437,7 +4474,7 @@

    SPL Functions

    @@ -4479,7 +4516,7 @@

    SPL Functions

    @@ -4507,7 +4544,7 @@

    SPL Functions

    @@ -4551,7 +4588,7 @@

    SPL Functions

    @@ -4601,7 +4638,7 @@

    SPL Functions

    @@ -4644,7 +4681,7 @@

    SPL Functions

    @@ -4692,7 +4729,7 @@

    SPL Functions

    @@ -4742,7 +4779,7 @@

    SPL Functions

    @@ -4789,7 +4826,7 @@

    Execution

    @@ -4842,7 +4879,7 @@

    Usage

    @@ -4870,7 +4907,7 @@

    Usage

    @@ -4913,7 +4950,7 @@

    Usage

    @@ -4961,7 +4998,7 @@

    Usage

    @@ -5014,7 +5051,7 @@

    Usage

    @@ -5061,7 +5098,7 @@

    Usage

    @@ -5110,7 +5147,7 @@

    Usage

    @@ -5162,7 +5199,7 @@

    Usage

    @@ -5205,7 +5242,7 @@

    Centralized Declaration

    @@ -5238,7 +5275,7 @@

    Centralized Declaration

    @@ -5266,7 +5303,7 @@

    Centralized Declaration

    @@ -5302,7 +5339,7 @@

    Centralized Declaration

    @@ -5337,7 +5374,7 @@

    Centralized Declaration

    @@ -5378,7 +5415,7 @@

    Centralized Declaration

    @@ -5406,7 +5443,7 @@

    Centralized Declaration

    @@ -5460,7 +5497,7 @@

    Centralized Declaration

    @@ -5506,7 +5543,7 @@

    Centralized Declaration

    @@ -5553,7 +5590,7 @@

    Centralized Declaration

    @@ -5581,7 +5618,7 @@

    Centralized Declaration

    @@ -5629,7 +5666,7 @@

    CRUD

    @@ -5676,7 +5713,7 @@

    CRUD

    @@ -5724,7 +5761,7 @@

    CRUD

    @@ -5776,7 +5813,7 @@

    CRUD

    @@ -5821,7 +5858,7 @@

    CRUD

    @@ -5868,7 +5905,7 @@

    CRUD

    @@ -5896,7 +5933,7 @@

    CRUD

    @@ -5943,7 +5980,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5998,7 +6035,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6026,7 +6063,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6079,7 +6116,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6128,7 +6165,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6156,7 +6193,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6203,7 +6240,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6231,7 +6268,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6274,7 +6311,7 @@

    PHP Data Object (PDO)

    @@ -6323,7 +6360,7 @@

    Usage

    @@ -6377,7 +6414,7 @@

    Usage

    @@ -6424,7 +6461,7 @@

    Usage

    @@ -6452,7 +6489,7 @@

    Usage

    @@ -6489,7 +6526,7 @@

    Usage

    @@ -6525,7 +6562,7 @@

    Code Snippet

    @@ -6561,7 +6598,7 @@

    Code Snippet

    @@ -6603,7 +6640,7 @@

    Code Snippet

    @@ -6643,7 +6680,7 @@

    Doctrine2 ORM

    @@ -6671,7 +6708,7 @@

    Doctrine2 ORM

    @@ -6725,7 +6762,7 @@

    Doctrine2 ORM

    @@ -6780,7 +6817,7 @@

    Doctrine2 ORM

    @@ -6808,7 +6845,7 @@

    Doctrine2 ORM

    @@ -6857,7 +6894,7 @@

    Doctrine2 ORM

    @@ -6896,7 +6933,7 @@

    Doctrine2 ORM

    @@ -6924,7 +6961,7 @@

    Doctrine2 ORM

    @@ -6980,7 +7017,7 @@

    Doctrine2 ORM

    @@ -7026,7 +7063,7 @@

    Usage

    @@ -7085,7 +7122,7 @@

    Usage

    @@ -7141,7 +7178,7 @@

    Usage

    @@ -7189,7 +7226,7 @@

    Usage

    @@ -7217,7 +7254,7 @@

    Usage

    @@ -7260,7 +7297,7 @@

    A few use cases:

    @@ -7309,7 +7346,7 @@

    A few use cases:

    @@ -7353,7 +7390,7 @@

    Workarounds

    @@ -7405,7 +7442,7 @@

    Workarounds

    @@ -7433,7 +7470,7 @@

    Workarounds

    @@ -7466,7 +7503,7 @@

    Workarounds

    @@ -7497,7 +7534,7 @@

    Workarounds

    @@ -7538,7 +7575,7 @@

    Event Dispatcher

    @@ -7586,7 +7623,7 @@

    Event Dispatcher

    @@ -7638,7 +7675,7 @@

    Event Dispatcher

    @@ -7682,7 +7719,7 @@

    Event Dispatcher

    @@ -7722,7 +7759,7 @@

    Event Dispatcher

    @@ -7779,7 +7816,7 @@

    Event Dispatcher

    @@ -7810,7 +7847,7 @@

    Event Dispatcher

    @@ -7867,7 +7904,7 @@

    Event Dispatcher

    @@ -7903,7 +7940,7 @@

    WSSE Username Token

    @@ -7947,7 +7984,7 @@

    WSSE Username Token

    @@ -7975,7 +8012,7 @@

    WSSE Username Token

    @@ -8015,7 +8052,7 @@

    WSSE Username Token

    @@ -8072,7 +8109,7 @@

    WSSE Username Token

    @@ -8116,7 +8153,7 @@

    Usage

    @@ -8161,7 +8198,7 @@

    Usage

    @@ -8199,7 +8236,7 @@

    Usage

    @@ -8249,7 +8286,7 @@

    Usage

    @@ -8303,7 +8340,7 @@

    Usage

    @@ -8345,7 +8382,7 @@

    Usage

    @@ -8387,7 +8424,7 @@

    Usage

    @@ -8436,7 +8473,7 @@

    Usage

    @@ -8469,7 +8506,7 @@

    Usage

    @@ -8512,7 +8549,7 @@

    Usage

    @@ -8561,7 +8598,7 @@

    Usage

    @@ -8604,7 +8641,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8641,7 +8678,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8683,7 +8720,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8724,7 +8761,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8770,7 +8807,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8798,7 +8835,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8826,7 +8863,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8860,7 +8897,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8888,7 +8925,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8934,7 +8971,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8982,7 +9019,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9021,7 +9058,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9071,7 +9108,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9099,7 +9136,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9136,7 +9173,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9164,7 +9201,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9207,7 +9244,7 @@

    StoryBDD

    @@ -9253,7 +9290,7 @@

    StoryBDD

    @@ -9301,7 +9338,7 @@

    StoryBDD

    @@ -9354,7 +9391,7 @@

    StoryBDD

    @@ -9382,7 +9419,7 @@

    StoryBDD

    @@ -9429,7 +9466,7 @@

    StoryBDD

    @@ -9484,7 +9521,7 @@

    StoryBDD

    @@ -9539,7 +9576,7 @@

    StoryBDD

    @@ -9596,7 +9633,7 @@

    StoryBDD

    @@ -9654,7 +9691,7 @@

    StoryBDD

    @@ -9707,7 +9744,7 @@

    Fallback to Default Value If Not Available

    @@ -9764,7 +9801,7 @@

    Fallback to Default Value If Not Available

    @@ -9796,7 +9833,7 @@

    Fallback to Default Value If Not Available

    @@ -9852,7 +9889,7 @@

    Fallback to Default Value If Not Available

    @@ -9887,7 +9924,7 @@

    Fallback to Default Value If Not Available

    @@ -9915,7 +9952,7 @@

    Fallback to Default Value If Not Available

    @@ -9943,7 +9980,7 @@

    Fallback to Default Value If Not Available

    @@ -9971,7 +10008,7 @@

    Fallback to Default Value If Not Available

    @@ -9999,7 +10036,7 @@

    Fallback to Default Value If Not Available

    @@ -10039,7 +10076,7 @@

    Fallback to Default Value If Not Available

    @@ -10067,7 +10104,7 @@

    Fallback to Default Value If Not Available

    @@ -10095,7 +10132,7 @@

    Fallback to Default Value If Not Available

    @@ -10435,211 +10472,211 @@

    Table of Contents

    - Level 3 = Content Negotiation + HATEOAS + Level 3 - Hypermedia Controls 55 - Media Types + Level 3 = Content Negotiation + HATEOAS 56 - Content Type Negotiation + Media Types 57 - HATEOAS + Content Type Negotiation 58 - PHP Autoloading + HATEOAS 59 - Why Is It Necessary? + PHP Autoloading 60 - The require() Way + Why Is It Necessary? 61 - The require_once() Way + The require() Way 62 - Working With Multiple Files + The require_once() Way 63 - Rethinking The Way You Load Classes + Working With Multiple Files 64 - Examples + Rethinking The Way You Load Classes 65 - Under The Hood + Examples 66 - Leveraging PHP APIs + Under The Hood 67 - Built-in Interfaces + Leveraging PHP APIs 68 - The Reflection API (1/2) + Built-in Interfaces 69 - The Reflection API (2/2) + The Reflection API (1/2) 70 - The Standard PHP Library (SPL) + The Reflection API (2/2) 71 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 72 - Observer Pattern (2/2) + Observer Pattern (1/2) 73 - Exceptions (1/2) + Observer Pattern (2/2) 74 - Exceptions (2/2) + Exceptions (1/2) 75 - Password Hashing + Exceptions (2/2) 76 - PHP Archive (PHAR) + Password Hashing 77 - Dependency Management + PHP Archive (PHAR) 78 - Composer + Dependency Management 79 - composer install + Composer 80 - Composer Autoloader + composer install 81 - Example + Composer Autoloader 82 - The Symfony2 Console Component + Example 83 - A Basic Command (1/2) + The Symfony2 Console Component 84 - A Basic Command (2/2) + A Basic Command (1/2) 85 - Model View Controller + A Basic Command (2/2) 86 - MVC Overview + Model View Controller 87 - The Model + MVC Overview 88 - The View + The Model 89 @@ -10657,55 +10694,55 @@

    Table of Contents

    - The Controller + The View 92 - Routing + The Controller 93 - Front Controller Pattern + Routing 94 - Databases + Front Controller Pattern 95 - Agenda + Databases 96 - Quick note + Agenda 97 - Database Design Patterns + Quick note 98 - Row Data Gateway + Database Design Patterns 99 - Row Data Gateway + Row Data Gateway 100 @@ -10723,13 +10760,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 103 - Table Data Gateway + Table Data Gateway 104 @@ -10765,13 +10802,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 110 - Active Record + Active Record 111 @@ -10783,13 +10820,13 @@

    Table of Contents

    - Data Mapper + Active Record 113 - Data Mapper + Data Mapper 114 @@ -10801,31 +10838,31 @@

    Table of Contents

    - Identity Map + Data Mapper 116 - Identity Map + Identity Map 117 - Data Access Layer + Identity Map 118 - Data Access Layer / Data Source Name + Data Access Layer 119 - Data Access Layer + Data Access Layer / Data Source Name 120 @@ -10843,67 +10880,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 123 - Object Relational Mapping (1/4) + Object Relational Mapping 124 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 125 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 126 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 127 - Existing Components + Object Relational Mapping (4/4) 128 - A Note About
    Domain-Driven Design
    + Existing Components 129 - Entities + A Note About
    Domain-Driven Design
    130 - Value Objects + Entities 131 - The Repository Pattern + Value Objects 132 - The Repository Pattern + The Repository Pattern 133 @@ -10915,25 +10952,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 135 - The Specification Pattern + The Specification Pattern 136 - Repository ♥ Specification + The Specification Pattern 137 - Combine Them! + Repository ♥ Specification 138 @@ -10945,169 +10982,169 @@

    Table of Contents

    - Specification For Business Rules + Combine Them! 140 - Sessions + Specification For Business Rules 141 - Overview + Sessions 142 - Code Please + Overview 143 - Security Concerns + Code Please 144 - Session Configuration + Security Concerns 145 - Authentication + Session Configuration 146 - What You Have Right Now + Authentication 147 - The Big Picture + What You Have Right Now 148 - The Interceptor Pattern + The Big Picture 149 - Introducing the Event Dispatcher + The Interceptor Pattern 150 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 151 - The Firewall (1/2) + Using the EventDispatcherTrait 152 - The Firewall (2/2) + The Firewall (1/2) 153 - Implementing The Firewall + The Firewall (2/2) 154 - Authentication Mechanism + Implementing The Firewall 155 - Adding New Routes + Authentication Mechanism 156 - Stateless Authentication + Adding New Routes 157 - Basic Security Thinking + Stateless Authentication 158 - Writing Better Code + Basic Security Thinking 159 - Agenda + Writing Better Code 160 - Coding Standards + Agenda 161 - PHP Coding Standards Fixer + Coding Standards 162 - Programming To The Interface + PHP Coding Standards Fixer 163 - Dependency Inversion Principle (DIP) + Programming To The Interface 164 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 165 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 166 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 167 @@ -11125,19 +11162,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 170 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 171 - PHP Implementations + Dependency Injection Container (DIC) 172 @@ -11149,49 +11186,49 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 174 - From STUPID to SOLID code! (1/2) + Component Driven Development 175 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 176 - Object Calisthenics + From STUPID to SOLID code! (2/2) 177 - - + Object Calisthenics 178 - Testing + - 179 - Agenda + Testing 180 - Unit Testing + Agenda 181 @@ -11203,25 +11240,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 183 - PHPUnit — Assertions + PHPUnit — The Rules 184 - Running PHPUnit + PHPUnit — Assertions 185 - Functional Testing + Running PHPUnit 186 @@ -11233,7 +11270,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 188 @@ -11245,131 +11282,137 @@

    Table of Contents

    - Behat + Behavior Driven Development 190 - Using Behat (1/2) + Behat 191 - Using Behat (2/2) + Using Behat (1/2) 192 - Awesome Projects + Using Behat (2/2) 193 - Assert + Awesome Projects 194 - Carbon + Assert 195 - Faker + Carbon 196 - Flysystem + Faker 197 - Mockery + Flysystem 198 - Option Type for PHP + Mockery 199 - PHP-Parser + Option Type for PHP 200 -
    React
    + PHP-Parser 201 - Swiftmailer +
    React
    202 - Whoops + Swiftmailer 203 - Embracing Open Source + Whoops 204 - + Embracing Open Source 205 - + 206 - + 207 - Golden Rules + 208 - The End. + Golden Rules 209 - Well... Maybe Not.
    PHP Extended + The End. 210 + + Well... Maybe Not.
    PHP Extended + 211 + + + diff --git a/isima.html b/isima.html index b2b8791..251208b 100644 --- a/isima.html +++ b/isima.html @@ -1300,7 +1300,7 @@ @@ -1328,7 +1328,7 @@ @@ -1356,7 +1356,7 @@ @@ -1384,7 +1384,7 @@ @@ -1412,7 +1412,7 @@ @@ -1463,7 +1463,7 @@ @@ -1491,7 +1491,7 @@ @@ -1508,12 +1508,12 @@

    Week #1

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server, REST

    -

    Week #2

    +

    Week #2

    Autoloading, Leveraging PHP APIs, Dependency Management, Model View Controller, Databases

    -

    Week #3

    +

    Week #3

    A Note About Domain-Driven Design, Sessions, Authentication, Writing Better Code

    -

    Week #4

    +

    Week #4

    Security 101

    @@ -1530,7 +1530,7 @@

    Week #4

    @@ -1558,7 +1558,7 @@

    Week #4

    @@ -1593,7 +1593,7 @@

    Week #4

    @@ -1629,7 +1629,7 @@

    Week #4

    @@ -1665,7 +1665,7 @@

    Week #4

    @@ -1699,7 +1699,7 @@

    Week #4

    @@ -1734,7 +1734,7 @@

    Week #4

    @@ -1762,7 +1762,7 @@

    Week #4

    @@ -1790,7 +1790,7 @@

    Week #4

    @@ -1828,7 +1828,7 @@

    Week #4

    @@ -1877,7 +1877,7 @@

    Week #4

    @@ -1928,7 +1928,7 @@

    Week #4

    @@ -1971,7 +1971,7 @@

    Abstract class definition

    @@ -2023,7 +2023,7 @@

    Abstract class definition

    @@ -2062,7 +2062,7 @@

    The Rules

    @@ -2115,7 +2115,7 @@

    The Rules

    @@ -2166,7 +2166,7 @@

    Type Hinting

    @@ -2211,7 +2211,7 @@

    Usage

    @@ -2259,7 +2259,7 @@

    Usage

    @@ -2307,7 +2307,7 @@

    Usage

    @@ -2366,7 +2366,7 @@

    Usage

    @@ -2410,7 +2410,7 @@

    Usage

    @@ -2462,7 +2462,7 @@

    Usage

    @@ -2510,7 +2510,7 @@

    PSR-0

    @@ -2557,7 +2557,7 @@

    PSR-0

    @@ -2609,7 +2609,7 @@

    PSR-0

    @@ -2652,7 +2652,7 @@

    PSR-0

    @@ -2698,7 +2698,7 @@

    PSR-0

    @@ -2741,7 +2741,7 @@

    PSR-0

    @@ -2782,7 +2782,7 @@

    PSR-0

    @@ -2810,7 +2810,7 @@

    PSR-0

    @@ -2862,7 +2862,7 @@

    PSR-0

    @@ -2910,7 +2910,7 @@

    PSR-0

    @@ -2962,7 +2962,7 @@

    PSR-0

    @@ -2990,7 +2990,7 @@

    PSR-0

    @@ -3030,7 +3030,7 @@

    PSR-0

    @@ -3074,7 +3074,7 @@

    Collections

    @@ -3119,7 +3119,7 @@

    Collections

    @@ -3159,7 +3159,7 @@

    Collections

    @@ -3209,7 +3209,7 @@

    Collections

    @@ -3251,7 +3251,7 @@

    3xx Redirections

    @@ -3295,7 +3295,7 @@

    5xx Server Error

    @@ -3338,7 +3338,7 @@

    5xx Server Error

    @@ -3388,7 +3388,7 @@

    5xx Server Error

    @@ -3416,7 +3416,7 @@

    5xx Server Error

    @@ -3457,7 +3457,7 @@

    5xx Server Error

    @@ -3489,7 +3489,7 @@

    5xx Server Error

    @@ -3526,7 +3526,7 @@

    5xx Server Error

    @@ -3563,7 +3563,7 @@

    5xx Server Error

    @@ -3600,7 +3600,44 @@

    5xx Server Error

    + + + + + +
    +
    +
    + +

    Level 3 - Hypermedia Controls

    + + +

    In A Nutshell

    +
      +
    • Service discovery via link relations
    • +
    • Hypermedia formats
    • +
    +


    +
    +

    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -3628,7 +3665,7 @@

    5xx Server Error

    @@ -3680,7 +3717,7 @@

    Hyper Media Types

    @@ -3732,7 +3769,7 @@

    Hyper Media Types

    @@ -3784,7 +3821,7 @@

    Hyper Media Types

    @@ -3812,7 +3849,7 @@

    Hyper Media Types

    @@ -3861,7 +3898,7 @@

    Hyper Media Types

    @@ -3911,7 +3948,7 @@

    Hyper Media Types

    @@ -3958,7 +3995,7 @@

    Hyper Media Types

    @@ -4007,7 +4044,7 @@

    Hyper Media Types

    @@ -4046,7 +4083,7 @@

    spl_autoload_functions()

    @@ -4095,7 +4132,7 @@

    spl_autoload_unregister()

    @@ -4150,7 +4187,7 @@

    spl_autoload_unregister()

    @@ -4178,7 +4215,7 @@

    spl_autoload_unregister()

    @@ -4223,7 +4260,7 @@

    Traversable

    @@ -4274,7 +4311,7 @@

    Traversable

    @@ -4325,7 +4362,7 @@

    Traversable

    @@ -4367,7 +4404,7 @@

    SPL Functions

    @@ -4420,7 +4457,7 @@

    SPL Functions

    @@ -4469,7 +4506,7 @@

    SPL Functions

    @@ -4518,7 +4555,7 @@

    SPL Functions

    @@ -4558,7 +4595,7 @@

    SPL Functions

    @@ -4609,7 +4646,7 @@

    SPL Functions

    @@ -4651,7 +4688,7 @@

    SPL Functions

    @@ -4679,7 +4716,7 @@

    SPL Functions

    @@ -4723,7 +4760,7 @@

    SPL Functions

    @@ -4773,7 +4810,7 @@

    SPL Functions

    @@ -4816,7 +4853,7 @@

    SPL Functions

    @@ -4844,7 +4881,7 @@

    SPL Functions

    @@ -4887,7 +4924,7 @@

    SPL Functions

    @@ -4935,7 +4972,7 @@

    SPL Functions

    @@ -4988,7 +5025,7 @@

    SPL Functions

    @@ -5035,7 +5072,7 @@

    Usage

    @@ -5084,7 +5121,7 @@

    Usage

    @@ -5136,7 +5173,7 @@

    Usage

    @@ -5179,7 +5216,7 @@

    Centralized Declaration

    @@ -5212,7 +5249,7 @@

    Centralized Declaration

    @@ -5240,7 +5277,7 @@

    Centralized Declaration

    @@ -5276,7 +5313,7 @@

    Centralized Declaration

    @@ -5311,7 +5348,7 @@

    Centralized Declaration

    @@ -5352,7 +5389,7 @@

    Centralized Declaration

    @@ -5380,7 +5417,7 @@

    Centralized Declaration

    @@ -5434,7 +5471,7 @@

    Centralized Declaration

    @@ -5480,7 +5517,7 @@

    Centralized Declaration

    @@ -5527,7 +5564,7 @@

    Centralized Declaration

    @@ -5555,7 +5592,7 @@

    Centralized Declaration

    @@ -5603,7 +5640,7 @@

    CRUD

    @@ -5650,7 +5687,7 @@

    CRUD

    @@ -5698,7 +5735,7 @@

    CRUD

    @@ -5750,7 +5787,7 @@

    CRUD

    @@ -5795,7 +5832,7 @@

    CRUD

    @@ -5842,7 +5879,7 @@

    CRUD

    @@ -5870,7 +5907,7 @@

    CRUD

    @@ -5917,7 +5954,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -5972,7 +6009,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6000,7 +6037,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6053,7 +6090,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6102,7 +6139,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6130,7 +6167,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6177,7 +6214,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6205,7 +6242,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6248,7 +6285,7 @@

    PHP Data Object (PDO)

    @@ -6297,7 +6334,7 @@

    Usage

    @@ -6351,7 +6388,7 @@

    Usage

    @@ -6398,7 +6435,7 @@

    Usage

    @@ -6426,7 +6463,7 @@

    Usage

    @@ -6463,7 +6500,7 @@

    Usage

    @@ -6499,7 +6536,7 @@

    Code Snippet

    @@ -6535,7 +6572,7 @@

    Code Snippet

    @@ -6577,7 +6614,7 @@

    Code Snippet

    @@ -6617,7 +6654,7 @@

    Doctrine2 ORM

    @@ -6645,7 +6682,7 @@

    Doctrine2 ORM

    @@ -6699,7 +6736,7 @@

    Doctrine2 ORM

    @@ -6754,7 +6791,7 @@

    Doctrine2 ORM

    @@ -6782,7 +6819,7 @@

    Doctrine2 ORM

    @@ -6831,7 +6868,7 @@

    Doctrine2 ORM

    @@ -6870,7 +6907,7 @@

    Doctrine2 ORM

    @@ -6898,7 +6935,7 @@

    Doctrine2 ORM

    @@ -6954,7 +6991,7 @@

    Doctrine2 ORM

    @@ -7000,7 +7037,7 @@

    Usage

    @@ -7059,7 +7096,7 @@

    Usage

    @@ -7115,7 +7152,7 @@

    Usage

    @@ -7163,7 +7200,7 @@

    Usage

    @@ -7191,7 +7228,7 @@

    Usage

    @@ -7234,7 +7271,7 @@

    A few use cases:

    @@ -7283,7 +7320,7 @@

    A few use cases:

    @@ -7327,7 +7364,7 @@

    Workarounds

    @@ -7379,7 +7416,7 @@

    Workarounds

    @@ -7407,7 +7444,7 @@

    Workarounds

    @@ -7440,7 +7477,7 @@

    Workarounds

    @@ -7471,7 +7508,7 @@

    Workarounds

    @@ -7512,7 +7549,7 @@

    Event Dispatcher

    @@ -7560,7 +7597,7 @@

    Event Dispatcher

    @@ -7612,7 +7649,7 @@

    Event Dispatcher

    @@ -7656,7 +7693,7 @@

    Event Dispatcher

    @@ -7696,7 +7733,7 @@

    Event Dispatcher

    @@ -7753,7 +7790,7 @@

    Event Dispatcher

    @@ -7784,7 +7821,7 @@

    Event Dispatcher

    @@ -7841,7 +7878,7 @@

    Event Dispatcher

    @@ -7877,7 +7914,7 @@

    WSSE Username Token

    @@ -7921,7 +7958,7 @@

    WSSE Username Token

    @@ -7949,7 +7986,7 @@

    WSSE Username Token

    @@ -7989,7 +8026,7 @@

    WSSE Username Token

    @@ -8046,7 +8083,7 @@

    WSSE Username Token

    @@ -8090,7 +8127,7 @@

    Usage

    @@ -8135,7 +8172,7 @@

    Usage

    @@ -8173,7 +8210,7 @@

    Usage

    @@ -8223,7 +8260,7 @@

    Usage

    @@ -8277,7 +8314,7 @@

    Usage

    @@ -8319,7 +8356,7 @@

    Usage

    @@ -8361,7 +8398,7 @@

    Usage

    @@ -8410,7 +8447,7 @@

    Usage

    @@ -8443,7 +8480,7 @@

    Usage

    @@ -8486,7 +8523,7 @@

    Usage

    @@ -8535,7 +8572,7 @@

    Usage

    @@ -8578,7 +8615,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8615,7 +8652,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8657,7 +8694,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8698,7 +8735,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8744,7 +8781,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8772,7 +8809,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8800,7 +8837,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8828,7 +8865,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9186,187 +9223,187 @@

    Table of Contents

    - Level 3 = Content Negotiation + HATEOAS + Level 3 - Hypermedia Controls 58 - Media Types + Level 3 = Content Negotiation + HATEOAS 59 - Content Type Negotiation + Media Types 60 - HATEOAS + Content Type Negotiation 61 - PHP Autoloading + HATEOAS 62 - Why Is It Necessary? + PHP Autoloading 63 - The require() Way + Why Is It Necessary? 64 - The require_once() Way + The require() Way 65 - Working With Multiple Files + The require_once() Way 66 - Rethinking The Way You Load Classes + Working With Multiple Files 67 - Examples + Rethinking The Way You Load Classes 68 - Under The Hood + Examples 69 - Leveraging PHP APIs + Under The Hood 70 - Built-in Interfaces + Leveraging PHP APIs 71 - The Reflection API (1/2) + Built-in Interfaces 72 - The Reflection API (2/2) + The Reflection API (1/2) 73 - The Standard PHP Library (SPL) + The Reflection API (2/2) 74 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 75 - Observer Pattern (2/2) + Observer Pattern (1/2) 76 - Exceptions (1/2) + Observer Pattern (2/2) 77 - Exceptions (2/2) + Exceptions (1/2) 78 - Password Hashing + Exceptions (2/2) 79 - PHP Archive (PHAR) + Password Hashing 80 - Dependency Management + PHP Archive (PHAR) 81 - Composer + Dependency Management 82 - composer install + Composer 83 - Composer Autoloader + composer install 84 - Model View Controller + Composer Autoloader 85 - MVC Overview + Model View Controller 86 - The Model + MVC Overview 87 - The View + The Model 88 @@ -9384,55 +9421,55 @@

    Table of Contents

    - The Controller + The View 91 - Routing + The Controller 92 - Front Controller Pattern + Routing 93 - Databases + Front Controller Pattern 94 - Agenda + Databases 95 - Quick note + Agenda 96 - Database Design Patterns + Quick note 97 - Row Data Gateway + Database Design Patterns 98 - Row Data Gateway + Row Data Gateway 99 @@ -9450,13 +9487,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 102 - Table Data Gateway + Table Data Gateway 103 @@ -9492,13 +9529,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 109 - Active Record + Active Record 110 @@ -9510,13 +9547,13 @@

    Table of Contents

    - Data Mapper + Active Record 112 - Data Mapper + Data Mapper 113 @@ -9528,31 +9565,31 @@

    Table of Contents

    - Identity Map + Data Mapper 115 - Identity Map + Identity Map 116 - Data Access Layer + Identity Map 117 - Data Access Layer / Data Source Name + Data Access Layer 118 - Data Access Layer + Data Access Layer / Data Source Name 119 @@ -9570,67 +9607,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 122 - Object Relational Mapping (1/4) + Object Relational Mapping 123 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 124 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 125 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 126 - Existing Components + Object Relational Mapping (4/4) 127 - A Note About
    Domain-Driven Design
    + Existing Components 128 - Entities + A Note About
    Domain-Driven Design
    129 - Value Objects + Entities 130 - The Repository Pattern + Value Objects 131 - The Repository Pattern + The Repository Pattern 132 @@ -9642,25 +9679,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 134 - The Specification Pattern + The Specification Pattern 135 - Repository ♥ Specification + The Specification Pattern 136 - Combine Them! + Repository ♥ Specification 137 @@ -9672,169 +9709,169 @@

    Table of Contents

    - Specification For Business Rules + Combine Them! 139 - Sessions + Specification For Business Rules 140 - Overview + Sessions 141 - Code Please + Overview 142 - Security Concerns + Code Please 143 - Session Configuration + Security Concerns 144 - Authentication + Session Configuration 145 - What You Have Right Now + Authentication 146 - The Big Picture + What You Have Right Now 147 - The Interceptor Pattern + The Big Picture 148 - Introducing the Event Dispatcher + The Interceptor Pattern 149 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 150 - The Firewall (1/2) + Using the EventDispatcherTrait 151 - The Firewall (2/2) + The Firewall (1/2) 152 - Implementing The Firewall + The Firewall (2/2) 153 - Authentication Mechanism + Implementing The Firewall 154 - Adding New Routes + Authentication Mechanism 155 - Stateless Authentication + Adding New Routes 156 - Basic Security Thinking + Stateless Authentication 157 - Writing Better Code + Basic Security Thinking 158 - Agenda + Writing Better Code 159 - Coding Standards + Agenda 160 - PHP Coding Standards Fixer + Coding Standards 161 - Programming To The Interface + PHP Coding Standards Fixer 162 - Dependency Inversion Principle (DIP) + Programming To The Interface 163 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 164 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 165 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 166 @@ -9852,19 +9889,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 169 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 170 - PHP Implementations + Dependency Injection Container (DIC) 171 @@ -9876,47 +9913,53 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 173 - From STUPID to SOLID code! (1/2) + Component Driven Development 174 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 175 - Object Calisthenics + From STUPID to SOLID code! (2/2) 176 - - + Object Calisthenics 177 - Next Week:
    Web Security 101
    + - 178 - The End. + Next Week:
    Web Security 101
    179 + + The End. + 180 + + + From fd1e40d5fd3aafe579406d3c82dc107eaec53d16 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 3 Feb 2014 10:09:09 +0100 Subject: [PATCH 37/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?= =?UTF-8?q?=202014=2010:09:09=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 2 +- isima.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 8bcf264..5ffe0a6 100644 --- a/index.html +++ b/index.html @@ -3449,7 +3449,7 @@

    5xx Server Error



    -

    +

    diff --git a/isima.html b/isima.html index 251208b..a05fb9a 100644 --- a/isima.html +++ b/isima.html @@ -3621,7 +3621,7 @@

    5xx Server Error



    -

    +

    From aa67802cd813586b69e970262d98d12b17a34f63 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 3 Feb 2014 10:31:29 +0100 Subject: [PATCH 38/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?= =?UTF-8?q?=202014=2010:31:29=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 3 +-- isima.html | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 5ffe0a6..537d506 100644 --- a/index.html +++ b/index.html @@ -3448,7 +3448,6 @@

    5xx Server Error

  • Hypermedia formats

  • -

    @@ -6944,7 +6943,7 @@

    Doctrine2 ORM

    -

    The Specification Pattern

    +

    The Specification Pattern

    diff --git a/isima.html b/isima.html index a05fb9a..1334750 100644 --- a/isima.html +++ b/isima.html @@ -3620,7 +3620,6 @@

    5xx Server Error

  • Hypermedia formats

  • -

    @@ -6918,7 +6917,7 @@

    Doctrine2 ORM

    -

    The Specification Pattern

    +

    The Specification Pattern

    From 3592edcbea16d7df02d4b784f1deb9015f05c7dc Mon Sep 17 00:00:00 2001 From: William DURAND Date: Mon, 3 Feb 2014 10:35:31 +0100 Subject: [PATCH 39/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?= =?UTF-8?q?=202014=2010:35:31=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 537d506..7062627 100644 --- a/index.html +++ b/index.html @@ -9590,12 +9590,11 @@

    StoryBDD

    Filesystem abstraction layer.

    -
    use League\Flysystem\Filesystem;
    -use League\Flysystem\Adapter\Local as LocalAdapter;
    +
    use League\Flysystem as F
     
     // Adapters: Local, Amazon Web Services - S3, Rackspace Cloud Files,
     //           Dropbox, Ftp, Sftp, Zip, WebDAV
    -$filesystem = new Filesystem(new LocalAdapter(__DIR__ . '/path/to/root'));
    +$filesystem = new F\Filesystem(new F\Adapter\Local(__DIR__.'/path/to/dir'));
     
     // Create a file
     $filesystem->write('path/to/file.txt', 'contents');
    
    From 3b2319607bf9e307ddb97db4c379e4188f7b9fc9 Mon Sep 17 00:00:00 2001
    From: William DURAND 
    Date: Mon, 3 Feb 2014 11:25:21 +0100
    Subject: [PATCH 40/71] =?UTF-8?q?Publish=20slides=20(Lun=20=203=20f=C3=A9v?=
     =?UTF-8?q?=202014=2011:25:21=20CET)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     index.html | 528 +++++++++++++++++++++++++++++------------------------
     1 file changed, 289 insertions(+), 239 deletions(-)
    
    diff --git a/index.html b/index.html
    index 7062627..08f4884 100644
    --- a/index.html
    +++ b/index.html
    @@ -1212,7 +1212,7 @@
                 
                 
                 
               
             
    @@ -1240,7 +1240,7 @@
    @@ -1291,7 +1291,7 @@
    @@ -1319,7 +1319,7 @@ @@ -1358,7 +1358,7 @@

    Week #4

    @@ -1386,7 +1386,7 @@

    Week #4

    @@ -1421,7 +1421,7 @@

    Week #4

    @@ -1457,7 +1457,7 @@

    Week #4

    @@ -1493,7 +1493,7 @@

    Week #4

    @@ -1527,7 +1527,7 @@

    Week #4

    @@ -1562,7 +1562,7 @@

    Week #4

    @@ -1590,7 +1590,7 @@

    Week #4

    @@ -1618,7 +1618,7 @@

    Week #4

    @@ -1656,7 +1656,7 @@

    Week #4

    @@ -1705,7 +1705,7 @@

    Week #4

    @@ -1756,7 +1756,7 @@

    Week #4

    @@ -1799,7 +1799,7 @@

    Abstract class definition

    @@ -1851,7 +1851,7 @@

    Abstract class definition

    @@ -1890,7 +1890,7 @@

    The Rules

    @@ -1943,7 +1943,7 @@

    The Rules

    @@ -1994,7 +1994,7 @@

    Type Hinting

    @@ -2039,7 +2039,7 @@

    Usage

    @@ -2087,7 +2087,7 @@

    Usage

    @@ -2135,7 +2135,7 @@

    Usage

    @@ -2194,7 +2194,7 @@

    Usage

    @@ -2238,7 +2238,7 @@

    Usage

    @@ -2290,7 +2290,7 @@

    Usage

    @@ -2338,7 +2338,7 @@

    PSR-0

    @@ -2385,7 +2385,7 @@

    PSR-0

    @@ -2437,7 +2437,7 @@

    PSR-0

    @@ -2480,7 +2480,7 @@

    PSR-0

    @@ -2526,7 +2526,7 @@

    PSR-0

    @@ -2569,7 +2569,7 @@

    PSR-0

    @@ -2610,7 +2610,7 @@

    PSR-0

    @@ -2638,7 +2638,7 @@

    PSR-0

    @@ -2690,7 +2690,7 @@

    PSR-0

    @@ -2738,7 +2738,7 @@

    PSR-0

    @@ -2790,7 +2790,7 @@

    PSR-0

    @@ -2818,7 +2818,7 @@

    PSR-0

    @@ -2858,7 +2858,7 @@

    PSR-0

    @@ -2902,7 +2902,7 @@

    Collections

    @@ -2947,7 +2947,7 @@

    Collections

    @@ -2987,7 +2987,7 @@

    Collections

    @@ -3037,7 +3037,7 @@

    Collections

    @@ -3079,7 +3079,7 @@

    3xx Redirections

    @@ -3123,7 +3123,7 @@

    5xx Server Error

    @@ -3166,7 +3166,7 @@

    5xx Server Error

    @@ -3216,7 +3216,7 @@

    5xx Server Error

    @@ -3244,7 +3244,7 @@

    5xx Server Error

    @@ -3285,7 +3285,7 @@

    5xx Server Error

    @@ -3317,7 +3317,7 @@

    5xx Server Error

    @@ -3354,7 +3354,7 @@

    5xx Server Error

    @@ -3391,7 +3391,7 @@

    5xx Server Error

    @@ -3428,7 +3428,7 @@

    5xx Server Error

    @@ -3464,7 +3464,7 @@

    5xx Server Error

    @@ -3492,7 +3492,7 @@

    5xx Server Error

    @@ -3544,7 +3544,7 @@

    Hyper Media Types

    @@ -3596,7 +3596,7 @@

    Hyper Media Types

    @@ -3648,7 +3648,7 @@

    Hyper Media Types

    @@ -3676,7 +3676,7 @@

    Hyper Media Types

    @@ -3725,7 +3725,7 @@

    Hyper Media Types

    @@ -3775,7 +3775,7 @@

    Hyper Media Types

    @@ -3822,7 +3822,7 @@

    Hyper Media Types

    @@ -3871,7 +3871,7 @@

    Hyper Media Types

    @@ -3910,7 +3910,7 @@

    spl_autoload_functions()

    @@ -3959,7 +3959,7 @@

    spl_autoload_unregister()

    @@ -4014,7 +4014,7 @@

    spl_autoload_unregister()

    @@ -4042,7 +4042,7 @@

    spl_autoload_unregister()

    @@ -4087,7 +4087,7 @@

    Traversable

    @@ -4138,7 +4138,7 @@

    Traversable

    @@ -4189,7 +4189,7 @@

    Traversable

    @@ -4231,7 +4231,7 @@

    SPL Functions

    @@ -4284,7 +4284,7 @@

    SPL Functions

    @@ -4333,7 +4333,7 @@

    SPL Functions

    @@ -4382,7 +4382,7 @@

    SPL Functions

    @@ -4422,7 +4422,7 @@

    SPL Functions

    @@ -4473,7 +4473,7 @@

    SPL Functions

    @@ -4515,7 +4515,7 @@

    SPL Functions

    @@ -4543,7 +4543,7 @@

    SPL Functions

    @@ -4587,7 +4587,7 @@

    SPL Functions

    @@ -4637,7 +4637,7 @@

    SPL Functions

    @@ -4680,7 +4680,7 @@

    SPL Functions

    @@ -4728,7 +4728,7 @@

    SPL Functions

    @@ -4778,7 +4778,7 @@

    SPL Functions

    @@ -4825,7 +4825,7 @@

    Execution

    @@ -4878,7 +4878,7 @@

    Usage

    @@ -4906,7 +4906,7 @@

    Usage

    @@ -4949,7 +4949,7 @@

    Usage

    @@ -4997,7 +4997,7 @@

    Usage

    @@ -5050,7 +5050,7 @@

    Usage

    @@ -5097,7 +5097,7 @@

    Usage

    @@ -5146,7 +5146,7 @@

    Usage

    @@ -5198,7 +5198,7 @@

    Usage

    @@ -5241,7 +5241,7 @@

    Centralized Declaration

    @@ -5274,7 +5274,7 @@

    Centralized Declaration

    @@ -5302,7 +5302,7 @@

    Centralized Declaration

    @@ -5338,7 +5338,7 @@

    Centralized Declaration

    @@ -5373,7 +5373,7 @@

    Centralized Declaration

    @@ -5414,7 +5414,7 @@

    Centralized Declaration

    @@ -5442,7 +5442,7 @@

    Centralized Declaration

    @@ -5496,7 +5496,7 @@

    Centralized Declaration

    @@ -5542,7 +5542,7 @@

    Centralized Declaration

    @@ -5589,7 +5589,7 @@

    Centralized Declaration

    @@ -5617,7 +5617,7 @@

    Centralized Declaration

    @@ -5665,7 +5665,7 @@

    CRUD

    @@ -5712,7 +5712,7 @@

    CRUD

    @@ -5760,7 +5760,7 @@

    CRUD

    @@ -5812,7 +5812,7 @@

    CRUD

    @@ -5857,7 +5857,7 @@

    CRUD

    @@ -5904,7 +5904,7 @@

    CRUD

    @@ -5932,7 +5932,7 @@

    CRUD

    @@ -5979,7 +5979,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6034,7 +6034,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6062,7 +6062,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6115,7 +6115,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6164,7 +6164,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6192,7 +6192,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6239,7 +6239,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6267,7 +6267,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6310,7 +6310,7 @@

    PHP Data Object (PDO)

    @@ -6359,7 +6359,7 @@

    Usage

    @@ -6413,7 +6413,7 @@

    Usage

    @@ -6460,7 +6460,7 @@

    Usage

    @@ -6488,7 +6488,7 @@

    Usage

    @@ -6525,7 +6525,7 @@

    Usage

    @@ -6561,7 +6561,7 @@

    Code Snippet

    @@ -6597,7 +6597,7 @@

    Code Snippet

    @@ -6639,7 +6639,7 @@

    Code Snippet

    @@ -6679,7 +6679,7 @@

    Doctrine2 ORM

    @@ -6707,7 +6707,7 @@

    Doctrine2 ORM

    @@ -6761,7 +6761,7 @@

    Doctrine2 ORM

    @@ -6816,7 +6816,7 @@

    Doctrine2 ORM

    @@ -6844,7 +6844,7 @@

    Doctrine2 ORM

    @@ -6893,7 +6893,7 @@

    Doctrine2 ORM

    @@ -6932,7 +6932,7 @@

    Doctrine2 ORM

    @@ -6960,7 +6960,7 @@

    Doctrine2 ORM

    @@ -7016,7 +7016,7 @@

    Doctrine2 ORM

    @@ -7062,7 +7062,7 @@

    Usage

    @@ -7121,7 +7121,7 @@

    Usage

    @@ -7177,7 +7177,7 @@

    Usage

    @@ -7225,7 +7225,7 @@

    Usage

    @@ -7253,7 +7253,7 @@

    Usage

    @@ -7296,7 +7296,7 @@

    A few use cases:

    @@ -7345,7 +7345,7 @@

    A few use cases:

    @@ -7389,7 +7389,7 @@

    Workarounds

    @@ -7441,7 +7441,7 @@

    Workarounds

    @@ -7469,7 +7469,7 @@

    Workarounds

    @@ -7502,7 +7502,7 @@

    Workarounds

    @@ -7533,7 +7533,7 @@

    Workarounds

    @@ -7574,7 +7574,7 @@

    Event Dispatcher

    @@ -7622,7 +7622,7 @@

    Event Dispatcher

    @@ -7674,7 +7674,7 @@

    Event Dispatcher

    @@ -7718,7 +7718,7 @@

    Event Dispatcher

    @@ -7758,7 +7758,7 @@

    Event Dispatcher

    @@ -7815,7 +7815,7 @@

    Event Dispatcher

    @@ -7846,7 +7846,7 @@

    Event Dispatcher

    @@ -7903,7 +7903,7 @@

    Event Dispatcher

    @@ -7939,7 +7939,7 @@

    WSSE Username Token

    @@ -7983,7 +7983,7 @@

    WSSE Username Token

    @@ -8011,7 +8011,7 @@

    WSSE Username Token

    @@ -8051,7 +8051,7 @@

    WSSE Username Token

    @@ -8108,7 +8108,7 @@

    WSSE Username Token

    @@ -8152,7 +8152,7 @@

    Usage

    @@ -8197,7 +8197,7 @@

    Usage

    @@ -8235,7 +8235,7 @@

    Usage

    @@ -8285,7 +8285,7 @@

    Usage

    @@ -8339,7 +8339,7 @@

    Usage

    @@ -8381,7 +8381,7 @@

    Usage

    @@ -8423,7 +8423,7 @@

    Usage

    @@ -8472,7 +8472,7 @@

    Usage

    @@ -8505,7 +8505,7 @@

    Usage

    @@ -8548,7 +8548,7 @@

    Usage

    @@ -8597,7 +8597,7 @@

    Usage

    @@ -8640,7 +8640,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8677,7 +8677,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8719,7 +8719,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8760,7 +8760,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8806,7 +8806,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8834,7 +8834,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8862,7 +8862,43 @@

    The Symfony2 DependencyInjection Component

    + + + + + +
    +
    +
    + +

    +
    + + +
    +

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -8896,7 +8932,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8924,7 +8960,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8970,7 +9006,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9018,7 +9054,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9057,7 +9093,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9107,7 +9143,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9135,7 +9171,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9172,7 +9208,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9200,7 +9236,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9243,7 +9279,7 @@

    StoryBDD

    @@ -9289,7 +9325,7 @@

    StoryBDD

    @@ -9337,7 +9373,7 @@

    StoryBDD

    @@ -9390,7 +9426,7 @@

    StoryBDD

    @@ -9418,7 +9454,7 @@

    StoryBDD

    @@ -9465,7 +9501,7 @@

    StoryBDD

    @@ -9520,7 +9556,7 @@

    StoryBDD

    @@ -9575,7 +9611,7 @@

    StoryBDD

    @@ -9631,7 +9667,7 @@

    StoryBDD

    @@ -9689,7 +9725,7 @@

    StoryBDD

    @@ -9742,7 +9778,7 @@

    Fallback to Default Value If Not Available

    @@ -9799,7 +9835,7 @@

    Fallback to Default Value If Not Available

    @@ -9831,7 +9867,7 @@

    Fallback to Default Value If Not Available

    @@ -9887,7 +9923,7 @@

    Fallback to Default Value If Not Available

    @@ -9922,7 +9958,7 @@

    Fallback to Default Value If Not Available

    @@ -9950,7 +9986,7 @@

    Fallback to Default Value If Not Available

    @@ -9978,7 +10014,7 @@

    Fallback to Default Value If Not Available

    @@ -10006,7 +10042,7 @@

    Fallback to Default Value If Not Available

    @@ -10034,7 +10070,7 @@

    Fallback to Default Value If Not Available

    @@ -10074,7 +10110,7 @@

    Fallback to Default Value If Not Available

    @@ -10102,7 +10138,7 @@

    Fallback to Default Value If Not Available

    @@ -10130,7 +10166,7 @@

    Fallback to Default Value If Not Available

    @@ -11226,13 +11262,21 @@

    Table of Contents

    - Agenda + +
    + + +
    + 181 - Unit Testing + Agenda 182 @@ -11244,25 +11288,25 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 184 - PHPUnit — Assertions + PHPUnit — The Rules 185 - Running PHPUnit + PHPUnit — Assertions 186 - Functional Testing + Running PHPUnit 187 @@ -11274,7 +11318,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 189 @@ -11286,131 +11330,137 @@

    Table of Contents

    - Behat + Behavior Driven Development 191 - Using Behat (1/2) + Behat 192 - Using Behat (2/2) + Using Behat (1/2) 193 - Awesome Projects + Using Behat (2/2) 194 - Assert + Awesome Projects 195 - Carbon + Assert 196 - Faker + Carbon 197 - Flysystem + Faker 198 - Mockery + Flysystem 199 - Option Type for PHP + Mockery 200 - PHP-Parser + Option Type for PHP 201 -
    React
    + PHP-Parser 202 - Swiftmailer +
    React
    203 - Whoops + Swiftmailer 204 - Embracing Open Source + Whoops 205 - + Embracing Open Source 206 - + 207 - + 208 - Golden Rules + 209 - The End. + Golden Rules 210 - Well... Maybe Not.
    PHP Extended + The End. 211 + + Well... Maybe Not.
    PHP Extended + 212 + + + From 8554803b26058d63833b1c678e5c86f49d497b1e Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 4 Feb 2014 09:32:55 +0100 Subject: [PATCH 41/71] =?UTF-8?q?Publish=20slides=20(Mar=20=204=20f=C3=A9v?= =?UTF-8?q?=202014=2009:32:55=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 520 +++++++++++++++++++++++++++++------------------------ 1 file changed, 285 insertions(+), 235 deletions(-) diff --git a/index.html b/index.html index 08f4884..1b926fa 100644 --- a/index.html +++ b/index.html @@ -1212,7 +1212,7 @@ @@ -1240,7 +1240,7 @@ @@ -1291,7 +1291,7 @@ @@ -1319,7 +1319,7 @@ @@ -1358,7 +1358,7 @@

    Week #4

    @@ -1386,7 +1386,7 @@

    Week #4

    @@ -1421,7 +1421,7 @@

    Week #4

    @@ -1457,7 +1457,7 @@

    Week #4

    @@ -1493,7 +1493,7 @@

    Week #4

    @@ -1527,7 +1527,7 @@

    Week #4

    @@ -1562,7 +1562,7 @@

    Week #4

    @@ -1590,7 +1590,7 @@

    Week #4

    @@ -1618,7 +1618,7 @@

    Week #4

    @@ -1656,7 +1656,7 @@

    Week #4

    @@ -1705,7 +1705,7 @@

    Week #4

    @@ -1756,7 +1756,7 @@

    Week #4

    @@ -1799,7 +1799,7 @@

    Abstract class definition

    @@ -1851,7 +1851,7 @@

    Abstract class definition

    @@ -1890,7 +1890,7 @@

    The Rules

    @@ -1943,7 +1943,7 @@

    The Rules

    @@ -1994,7 +1994,7 @@

    Type Hinting

    @@ -2039,7 +2039,7 @@

    Usage

    @@ -2087,7 +2087,7 @@

    Usage

    @@ -2135,7 +2135,7 @@

    Usage

    @@ -2194,7 +2194,7 @@

    Usage

    @@ -2238,7 +2238,7 @@

    Usage

    @@ -2290,7 +2290,7 @@

    Usage

    @@ -2338,7 +2338,7 @@

    PSR-0

    @@ -2385,7 +2385,7 @@

    PSR-0

    @@ -2437,7 +2437,7 @@

    PSR-0

    @@ -2480,7 +2480,7 @@

    PSR-0

    @@ -2526,7 +2526,7 @@

    PSR-0

    @@ -2569,7 +2569,7 @@

    PSR-0

    @@ -2610,7 +2610,7 @@

    PSR-0

    @@ -2638,7 +2638,7 @@

    PSR-0

    @@ -2690,7 +2690,7 @@

    PSR-0

    @@ -2738,7 +2738,7 @@

    PSR-0

    @@ -2790,7 +2790,7 @@

    PSR-0

    @@ -2818,7 +2818,7 @@

    PSR-0

    @@ -2858,7 +2858,7 @@

    PSR-0

    @@ -2902,7 +2902,7 @@

    Collections

    @@ -2947,7 +2947,7 @@

    Collections

    @@ -2987,7 +2987,7 @@

    Collections

    @@ -3037,7 +3037,7 @@

    Collections

    @@ -3079,7 +3079,7 @@

    3xx Redirections

    @@ -3123,7 +3123,7 @@

    5xx Server Error

    @@ -3166,7 +3166,7 @@

    5xx Server Error

    @@ -3216,7 +3216,7 @@

    5xx Server Error

    @@ -3244,7 +3244,7 @@

    5xx Server Error

    @@ -3285,7 +3285,7 @@

    5xx Server Error

    @@ -3317,7 +3317,7 @@

    5xx Server Error

    @@ -3354,7 +3354,7 @@

    5xx Server Error

    @@ -3391,7 +3391,7 @@

    5xx Server Error

    @@ -3428,7 +3428,7 @@

    5xx Server Error

    @@ -3464,7 +3464,7 @@

    5xx Server Error

    @@ -3492,7 +3492,7 @@

    5xx Server Error

    @@ -3544,7 +3544,7 @@

    Hyper Media Types

    @@ -3596,7 +3596,7 @@

    Hyper Media Types

    @@ -3648,7 +3648,7 @@

    Hyper Media Types

    @@ -3676,7 +3676,7 @@

    Hyper Media Types

    @@ -3725,7 +3725,7 @@

    Hyper Media Types

    @@ -3775,7 +3775,7 @@

    Hyper Media Types

    @@ -3822,7 +3822,7 @@

    Hyper Media Types

    @@ -3871,7 +3871,7 @@

    Hyper Media Types

    @@ -3910,7 +3910,7 @@

    spl_autoload_functions()

    @@ -3959,7 +3959,7 @@

    spl_autoload_unregister()

    @@ -4014,7 +4014,7 @@

    spl_autoload_unregister()

    @@ -4042,7 +4042,7 @@

    spl_autoload_unregister()

    @@ -4087,7 +4087,7 @@

    Traversable

    @@ -4138,7 +4138,7 @@

    Traversable

    @@ -4189,7 +4189,7 @@

    Traversable

    @@ -4231,7 +4231,7 @@

    SPL Functions

    @@ -4284,7 +4284,7 @@

    SPL Functions

    @@ -4333,7 +4333,7 @@

    SPL Functions

    @@ -4382,7 +4382,7 @@

    SPL Functions

    @@ -4422,7 +4422,7 @@

    SPL Functions

    @@ -4473,7 +4473,7 @@

    SPL Functions

    @@ -4515,7 +4515,7 @@

    SPL Functions

    @@ -4543,7 +4543,7 @@

    SPL Functions

    @@ -4587,7 +4587,7 @@

    SPL Functions

    @@ -4637,7 +4637,7 @@

    SPL Functions

    @@ -4680,7 +4680,7 @@

    SPL Functions

    @@ -4728,7 +4728,7 @@

    SPL Functions

    @@ -4778,7 +4778,7 @@

    SPL Functions

    @@ -4825,7 +4825,7 @@

    Execution

    @@ -4878,7 +4878,7 @@

    Usage

    @@ -4906,7 +4906,7 @@

    Usage

    @@ -4949,7 +4949,7 @@

    Usage

    @@ -4997,7 +4997,7 @@

    Usage

    @@ -5050,7 +5050,7 @@

    Usage

    @@ -5097,7 +5097,7 @@

    Usage

    @@ -5146,7 +5146,7 @@

    Usage

    @@ -5198,7 +5198,7 @@

    Usage

    @@ -5241,7 +5241,7 @@

    Centralized Declaration

    @@ -5274,7 +5274,7 @@

    Centralized Declaration

    @@ -5302,7 +5302,7 @@

    Centralized Declaration

    @@ -5338,7 +5338,7 @@

    Centralized Declaration

    @@ -5373,7 +5373,7 @@

    Centralized Declaration

    @@ -5414,7 +5414,7 @@

    Centralized Declaration

    @@ -5442,7 +5442,7 @@

    Centralized Declaration

    @@ -5496,7 +5496,7 @@

    Centralized Declaration

    @@ -5542,7 +5542,7 @@

    Centralized Declaration

    @@ -5589,7 +5589,7 @@

    Centralized Declaration

    @@ -5617,7 +5617,7 @@

    Centralized Declaration

    @@ -5665,7 +5665,7 @@

    CRUD

    @@ -5712,7 +5712,7 @@

    CRUD

    @@ -5760,7 +5760,7 @@

    CRUD

    @@ -5812,7 +5812,7 @@

    CRUD

    @@ -5857,7 +5857,7 @@

    CRUD

    @@ -5904,7 +5904,7 @@

    CRUD

    @@ -5932,7 +5932,7 @@

    CRUD

    @@ -5979,7 +5979,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6034,7 +6034,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6062,7 +6062,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6115,7 +6115,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6164,7 +6164,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6192,7 +6192,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6239,7 +6239,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6267,7 +6267,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6310,7 +6310,7 @@

    PHP Data Object (PDO)

    @@ -6359,7 +6359,7 @@

    Usage

    @@ -6413,7 +6413,7 @@

    Usage

    @@ -6460,7 +6460,7 @@

    Usage

    @@ -6488,7 +6488,7 @@

    Usage

    @@ -6525,7 +6525,7 @@

    Usage

    @@ -6561,7 +6561,7 @@

    Code Snippet

    @@ -6597,7 +6597,7 @@

    Code Snippet

    @@ -6639,7 +6639,7 @@

    Code Snippet

    @@ -6679,7 +6679,7 @@

    Doctrine2 ORM

    @@ -6707,7 +6707,7 @@

    Doctrine2 ORM

    @@ -6761,7 +6761,7 @@

    Doctrine2 ORM

    @@ -6816,7 +6816,7 @@

    Doctrine2 ORM

    @@ -6844,7 +6844,7 @@

    Doctrine2 ORM

    @@ -6893,7 +6893,7 @@

    Doctrine2 ORM

    @@ -6932,7 +6932,7 @@

    Doctrine2 ORM

    @@ -6960,7 +6960,7 @@

    Doctrine2 ORM

    @@ -7016,7 +7016,7 @@

    Doctrine2 ORM

    @@ -7062,7 +7062,7 @@

    Usage

    @@ -7121,7 +7121,7 @@

    Usage

    @@ -7177,7 +7177,7 @@

    Usage

    @@ -7225,7 +7225,7 @@

    Usage

    @@ -7253,7 +7253,7 @@

    Usage

    @@ -7296,7 +7296,7 @@

    A few use cases:

    @@ -7345,7 +7345,7 @@

    A few use cases:

    @@ -7389,7 +7389,7 @@

    Workarounds

    @@ -7441,7 +7441,7 @@

    Workarounds

    @@ -7469,7 +7469,7 @@

    Workarounds

    @@ -7502,7 +7502,7 @@

    Workarounds

    @@ -7533,7 +7533,7 @@

    Workarounds

    @@ -7574,7 +7574,7 @@

    Event Dispatcher

    @@ -7622,7 +7622,7 @@

    Event Dispatcher

    @@ -7674,7 +7674,7 @@

    Event Dispatcher

    @@ -7718,7 +7718,7 @@

    Event Dispatcher

    @@ -7758,7 +7758,7 @@

    Event Dispatcher

    @@ -7815,7 +7815,7 @@

    Event Dispatcher

    @@ -7846,7 +7846,7 @@

    Event Dispatcher

    @@ -7903,7 +7903,7 @@

    Event Dispatcher

    @@ -7939,7 +7939,7 @@

    WSSE Username Token

    @@ -7983,7 +7983,7 @@

    WSSE Username Token

    @@ -8011,7 +8011,7 @@

    WSSE Username Token

    @@ -8051,7 +8051,7 @@

    WSSE Username Token

    @@ -8108,7 +8108,7 @@

    WSSE Username Token

    @@ -8152,7 +8152,7 @@

    Usage

    @@ -8197,7 +8197,7 @@

    Usage

    @@ -8235,7 +8235,7 @@

    Usage

    @@ -8285,7 +8285,7 @@

    Usage

    @@ -8339,7 +8339,7 @@

    Usage

    @@ -8381,7 +8381,7 @@

    Usage

    @@ -8423,7 +8423,7 @@

    Usage

    @@ -8472,7 +8472,7 @@

    Usage

    @@ -8505,7 +8505,7 @@

    Usage

    @@ -8548,7 +8548,7 @@

    Usage

    @@ -8597,7 +8597,7 @@

    Usage

    @@ -8640,7 +8640,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8677,7 +8677,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8719,7 +8719,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8760,7 +8760,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8806,7 +8806,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8834,7 +8834,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8862,7 +8862,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8898,7 +8898,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8932,7 +8932,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8960,7 +8960,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9006,7 +9006,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9054,7 +9054,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9093,7 +9093,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9143,7 +9143,51 @@

    The Symfony2 DependencyInjection Component

    + + + + + +
    +
    +
    + +

    Test Double

    + + +
      +
    • Dummy objects are passed around but never actually used. Usually they are + just used to fill parameter lists;
    • +
    • Fake objects actually have working implementations, but usually take some + shortcut which makes them not suitable for production (an in memory database + is a good example);
    • +
    • Stubs provide canned answers to calls made during the test, usually not + responding at all to anything outside what's programmed in for the test. Stubs + may also record information about calls, such as an email gateway stub that + remembers the messages it 'sent', or maybe only how many messages it 'sent' + → State verification;
    • +
    • Mocks are objects pre-programmed with expectations which form a + specification of the calls they are expected to receive → Behavior + verification.
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    @@ -9171,7 +9215,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9208,7 +9252,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9236,7 +9280,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9279,7 +9323,7 @@

    StoryBDD

    @@ -9325,7 +9369,7 @@

    StoryBDD

    @@ -9373,7 +9417,7 @@

    StoryBDD

    @@ -9426,7 +9470,7 @@

    StoryBDD

    @@ -9454,7 +9498,7 @@

    StoryBDD

    @@ -9501,7 +9545,7 @@

    StoryBDD

    @@ -9556,7 +9600,7 @@

    StoryBDD

    @@ -9611,7 +9655,7 @@

    StoryBDD

    @@ -9667,7 +9711,7 @@

    StoryBDD

    @@ -9725,7 +9769,7 @@

    StoryBDD

    @@ -9778,7 +9822,7 @@

    Fallback to Default Value If Not Available

    @@ -9835,7 +9879,7 @@

    Fallback to Default Value If Not Available

    @@ -9867,7 +9911,7 @@

    Fallback to Default Value If Not Available

    @@ -9923,7 +9967,7 @@

    Fallback to Default Value If Not Available

    @@ -9958,7 +10002,7 @@

    Fallback to Default Value If Not Available

    @@ -9986,7 +10030,7 @@

    Fallback to Default Value If Not Available

    @@ -10014,7 +10058,7 @@

    Fallback to Default Value If Not Available

    @@ -10042,7 +10086,7 @@

    Fallback to Default Value If Not Available

    @@ -10070,7 +10114,7 @@

    Fallback to Default Value If Not Available

    @@ -10110,7 +10154,7 @@

    Fallback to Default Value If Not Available

    @@ -10138,7 +10182,7 @@

    Fallback to Default Value If Not Available

    @@ -10166,7 +10210,7 @@

    Fallback to Default Value If Not Available

    @@ -11312,7 +11356,7 @@

    Table of Contents

    - Functional Testing + Test Double 188 @@ -11324,7 +11368,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 190 @@ -11336,131 +11380,137 @@

    Table of Contents

    - Behat + Behavior Driven Development 192 - Using Behat (1/2) + Behat 193 - Using Behat (2/2) + Using Behat (1/2) 194 - Awesome Projects + Using Behat (2/2) 195 - Assert + Awesome Projects 196 - Carbon + Assert 197 - Faker + Carbon 198 - Flysystem + Faker 199 - Mockery + Flysystem 200 - Option Type for PHP + Mockery 201 - PHP-Parser + Option Type for PHP 202 -
    React
    + PHP-Parser 203 - Swiftmailer +
    React
    204 - Whoops + Swiftmailer 205 - Embracing Open Source + Whoops 206 - + Embracing Open Source 207 - + 208 - + 209 - Golden Rules + 210 - The End. + Golden Rules 211 - Well... Maybe Not.
    PHP Extended + The End. 212 + + Well... Maybe Not.
    PHP Extended + 213 + + + From af5ffe258f581f55794e340dd0fc7ffeae6dd86c Mon Sep 17 00:00:00 2001 From: William DURAND Date: Tue, 4 Feb 2014 14:05:02 +0100 Subject: [PATCH 42/71] =?UTF-8?q?Publish=20slides=20(Mar=20=204=20f=C3=A9v?= =?UTF-8?q?=202014=2014:05:01=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 4 ++-- isima.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 1b926fa..5d30726 100644 --- a/index.html +++ b/index.html @@ -7405,12 +7405,12 @@

    Workarounds

    An example of PHP session configuration that is more secure:

    ; Helps mitigate XSS by telling the browser not to expose the cookie to
    -; client side scripting such as JavaScrip
    +; client side scripting such as JavaScript
     session.cookie_httponly = 1
     
     ; Prevents session fixation by making sure that PHP only uses cookies for
     ; sessions and disallow session ID passing as a GET parameter
    -session.session.use_only_cookies = 1
    +session.use_only_cookies = 1
     
     ; Better entropy source
     ; Evades insufficient entropy vulnerabilities
    diff --git a/isima.html b/isima.html
    index 1334750..9b384e2 100644
    --- a/isima.html
    +++ b/isima.html
    @@ -7379,12 +7379,12 @@ 

    Workarounds

    An example of PHP session configuration that is more secure:

    ; Helps mitigate XSS by telling the browser not to expose the cookie to
    -; client side scripting such as JavaScrip
    +; client side scripting such as JavaScript
     session.cookie_httponly = 1
     
     ; Prevents session fixation by making sure that PHP only uses cookies for
     ; sessions and disallow session ID passing as a GET parameter
    -session.session.use_only_cookies = 1
    +session.use_only_cookies = 1
     
     ; Better entropy source
     ; Evades insufficient entropy vulnerabilities
    
    From 1801670037d507189b258f0278485370a82408a6 Mon Sep 17 00:00:00 2001
    From: William DURAND 
    Date: Wed, 5 Feb 2014 13:25:17 +0100
    Subject: [PATCH 43/71] =?UTF-8?q?Publish=20slides=20(Mer=20=205=20f=C3=A9v?=
     =?UTF-8?q?=202014=2013:25:17=20CET)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     index.html | 6 ++----
     isima.html | 6 ++----
     2 files changed, 4 insertions(+), 8 deletions(-)
    
    diff --git a/index.html b/index.html
    index 5d30726..ac181a5 100644
    --- a/index.html
    +++ b/index.html
    @@ -5164,10 +5164,8 @@ 

    Usage

    It should not contain any business logic.

    class BananaController
     {
    -    public function __construct(
    -        BananaMapper $mapper,
    -        TemplateEngine $engine
    -    ) {
    +    public function __construct(BananaMapper $mapper, TemplateEngine $engine)
    +    {
             $this->mapper = $mapper;
             $this->engine = $engine;
         }
    diff --git a/isima.html b/isima.html
    index 9b384e2..a7949c7 100644
    --- a/isima.html
    +++ b/isima.html
    @@ -5138,10 +5138,8 @@ 

    Usage

    It should not contain any business logic.

    class BananaController
     {
    -    public function __construct(
    -        BananaMapper $mapper,
    -        TemplateEngine $engine
    -    ) {
    +    public function __construct(BananaMapper $mapper, TemplateEngine $engine)
    +    {
             $this->mapper = $mapper;
             $this->engine = $engine;
         }
    
    From 189668f2889d565c1cbe5039f3a4c68e3e269630 Mon Sep 17 00:00:00 2001
    From: William DURAND 
    Date: Wed, 5 Feb 2014 16:41:14 +0100
    Subject: [PATCH 44/71] =?UTF-8?q?Publish=20slides=20(Mer=20=205=20f=C3=A9v?=
     =?UTF-8?q?=202014=2016:41:14=20CET)?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     index.html | 2 +-
     isima.html | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/index.html b/index.html
    index ac181a5..c92066c 100644
    --- a/index.html
    +++ b/index.html
    @@ -5223,7 +5223,7 @@ 

    Centralized Declaration

    Modern frameworks provide a routing component such as the Symfony2 Routing component allowing to define routes in a centralized place, and easing URI generation.

    -

    This require a single entry point: the Frontend Controller.

    +

    This require a single entry point: the Front Controller.

    diff --git a/isima.html b/isima.html index a7949c7..e681d78 100644 --- a/isima.html +++ b/isima.html @@ -5197,7 +5197,7 @@

    Centralized Declaration

    Modern frameworks provide a routing component such as the Symfony2 Routing component allowing to define routes in a centralized place, and easing URI generation.

    -

    This require a single entry point: the Frontend Controller.

    +

    This require a single entry point: the Front Controller.

    From 8f0405c02ecdde6c2a0ca3246b7e2eb604fca7e2 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Fri, 7 Feb 2014 00:51:27 +0100 Subject: [PATCH 45/71] =?UTF-8?q?Publish=20slides=20(Ven=20=207=20f=C3=A9v?= =?UTF-8?q?=202014=2000:51:27=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 7 +++++-- isima.html | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index c92066c..5f0bc24 100644 --- a/index.html +++ b/index.html @@ -2592,7 +2592,7 @@

    PSR-0

  • http://www.php.net/manual/en/language.generators.php;
  • What Generators Can Do For You;
  • -
  • https://github.com/nikic/iter (exemples).
  • +
  • https://github.com/nikic/iter (examples).
  • @@ -3148,7 +3148,9 @@

    5xx Server Error

    You can always use the following, but you need to parse them by yourself:

    • query string: $_SERVER['QUERY_STRING'];
    • -
    • request body: $HTTP_RAW_POST_DATA.
    • +
    • request body: $HTTP_RAW_POST_DATA + (deprecated, + do not use).

    Note: Don't use $_REQUEST, as there is a collision risk!

    @@ -4759,6 +4761,7 @@

    SPL Functions

    InputInterface $input, OutputInterface $output ) { + // do greet } }
    diff --git a/isima.html b/isima.html index e681d78..e8cc5e2 100644 --- a/isima.html +++ b/isima.html @@ -2764,7 +2764,7 @@

    PSR-0

  • http://www.php.net/manual/en/language.generators.php;
  • What Generators Can Do For You;
  • -
  • https://github.com/nikic/iter (exemples).
  • +
  • https://github.com/nikic/iter (examples).
  • @@ -3320,7 +3320,9 @@

    5xx Server Error

    You can always use the following, but you need to parse them by yourself:

    • query string: $_SERVER['QUERY_STRING'];
    • -
    • request body: $HTTP_RAW_POST_DATA.
    • +
    • request body: $HTTP_RAW_POST_DATA + (deprecated, + do not use).

    Note: Don't use $_REQUEST, as there is a collision risk!

    From 8ff76ea9271ba79ad59ff62866f32012bce105b7 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Fri, 7 Feb 2014 19:23:06 +0100 Subject: [PATCH 46/71] =?UTF-8?q?Publish=20slides=20(Ven=20=207=20f=C3=A9v?= =?UTF-8?q?=202014=2019:23:06=20CET)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extended.html | 602 ++++++++++++++++++++++++--------- index.html | 909 +++++++++++++++++++++++++++++++++++++------------- isima.html | 777 ++++++++++++++++++++++++++++++------------ 3 files changed, 1695 insertions(+), 593 deletions(-) diff --git a/extended.html b/extended.html index 4f2f064..047f581 100644 --- a/extended.html +++ b/extended.html @@ -1208,7 +1208,9 @@
    @@ -1758,6 +1791,8 @@

    Week #4

    ! $a; // `true` if $a is not `true` $a . 'foo'; // concatenation + +2 ** 3 = 8 // exponentiation (PHP 5.6+)

    But also:

    @@ -1768,6 +1803,9 @@

    Week #4

    $b = 0; $b += 1; // $b = 1 $b -= 1; // $b = 0 + +$c = 2; +$c **= 3; // $c = 8 @@ -1787,7 +1825,7 @@

    Week #4

    @@ -1832,7 +1870,7 @@

    Abstract class definition

    @@ -1886,7 +1924,7 @@

    Abstract class definition

    @@ -1927,7 +1965,7 @@

    The Rules

    @@ -1944,6 +1982,9 @@

    The Rules

    class Foo
     {
         const VALUE = 123;
    +    // PHP 5.6+
    +    const SENTENCE        = 'The value of VALUE is ' . self::VALUE;
    +    const ARRAY_OF_VALUES = ['a', 'b'];
     
         /**
          * @var int
    @@ -1984,7 +2025,7 @@ 

    The Rules

    @@ -2037,7 +2078,7 @@

    Type Hinting

    @@ -2084,7 +2125,7 @@

    Usage

    @@ -2134,7 +2175,7 @@

    Usage

    @@ -2184,7 +2225,7 @@

    Usage

    @@ -2245,7 +2286,7 @@

    Usage

    @@ -2291,7 +2332,54 @@

    Usage

    + + + + + +
    +
    +
    + +

    Variadic Functions

    + + +

    New operator ... as of PHP 5.6:

    +
    function sum(...$numbers)
    +{
    +    return array_sum($numbers);
    +}
    +
    +echo sum(1, 2);
    +// 3
    +
    + +

    Argument Unpacking

    +
    $numbers = [ 2, 3 ];
    +echo sum(1, ...$numbers);
    +// 6
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -2345,7 +2433,7 @@

    Usage

    @@ -2395,7 +2483,7 @@

    PSR-0

    @@ -2444,7 +2532,7 @@

    PSR-0

    @@ -2498,7 +2586,7 @@

    PSR-0

    @@ -2543,7 +2631,7 @@

    PSR-0

    @@ -2591,7 +2679,7 @@

    PSR-0

    @@ -2636,7 +2724,7 @@

    PSR-0

    @@ -2679,7 +2767,7 @@

    PSR-0

    @@ -2709,7 +2797,7 @@

    PSR-0

    @@ -2763,7 +2851,7 @@

    PSR-0

    @@ -2813,7 +2901,7 @@

    PSR-0

    @@ -2867,7 +2955,7 @@

    PSR-0

    @@ -2897,7 +2985,7 @@

    PSR-0

    @@ -2939,7 +3027,7 @@

    PSR-0

    @@ -2985,7 +3073,7 @@

    Collections

    @@ -3032,7 +3120,7 @@

    Collections

    @@ -3074,7 +3162,7 @@

    Collections

    @@ -3126,7 +3214,7 @@

    Collections

    @@ -3170,7 +3258,7 @@

    3xx Redirections

    @@ -3216,7 +3304,7 @@

    5xx Server Error

    @@ -3263,7 +3351,7 @@

    5xx Server Error

    @@ -3315,7 +3403,7 @@

    5xx Server Error

    @@ -3345,7 +3433,7 @@

    5xx Server Error

    @@ -3388,7 +3476,7 @@

    5xx Server Error

    @@ -3422,7 +3510,7 @@

    5xx Server Error

    @@ -3461,7 +3549,7 @@

    5xx Server Error

    @@ -3500,7 +3588,7 @@

    5xx Server Error

    @@ -3539,7 +3627,7 @@

    5xx Server Error

    @@ -3577,7 +3665,7 @@

    5xx Server Error

    @@ -3607,7 +3695,7 @@

    5xx Server Error

    @@ -3661,7 +3749,7 @@

    Hyper Media Types

    @@ -3715,7 +3803,7 @@

    Hyper Media Types

    @@ -3769,7 +3857,7 @@

    Hyper Media Types

    @@ -3799,7 +3887,7 @@

    Hyper Media Types

    @@ -3850,7 +3938,7 @@

    Hyper Media Types

    @@ -3902,7 +3990,7 @@

    Hyper Media Types

    @@ -3951,7 +4039,7 @@

    Hyper Media Types

    @@ -4002,7 +4090,7 @@

    Hyper Media Types

    @@ -4043,7 +4131,7 @@

    spl_autoload_functions()

    @@ -4094,7 +4182,7 @@

    spl_autoload_unregister()

    @@ -4151,7 +4239,7 @@

    spl_autoload_unregister()

    @@ -4181,7 +4269,7 @@

    spl_autoload_unregister()

    @@ -4228,7 +4316,7 @@

    Traversable

    @@ -4281,7 +4369,7 @@

    Traversable

    @@ -4334,7 +4422,7 @@

    Traversable

    @@ -4378,7 +4466,7 @@

    SPL Functions

    @@ -4433,7 +4521,7 @@

    SPL Functions

    @@ -4484,7 +4572,7 @@

    SPL Functions

    @@ -4535,7 +4623,7 @@

    SPL Functions

    @@ -4577,7 +4665,7 @@

    SPL Functions

    @@ -4630,7 +4718,7 @@

    SPL Functions

    @@ -4674,7 +4762,7 @@

    SPL Functions

    @@ -4704,7 +4792,7 @@

    SPL Functions

    @@ -4750,7 +4838,7 @@

    SPL Functions

    @@ -4802,7 +4890,7 @@

    SPL Functions

    @@ -4847,7 +4935,7 @@

    SPL Functions

    @@ -4897,7 +4985,7 @@

    SPL Functions

    @@ -4950,7 +5038,7 @@

    SPL Functions

    @@ -4999,7 +5087,7 @@

    Execution

    @@ -5054,7 +5142,7 @@

    Usage

    @@ -5084,7 +5172,7 @@

    Usage

    @@ -5129,7 +5217,7 @@

    Usage

    @@ -5179,7 +5267,7 @@

    Usage

    @@ -5234,7 +5322,7 @@

    Usage

    @@ -5283,7 +5371,7 @@

    Usage

    @@ -5334,7 +5422,7 @@

    Usage

    @@ -5388,7 +5476,7 @@

    Usage

    @@ -5433,7 +5521,7 @@

    Centralized Declaration

    @@ -5468,7 +5556,7 @@

    Centralized Declaration

    @@ -5498,7 +5586,7 @@

    Centralized Declaration

    @@ -5536,7 +5624,7 @@

    Centralized Declaration

    @@ -5573,7 +5661,7 @@

    Centralized Declaration

    @@ -5616,7 +5704,7 @@

    Centralized Declaration

    @@ -5646,7 +5734,7 @@

    Centralized Declaration

    @@ -5703,7 +5791,7 @@

    Centralized Declaration

    @@ -5751,7 +5839,7 @@

    Centralized Declaration

    @@ -5800,7 +5888,7 @@

    Centralized Declaration

    @@ -5830,7 +5918,7 @@

    Centralized Declaration

    @@ -5880,7 +5968,7 @@

    CRUD

    @@ -5929,7 +6017,7 @@

    CRUD

    @@ -5979,7 +6067,7 @@

    CRUD

    @@ -6033,7 +6121,7 @@

    CRUD

    @@ -6080,7 +6168,7 @@

    CRUD

    @@ -6129,7 +6217,7 @@

    CRUD

    @@ -6159,7 +6247,7 @@

    CRUD

    @@ -6208,7 +6296,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6265,7 +6353,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6295,7 +6383,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6350,7 +6438,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6397,7 +6485,7 @@

    Remove

    @@ -6427,7 +6515,7 @@

    Remove

    @@ -6476,7 +6564,7 @@

    Remove

    @@ -6506,7 +6594,7 @@

    Remove

    @@ -6551,7 +6639,7 @@

    PHP Data Object (PDO)

    @@ -6602,7 +6690,7 @@

    Usage

    @@ -6658,7 +6746,7 @@

    Usage

    @@ -6707,7 +6795,7 @@

    Usage

    @@ -6737,7 +6825,7 @@

    Usage

    @@ -6776,7 +6864,7 @@

    Usage

    @@ -6814,7 +6902,7 @@

    Code Snippet

    @@ -6852,7 +6940,7 @@

    Code Snippet

    @@ -6896,7 +6984,7 @@

    Code Snippet

    @@ -6938,7 +7026,7 @@

    Doctrine2 ORM

    @@ -6968,7 +7056,7 @@

    Doctrine2 ORM

    @@ -7024,7 +7112,7 @@

    Doctrine2 ORM

    @@ -7081,7 +7169,7 @@

    Doctrine2 ORM

    @@ -7111,7 +7199,7 @@

    Doctrine2 ORM

    @@ -7162,7 +7250,7 @@

    Doctrine2 ORM

    @@ -7203,7 +7291,7 @@

    Doctrine2 ORM

    @@ -7233,7 +7321,7 @@

    Doctrine2 ORM

    @@ -7291,7 +7379,7 @@

    Doctrine2 ORM

    @@ -7339,7 +7427,7 @@

    Usage

    @@ -7400,7 +7488,7 @@

    Usage

    @@ -7458,7 +7546,7 @@

    Usage

    @@ -7508,7 +7596,7 @@

    Usage

    @@ -7538,7 +7626,7 @@

    Usage

    @@ -7583,7 +7671,7 @@

    A few use cases:

    @@ -7634,7 +7722,7 @@

    A few use cases:

    @@ -7680,7 +7768,7 @@

    Workarounds

    @@ -7734,7 +7822,7 @@

    Workarounds

    @@ -7764,7 +7852,7 @@

    Workarounds

    @@ -7799,7 +7887,7 @@

    Workarounds

    @@ -7832,7 +7920,7 @@

    Workarounds

    @@ -7875,7 +7963,7 @@

    Event Dispatcher

    @@ -7925,7 +8013,7 @@

    Event Dispatcher

    @@ -7979,7 +8067,7 @@

    Event Dispatcher

    @@ -8025,7 +8113,7 @@

    Event Dispatcher

    @@ -8067,7 +8155,7 @@

    Event Dispatcher

    @@ -8126,7 +8214,7 @@

    Event Dispatcher

    @@ -8159,7 +8247,7 @@

    Event Dispatcher

    @@ -8218,7 +8306,7 @@

    Event Dispatcher

    @@ -8256,7 +8344,7 @@

    WSSE Username Token

    @@ -8302,7 +8390,7 @@

    WSSE Username Token

    @@ -8332,7 +8420,7 @@

    WSSE Username Token

    @@ -8374,7 +8462,7 @@

    WSSE Username Token

    @@ -8433,7 +8521,7 @@

    WSSE Username Token

    @@ -8479,7 +8567,7 @@

    Usage

    @@ -8526,7 +8614,7 @@

    Usage

    @@ -8566,7 +8654,7 @@

    Usage

    @@ -8618,7 +8706,7 @@

    Usage

    @@ -8674,7 +8762,7 @@

    Usage

    @@ -8718,7 +8806,7 @@

    Usage

    @@ -8762,7 +8850,7 @@

    Usage

    @@ -8813,7 +8901,7 @@

    Usage

    @@ -8848,7 +8936,7 @@

    Usage

    @@ -8893,7 +8981,7 @@

    Usage

    @@ -8944,7 +9032,7 @@

    Usage

    @@ -8989,7 +9077,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9028,7 +9116,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9072,7 +9160,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9115,7 +9203,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9163,7 +9251,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9193,7 +9281,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9223,7 +9311,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9261,7 +9349,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9297,7 +9385,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9327,7 +9415,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9375,7 +9463,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9425,7 +9513,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9466,7 +9554,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9518,7 +9606,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9564,7 +9652,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9594,7 +9682,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9633,7 +9721,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9663,7 +9751,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9708,7 +9796,7 @@

    StoryBDD

    @@ -9756,7 +9844,7 @@

    StoryBDD

    @@ -9806,7 +9894,7 @@

    StoryBDD

    @@ -9861,7 +9949,7 @@

    StoryBDD

    @@ -9891,7 +9979,7 @@

    StoryBDD

    @@ -9940,7 +10028,7 @@

    StoryBDD

    @@ -9997,7 +10085,7 @@

    StoryBDD

    @@ -10054,7 +10142,7 @@

    StoryBDD

    @@ -10112,7 +10200,7 @@

    StoryBDD

    @@ -10172,7 +10260,7 @@

    StoryBDD

    @@ -10227,7 +10315,7 @@

    Fallback to Default Value If Not Available

    @@ -10286,7 +10374,7 @@

    Fallback to Default Value If Not Available

    @@ -10320,7 +10408,7 @@

    Fallback to Default Value If Not Available

    @@ -10378,7 +10466,7 @@

    Fallback to Default Value If Not Available

    @@ -10415,7 +10503,7 @@

    Fallback to Default Value If Not Available

    @@ -10445,7 +10533,7 @@

    Fallback to Default Value If Not Available

    @@ -10475,7 +10563,7 @@

    Fallback to Default Value If Not Available

    @@ -10505,7 +10593,7 @@

    Fallback to Default Value If Not Available

    @@ -10535,7 +10623,7 @@

    Fallback to Default Value If Not Available

    @@ -10577,7 +10665,7 @@

    Fallback to Default Value If Not Available

    @@ -10607,7 +10695,7 @@

    Fallback to Default Value If Not Available

    @@ -10637,7 +10725,7 @@

    Fallback to Default Value If Not Available

    @@ -10671,31 +10759,31 @@

    Table of Contents

    - + edu@drnd.me 4 - Agenda + 5 - PHP: Hypertext Preprocessor + Agenda 6 - History & Numbers + PHP: Hypertext Preprocessor 7 - Getting Started + History & Numbers 8 @@ -10713,487 +10801,487 @@

    Table of Contents

    - HHVM + Getting Started 11 - RTFM: http://www.php.net + HHVM 12 - The PHP Syntax + RTFM: http://www.php.net 13 - Primitive Types + The PHP Syntax 14 - Comparison Operators + Primitive Types 15 - Operators + Comparison Operators 16 - Classes (1/2) + Operators 17 - Classes (2/2) + Classes (1/2) 18 - Visibility + Classes (2/2) 19 - Properties + Visibility 20 - Methods (1/3) + Properties 21 - Methods (2/3) + Methods (1/3) 22 - Methods (3/3) + Methods (2/3) 23 - Static Keyword + Methods (3/3) 24 - Late Static Bindings + Static Keyword 25 - Static Keyword + Late Static Bindings 26 - Interfaces + Static Keyword 27 - Namespaces + Variadic Functions 28 - The class Keyword + Interfaces 29 - Traits + Namespaces 30 - Anonymous Functions + The class Keyword 31 - Closures + Traits 32 - Magic Methods + Anonymous Functions 33 - Generators + Closures 34 - The PHP Command Line + Magic Methods 35 - The PHP Command Line (1/2) + Generators 36 - The PHP Command Line (2/2) + The PHP Command Line 37 - Writing a CLI program + The PHP Command Line (1/2) 38 - Client/Server + The PHP Command Line (2/2) 39 - Client/Server Basics + Writing a CLI program 40 - Unified Resource Identifier (URI) + Client/Server 41 - HTTP Request + Client/Server Basics 42 - HTTP Verbs + Unified Resource Identifier (URI) 43 - HTTP Response + HTTP Request 44 - Status Codes (1/2) + HTTP Verbs 45 - Status Codes (2/2) + HTTP Response 46 - HTTP Parameters (1/2) + Status Codes (1/2) 47 - HTTP Parameters (2/2) + Status Codes (2/2) 48 - REST + HTTP Parameters (1/2) 49 - REpresentational State Transfer + HTTP Parameters (2/2) 50 - Richardson Maturity Model + REST 51 - Level 0 - The Swamp of POX + REpresentational State Transfer 52 - Level 1 - Resources + Richardson Maturity Model 53 - Level 2 - HTTP Verbs + Level 0 - The Swamp of POX 54 - Level 3 - Hypermedia Controls + Level 1 - Resources 55 - Level 3 = Content Negotiation + HATEOAS + Level 2 - HTTP Verbs 56 - Media Types + Level 3 - Hypermedia Controls 57 - Content Type Negotiation + Level 3 = Content Negotiation + HATEOAS 58 - HATEOAS + Media Types 59 - PHP Autoloading + Content Type Negotiation 60 - Why Is It Necessary? + HATEOAS 61 - The require() Way + PHP Autoloading 62 - The require_once() Way + Why Is It Necessary? 63 - Working With Multiple Files + The require() Way 64 - Rethinking The Way You Load Classes + The require_once() Way 65 - Examples + Working With Multiple Files 66 - Under The Hood + Rethinking The Way You Load Classes 67 - Leveraging PHP APIs + Examples 68 - Built-in Interfaces + Under The Hood 69 - The Reflection API (1/2) + Leveraging PHP APIs 70 - The Reflection API (2/2) + Built-in Interfaces 71 - The Standard PHP Library (SPL) + The Reflection API (1/2) 72 - Observer Pattern (1/2) + The Reflection API (2/2) 73 - Observer Pattern (2/2) + The Standard PHP Library (SPL) 74 - Exceptions (1/2) + Observer Pattern (1/2) 75 - Exceptions (2/2) + Observer Pattern (2/2) 76 - Password Hashing + Exceptions (1/2) 77 - PHP Archive (PHAR) + Exceptions (2/2) 78 - Dependency Management + Password Hashing 79 - Composer + PHP Archive (PHAR) 80 - composer install + Dependency Management 81 - Composer Autoloader + Composer 82 - Example + composer install 83 - The Symfony2 Console Component + Composer Autoloader 84 - A Basic Command (1/2) + Example 85 - A Basic Command (2/2) + The Symfony2 Console Component 86 - Model View Controller + A Basic Command (1/2) 87 - MVC Overview + A Basic Command (2/2) 88 - The Model + Model View Controller 89 - The View + MVC Overview 90 - The View + The Model 91 @@ -11205,61 +11293,61 @@

    Table of Contents

    - The Controller + The View 93 - Routing + The View 94 - Front Controller Pattern + The Controller 95 - Databases + Routing 96 - Agenda + Front Controller Pattern 97 - Quick note + Databases 98 - Database Design Patterns + Agenda 99 - Row Data Gateway + Quick note 100 - Row Data Gateway + Database Design Patterns 101 - Row Data Gateway + Row Data Gateway 102 @@ -11271,19 +11359,19 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 104 - Table Data Gateway + Row Data Gateway 105 - Table Data Gateway + Table Data Gateway 106 @@ -11313,61 +11401,61 @@

    Table of Contents

    - Active Record + Table Data Gateway 111 - Active Record + Table Data Gateway 112 - Active Record + Active Record 113 - Data Mapper + Active Record 114 - Data Mapper + Active Record 115 - Data Mapper + Data Mapper 116 - Identity Map + Data Mapper 117 - Identity Map + Data Mapper 118 - Data Access Layer + Identity Map 119 - Data Access Layer / Data Source Name + Identity Map 120 @@ -11379,7 +11467,7 @@

    Table of Contents

    - Data Access Layer + Data Access Layer / Data Source Name 122 @@ -11391,277 +11479,277 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 124 - Object Relational Mapping (1/4) + Data Access Layer 125 - Object Relational Mapping (2/4) + Object Relational Mapping 126 - Object Relational Mapping (3/4) + Object Relational Mapping (1/4) 127 - Object Relational Mapping (4/4) + Object Relational Mapping (2/4) 128 - Existing Components + Object Relational Mapping (3/4) 129 - A Note About
    Domain-Driven Design
    + Object Relational Mapping (4/4) 130 - Entities + Existing Components 131 - Value Objects + A Note About
    Domain-Driven Design
    132 - The Repository Pattern + Entities 133 - The Repository Pattern + Value Objects 134 - The Repository Pattern + The Repository Pattern 135 - The Specification Pattern + The Repository Pattern 136 - The Specification Pattern + The Repository Pattern 137 - Repository ♥ Specification + The Specification Pattern 138 - Combine Them! + The Specification Pattern 139 - Combine Them! + Repository ♥ Specification 140 - Specification For Business Rules + Combine Them! 141 - Sessions + Combine Them! 142 - Overview + Specification For Business Rules 143 - Code Please + Sessions 144 - Security Concerns + Overview 145 - Session Configuration + Code Please 146 - Authentication + Security Concerns 147 - What You Have Right Now + Session Configuration 148 - The Big Picture + Authentication 149 - The Interceptor Pattern + What You Have Right Now 150 - Introducing the Event Dispatcher + The Big Picture 151 - Using the EventDispatcherTrait + The Interceptor Pattern 152 - The Firewall (1/2) + Introducing the Event Dispatcher 153 - The Firewall (2/2) + Using the EventDispatcherTrait 154 - Implementing The Firewall + The Firewall (1/2) 155 - Authentication Mechanism + The Firewall (2/2) 156 - Adding New Routes + Implementing The Firewall 157 - Stateless Authentication + Authentication Mechanism 158 - Basic Security Thinking + Adding New Routes 159 - Writing Better Code + Stateless Authentication 160 - Agenda + Basic Security Thinking 161 - Coding Standards + Writing Better Code 162 - PHP Coding Standards Fixer + Agenda 163 - Programming To The Interface + Coding Standards 164 - Dependency Inversion Principle (DIP) + PHP Coding Standards Fixer 165 - Dependency Injection (DI) + Programming To The Interface 166 - Dependency Injection (Anti) Pattern + Dependency Inversion Principle (DIP) 167 - Dependency Injection Patterns + Dependency Injection (DI) 168 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 169 @@ -11673,271 +11761,283 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 171 - Dependency Injection Container (DIC) + Dependency Injection Patterns 172 - PHP Implementations + Inversion of Control (IoC) 173 - PHP Implementations + Dependency Injection Container (DIC) 174 - Component Driven Development + PHP Implementations 175 - From STUPID to SOLID code! (1/2) + PHP Implementations 176 - From STUPID to SOLID code! (2/2) + Component Driven Development 177 - Object Calisthenics + From STUPID to SOLID code! (1/2) 178 - - + From STUPID to SOLID code! (2/2) 179 - Testing + Object Calisthenics 180 - -
    - - -
    - + - 181 - Agenda + Testing 182 - Unit Testing + +
    + + +
    + 183 - Unit Testing + Agenda 184 - PHPUnit — The Rules + Unit Testing 185 - PHPUnit — Assertions + Unit Testing 186 - Running PHPUnit + PHPUnit — The Rules 187 - Test Double + PHPUnit — Assertions 188 - Functional Testing + Running PHPUnit 189 - Functional Testing + Test Double 190 - Behavior Driven Development + Functional Testing 191 - Behavior Driven Development + Functional Testing 192 - Behat + Behavior Driven Development 193 - Using Behat (1/2) + Behavior Driven Development 194 - Using Behat (2/2) + Behat 195 - Awesome Projects + Using Behat (1/2) 196 - Assert + Using Behat (2/2) 197 - Carbon + Awesome Projects 198 - Faker + Assert 199 - Flysystem + Carbon 200 - Mockery + Faker 201 - Option Type for PHP + Flysystem 202 - PHP-Parser + Mockery 203 -
    React
    + Option Type for PHP 204 - Swiftmailer + PHP-Parser 205 - Whoops +
    React
    206 - Embracing Open Source + Swiftmailer 207 - + Whoops 208 - + Embracing Open Source 209 - + 210 - Golden Rules + 211 - The End. + 212 - Well... Maybe Not.
    PHP Extended + Golden Rules 213 + + The End. + 214 + + + + + Well... Maybe Not.
    PHP Extended + 215 + + + diff --git a/isima.html b/isima.html index 749417e..2b2d587 100644 --- a/isima.html +++ b/isima.html @@ -1302,7 +1302,7 @@ @@ -1332,7 +1332,7 @@ @@ -1362,7 +1362,7 @@ @@ -1392,7 +1392,7 @@ @@ -1422,7 +1422,7 @@ @@ -1448,7 +1448,7 @@

    twitter.com/couac @@ -1474,7 +1474,37 @@

    + + + + + +
    +
    +
    + +

    edu@drnd.me

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -1504,7 +1534,7 @@
    @@ -1545,7 +1575,7 @@

    Week #4

    @@ -1575,7 +1605,7 @@

    Week #4

    @@ -1612,7 +1642,7 @@

    Week #4

    @@ -1650,7 +1680,7 @@

    Week #4

    @@ -1688,7 +1718,7 @@

    Week #4

    @@ -1724,7 +1754,7 @@

    Week #4

    @@ -1761,7 +1791,7 @@

    Week #4

    @@ -1791,7 +1821,7 @@

    Week #4

    @@ -1821,7 +1851,7 @@

    Week #4

    @@ -1861,7 +1891,7 @@

    Week #4

    @@ -1894,7 +1924,10 @@

    Week #4

    Read more about comparison operators: http://php.net/manual/en/language.operators.comparison.php.

    -
    + +

    Timing Attack Safe String Comparison

    +

    The hash_equals() +function has been added in PHP 5.6 to compare two strings in constant time.

    @@ -1912,7 +1945,7 @@

    Week #4

    @@ -1936,6 +1969,8 @@

    Week #4

    ! $a; // `true` if $a is not `true` $a . 'foo'; // concatenation + +2 ** 3 = 8 // exponentiation (PHP 5.6+)

    But also:

    @@ -1946,6 +1981,9 @@

    Week #4

    $b = 0; $b += 1; // $b = 1 $b -= 1; // $b = 0 + +$c = 2; +$c **= 3; // $c = 8 @@ -1965,7 +2003,7 @@

    Week #4

    @@ -2010,7 +2048,7 @@

    Abstract class definition

    @@ -2064,7 +2102,7 @@

    Abstract class definition

    @@ -2105,7 +2143,7 @@

    The Rules

    @@ -2122,6 +2160,9 @@

    The Rules

    class Foo
     {
         const VALUE = 123;
    +    // PHP 5.6+
    +    const SENTENCE        = 'The value of VALUE is ' . self::VALUE;
    +    const ARRAY_OF_VALUES = ['a', 'b'];
     
         /**
          * @var int
    @@ -2162,7 +2203,7 @@ 

    The Rules

    @@ -2215,7 +2256,7 @@

    Type Hinting

    @@ -2262,7 +2303,7 @@

    Usage

    @@ -2312,7 +2353,7 @@

    Usage

    @@ -2362,7 +2403,7 @@

    Usage

    @@ -2423,7 +2464,7 @@

    Usage

    @@ -2469,7 +2510,54 @@

    Usage

    + + + + + +
    +
    +
    + +

    Variadic Functions

    + + +

    New operator ... as of PHP 5.6:

    +
    function sum(...$numbers)
    +{
    +    return array_sum($numbers);
    +}
    +
    +echo sum(1, 2);
    +// 3
    +
    + +

    Argument Unpacking

    +
    $numbers = [ 2, 3 ];
    +echo sum(1, ...$numbers);
    +// 6
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -2523,7 +2611,7 @@

    Usage

    @@ -2573,7 +2661,7 @@

    PSR-0

    @@ -2622,7 +2710,7 @@

    PSR-0

    @@ -2676,7 +2764,7 @@

    PSR-0

    @@ -2721,7 +2809,7 @@

    PSR-0

    @@ -2769,7 +2857,7 @@

    PSR-0

    @@ -2814,7 +2902,7 @@

    PSR-0

    @@ -2857,7 +2945,7 @@

    PSR-0

    @@ -2887,7 +2975,7 @@

    PSR-0

    @@ -2941,7 +3029,7 @@

    PSR-0

    @@ -2991,7 +3079,7 @@

    PSR-0

    @@ -3045,7 +3133,7 @@

    PSR-0

    @@ -3075,7 +3163,7 @@

    PSR-0

    @@ -3117,7 +3205,7 @@

    PSR-0

    @@ -3163,7 +3251,7 @@

    Collections

    @@ -3210,7 +3298,7 @@

    Collections

    @@ -3252,7 +3340,7 @@

    Collections

    @@ -3304,7 +3392,7 @@

    Collections

    @@ -3348,7 +3436,7 @@

    3xx Redirections

    @@ -3394,7 +3482,7 @@

    5xx Server Error

    @@ -3441,7 +3529,7 @@

    5xx Server Error

    @@ -3493,7 +3581,7 @@

    5xx Server Error

    @@ -3523,7 +3611,7 @@

    5xx Server Error

    @@ -3566,7 +3654,7 @@

    5xx Server Error

    @@ -3600,7 +3688,7 @@

    5xx Server Error

    @@ -3639,7 +3727,7 @@

    5xx Server Error

    @@ -3678,7 +3766,7 @@

    5xx Server Error

    @@ -3717,7 +3805,7 @@

    5xx Server Error

    @@ -3755,7 +3843,7 @@

    5xx Server Error

    @@ -3785,7 +3873,7 @@

    5xx Server Error

    @@ -3839,7 +3927,7 @@

    Hyper Media Types

    @@ -3893,7 +3981,7 @@

    Hyper Media Types

    @@ -3947,7 +4035,7 @@

    Hyper Media Types

    @@ -3977,7 +4065,7 @@

    Hyper Media Types

    @@ -4028,7 +4116,7 @@

    Hyper Media Types

    @@ -4080,7 +4168,7 @@

    Hyper Media Types

    @@ -4129,7 +4217,7 @@

    Hyper Media Types

    @@ -4180,7 +4268,7 @@

    Hyper Media Types

    @@ -4221,7 +4309,7 @@

    spl_autoload_functions()

    @@ -4272,7 +4360,7 @@

    spl_autoload_unregister()

    @@ -4329,7 +4417,7 @@

    spl_autoload_unregister()

    @@ -4359,7 +4447,7 @@

    spl_autoload_unregister()

    @@ -4406,7 +4494,7 @@

    Traversable

    @@ -4459,7 +4547,7 @@

    Traversable

    @@ -4512,7 +4600,7 @@

    Traversable

    @@ -4556,7 +4644,7 @@

    SPL Functions

    @@ -4611,7 +4699,7 @@

    SPL Functions

    @@ -4662,7 +4750,7 @@

    SPL Functions

    @@ -4713,7 +4801,7 @@

    SPL Functions

    @@ -4755,7 +4843,7 @@

    SPL Functions

    @@ -4808,7 +4896,7 @@

    SPL Functions

    @@ -4852,7 +4940,7 @@

    SPL Functions

    @@ -4882,7 +4970,7 @@

    SPL Functions

    @@ -4928,7 +5016,7 @@

    SPL Functions

    @@ -4980,7 +5068,7 @@

    SPL Functions

    @@ -5025,7 +5113,7 @@

    SPL Functions

    @@ -5055,7 +5143,7 @@

    SPL Functions

    @@ -5100,7 +5188,7 @@

    SPL Functions

    @@ -5150,7 +5238,7 @@

    SPL Functions

    @@ -5205,7 +5293,7 @@

    SPL Functions

    @@ -5254,7 +5342,7 @@

    Usage

    @@ -5305,7 +5393,7 @@

    Usage

    @@ -5359,7 +5447,7 @@

    Usage

    @@ -5404,7 +5492,7 @@

    Centralized Declaration

    @@ -5439,7 +5527,7 @@

    Centralized Declaration

    @@ -5469,7 +5557,7 @@

    Centralized Declaration

    @@ -5507,7 +5595,7 @@

    Centralized Declaration

    @@ -5544,7 +5632,7 @@

    Centralized Declaration

    @@ -5587,7 +5675,7 @@

    Centralized Declaration

    @@ -5617,7 +5705,7 @@

    Centralized Declaration

    @@ -5674,7 +5762,7 @@

    Centralized Declaration

    @@ -5722,7 +5810,7 @@

    Centralized Declaration

    @@ -5771,7 +5859,7 @@

    Centralized Declaration

    @@ -5801,7 +5889,7 @@

    Centralized Declaration

    @@ -5851,7 +5939,7 @@

    CRUD

    @@ -5900,7 +5988,7 @@

    CRUD

    @@ -5950,7 +6038,7 @@

    CRUD

    @@ -6004,7 +6092,7 @@

    CRUD

    @@ -6051,7 +6139,7 @@

    CRUD

    @@ -6100,7 +6188,7 @@

    CRUD

    @@ -6130,7 +6218,7 @@

    CRUD

    @@ -6179,7 +6267,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6236,7 +6324,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6266,7 +6354,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6321,7 +6409,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6368,7 +6456,7 @@

    Remove

    @@ -6398,7 +6486,7 @@

    Remove

    @@ -6447,7 +6535,7 @@

    Remove

    @@ -6477,7 +6565,7 @@

    Remove

    @@ -6522,7 +6610,7 @@

    PHP Data Object (PDO)

    @@ -6573,7 +6661,7 @@

    Usage

    @@ -6629,7 +6717,7 @@

    Usage

    @@ -6678,7 +6766,7 @@

    Usage

    @@ -6708,7 +6796,7 @@

    Usage

    @@ -6747,7 +6835,7 @@

    Usage

    @@ -6785,7 +6873,7 @@

    Code Snippet

    @@ -6823,7 +6911,7 @@

    Code Snippet

    @@ -6867,7 +6955,7 @@

    Code Snippet

    @@ -6909,7 +6997,7 @@

    Doctrine2 ORM

    @@ -6939,7 +7027,7 @@

    Doctrine2 ORM

    @@ -6995,7 +7083,7 @@

    Doctrine2 ORM

    @@ -7052,7 +7140,7 @@

    Doctrine2 ORM

    @@ -7082,7 +7170,7 @@

    Doctrine2 ORM

    @@ -7133,7 +7221,7 @@

    Doctrine2 ORM

    @@ -7174,7 +7262,7 @@

    Doctrine2 ORM

    @@ -7204,7 +7292,7 @@

    Doctrine2 ORM

    @@ -7262,7 +7350,7 @@

    Doctrine2 ORM

    @@ -7310,7 +7398,7 @@

    Usage

    @@ -7371,7 +7459,7 @@

    Usage

    @@ -7429,7 +7517,7 @@

    Usage

    @@ -7479,7 +7567,7 @@

    Usage

    @@ -7509,7 +7597,7 @@

    Usage

    @@ -7554,7 +7642,7 @@

    A few use cases:

    @@ -7605,7 +7693,7 @@

    A few use cases:

    @@ -7651,7 +7739,7 @@

    Workarounds

    @@ -7705,7 +7793,7 @@

    Workarounds

    @@ -7735,7 +7823,7 @@

    Workarounds

    @@ -7770,7 +7858,7 @@

    Workarounds

    @@ -7803,7 +7891,7 @@

    Workarounds

    @@ -7846,7 +7934,7 @@

    Event Dispatcher

    @@ -7896,7 +7984,7 @@

    Event Dispatcher

    @@ -7950,7 +8038,7 @@

    Event Dispatcher

    @@ -7996,7 +8084,7 @@

    Event Dispatcher

    @@ -8038,7 +8126,7 @@

    Event Dispatcher

    @@ -8097,7 +8185,7 @@

    Event Dispatcher

    @@ -8130,7 +8218,7 @@

    Event Dispatcher

    @@ -8189,7 +8277,7 @@

    Event Dispatcher

    @@ -8227,7 +8315,7 @@

    WSSE Username Token

    @@ -8273,7 +8361,7 @@

    WSSE Username Token

    @@ -8303,7 +8391,7 @@

    WSSE Username Token

    @@ -8345,7 +8433,7 @@

    WSSE Username Token

    @@ -8404,7 +8492,7 @@

    WSSE Username Token

    @@ -8450,7 +8538,7 @@

    Usage

    @@ -8497,7 +8585,7 @@

    Usage

    @@ -8537,7 +8625,7 @@

    Usage

    @@ -8589,7 +8677,7 @@

    Usage

    @@ -8645,7 +8733,7 @@

    Usage

    @@ -8689,7 +8777,7 @@

    Usage

    @@ -8733,7 +8821,7 @@

    Usage

    @@ -8784,7 +8872,7 @@

    Usage

    @@ -8819,7 +8907,7 @@

    Usage

    @@ -8864,7 +8952,7 @@

    Usage

    @@ -8915,7 +9003,7 @@

    Usage

    @@ -8960,7 +9048,7 @@

    The Symfony2 DependencyInjection Component

    @@ -8999,7 +9087,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9043,7 +9131,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9086,7 +9174,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9134,7 +9222,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9164,7 +9252,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9194,7 +9282,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9224,7 +9312,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9276,31 +9364,31 @@

    Table of Contents

    - + edu@drnd.me 7 - Agenda + 8 - PHP: Hypertext Preprocessor + Agenda 9 - History & Numbers + PHP: Hypertext Preprocessor 10 - Getting Started + History & Numbers 11 @@ -9318,463 +9406,463 @@

    Table of Contents

    - HHVM + Getting Started 14 - RTFM: http://www.php.net + HHVM 15 - The PHP Syntax + RTFM: http://www.php.net 16 - Primitive Types + The PHP Syntax 17 - Comparison Operators + Primitive Types 18 - Operators + Comparison Operators 19 - Classes (1/2) + Operators 20 - Classes (2/2) + Classes (1/2) 21 - Visibility + Classes (2/2) 22 - Properties + Visibility 23 - Methods (1/3) + Properties 24 - Methods (2/3) + Methods (1/3) 25 - Methods (3/3) + Methods (2/3) 26 - Static Keyword + Methods (3/3) 27 - Late Static Bindings + Static Keyword 28 - Static Keyword + Late Static Bindings 29 - Interfaces + Static Keyword 30 - Namespaces + Variadic Functions 31 - The class Keyword + Interfaces 32 - Traits + Namespaces 33 - Anonymous Functions + The class Keyword 34 - Closures + Traits 35 - Magic Methods + Anonymous Functions 36 - Generators + Closures 37 - The PHP Command Line + Magic Methods 38 - The PHP Command Line (1/2) + Generators 39 - The PHP Command Line (2/2) + The PHP Command Line 40 - Writing a CLI program + The PHP Command Line (1/2) 41 - Client/Server + The PHP Command Line (2/2) 42 - Client/Server Basics + Writing a CLI program 43 - Unified Resource Identifier (URI) + Client/Server 44 - HTTP Request + Client/Server Basics 45 - HTTP Verbs + Unified Resource Identifier (URI) 46 - HTTP Response + HTTP Request 47 - Status Codes (1/2) + HTTP Verbs 48 - Status Codes (2/2) + HTTP Response 49 - HTTP Parameters (1/2) + Status Codes (1/2) 50 - HTTP Parameters (2/2) + Status Codes (2/2) 51 - REST + HTTP Parameters (1/2) 52 - REpresentational State Transfer + HTTP Parameters (2/2) 53 - Richardson Maturity Model + REST 54 - Level 0 - The Swamp of POX + REpresentational State Transfer 55 - Level 1 - Resources + Richardson Maturity Model 56 - Level 2 - HTTP Verbs + Level 0 - The Swamp of POX 57 - Level 3 - Hypermedia Controls + Level 1 - Resources 58 - Level 3 = Content Negotiation + HATEOAS + Level 2 - HTTP Verbs 59 - Media Types + Level 3 - Hypermedia Controls 60 - Content Type Negotiation + Level 3 = Content Negotiation + HATEOAS 61 - HATEOAS + Media Types 62 - PHP Autoloading + Content Type Negotiation 63 - Why Is It Necessary? + HATEOAS 64 - The require() Way + PHP Autoloading 65 - The require_once() Way + Why Is It Necessary? 66 - Working With Multiple Files + The require() Way 67 - Rethinking The Way You Load Classes + The require_once() Way 68 - Examples + Working With Multiple Files 69 - Under The Hood + Rethinking The Way You Load Classes 70 - Leveraging PHP APIs + Examples 71 - Built-in Interfaces + Under The Hood 72 - The Reflection API (1/2) + Leveraging PHP APIs 73 - The Reflection API (2/2) + Built-in Interfaces 74 - The Standard PHP Library (SPL) + The Reflection API (1/2) 75 - Observer Pattern (1/2) + The Reflection API (2/2) 76 - Observer Pattern (2/2) + The Standard PHP Library (SPL) 77 - Exceptions (1/2) + Observer Pattern (1/2) 78 - Exceptions (2/2) + Observer Pattern (2/2) 79 - Password Hashing + Exceptions (1/2) 80 - PHP Archive (PHAR) + Exceptions (2/2) 81 - Dependency Management + Password Hashing 82 - Composer + PHP Archive (PHAR) 83 - composer install + Dependency Management 84 - Composer Autoloader + Composer 85 - Model View Controller + composer install 86 - MVC Overview + Composer Autoloader 87 - The Model + Model View Controller 88 - The View + MVC Overview 89 - The View + The Model 90 @@ -9786,61 +9874,61 @@

    Table of Contents

    - The Controller + The View 92 - Routing + The View 93 - Front Controller Pattern + The Controller 94 - Databases + Routing 95 - Agenda + Front Controller Pattern 96 - Quick note + Databases 97 - Database Design Patterns + Agenda 98 - Row Data Gateway + Quick note 99 - Row Data Gateway + Database Design Patterns 100 - Row Data Gateway + Row Data Gateway 101 @@ -9852,19 +9940,19 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 103 - Table Data Gateway + Row Data Gateway 104 - Table Data Gateway + Table Data Gateway 105 @@ -9894,61 +9982,61 @@

    Table of Contents

    - Active Record + Table Data Gateway 110 - Active Record + Table Data Gateway 111 - Active Record + Active Record 112 - Data Mapper + Active Record 113 - Data Mapper + Active Record 114 - Data Mapper + Data Mapper 115 - Identity Map + Data Mapper 116 - Identity Map + Data Mapper 117 - Data Access Layer + Identity Map 118 - Data Access Layer / Data Source Name + Identity Map 119 @@ -9960,7 +10048,7 @@

    Table of Contents

    - Data Access Layer + Data Access Layer / Data Source Name 121 @@ -9972,277 +10060,277 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 123 - Object Relational Mapping (1/4) + Data Access Layer 124 - Object Relational Mapping (2/4) + Object Relational Mapping 125 - Object Relational Mapping (3/4) + Object Relational Mapping (1/4) 126 - Object Relational Mapping (4/4) + Object Relational Mapping (2/4) 127 - Existing Components + Object Relational Mapping (3/4) 128 - A Note About
    Domain-Driven Design
    + Object Relational Mapping (4/4) 129 - Entities + Existing Components 130 - Value Objects + A Note About
    Domain-Driven Design
    131 - The Repository Pattern + Entities 132 - The Repository Pattern + Value Objects 133 - The Repository Pattern + The Repository Pattern 134 - The Specification Pattern + The Repository Pattern 135 - The Specification Pattern + The Repository Pattern 136 - Repository ♥ Specification + The Specification Pattern 137 - Combine Them! + The Specification Pattern 138 - Combine Them! + Repository ♥ Specification 139 - Specification For Business Rules + Combine Them! 140 - Sessions + Combine Them! 141 - Overview + Specification For Business Rules 142 - Code Please + Sessions 143 - Security Concerns + Overview 144 - Session Configuration + Code Please 145 - Authentication + Security Concerns 146 - What You Have Right Now + Session Configuration 147 - The Big Picture + Authentication 148 - The Interceptor Pattern + What You Have Right Now 149 - Introducing the Event Dispatcher + The Big Picture 150 - Using the EventDispatcherTrait + The Interceptor Pattern 151 - The Firewall (1/2) + Introducing the Event Dispatcher 152 - The Firewall (2/2) + Using the EventDispatcherTrait 153 - Implementing The Firewall + The Firewall (1/2) 154 - Authentication Mechanism + The Firewall (2/2) 155 - Adding New Routes + Implementing The Firewall 156 - Stateless Authentication + Authentication Mechanism 157 - Basic Security Thinking + Adding New Routes 158 - Writing Better Code + Stateless Authentication 159 - Agenda + Basic Security Thinking 160 - Coding Standards + Writing Better Code 161 - PHP Coding Standards Fixer + Agenda 162 - Programming To The Interface + Coding Standards 163 - Dependency Inversion Principle (DIP) + PHP Coding Standards Fixer 164 - Dependency Injection (DI) + Programming To The Interface 165 - Dependency Injection (Anti) Pattern + Dependency Inversion Principle (DIP) 166 - Dependency Injection Patterns + Dependency Injection (DI) 167 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 168 @@ -10254,71 +10342,83 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 170 - Dependency Injection Container (DIC) + Dependency Injection Patterns 171 - PHP Implementations + Inversion of Control (IoC) 172 - PHP Implementations + Dependency Injection Container (DIC) 173 - Component Driven Development + PHP Implementations 174 - From STUPID to SOLID code! (1/2) + PHP Implementations 175 - From STUPID to SOLID code! (2/2) + Component Driven Development 176 - Object Calisthenics + From STUPID to SOLID code! (1/2) 177 - - + From STUPID to SOLID code! (2/2) 178 - Next Week:
    Web Security 101
    + Object Calisthenics 179 - The End. + - 180 + + Next Week:
    Web Security 101
    + 181 + + + + + The End. + 182 + + + From 9ca2c3dc17941ea6e66e5cbc111adcf463974de1 Mon Sep 17 00:00:00 2001 From: William Durand Date: Fri, 2 Jan 2015 15:34:09 +0100 Subject: [PATCH 58/71] Publish slides (Fri Jan 2 15:34:09 CET 2015) --- index.html | 519 +++++++++++++++++++++++++++++------------------------ 1 file changed, 286 insertions(+), 233 deletions(-) diff --git a/index.html b/index.html index 47c65c9..4d4bf11 100644 --- a/index.html +++ b/index.html @@ -1214,7 +1214,7 @@ @@ -1244,7 +1244,7 @@ @@ -1296,7 +1296,7 @@ @@ -1326,7 +1326,7 @@ @@ -1356,7 +1356,7 @@ @@ -1397,7 +1397,7 @@

    Week #4

    @@ -1427,7 +1427,7 @@

    Week #4

    @@ -1464,7 +1464,7 @@

    Week #4

    @@ -1502,7 +1502,7 @@

    Week #4

    @@ -1540,7 +1540,7 @@

    Week #4

    @@ -1576,7 +1576,7 @@

    Week #4

    @@ -1613,7 +1613,7 @@

    Week #4

    @@ -1643,7 +1643,7 @@

    Week #4

    @@ -1673,7 +1673,7 @@

    Week #4

    @@ -1713,7 +1713,7 @@

    Week #4

    @@ -1767,7 +1767,7 @@

    Timing Attack Safe String Comparison

    @@ -1825,7 +1825,7 @@

    Timing Attack Safe String Comparison

    @@ -1870,7 +1870,7 @@

    Abstract class definition

    @@ -1924,7 +1924,7 @@

    Abstract class definition

    @@ -1965,7 +1965,7 @@

    The Rules

    @@ -2025,7 +2025,7 @@

    The Rules

    @@ -2078,7 +2078,7 @@

    Type Hinting

    @@ -2125,7 +2125,7 @@

    Usage

    @@ -2175,7 +2175,7 @@

    Usage

    @@ -2225,7 +2225,7 @@

    Usage

    @@ -2286,7 +2286,7 @@

    Usage

    @@ -2332,7 +2332,7 @@

    Usage

    @@ -2379,7 +2379,7 @@

    Argument Unpacking

    @@ -2433,7 +2433,7 @@

    Usage

    @@ -2483,7 +2483,7 @@

    PSR-0

    @@ -2532,7 +2532,7 @@

    PSR-0

    @@ -2586,7 +2586,7 @@

    PSR-0

    @@ -2631,7 +2631,7 @@

    PSR-0

    @@ -2679,7 +2679,7 @@

    PSR-0

    @@ -2724,7 +2724,7 @@

    PSR-0

    @@ -2767,7 +2767,7 @@

    PSR-0

    @@ -2797,7 +2797,7 @@

    PSR-0

    @@ -2851,7 +2851,7 @@

    PSR-0

    @@ -2901,7 +2901,7 @@

    PSR-0

    @@ -2955,7 +2955,7 @@

    PSR-0

    @@ -2985,7 +2985,7 @@

    PSR-0

    @@ -3027,7 +3027,7 @@

    PSR-0

    @@ -3073,7 +3073,7 @@

    Collections

    @@ -3120,7 +3120,7 @@

    Collections

    @@ -3162,7 +3162,7 @@

    Collections

    @@ -3214,7 +3214,7 @@

    Collections

    @@ -3258,7 +3258,7 @@

    3xx Redirections

    @@ -3304,7 +3304,7 @@

    5xx Server Error

    @@ -3351,7 +3351,7 @@

    5xx Server Error

    @@ -3403,7 +3403,7 @@

    5xx Server Error

    @@ -3433,7 +3433,7 @@

    5xx Server Error

    @@ -3476,7 +3476,7 @@

    5xx Server Error

    @@ -3510,7 +3510,7 @@

    5xx Server Error

    @@ -3549,7 +3549,7 @@

    5xx Server Error

    @@ -3588,7 +3588,7 @@

    5xx Server Error

    @@ -3627,7 +3627,7 @@

    5xx Server Error

    @@ -3665,7 +3665,7 @@

    5xx Server Error

    @@ -3695,7 +3695,7 @@

    5xx Server Error

    @@ -3749,7 +3749,7 @@

    Hyper Media Types

    @@ -3803,7 +3803,7 @@

    Hyper Media Types

    @@ -3857,7 +3857,7 @@

    Hyper Media Types

    @@ -3887,7 +3887,7 @@

    Hyper Media Types

    @@ -3938,7 +3938,7 @@

    Hyper Media Types

    @@ -3990,7 +3990,7 @@

    Hyper Media Types

    @@ -4039,7 +4039,7 @@

    Hyper Media Types

    @@ -4090,7 +4090,7 @@

    Hyper Media Types

    @@ -4131,7 +4131,7 @@

    spl_autoload_functions()

    @@ -4182,7 +4182,7 @@

    spl_autoload_unregister()

    @@ -4239,7 +4239,7 @@

    spl_autoload_unregister()

    @@ -4269,7 +4269,7 @@

    spl_autoload_unregister()

    @@ -4316,7 +4316,7 @@

    Traversable

    @@ -4369,7 +4369,7 @@

    Traversable

    @@ -4422,7 +4422,7 @@

    Traversable

    @@ -4466,7 +4466,7 @@

    SPL Functions

    @@ -4521,7 +4521,7 @@

    SPL Functions

    @@ -4572,7 +4572,7 @@

    SPL Functions

    @@ -4623,7 +4623,7 @@

    SPL Functions

    @@ -4665,7 +4665,7 @@

    SPL Functions

    @@ -4718,7 +4718,7 @@

    SPL Functions

    @@ -4762,7 +4762,7 @@

    SPL Functions

    @@ -4792,7 +4792,7 @@

    SPL Functions

    @@ -4838,7 +4838,7 @@

    SPL Functions

    @@ -4890,7 +4890,7 @@

    SPL Functions

    @@ -4935,7 +4935,7 @@

    SPL Functions

    @@ -4985,7 +4985,7 @@

    SPL Functions

    @@ -5038,7 +5038,7 @@

    SPL Functions

    @@ -5087,7 +5087,7 @@

    Execution

    @@ -5142,7 +5142,7 @@

    Usage

    @@ -5172,7 +5172,7 @@

    Usage

    @@ -5217,7 +5217,7 @@

    Usage

    @@ -5267,7 +5267,7 @@

    Usage

    @@ -5322,7 +5322,7 @@

    Usage

    @@ -5371,7 +5371,7 @@

    Usage

    @@ -5422,7 +5422,7 @@

    Usage

    @@ -5476,7 +5476,7 @@

    Usage

    @@ -5521,7 +5521,7 @@

    Centralized Declaration

    @@ -5556,7 +5556,7 @@

    Centralized Declaration

    @@ -5586,7 +5586,7 @@

    Centralized Declaration

    @@ -5624,7 +5624,7 @@

    Centralized Declaration

    @@ -5661,7 +5661,7 @@

    Centralized Declaration

    @@ -5704,7 +5704,7 @@

    Centralized Declaration

    @@ -5734,7 +5734,7 @@

    Centralized Declaration

    @@ -5791,7 +5791,7 @@

    Centralized Declaration

    @@ -5839,7 +5839,7 @@

    Centralized Declaration

    @@ -5888,7 +5888,7 @@

    Centralized Declaration

    @@ -5918,7 +5918,7 @@

    Centralized Declaration

    @@ -5968,7 +5968,7 @@

    CRUD

    @@ -6017,7 +6017,7 @@

    CRUD

    @@ -6067,7 +6067,7 @@

    CRUD

    @@ -6121,7 +6121,7 @@

    CRUD

    @@ -6168,7 +6168,7 @@

    CRUD

    @@ -6217,7 +6217,7 @@

    CRUD

    @@ -6247,7 +6247,7 @@

    CRUD

    @@ -6296,7 +6296,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6353,7 +6353,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6383,7 +6383,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6438,7 +6438,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6485,7 +6485,7 @@

    Remove

    @@ -6515,7 +6515,7 @@

    Remove

    @@ -6564,7 +6564,7 @@

    Remove

    @@ -6594,7 +6594,7 @@

    Remove

    @@ -6639,7 +6639,7 @@

    PHP Data Object (PDO)

    @@ -6690,7 +6690,7 @@

    Usage

    @@ -6746,7 +6746,7 @@

    Usage

    @@ -6795,7 +6795,7 @@

    Usage

    @@ -6825,7 +6825,7 @@

    Usage

    @@ -6864,7 +6864,7 @@

    Usage

    @@ -6902,7 +6902,7 @@

    Code Snippet

    @@ -6940,7 +6940,7 @@

    Code Snippet

    @@ -6984,7 +6984,7 @@

    Code Snippet

    @@ -7026,7 +7026,7 @@

    Doctrine2 ORM

    @@ -7056,7 +7056,7 @@

    Doctrine2 ORM

    @@ -7112,7 +7112,7 @@

    Doctrine2 ORM

    @@ -7169,7 +7169,7 @@

    Doctrine2 ORM

    @@ -7199,7 +7199,7 @@

    Doctrine2 ORM

    @@ -7250,7 +7250,7 @@

    Doctrine2 ORM

    @@ -7291,7 +7291,7 @@

    Doctrine2 ORM

    @@ -7321,7 +7321,7 @@

    Doctrine2 ORM

    @@ -7379,7 +7379,7 @@

    Doctrine2 ORM

    @@ -7427,7 +7427,7 @@

    Usage

    @@ -7488,7 +7488,7 @@

    Usage

    @@ -7546,7 +7546,7 @@

    Usage

    @@ -7596,7 +7596,7 @@

    Usage

    @@ -7626,7 +7626,7 @@

    Usage

    @@ -7671,7 +7671,7 @@

    A few use cases:

    @@ -7722,7 +7722,7 @@

    A few use cases:

    @@ -7768,7 +7768,7 @@

    Workarounds

    @@ -7822,7 +7822,7 @@

    Workarounds

    @@ -7852,7 +7852,7 @@

    Workarounds

    @@ -7887,7 +7887,7 @@

    Workarounds

    @@ -7920,7 +7920,7 @@

    Workarounds

    @@ -7963,7 +7963,7 @@

    Event Dispatcher

    @@ -8013,7 +8013,7 @@

    Event Dispatcher

    @@ -8067,7 +8067,7 @@

    Event Dispatcher

    @@ -8113,7 +8113,7 @@

    Event Dispatcher

    @@ -8155,7 +8155,7 @@

    Event Dispatcher

    @@ -8214,7 +8214,7 @@

    Event Dispatcher

    @@ -8247,7 +8247,7 @@

    Event Dispatcher

    @@ -8306,7 +8306,7 @@

    Event Dispatcher

    @@ -8344,7 +8344,7 @@

    WSSE Username Token

    @@ -8390,7 +8390,7 @@

    WSSE Username Token

    @@ -8420,7 +8420,7 @@

    WSSE Username Token

    @@ -8462,7 +8462,7 @@

    WSSE Username Token

    @@ -8521,7 +8521,7 @@

    WSSE Username Token

    @@ -8567,7 +8567,7 @@

    Usage

    @@ -8614,7 +8614,7 @@

    Usage

    @@ -8654,7 +8654,7 @@

    Usage

    @@ -8706,7 +8706,7 @@

    Usage

    @@ -8762,7 +8762,7 @@

    Usage

    @@ -8806,7 +8806,7 @@

    Usage

    @@ -8850,7 +8850,7 @@

    Usage

    @@ -8901,7 +8901,7 @@

    Usage

    @@ -8936,7 +8936,7 @@

    Usage

    @@ -8981,7 +8981,7 @@

    Usage

    @@ -9032,7 +9032,7 @@

    Usage

    @@ -9077,7 +9077,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9116,7 +9116,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9160,7 +9160,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9203,7 +9203,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9251,7 +9251,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9281,7 +9281,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9311,7 +9311,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9349,7 +9349,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9367,6 +9367,7 @@

    The Symfony2 DependencyInjection Component

  • Unit Testing
  • Functional Testing
  • Behavior Driven Development
  • +
  • Testing Tweet Frameworks
  • @@ -9385,7 +9386,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9415,7 +9416,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9463,7 +9464,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9513,7 +9514,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9554,7 +9555,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9606,7 +9607,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9652,7 +9653,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9682,7 +9683,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9721,7 +9722,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9751,7 +9752,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9796,7 +9797,7 @@

    StoryBDD

    @@ -9844,7 +9845,7 @@

    StoryBDD

    @@ -9894,7 +9895,7 @@

    StoryBDD

    @@ -9949,7 +9950,53 @@

    StoryBDD

    + + + + + +
    +
    +
    + +

    Testing Tweet Frameworks

    + + +

    Tweetest

    +
    function tweetest($c,$m) {$c=is_callable($c)?$c():$c;echo($c)?'.':"F[{$m}]";}
    +
    +tweetest($testValue !== 'bar', '$testValue should never equal bar');
    +
    + +

    TestFrameworkInATweet.php

    +
    function it($m,$p){echo ($p?'✔︎':'✘')." It $m\n";if(!$p){$GLOBALS['f']=1;}}
    +function done(){if(@$GLOBALS['f'])die(1);}
    +
    +it("should sum two numbers", 1 + 1 == 2);
    +it("should display an X for a failing test", 1 + 1 == 3);
    +done();
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -9979,7 +10026,7 @@

    StoryBDD

    @@ -10028,7 +10075,7 @@

    StoryBDD

    @@ -10085,7 +10132,7 @@

    StoryBDD

    @@ -10142,7 +10189,7 @@

    StoryBDD

    @@ -10200,7 +10247,7 @@

    StoryBDD

    @@ -10260,7 +10307,7 @@

    StoryBDD

    @@ -10315,7 +10362,7 @@

    Fallback to Default Value If Not Available

    @@ -10374,7 +10421,7 @@

    Fallback to Default Value If Not Available

    @@ -10408,7 +10455,7 @@

    Fallback to Default Value If Not Available

    @@ -10466,7 +10513,7 @@

    Fallback to Default Value If Not Available

    @@ -10503,7 +10550,7 @@

    Fallback to Default Value If Not Available

    @@ -10533,7 +10580,7 @@

    Fallback to Default Value If Not Available

    @@ -10563,7 +10610,7 @@

    Fallback to Default Value If Not Available

    @@ -10593,7 +10640,7 @@

    Fallback to Default Value If Not Available

    @@ -10623,7 +10670,7 @@

    Fallback to Default Value If Not Available

    @@ -10665,7 +10712,7 @@

    Fallback to Default Value If Not Available

    @@ -10695,7 +10742,7 @@

    Fallback to Default Value If Not Available

    @@ -10725,7 +10772,7 @@

    Fallback to Default Value If Not Available

    @@ -11931,113 +11978,119 @@

    Table of Contents

    - Awesome Projects + Testing Tweet Frameworks 198 - Assert + Awesome Projects 199 - Carbon + Assert 200 - Faker + Carbon 201 - Flysystem + Faker 202 - Mockery + Flysystem 203 - Option Type for PHP + Mockery 204 - PHP-Parser + Option Type for PHP 205 -
    React
    + PHP-Parser 206 - Swiftmailer +
    React
    207 - Whoops + Swiftmailer 208 - Embracing Open Source + Whoops 209 - + Embracing Open Source 210 - + 211 - + 212 - Golden Rules + 213 - The End. + Golden Rules 214 - Well... Maybe Not.
    PHP Extended + The End. 215 + + Well... Maybe Not.
    PHP Extended + 216 + + + From 152d1618cd6eb2f2528f10bbd2d11a4d558b0251 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 12 Jan 2015 01:19:31 +0100 Subject: [PATCH 59/71] Publish slides (Mon Jan 12 01:19:31 CET 2015) --- index.html | 799 ++++++++++++++++++++++++++++------------------------- isima.html | 648 +++++++++++++++++++++++-------------------- 2 files changed, 770 insertions(+), 677 deletions(-) diff --git a/index.html b/index.html index 4d4bf11..2ad86ed 100644 --- a/index.html +++ b/index.html @@ -1214,7 +1214,7 @@ @@ -1244,7 +1244,7 @@ @@ -1296,7 +1296,7 @@ @@ -1326,7 +1326,7 @@ @@ -1356,7 +1356,7 @@ @@ -1397,7 +1397,7 @@

    Week #4

    @@ -1427,7 +1427,7 @@

    Week #4

    @@ -1464,7 +1464,7 @@

    Week #4

    @@ -1502,7 +1502,7 @@

    Week #4

    @@ -1517,7 +1517,7 @@

    Week #4

    Mac OS X

    -
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.5
    +
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6
     
    @@ -1540,7 +1540,7 @@

    Week #4

    @@ -1576,7 +1576,7 @@

    Week #4

    @@ -1613,7 +1613,7 @@

    Week #4

    @@ -1643,7 +1643,7 @@

    Week #4

    @@ -1673,7 +1673,7 @@

    Week #4

    @@ -1713,7 +1713,7 @@

    Week #4

    @@ -1767,7 +1767,7 @@

    Timing Attack Safe String Comparison

    @@ -1825,7 +1825,7 @@

    Timing Attack Safe String Comparison

    @@ -1870,7 +1870,7 @@

    Abstract class definition

    @@ -1924,7 +1924,7 @@

    Abstract class definition

    @@ -1965,7 +1965,7 @@

    The Rules

    @@ -2025,7 +2025,7 @@

    The Rules

    @@ -2078,7 +2078,7 @@

    Type Hinting

    @@ -2125,7 +2125,7 @@

    Usage

    @@ -2175,7 +2175,7 @@

    Usage

    @@ -2225,7 +2225,7 @@

    Usage

    @@ -2286,7 +2286,7 @@

    Usage

    @@ -2332,7 +2332,7 @@

    Usage

    @@ -2379,7 +2379,7 @@

    Argument Unpacking

    @@ -2433,7 +2433,7 @@

    Usage

    @@ -2460,8 +2460,8 @@

    Usage

    PSR-0

    -

    PSR-0 -describes a set of rules related to namespaces for autoloader interoperability.

    +

    PSR-0 describes a set of rules related to +namespaces for autoloader interoperability:

    \ns\package\Class_Name      => vendor/ns/package/Class/Name.php
     \ns\package_name\Class_Name => vendor/ns/package_name/Class/Name.php
     
    @@ -2483,7 +2483,7 @@

    PSR-0

    @@ -2532,7 +2532,7 @@

    PSR-0

    @@ -2586,7 +2586,7 @@

    PSR-0

    @@ -2631,7 +2631,7 @@

    PSR-0

    @@ -2679,7 +2679,7 @@

    PSR-0

    @@ -2724,7 +2724,7 @@

    PSR-0

    @@ -2767,7 +2767,7 @@

    PSR-0

    @@ -2797,7 +2797,7 @@

    PSR-0

    @@ -2851,7 +2851,7 @@

    PSR-0

    @@ -2901,7 +2901,7 @@

    PSR-0

    @@ -2955,7 +2955,7 @@

    PSR-0

    @@ -2985,7 +2985,7 @@

    PSR-0

    @@ -3027,7 +3027,7 @@

    PSR-0

    @@ -3073,7 +3073,7 @@

    Collections

    @@ -3120,7 +3120,7 @@

    Collections

    @@ -3162,7 +3162,7 @@

    Collections

    @@ -3214,7 +3214,7 @@

    Collections

    @@ -3240,7 +3240,10 @@

    3xx Redirections

  • 301 Moved Permanently
  • 302 Found
  • 304 Not Modified
  • -
    + +
    +

    httpstatus.es

    +
    @@ -3258,7 +3261,7 @@

    3xx Redirections

    @@ -3304,7 +3307,7 @@

    5xx Server Error

    @@ -3351,7 +3354,7 @@

    5xx Server Error

    @@ -3403,7 +3406,7 @@

    5xx Server Error

    @@ -3433,7 +3436,7 @@

    5xx Server Error

    @@ -3476,7 +3479,7 @@

    5xx Server Error

    @@ -3510,7 +3513,7 @@

    5xx Server Error

    @@ -3549,7 +3552,7 @@

    5xx Server Error

    @@ -3588,7 +3591,7 @@

    5xx Server Error

    @@ -3627,7 +3630,7 @@

    5xx Server Error

    @@ -3665,7 +3668,7 @@

    5xx Server Error

    @@ -3695,7 +3698,7 @@

    5xx Server Error

    @@ -3749,7 +3752,7 @@

    Hyper Media Types

    @@ -3803,7 +3806,7 @@

    Hyper Media Types

    @@ -3857,7 +3860,7 @@

    Hyper Media Types

    @@ -3887,7 +3890,7 @@

    Hyper Media Types

    @@ -3938,7 +3941,7 @@

    Hyper Media Types

    @@ -3990,7 +3993,7 @@

    Hyper Media Types

    @@ -4039,7 +4042,7 @@

    Hyper Media Types

    @@ -4090,7 +4093,7 @@

    Hyper Media Types

    @@ -4131,7 +4134,7 @@

    spl_autoload_functions()

    @@ -4182,7 +4185,7 @@

    spl_autoload_unregister()

    @@ -4239,7 +4242,56 @@

    spl_autoload_unregister()

    + + + + + +
    +
    +
    + +

    PSR-0 vs PSR-4

    + + +

    PSR-0

    +
    \Zend\Mail\Message
    +// => /path/to/project/lib/vendor/Zend/Mail/Message.php
    +
    + +

    + +
    Zend_Mail_Message
    +// => /path/to/project/lib/vendor/Zend/Mail/Message.php
    +
    + +

    Important: as of 2014-10-21 PSR-0 has been marked as deprecated.

    +

    PSR-4

    +

    Like PSR-0, but better:

    +
      +
    • more concise folder structure;
    • +
    • remove the remnants of PSR-0 (e.g. PEAR support).
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -4269,7 +4321,7 @@

    spl_autoload_unregister()

    @@ -4316,7 +4368,7 @@

    Traversable

    @@ -4369,7 +4421,7 @@

    Traversable

    @@ -4422,7 +4474,7 @@

    Traversable

    @@ -4466,7 +4518,7 @@

    SPL Functions

    @@ -4521,7 +4573,7 @@

    SPL Functions

    @@ -4572,7 +4624,7 @@

    SPL Functions

    @@ -4597,15 +4649,16 @@

    SPL Functions

    Create your own exceptions:

    -
    class MyException extends RuntimeException
    +
    class SomethingWentWrong extends RuntimeException
     {
     }
     
    -class MyException extends Exception implements ExceptionInterface
    +class ErrorWhileDoingSomething extends Exception implements ExceptionInterface
     {
     }
     
    - + +

    Name your named exceptions!

    @@ -4623,7 +4676,7 @@

    SPL Functions

    @@ -4665,7 +4718,7 @@

    SPL Functions

    @@ -4718,7 +4771,7 @@

    SPL Functions

    @@ -4762,7 +4815,7 @@

    SPL Functions

    @@ -4792,7 +4845,7 @@

    SPL Functions

    @@ -4838,7 +4891,7 @@

    SPL Functions

    @@ -4860,8 +4913,8 @@

    SPL Functions

    } -

    You can also require a library by using the composer command:

    -
    $ php composer.phar require "willdurand/geocoder:~2.0"
    +

    You can also require a library by using the require command:

    +
    $ php composer.phar require willdurand/geocoder
     

    Run the following command to download and install the project dependencies into @@ -4890,7 +4943,7 @@

    SPL Functions

    @@ -4904,9 +4957,10 @@

    SPL Functions

    Composer Autoloader

    -

    Composer automatically generates a PSR-0 compliant and optimized autoloader for -your entire application. Thanks to Composer, you don't have to take care about -how to autoload classes/functions anymore.

    +

    Composer automatically generates a PSR-4 +compliant and optimized autoloader for your entire application. Thanks to +Composer, you don't have to take care about how to autoload classes/functions +anymore.

    Require the generated autoloader in your project as follows:

    <?php
     
    @@ -4935,7 +4989,7 @@ 

    SPL Functions

    @@ -4985,7 +5039,7 @@

    SPL Functions

    @@ -5012,10 +5066,7 @@

    SPL Functions

    // configure the name, arguments, options, etc. } - protected function execute( - InputInterface $input, - OutputInterface $output - ) { + protected function execute(InputInterface $in, OutputInterface $out) { // do greet } } @@ -5038,7 +5089,7 @@

    SPL Functions

    @@ -5087,7 +5138,7 @@

    Execution

    @@ -5142,7 +5193,7 @@

    Usage

    @@ -5172,7 +5223,7 @@

    Usage

    @@ -5187,25 +5238,13 @@

    Usage

    Typical client request process in MVC architecture:

    -

    -
    +

    Notes

    -
      -
    1. Client makes a request
    2. -
    3. Controller handles request:
        -
      • interactions with model
      • -
      • data preparation
      • -
      • send data to view
      • -
      -
    4. -
    5. View format data
    6. -
    -
    @@ -5217,7 +5256,7 @@

    Usage

    @@ -5267,7 +5306,7 @@

    Usage

    @@ -5322,7 +5361,7 @@

    Usage

    @@ -5371,7 +5410,7 @@

    Usage

    @@ -5422,7 +5461,7 @@

    Usage

    @@ -5476,7 +5515,7 @@

    Usage

    @@ -5521,7 +5560,7 @@

    Centralized Declaration

    @@ -5536,7 +5575,7 @@

    Centralized Declaration

    A controller that handles all requests for a web application:

    -

    +

    This controller dispatches the request to the specialized controllers.

    It is usually tied to URL rewriting.

    @@ -5556,7 +5595,7 @@

    Centralized Declaration

    @@ -5586,7 +5625,7 @@

    Centralized Declaration

    @@ -5624,7 +5663,7 @@

    Centralized Declaration

    @@ -5661,7 +5700,7 @@

    Centralized Declaration

    @@ -5704,7 +5743,7 @@

    Centralized Declaration

    @@ -5734,7 +5773,7 @@

    Centralized Declaration

    @@ -5791,7 +5830,7 @@

    Centralized Declaration

    @@ -5839,7 +5878,7 @@

    Centralized Declaration

    @@ -5888,7 +5927,7 @@

    Centralized Declaration

    @@ -5918,7 +5957,7 @@

    Centralized Declaration

    @@ -5968,7 +6007,7 @@

    CRUD

    @@ -6017,7 +6056,7 @@

    CRUD

    @@ -6067,7 +6106,7 @@

    CRUD

    @@ -6121,7 +6160,7 @@

    CRUD

    @@ -6168,7 +6207,7 @@

    CRUD

    @@ -6217,7 +6256,7 @@

    CRUD

    @@ -6247,7 +6286,7 @@

    CRUD

    @@ -6296,7 +6335,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6353,7 +6392,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6383,7 +6422,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6438,7 +6477,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6485,7 +6524,7 @@

    Remove

    @@ -6515,7 +6554,7 @@

    Remove

    @@ -6564,7 +6603,7 @@

    Remove

    @@ -6594,7 +6633,7 @@

    Remove

    @@ -6639,7 +6678,7 @@

    PHP Data Object (PDO)

    @@ -6690,7 +6729,7 @@

    Usage

    @@ -6746,7 +6785,7 @@

    Usage

    @@ -6795,7 +6834,7 @@

    Usage

    @@ -6825,7 +6864,7 @@

    Usage

    @@ -6864,7 +6903,7 @@

    Usage

    @@ -6902,7 +6941,7 @@

    Code Snippet

    @@ -6940,7 +6979,7 @@

    Code Snippet

    @@ -6984,7 +7023,7 @@

    Code Snippet

    @@ -7026,7 +7065,7 @@

    Doctrine2 ORM

    @@ -7056,7 +7095,7 @@

    Doctrine2 ORM

    @@ -7112,7 +7151,7 @@

    Doctrine2 ORM

    @@ -7169,7 +7208,7 @@

    Doctrine2 ORM

    @@ -7199,7 +7238,7 @@

    Doctrine2 ORM

    @@ -7250,7 +7289,7 @@

    Doctrine2 ORM

    @@ -7291,7 +7330,7 @@

    Doctrine2 ORM

    @@ -7321,7 +7360,7 @@

    Doctrine2 ORM

    @@ -7379,7 +7418,7 @@

    Doctrine2 ORM

    @@ -7427,7 +7466,7 @@

    Usage

    @@ -7488,7 +7527,7 @@

    Usage

    @@ -7546,7 +7585,7 @@

    Usage

    @@ -7596,7 +7635,7 @@

    Usage

    @@ -7626,7 +7665,7 @@

    Usage

    @@ -7671,7 +7710,7 @@

    A few use cases:

    @@ -7722,7 +7761,7 @@

    A few use cases:

    @@ -7768,7 +7807,7 @@

    Workarounds

    @@ -7822,7 +7861,7 @@

    Workarounds

    @@ -7852,7 +7891,7 @@

    Workarounds

    @@ -7887,7 +7926,7 @@

    Workarounds

    @@ -7920,7 +7959,7 @@

    Workarounds

    @@ -7963,7 +8002,7 @@

    Event Dispatcher

    @@ -8013,7 +8052,7 @@

    Event Dispatcher

    @@ -8067,7 +8106,7 @@

    Event Dispatcher

    @@ -8113,7 +8152,7 @@

    Event Dispatcher

    @@ -8155,7 +8194,7 @@

    Event Dispatcher

    @@ -8214,7 +8253,7 @@

    Event Dispatcher

    @@ -8247,7 +8286,7 @@

    Event Dispatcher

    @@ -8306,7 +8345,7 @@

    Event Dispatcher

    @@ -8344,7 +8383,7 @@

    WSSE Username Token

    @@ -8390,7 +8429,7 @@

    WSSE Username Token

    @@ -8420,7 +8459,7 @@

    WSSE Username Token

    @@ -8462,7 +8501,7 @@

    WSSE Username Token

    @@ -8521,7 +8560,7 @@

    WSSE Username Token

    @@ -8567,7 +8606,7 @@

    Usage

    @@ -8614,7 +8653,7 @@

    Usage

    @@ -8654,7 +8693,7 @@

    Usage

    @@ -8706,7 +8745,7 @@

    Usage

    @@ -8762,7 +8801,7 @@

    Usage

    @@ -8806,7 +8845,7 @@

    Usage

    @@ -8850,7 +8889,7 @@

    Usage

    @@ -8901,7 +8940,7 @@

    Usage

    @@ -8936,7 +8975,7 @@

    Usage

    @@ -8981,7 +9020,7 @@

    Usage

    @@ -9032,7 +9071,7 @@

    Usage

    @@ -9077,7 +9116,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9116,7 +9155,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9160,7 +9199,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9203,7 +9242,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9251,7 +9290,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9281,7 +9320,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9311,7 +9350,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9349,7 +9388,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9386,7 +9425,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9416,7 +9455,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9464,7 +9503,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9514,7 +9553,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9555,7 +9594,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9607,7 +9646,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9653,7 +9692,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9683,7 +9722,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9722,7 +9761,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9752,7 +9791,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9797,7 +9836,7 @@

    StoryBDD

    @@ -9845,7 +9884,7 @@

    StoryBDD

    @@ -9895,7 +9934,7 @@

    StoryBDD

    @@ -9950,7 +9989,7 @@

    StoryBDD

    @@ -9996,7 +10035,7 @@

    TestFrameworkInATw @@ -10026,7 +10065,7 @@

    TestFrameworkInATw @@ -10075,7 +10114,7 @@

    TestFrameworkInATw @@ -10132,7 +10171,7 @@

    TestFrameworkInATw @@ -10189,7 +10228,7 @@

    TestFrameworkInATw @@ -10247,7 +10286,7 @@

    TestFrameworkInATw @@ -10307,7 +10346,7 @@

    TestFrameworkInATw @@ -10362,7 +10401,7 @@

    Fallback to Default Value If Not Available

    @@ -10421,7 +10460,7 @@

    Fallback to Default Value If Not Available

    @@ -10455,7 +10494,7 @@

    Fallback to Default Value If Not Available

    @@ -10513,7 +10552,7 @@

    Fallback to Default Value If Not Available

    @@ -10550,7 +10589,7 @@

    Fallback to Default Value If Not Available

    @@ -10580,7 +10619,7 @@

    Fallback to Default Value If Not Available

    @@ -10610,7 +10649,7 @@

    Fallback to Default Value If Not Available

    @@ -10640,7 +10679,7 @@

    Fallback to Default Value If Not Available

    @@ -10670,7 +10709,7 @@

    Fallback to Default Value If Not Available

    @@ -10712,7 +10751,7 @@

    Fallback to Default Value If Not Available

    @@ -10742,7 +10781,7 @@

    Fallback to Default Value If Not Available

    @@ -10772,7 +10811,7 @@

    Fallback to Default Value If Not Available

    @@ -11202,139 +11241,139 @@

    Table of Contents

    -
    Leveraging PHP APIs + PSR-0 vs PSR-4 70 - Built-in Interfaces + Leveraging PHP APIs 71 - The Reflection API (1/2) + Built-in Interfaces 72 - The Reflection API (2/2) + The Reflection API (1/2) 73 - The Standard PHP Library (SPL) + The Reflection API (2/2) 74 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 75 - Observer Pattern (2/2) + Observer Pattern (1/2) 76 - Exceptions (1/2) + Observer Pattern (2/2) 77 - Exceptions (2/2) + Exceptions (1/2) 78 - Password Hashing + Exceptions (2/2) 79 - PHP Archive (PHAR) + Password Hashing 80 - Dependency Management + PHP Archive (PHAR) 81 - Composer + Dependency Management 82 - composer install + Composer 83 - Composer Autoloader + composer install 84 - Example + Composer Autoloader 85 - The Symfony2 Console Component + Example 86 - A Basic Command (1/2) + The Symfony2 Console Component 87 - A Basic Command (2/2) + A Basic Command (1/2) 88 - Model View Controller + A Basic Command (2/2) 89 - MVC Overview + Model View Controller 90 - The Model + MVC Overview 91 - The View + The Model 92 @@ -11352,55 +11391,55 @@

    Table of Contents

    - The Controller + The View 95 - Routing + The Controller 96 - Front Controller Pattern + Routing 97 - Databases + Front Controller Pattern 98 - Agenda + Databases 99 - Quick note + Agenda 100 - Database Design Patterns + Quick note 101 - Row Data Gateway + Database Design Patterns 102 - Row Data Gateway + Row Data Gateway 103 @@ -11418,13 +11457,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 106 - Table Data Gateway + Table Data Gateway 107 @@ -11460,13 +11499,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 113 - Active Record + Active Record 114 @@ -11478,13 +11517,13 @@

    Table of Contents

    - Data Mapper + Active Record 116 - Data Mapper + Data Mapper 117 @@ -11496,31 +11535,31 @@

    Table of Contents

    - Identity Map + Data Mapper 119 - Identity Map + Identity Map 120 - Data Access Layer + Identity Map 121 - Data Access Layer / Data Source Name + Data Access Layer 122 - Data Access Layer + Data Access Layer / Data Source Name 123 @@ -11538,67 +11577,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 126 - Object Relational Mapping (1/4) + Object Relational Mapping 127 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 128 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 129 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 130 - Existing Components + Object Relational Mapping (4/4) 131 - A Note About
    Domain-Driven Design
    + Existing Components 132 - Entities + A Note About
    Domain-Driven Design
    133 - Value Objects + Entities 134 - The Repository Pattern + Value Objects 135 - The Repository Pattern + The Repository Pattern 136 @@ -11610,25 +11649,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 138 - The Specification Pattern + The Specification Pattern 139 - Repository ♥ Specification + The Specification Pattern 140 - Combine Them! + Repository ♥ Specification 141 @@ -11640,169 +11679,169 @@

    Table of Contents

    - Specification For Business Rules + Combine Them! 143 - Sessions + Specification For Business Rules 144 - Overview + Sessions 145 - Code Please + Overview 146 - Security Concerns + Code Please 147 - Session Configuration + Security Concerns 148 - Authentication + Session Configuration 149 - What You Have Right Now + Authentication 150 - The Big Picture + What You Have Right Now 151 - The Interceptor Pattern + The Big Picture 152 - Introducing the Event Dispatcher + The Interceptor Pattern 153 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 154 - The Firewall (1/2) + Using the EventDispatcherTrait 155 - The Firewall (2/2) + The Firewall (1/2) 156 - Implementing The Firewall + The Firewall (2/2) 157 - Authentication Mechanism + Implementing The Firewall 158 - Adding New Routes + Authentication Mechanism 159 - Stateless Authentication + Adding New Routes 160 - Basic Security Thinking + Stateless Authentication 161 - Writing Better Code + Basic Security Thinking 162 - Agenda + Writing Better Code 163 - Coding Standards + Agenda 164 - PHP Coding Standards Fixer + Coding Standards 165 - Programming To The Interface + PHP Coding Standards Fixer 166 - Dependency Inversion Principle (DIP) + Programming To The Interface 167 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 168 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 169 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 170 @@ -11820,19 +11859,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 173 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 174 - PHP Implementations + Dependency Injection Container (DIC) 175 @@ -11844,43 +11883,49 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 177 - From STUPID to SOLID code! (1/2) + Component Driven Development 178 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 179 - Object Calisthenics + From STUPID to SOLID code! (2/2) 180 - - + Object Calisthenics 181 - Testing + - 182 - + Testing + 183 + + + + +
    - 183 - - - - - Agenda 184 - Unit Testing + Agenda 185 @@ -11912,31 +11951,31 @@

    Table of Contents

    - PHPUnit — The Rules + Unit Testing 187 - PHPUnit — Assertions + PHPUnit — The Rules 188 - Running PHPUnit + PHPUnit — Assertions 189 - Test Double + Running PHPUnit 190 - Functional Testing + Test Double 191 @@ -11948,7 +11987,7 @@

    Table of Contents

    - Behavior Driven Development + Functional Testing 193 @@ -11960,137 +11999,143 @@

    Table of Contents

    - Behat + Behavior Driven Development 195 - Using Behat (1/2) + Behat 196 - Using Behat (2/2) + Using Behat (1/2) 197 - Testing Tweet Frameworks + Using Behat (2/2) 198 - Awesome Projects + Testing Tweet Frameworks 199 - Assert + Awesome Projects 200 - Carbon + Assert 201 - Faker + Carbon 202 - Flysystem + Faker 203 - Mockery + Flysystem 204 - Option Type for PHP + Mockery 205 - PHP-Parser + Option Type for PHP 206 -
    React
    + PHP-Parser 207 - Swiftmailer +
    React
    208 - Whoops + Swiftmailer 209 - Embracing Open Source + Whoops 210 - + Embracing Open Source 211 - + 212 - + 213 - Golden Rules + 214 - The End. + Golden Rules 215 - Well... Maybe Not.
    PHP Extended + The End. 216 + + Well... Maybe Not.
    PHP Extended + 217 + + + diff --git a/isima.html b/isima.html index 2b2d587..ffd8c61 100644 --- a/isima.html +++ b/isima.html @@ -1302,7 +1302,7 @@ @@ -1332,7 +1332,7 @@ @@ -1362,7 +1362,7 @@ @@ -1392,7 +1392,7 @@ @@ -1422,7 +1422,7 @@ @@ -1474,7 +1474,7 @@ @@ -1504,7 +1504,7 @@ @@ -1534,7 +1534,7 @@ @@ -1575,7 +1575,7 @@

    Week #4

    @@ -1605,7 +1605,7 @@

    Week #4

    @@ -1642,7 +1642,7 @@

    Week #4

    @@ -1680,7 +1680,7 @@

    Week #4

    @@ -1695,7 +1695,7 @@

    Week #4

    Mac OS X

    -
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.5
    +
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6
     
    @@ -1718,7 +1718,7 @@

    Week #4

    @@ -1754,7 +1754,7 @@

    Week #4

    @@ -1791,7 +1791,7 @@

    Week #4

    @@ -1821,7 +1821,7 @@

    Week #4

    @@ -1851,7 +1851,7 @@

    Week #4

    @@ -1891,7 +1891,7 @@

    Week #4

    @@ -1945,7 +1945,7 @@

    Timing Attack Safe String Comparison

    @@ -2003,7 +2003,7 @@

    Timing Attack Safe String Comparison

    @@ -2048,7 +2048,7 @@

    Abstract class definition

    @@ -2102,7 +2102,7 @@

    Abstract class definition

    @@ -2143,7 +2143,7 @@

    The Rules

    @@ -2203,7 +2203,7 @@

    The Rules

    @@ -2256,7 +2256,7 @@

    Type Hinting

    @@ -2303,7 +2303,7 @@

    Usage

    @@ -2353,7 +2353,7 @@

    Usage

    @@ -2403,7 +2403,7 @@

    Usage

    @@ -2464,7 +2464,7 @@

    Usage

    @@ -2510,7 +2510,7 @@

    Usage

    @@ -2557,7 +2557,7 @@

    Argument Unpacking

    @@ -2611,7 +2611,7 @@

    Usage

    @@ -2638,8 +2638,8 @@

    Usage

    PSR-0

    -

    PSR-0 -describes a set of rules related to namespaces for autoloader interoperability.

    +

    PSR-0 describes a set of rules related to +namespaces for autoloader interoperability:

    \ns\package\Class_Name      => vendor/ns/package/Class/Name.php
     \ns\package_name\Class_Name => vendor/ns/package_name/Class/Name.php
     
    @@ -2661,7 +2661,7 @@

    PSR-0

    @@ -2710,7 +2710,7 @@

    PSR-0

    @@ -2764,7 +2764,7 @@

    PSR-0

    @@ -2809,7 +2809,7 @@

    PSR-0

    @@ -2857,7 +2857,7 @@

    PSR-0

    @@ -2902,7 +2902,7 @@

    PSR-0

    @@ -2945,7 +2945,7 @@

    PSR-0

    @@ -2975,7 +2975,7 @@

    PSR-0

    @@ -3029,7 +3029,7 @@

    PSR-0

    @@ -3079,7 +3079,7 @@

    PSR-0

    @@ -3133,7 +3133,7 @@

    PSR-0

    @@ -3163,7 +3163,7 @@

    PSR-0

    @@ -3205,7 +3205,7 @@

    PSR-0

    @@ -3251,7 +3251,7 @@

    Collections

    @@ -3298,7 +3298,7 @@

    Collections

    @@ -3340,7 +3340,7 @@

    Collections

    @@ -3392,7 +3392,7 @@

    Collections

    @@ -3418,7 +3418,10 @@

    3xx Redirections

  • 301 Moved Permanently
  • 302 Found
  • 304 Not Modified
  • -
    + +
    +

    httpstatus.es

    +
    @@ -3436,7 +3439,7 @@

    3xx Redirections

    @@ -3482,7 +3485,7 @@

    5xx Server Error

    @@ -3529,7 +3532,7 @@

    5xx Server Error

    @@ -3581,7 +3584,7 @@

    5xx Server Error

    @@ -3611,7 +3614,7 @@

    5xx Server Error

    @@ -3654,7 +3657,7 @@

    5xx Server Error

    @@ -3688,7 +3691,7 @@

    5xx Server Error

    @@ -3727,7 +3730,7 @@

    5xx Server Error

    @@ -3766,7 +3769,7 @@

    5xx Server Error

    @@ -3805,7 +3808,7 @@

    5xx Server Error

    @@ -3843,7 +3846,7 @@

    5xx Server Error

    @@ -3873,7 +3876,7 @@

    5xx Server Error

    @@ -3927,7 +3930,7 @@

    Hyper Media Types

    @@ -3981,7 +3984,7 @@

    Hyper Media Types

    @@ -4035,7 +4038,7 @@

    Hyper Media Types

    @@ -4065,7 +4068,7 @@

    Hyper Media Types

    @@ -4116,7 +4119,7 @@

    Hyper Media Types

    @@ -4168,7 +4171,7 @@

    Hyper Media Types

    @@ -4217,7 +4220,7 @@

    Hyper Media Types

    @@ -4268,7 +4271,7 @@

    Hyper Media Types

    @@ -4309,7 +4312,7 @@

    spl_autoload_functions()

    @@ -4360,7 +4363,7 @@

    spl_autoload_unregister()

    @@ -4417,7 +4420,56 @@

    spl_autoload_unregister()

    + + + + + +
    +
    +
    + +

    PSR-0 vs PSR-4

    + + +

    PSR-0

    +
    \Zend\Mail\Message
    +// => /path/to/project/lib/vendor/Zend/Mail/Message.php
    +
    + +

    + +
    Zend_Mail_Message
    +// => /path/to/project/lib/vendor/Zend/Mail/Message.php
    +
    + +

    Important: as of 2014-10-21 PSR-0 has been marked as deprecated.

    +

    PSR-4

    +

    Like PSR-0, but better:

    +
      +
    • more concise folder structure;
    • +
    • remove the remnants of PSR-0 (e.g. PEAR support).
    • +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -4447,7 +4499,7 @@

    spl_autoload_unregister()

    @@ -4494,7 +4546,7 @@

    Traversable

    @@ -4547,7 +4599,7 @@

    Traversable

    @@ -4600,7 +4652,7 @@

    Traversable

    @@ -4644,7 +4696,7 @@

    SPL Functions

    @@ -4699,7 +4751,7 @@

    SPL Functions

    @@ -4750,7 +4802,7 @@

    SPL Functions

    @@ -4775,15 +4827,16 @@

    SPL Functions

    Create your own exceptions:

    -
    class MyException extends RuntimeException
    +
    class SomethingWentWrong extends RuntimeException
     {
     }
     
    -class MyException extends Exception implements ExceptionInterface
    +class ErrorWhileDoingSomething extends Exception implements ExceptionInterface
     {
     }
     
    - + +

    Name your named exceptions!

    @@ -4801,7 +4854,7 @@

    SPL Functions

    @@ -4843,7 +4896,7 @@

    SPL Functions

    @@ -4896,7 +4949,7 @@

    SPL Functions

    @@ -4940,7 +4993,7 @@

    SPL Functions

    @@ -4970,7 +5023,7 @@

    SPL Functions

    @@ -5016,7 +5069,7 @@

    SPL Functions

    @@ -5038,8 +5091,8 @@

    SPL Functions

    } -

    You can also require a library by using the composer command:

    -
    $ php composer.phar require "willdurand/geocoder:~2.0"
    +

    You can also require a library by using the require command:

    +
    $ php composer.phar require willdurand/geocoder
     

    Run the following command to download and install the project dependencies into @@ -5068,7 +5121,7 @@

    SPL Functions

    @@ -5082,9 +5135,10 @@

    SPL Functions

    Composer Autoloader

    -

    Composer automatically generates a PSR-0 compliant and optimized autoloader for -your entire application. Thanks to Composer, you don't have to take care about -how to autoload classes/functions anymore.

    +

    Composer automatically generates a PSR-4 +compliant and optimized autoloader for your entire application. Thanks to +Composer, you don't have to take care about how to autoload classes/functions +anymore.

    Require the generated autoloader in your project as follows:

    <?php
     
    @@ -5113,7 +5167,7 @@ 

    SPL Functions

    @@ -5143,7 +5197,7 @@

    SPL Functions

    @@ -5158,25 +5212,13 @@

    SPL Functions

    Typical client request process in MVC architecture:

    -

    -
    +

    Notes

    -
      -
    1. Client makes a request
    2. -
    3. Controller handles request:
        -
      • interactions with model
      • -
      • data preparation
      • -
      • send data to view
      • -
      -
    4. -
    5. View format data
    6. -
    -
    @@ -5188,7 +5230,7 @@

    SPL Functions

    @@ -5238,7 +5280,7 @@

    SPL Functions

    @@ -5293,7 +5335,7 @@

    SPL Functions

    @@ -5342,7 +5384,7 @@

    Usage

    @@ -5393,7 +5435,7 @@

    Usage

    @@ -5447,7 +5489,7 @@

    Usage

    @@ -5492,7 +5534,7 @@

    Centralized Declaration

    @@ -5507,7 +5549,7 @@

    Centralized Declaration

    A controller that handles all requests for a web application:

    -

    +

    This controller dispatches the request to the specialized controllers.

    It is usually tied to URL rewriting.

    @@ -5527,7 +5569,7 @@

    Centralized Declaration

    @@ -5557,7 +5599,7 @@

    Centralized Declaration

    @@ -5595,7 +5637,7 @@

    Centralized Declaration

    @@ -5632,7 +5674,7 @@

    Centralized Declaration

    @@ -5675,7 +5717,7 @@

    Centralized Declaration

    @@ -5705,7 +5747,7 @@

    Centralized Declaration

    @@ -5762,7 +5804,7 @@

    Centralized Declaration

    @@ -5810,7 +5852,7 @@

    Centralized Declaration

    @@ -5859,7 +5901,7 @@

    Centralized Declaration

    @@ -5889,7 +5931,7 @@

    Centralized Declaration

    @@ -5939,7 +5981,7 @@

    CRUD

    @@ -5988,7 +6030,7 @@

    CRUD

    @@ -6038,7 +6080,7 @@

    CRUD

    @@ -6092,7 +6134,7 @@

    CRUD

    @@ -6139,7 +6181,7 @@

    CRUD

    @@ -6188,7 +6230,7 @@

    CRUD

    @@ -6218,7 +6260,7 @@

    CRUD

    @@ -6267,7 +6309,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6324,7 +6366,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6354,7 +6396,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6409,7 +6451,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6456,7 +6498,7 @@

    Remove

    @@ -6486,7 +6528,7 @@

    Remove

    @@ -6535,7 +6577,7 @@

    Remove

    @@ -6565,7 +6607,7 @@

    Remove

    @@ -6610,7 +6652,7 @@

    PHP Data Object (PDO)

    @@ -6661,7 +6703,7 @@

    Usage

    @@ -6717,7 +6759,7 @@

    Usage

    @@ -6766,7 +6808,7 @@

    Usage

    @@ -6796,7 +6838,7 @@

    Usage

    @@ -6835,7 +6877,7 @@

    Usage

    @@ -6873,7 +6915,7 @@

    Code Snippet

    @@ -6911,7 +6953,7 @@

    Code Snippet

    @@ -6955,7 +6997,7 @@

    Code Snippet

    @@ -6997,7 +7039,7 @@

    Doctrine2 ORM

    @@ -7027,7 +7069,7 @@

    Doctrine2 ORM

    @@ -7083,7 +7125,7 @@

    Doctrine2 ORM

    @@ -7140,7 +7182,7 @@

    Doctrine2 ORM

    @@ -7170,7 +7212,7 @@

    Doctrine2 ORM

    @@ -7221,7 +7263,7 @@

    Doctrine2 ORM

    @@ -7262,7 +7304,7 @@

    Doctrine2 ORM

    @@ -7292,7 +7334,7 @@

    Doctrine2 ORM

    @@ -7350,7 +7392,7 @@

    Doctrine2 ORM

    @@ -7398,7 +7440,7 @@

    Usage

    @@ -7459,7 +7501,7 @@

    Usage

    @@ -7517,7 +7559,7 @@

    Usage

    @@ -7567,7 +7609,7 @@

    Usage

    @@ -7597,7 +7639,7 @@

    Usage

    @@ -7642,7 +7684,7 @@

    A few use cases:

    @@ -7693,7 +7735,7 @@

    A few use cases:

    @@ -7739,7 +7781,7 @@

    Workarounds

    @@ -7793,7 +7835,7 @@

    Workarounds

    @@ -7823,7 +7865,7 @@

    Workarounds

    @@ -7858,7 +7900,7 @@

    Workarounds

    @@ -7891,7 +7933,7 @@

    Workarounds

    @@ -7934,7 +7976,7 @@

    Event Dispatcher

    @@ -7984,7 +8026,7 @@

    Event Dispatcher

    @@ -8038,7 +8080,7 @@

    Event Dispatcher

    @@ -8084,7 +8126,7 @@

    Event Dispatcher

    @@ -8126,7 +8168,7 @@

    Event Dispatcher

    @@ -8185,7 +8227,7 @@

    Event Dispatcher

    @@ -8218,7 +8260,7 @@

    Event Dispatcher

    @@ -8277,7 +8319,7 @@

    Event Dispatcher

    @@ -8315,7 +8357,7 @@

    WSSE Username Token

    @@ -8361,7 +8403,7 @@

    WSSE Username Token

    @@ -8391,7 +8433,7 @@

    WSSE Username Token

    @@ -8433,7 +8475,7 @@

    WSSE Username Token

    @@ -8492,7 +8534,7 @@

    WSSE Username Token

    @@ -8538,7 +8580,7 @@

    Usage

    @@ -8585,7 +8627,7 @@

    Usage

    @@ -8625,7 +8667,7 @@

    Usage

    @@ -8677,7 +8719,7 @@

    Usage

    @@ -8733,7 +8775,7 @@

    Usage

    @@ -8777,7 +8819,7 @@

    Usage

    @@ -8821,7 +8863,7 @@

    Usage

    @@ -8872,7 +8914,7 @@

    Usage

    @@ -8907,7 +8949,7 @@

    Usage

    @@ -8952,7 +8994,7 @@

    Usage

    @@ -9003,7 +9045,7 @@

    Usage

    @@ -9048,7 +9090,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9087,7 +9129,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9131,7 +9173,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9174,7 +9216,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9222,7 +9264,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9252,7 +9294,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9282,7 +9324,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9312,7 +9354,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9760,115 +9802,115 @@

    Table of Contents

    - Leveraging PHP APIs + PSR-0 vs PSR-4 73 - Built-in Interfaces + Leveraging PHP APIs 74 - The Reflection API (1/2) + Built-in Interfaces 75 - The Reflection API (2/2) + The Reflection API (1/2) 76 - The Standard PHP Library (SPL) + The Reflection API (2/2) 77 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 78 - Observer Pattern (2/2) + Observer Pattern (1/2) 79 - Exceptions (1/2) + Observer Pattern (2/2) 80 - Exceptions (2/2) + Exceptions (1/2) 81 - Password Hashing + Exceptions (2/2) 82 - PHP Archive (PHAR) + Password Hashing 83 - Dependency Management + PHP Archive (PHAR) 84 - Composer + Dependency Management 85 - composer install + Composer 86 - Composer Autoloader + composer install 87 - Model View Controller + Composer Autoloader 88 - MVC Overview + Model View Controller 89 - The Model + MVC Overview 90 - The View + The Model 91 @@ -9886,55 +9928,55 @@

    Table of Contents

    - The Controller + The View 94 - Routing + The Controller 95 - Front Controller Pattern + Routing 96 - Databases + Front Controller Pattern 97 - Agenda + Databases 98 - Quick note + Agenda 99 - Database Design Patterns + Quick note 100 - Row Data Gateway + Database Design Patterns 101 - Row Data Gateway + Row Data Gateway 102 @@ -9952,13 +9994,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 105 - Table Data Gateway + Table Data Gateway 106 @@ -9994,13 +10036,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 112 - Active Record + Active Record 113 @@ -10012,13 +10054,13 @@

    Table of Contents

    - Data Mapper + Active Record 115 - Data Mapper + Data Mapper 116 @@ -10030,31 +10072,31 @@

    Table of Contents

    - Identity Map + Data Mapper 118 - Identity Map + Identity Map 119 - Data Access Layer + Identity Map 120 - Data Access Layer / Data Source Name + Data Access Layer 121 - Data Access Layer + Data Access Layer / Data Source Name 122 @@ -10072,67 +10114,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 125 - Object Relational Mapping (1/4) + Object Relational Mapping 126 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 127 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 128 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 129 - Existing Components + Object Relational Mapping (4/4) 130 - A Note About
    Domain-Driven Design
    + Existing Components 131 - Entities + A Note About
    Domain-Driven Design
    132 - Value Objects + Entities 133 - The Repository Pattern + Value Objects 134 - The Repository Pattern + The Repository Pattern 135 @@ -10144,25 +10186,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 137 - The Specification Pattern + The Specification Pattern 138 - Repository ♥ Specification + The Specification Pattern 139 - Combine Them! + Repository ♥ Specification 140 @@ -10174,169 +10216,169 @@

    Table of Contents

    - Specification For Business Rules + Combine Them! 142 - Sessions + Specification For Business Rules 143 - Overview + Sessions 144 - Code Please + Overview 145 - Security Concerns + Code Please 146 - Session Configuration + Security Concerns 147 - Authentication + Session Configuration 148 - What You Have Right Now + Authentication 149 - The Big Picture + What You Have Right Now 150 - The Interceptor Pattern + The Big Picture 151 - Introducing the Event Dispatcher + The Interceptor Pattern 152 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 153 - The Firewall (1/2) + Using the EventDispatcherTrait 154 - The Firewall (2/2) + The Firewall (1/2) 155 - Implementing The Firewall + The Firewall (2/2) 156 - Authentication Mechanism + Implementing The Firewall 157 - Adding New Routes + Authentication Mechanism 158 - Stateless Authentication + Adding New Routes 159 - Basic Security Thinking + Stateless Authentication 160 - Writing Better Code + Basic Security Thinking 161 - Agenda + Writing Better Code 162 - Coding Standards + Agenda 163 - PHP Coding Standards Fixer + Coding Standards 164 - Programming To The Interface + PHP Coding Standards Fixer 165 - Dependency Inversion Principle (DIP) + Programming To The Interface 166 - Dependency Injection (DI) + Dependency Inversion Principle (DIP) 167 - Dependency Injection (Anti) Pattern + Dependency Injection (DI) 168 - Dependency Injection Patterns + Dependency Injection (Anti) Pattern 169 @@ -10354,19 +10396,19 @@

    Table of Contents

    - Inversion of Control (IoC) + Dependency Injection Patterns 172 - Dependency Injection Container (DIC) + Inversion of Control (IoC) 173 - PHP Implementations + Dependency Injection Container (DIC) 174 @@ -10378,47 +10420,53 @@

    Table of Contents

    - Component Driven Development + PHP Implementations 176 - From STUPID to SOLID code! (1/2) + Component Driven Development 177 - From STUPID to SOLID code! (2/2) + From STUPID to SOLID code! (1/2) 178 - Object Calisthenics + From STUPID to SOLID code! (2/2) 179 - - + Object Calisthenics 180 - Next Week:
    Web Security 101
    + - 181 - The End. + Next Week:
    Web Security 101
    182 + + The End. + 183 + + + From 84b9b45bb297f0a617d17fa88ff07a2e18556aef Mon Sep 17 00:00:00 2001 From: William Durand Date: Sun, 25 Jan 2015 23:01:20 +0100 Subject: [PATCH 60/71] Publish slides (Sun Jan 25 23:01:20 CET 2015) --- index.html | 4 ++-- isima.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 2ad86ed..bf0a937 100644 --- a/index.html +++ b/index.html @@ -2648,14 +2648,14 @@

    PSR-0

    A closure is an anonymous function that owns a context.

    $fibonacci = function ($n) use (&$fibonacci) {
         if (0 === $n || 1 === $n) {
    -        return 1;
    +        return $n;
         }
     
         return $fibonacci($n - 1) + $fibonacci($n - 2);
     };
     
     echo (int) $fibonacci(6);
    -=> 13
    +=> 8
     
    diff --git a/isima.html b/isima.html index ffd8c61..3d318bb 100644 --- a/isima.html +++ b/isima.html @@ -2826,14 +2826,14 @@

    PSR-0

    A closure is an anonymous function that owns a context.

    $fibonacci = function ($n) use (&$fibonacci) {
         if (0 === $n || 1 === $n) {
    -        return 1;
    +        return $n;
         }
     
         return $fibonacci($n - 1) + $fibonacci($n - 2);
     };
     
     echo (int) $fibonacci(6);
    -=> 13
    +=> 8
     
    From d4f02edd6b5e1f218d80e671b312564259fb9296 Mon Sep 17 00:00:00 2001 From: William Durand Date: Wed, 28 Jan 2015 09:49:41 +0100 Subject: [PATCH 61/71] Publish slides (Wed Jan 28 09:49:41 CET 2015) --- index.html | 80 ++-- isima.html | 1356 +++++++--------------------------------------------- 2 files changed, 212 insertions(+), 1224 deletions(-) diff --git a/index.html b/index.html index bf0a937..e9f80f8 100644 --- a/index.html +++ b/index.html @@ -8435,7 +8435,7 @@

    WSSE Username Token

    - +
    @@ -8453,7 +8453,7 @@

    WSSE Username Token

    @@ -8465,7 +8465,7 @@

    WSSE Username Token

    - +
    @@ -8495,7 +8495,7 @@

    WSSE Username Token

    @@ -8507,7 +8507,7 @@

    WSSE Username Token

    - +
    @@ -8554,7 +8554,7 @@

    WSSE Username Token

    @@ -8566,7 +8566,7 @@

    WSSE Username Token

    - +
    @@ -8600,7 +8600,7 @@

    Usage

    @@ -8612,7 +8612,7 @@

    Usage

    - +
    @@ -8647,7 +8647,7 @@

    Usage

    @@ -8659,7 +8659,7 @@

    Usage

    - +
    @@ -8687,7 +8687,7 @@

    Usage

    @@ -8699,7 +8699,7 @@

    Usage

    - +
    @@ -8739,7 +8739,7 @@

    Usage

    @@ -8751,7 +8751,7 @@

    Usage

    - +
    @@ -8795,7 +8795,7 @@

    Usage

    @@ -8807,7 +8807,7 @@

    Usage

    - +
    @@ -8839,7 +8839,7 @@

    Usage

    @@ -8851,7 +8851,7 @@

    Usage

    - +
    @@ -8883,7 +8883,7 @@

    Usage

    @@ -8895,7 +8895,7 @@

    Usage

    - +
    @@ -8934,7 +8934,7 @@

    Usage

    @@ -8946,7 +8946,7 @@

    Usage

    - +
    @@ -8969,7 +8969,7 @@

    Usage

    @@ -8981,7 +8981,7 @@

    Usage

    - +
    @@ -9014,7 +9014,7 @@

    Usage

    @@ -9026,7 +9026,7 @@

    Usage

    - +
    @@ -9065,7 +9065,7 @@

    Usage

    @@ -9077,7 +9077,7 @@

    Usage

    - +
    @@ -9110,7 +9110,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9122,7 +9122,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -9149,7 +9149,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9161,7 +9161,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -9193,7 +9193,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9205,7 +9205,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -9236,7 +9236,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9248,7 +9248,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -9284,7 +9284,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9296,7 +9296,7 @@

    The Symfony2 DependencyInjection Component

    - +
    @@ -9314,7 +9314,7 @@

    The Symfony2 DependencyInjection Component

    diff --git a/isima.html b/isima.html index 3d318bb..c8be81f 100644 --- a/isima.html +++ b/isima.html @@ -1302,7 +1302,7 @@
    @@ -1332,7 +1332,7 @@
    @@ -1362,7 +1362,7 @@
    @@ -1392,7 +1392,7 @@
    @@ -1422,7 +1422,7 @@
    @@ -1474,7 +1474,7 @@
    @@ -1504,7 +1504,7 @@
    @@ -1534,7 +1534,7 @@
    @@ -1548,15 +1548,14 @@

    Agenda

    -

    Week #1

    +

    Week #1

    PHP: Hypertext Preprocessor, The PHP Syntax, The PHP Command Line, Client/Server, REST

    -

    Week #2

    -

    Autoloading, Leveraging PHP APIs, Dependency Management, Model View Controller, -Databases

    -

    Week #3

    -

    A Note About Domain-Driven Design, Sessions, Authentication, Writing Better Code

    -

    Week #4

    +

    Week #2

    +

    Autoloading, Leveraging PHP APIs, Dependency Management, Model View Controller

    +

    Week #3

    +

    Databases, Sessions, Authentication

    +

    Week #4

    Security 101

    @@ -1575,7 +1574,7 @@

    Week #4

    @@ -1605,7 +1604,7 @@

    Week #4

    @@ -1642,7 +1641,7 @@

    Week #4

    @@ -1680,7 +1679,7 @@

    Week #4

    @@ -1718,7 +1717,7 @@

    Week #4

    @@ -1754,7 +1753,7 @@

    Week #4

    @@ -1791,7 +1790,7 @@

    Week #4

    @@ -1821,7 +1820,7 @@

    Week #4

    @@ -1851,7 +1850,7 @@

    Week #4

    @@ -1891,7 +1890,7 @@

    Week #4

    @@ -1945,7 +1944,7 @@

    Timing Attack Safe String Comparison

    @@ -2003,7 +2002,7 @@

    Timing Attack Safe String Comparison

    @@ -2048,7 +2047,7 @@

    Abstract class definition

    @@ -2102,7 +2101,7 @@

    Abstract class definition

    @@ -2143,7 +2142,7 @@

    The Rules

    @@ -2203,7 +2202,7 @@

    The Rules

    @@ -2256,7 +2255,7 @@

    Type Hinting

    @@ -2303,7 +2302,7 @@

    Usage

    @@ -2353,7 +2352,7 @@

    Usage

    @@ -2403,7 +2402,7 @@

    Usage

    @@ -2464,7 +2463,7 @@

    Usage

    @@ -2510,7 +2509,7 @@

    Usage

    @@ -2557,7 +2556,7 @@

    Argument Unpacking

    @@ -2611,7 +2610,7 @@

    Usage

    @@ -2661,7 +2660,7 @@

    PSR-0

    @@ -2710,7 +2709,7 @@

    PSR-0

    @@ -2764,7 +2763,7 @@

    PSR-0

    @@ -2809,7 +2808,7 @@

    PSR-0

    @@ -2857,7 +2856,7 @@

    PSR-0

    @@ -2902,7 +2901,7 @@

    PSR-0

    @@ -2945,7 +2944,7 @@

    PSR-0

    @@ -2975,7 +2974,7 @@

    PSR-0

    @@ -3029,7 +3028,7 @@

    PSR-0

    @@ -3079,7 +3078,7 @@

    PSR-0

    @@ -3133,7 +3132,7 @@

    PSR-0

    @@ -3163,7 +3162,7 @@

    PSR-0

    @@ -3205,7 +3204,7 @@

    PSR-0

    @@ -3251,7 +3250,7 @@

    Collections

    @@ -3298,7 +3297,7 @@

    Collections

    @@ -3340,7 +3339,7 @@

    Collections

    @@ -3392,7 +3391,7 @@

    Collections

    @@ -3439,7 +3438,7 @@

    3xx Redirections

    @@ -3485,7 +3484,7 @@

    5xx Server Error

    @@ -3532,7 +3531,7 @@

    5xx Server Error

    @@ -3584,7 +3583,7 @@

    5xx Server Error

    @@ -3614,7 +3613,7 @@

    5xx Server Error

    @@ -3657,7 +3656,7 @@

    5xx Server Error

    @@ -3691,7 +3690,7 @@

    5xx Server Error

    @@ -3730,7 +3729,7 @@

    5xx Server Error

    @@ -3769,7 +3768,7 @@

    5xx Server Error

    @@ -3808,7 +3807,7 @@

    5xx Server Error

    @@ -3846,7 +3845,7 @@

    5xx Server Error

    @@ -3876,7 +3875,7 @@

    5xx Server Error

    @@ -3930,7 +3929,7 @@

    Hyper Media Types

    @@ -3984,7 +3983,7 @@

    Hyper Media Types

    @@ -4038,7 +4037,7 @@

    Hyper Media Types

    @@ -4068,7 +4067,7 @@

    Hyper Media Types

    @@ -4119,7 +4118,7 @@

    Hyper Media Types

    @@ -4171,7 +4170,7 @@

    Hyper Media Types

    @@ -4220,7 +4219,7 @@

    Hyper Media Types

    @@ -4271,7 +4270,7 @@

    Hyper Media Types

    @@ -4312,7 +4311,7 @@

    spl_autoload_functions()

    @@ -4363,7 +4362,7 @@

    spl_autoload_unregister()

    @@ -4420,7 +4419,7 @@

    spl_autoload_unregister()

    @@ -4469,7 +4468,7 @@

    PSR-4

    @@ -4499,7 +4498,7 @@

    PSR-4

    @@ -4546,7 +4545,7 @@

    Traversable

    @@ -4599,7 +4598,7 @@

    Traversable

    @@ -4652,7 +4651,7 @@

    Traversable

    @@ -4696,7 +4695,7 @@

    SPL Functions

    @@ -4751,7 +4750,7 @@

    SPL Functions

    @@ -4802,7 +4801,7 @@

    SPL Functions

    @@ -4854,7 +4853,7 @@

    SPL Functions

    @@ -4896,7 +4895,7 @@

    SPL Functions

    @@ -4949,7 +4948,7 @@

    SPL Functions

    @@ -4993,7 +4992,7 @@

    SPL Functions

    @@ -5023,7 +5022,7 @@

    SPL Functions

    @@ -5069,7 +5068,7 @@

    SPL Functions

    @@ -5121,7 +5120,7 @@

    SPL Functions

    @@ -5167,7 +5166,7 @@

    SPL Functions

    @@ -5197,7 +5196,7 @@

    SPL Functions

    @@ -5230,7 +5229,7 @@

    SPL Functions

    @@ -5280,7 +5279,7 @@

    SPL Functions

    @@ -5335,7 +5334,7 @@

    SPL Functions

    @@ -5384,7 +5383,7 @@

    Usage

    @@ -5435,7 +5434,7 @@

    Usage

    @@ -5489,7 +5488,7 @@

    Usage

    @@ -5534,7 +5533,7 @@

    Centralized Declaration

    @@ -5569,7 +5568,7 @@

    Centralized Declaration

    @@ -5599,7 +5598,7 @@

    Centralized Declaration

    @@ -5637,7 +5636,7 @@

    Centralized Declaration

    @@ -5674,7 +5673,7 @@

    Centralized Declaration

    @@ -5717,7 +5716,7 @@

    Centralized Declaration

    @@ -5747,7 +5746,7 @@

    Centralized Declaration

    @@ -5804,7 +5803,7 @@

    Centralized Declaration

    @@ -5852,7 +5851,7 @@

    Centralized Declaration

    @@ -5901,7 +5900,7 @@

    Centralized Declaration

    @@ -5931,7 +5930,7 @@

    Centralized Declaration

    @@ -5981,7 +5980,7 @@

    CRUD

    @@ -6030,7 +6029,7 @@

    CRUD

    @@ -6080,7 +6079,7 @@

    CRUD

    @@ -6134,7 +6133,7 @@

    CRUD

    @@ -6181,7 +6180,7 @@

    CRUD

    @@ -6230,7 +6229,7 @@

    CRUD

    @@ -6260,7 +6259,7 @@

    CRUD

    @@ -6309,7 +6308,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6366,7 +6365,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6396,7 +6395,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6451,7 +6450,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6498,7 +6497,7 @@

    Remove

    @@ -6528,7 +6527,7 @@

    Remove

    @@ -6577,7 +6576,7 @@

    Remove

    @@ -6607,7 +6606,7 @@

    Remove

    @@ -6652,7 +6651,7 @@

    PHP Data Object (PDO)

    @@ -6703,7 +6702,7 @@

    Usage

    @@ -6759,7 +6758,7 @@

    Usage

    @@ -6808,7 +6807,7 @@

    Usage

    @@ -6838,7 +6837,7 @@

    Usage

    @@ -6877,7 +6876,7 @@

    Usage

    @@ -6915,7 +6914,7 @@

    Code Snippet

    @@ -6953,7 +6952,7 @@

    Code Snippet

    @@ -6997,7 +6996,7 @@

    Code Snippet

    @@ -7039,7 +7038,7 @@

    Doctrine2 ORM

    @@ -7069,7 +7068,7 @@

    Doctrine2 ORM

    @@ -7125,7 +7124,7 @@

    Doctrine2 ORM

    @@ -7182,7 +7181,7 @@

    Doctrine2 ORM

    @@ -7212,7 +7211,7 @@

    Doctrine2 ORM

    @@ -7263,7 +7262,7 @@

    Doctrine2 ORM

    @@ -7304,7 +7303,7 @@

    Doctrine2 ORM

    @@ -7334,7 +7333,7 @@

    Doctrine2 ORM

    @@ -7392,7 +7391,7 @@

    Doctrine2 ORM

    @@ -7440,7 +7439,7 @@

    Usage

    @@ -7501,7 +7500,7 @@

    Usage

    @@ -7559,7 +7558,7 @@

    Usage

    @@ -7609,7 +7608,7 @@

    Usage

    @@ -7639,7 +7638,7 @@

    Usage

    @@ -7684,7 +7683,7 @@

    A few use cases:

    @@ -7735,7 +7734,7 @@

    A few use cases:

    @@ -7781,7 +7780,7 @@

    Workarounds

    @@ -7835,7 +7834,7 @@

    Workarounds

    @@ -7865,7 +7864,7 @@

    Workarounds

    @@ -7900,7 +7899,7 @@

    Workarounds

    @@ -7933,7 +7932,7 @@

    Workarounds

    @@ -7976,7 +7975,7 @@

    Event Dispatcher

    @@ -8026,7 +8025,7 @@

    Event Dispatcher

    @@ -8080,7 +8079,7 @@

    Event Dispatcher

    @@ -8126,7 +8125,7 @@

    Event Dispatcher

    @@ -8168,7 +8167,7 @@

    Event Dispatcher

    @@ -8227,7 +8226,7 @@

    Event Dispatcher

    @@ -8260,7 +8259,7 @@

    Event Dispatcher

    @@ -8319,7 +8318,7 @@

    Event Dispatcher

    @@ -8357,7 +8356,7 @@

    WSSE Username Token

    @@ -8403,898 +8402,7 @@

    WSSE Username Token

    - - - - - -
    -
    -
    - -

    Writing Better Code

    - - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Agenda

    - - -
      -
    • Coding Standards
    • -
    • Programming To The Interface
    • -
    • Dependency Inversion Principle (DIP)
    • -
    • Dependency Injection (DI)
    • -
    • Inversion of Control (IoC)
    • -
    • Dependency Injection Container (DIC)
    • -
    • Component Driven Development
    • -
    • From STUPID to SOLID code!
    • -
    • Object Calisthenics
    • -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Coding Standards

    - - -
    <?php
    -
    -namespace Vendor\Model;
    -
    -class Foo
    -{
    -    const VERSION = '1.0';
    -
    -    public $bar = null;
    -
    -    protected $opts;
    -
    -    private $var3 = 123;
    -
    -    public function __construct(BarInterface $bar, array $opts = [])
    -    {
    -        $this->bar  = $bar;
    -        $this->opts = $opts;
    -    }
    -}
    -
    - -
    -

    Read more about coding standards with -PSR-1 -and -PSR-2.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    PHP Coding Standards Fixer

    - - -

    The PHP Coding Standards Fixer tool fixes most issues in your code when -you want to follow the PHP coding standards as defined in the PSR-1 and -PSR-2 documents.

    -

    Installation

    -
    $ wget http://cs.sensiolabs.org/get/php-cs-fixer.phar
    -
    - -

    Usage

    -
    $ php php-cs-fixer.phar fix /path/to/dir/or/file
    -
    - -
    -

    More information at: -http://cs.sensiolabs.org/.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Programming To The Interface

    - - -

    Reduces dependency on implementation specifics and makes code more reusable.

    -

    The BananaController can use either Twig or the raw PHP implementation -as template engine thanks to the TemplateEngine interface:

    -
    interface TemplateEngine
    -{
    -    /**
    -     * @param string $template
    -     * @param array  $parameters
    -     *
    -     * @return string
    -     */
    -    public function render($template, array $parameters = []);
    -}
    -
    - -

    You should think about interfaces, not about internal implementation details.

    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Inversion Principle (DIP)

    - - -

    The Dependency Inversion Principle has two parts:

    -
      -
    • High-level modules should not depend on low-level modules. Both should depend - on abstractions;
    • -
    • Abstractions should not depend upon details. Details should depend upon - abstractions.
    • -
    -

    DIP is about the level of the abstraction in the messages sent from your code to -the thing it is calling.

    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection (DI)

    - - -

    Dependency Injection is about how one object acquires a dependency.

    -
    class Foo
    -{
    -    private $bar;
    -
    -    // **NOT** DI
    -    public function __construct()
    -    {
    -        $this->bar = new Bar();
    -    }
    -}
    -
    - -

    When a dependency is provided externally, then the system is using DI:

    -
    // DI!
    -public function __construct(Bar $bar)
    -{
    -    $this->bar = $bar;
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection (Anti) Pattern

    - - -

    ServiceLocator

    -

    The basic idea behind a service locator is to have an object that knows how to -get hold of all of the services that an application might need.

    -
    class ServiceLocator
    -{
    -    public static function getBar()
    -    {
    -        return new Bar();
    -    }
    -}
    -
    - -

    - -
    class Foo
    -{
    -    private $bar;
    -
    -    public function __construct()
    -    {
    -        $this->bar = ServiceLocator::getBar();
    -    }
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection Patterns

    - - -

    Constructor Injection

    -

    All dependencies are injected using a constructor:

    -
    class Foo
    -{
    -    private $bar;
    -
    -    public function __construct(BarInterface $bar)
    -    {
    -        $this->bar = $bar;
    -    }
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection Patterns

    - - -

    Setter Injection

    -

    Dependencies are injected through setters:

    -
    class Foo
    -{
    -    private $bar;
    -
    -    public function setBar(BarInterface $bar)
    -    {
    -        $this->bar = $bar;
    -    }
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection Patterns

    - - -

    Interface Injection

    -

    An interface describes the injection:

    -
    interface BarAware
    -{
    -    public function setBar(BarInterface $bar);
    -}
    -
    - -

    It needs to be implemented by the class that wants to use a BarInterface:

    -
    class Foo implements BarAware
    -{
    -    private $bar;
    -
    -    public function setBar(BarInterface $bar)
    -    {
    -        $this->bar = $bar;
    -    }
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Inversion of Control (IoC)

    - - -

    Inversion of Control is about who initiates the call. If your code -initiates a call, it is not IoC, if the container/system/library calls back -into code that you provided it, it is IoC.

    -

    Hollywood Principle: Don't call us, we'll call you.

    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Dependency Injection Container (DIC)

    - - -

    A framework or library for building graphs of objects by passing in (injecting) -each object's dependencies. Object lifetimes are handled by the container -instead of by the consuming object.

    -

    Most of the time, you rely on configuration files to describe your classes -and their dependencies. A class in this context is also known as a -service.

    -

    You ask this container to retrieve a service, and it is lazy loaded and -dynamically built:

    -
    // It's an instance of `TemplateEngine`, but you don't know
    -// anything about its internal implementation.
    -// Is it the raw PHP implementation or Twig?
    -$engine = $container->get('template_engine');
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    PHP Implementations

    - - -

    Twittee

    -

    Twittee is the smallest Dependency Injection -Container written in PHP. -It fits in a tweet (less than 140 characters):

    -
    class Container
    -{
    -    protected $s = array();
    -
    -    function __set($k, $c)
    -    {
    -        $this->s[$k] = $c;
    -    }
    -
    -    function __get($k)
    -    {
    -        return $this->s[$k]($this);
    -    }
    -}
    -
    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    PHP Implementations

    - - -

    Pimple

    -

    Pimple is a small Dependency Injection Container -for PHP 5.3 that consists of just one file and one class.

    -

    The Symfony2 DependencyInjection Component

    -

    The DependencyInjection component -allows you to standardize and centralize the way objects are constructed in your -application.

    -
    -

    Read more:

    - -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Component Driven Development

    - - -

    It’s all about Separation of Concerns (SoC).

    -

    You design components with their own logic, each component does one thing -well, and only one thing.

    -

    How to manage these components in your application?

    -
    -

    Read more: Component Driven Development: it's like -Lego!

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    From STUPID to SOLID code! (1/2)

    - - -

    STUPID

    -
      -
    • Singleton
    • -
    • Tight Coupling
    • -
    • Untestability
    • -
    • Premature Optimization
    • -
    • Indescriptive Naming
    • -
    • Duplication
    • -
    -
    -

    Read more: -http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/#stupid-code-seriously.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    From STUPID to SOLID code! (2/2)

    - - -

    SOLID

    -
      -
    • Single Responsibility Principle
    • -
    • Open/Closed Principle
    • -
    • Liskov Substitution Principle
    • -
    • Interface Segregation Principle
    • -
    • Dependency Inversion Principle
    • -
    -
    -

    Read more: -http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/#solid-to-the-rescue.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - -

    Object Calisthenics

    - - -

    9 rules invented by Jeff Bay in his book The ThoughWorks -Anthology:

    -
      -
    1. Only One Level Of Indentation Per Method
    2. -
    3. Don't Use The ELSE Keyword
    4. -
    5. Wrap All Primitives And Strings
    6. -
    7. First Class Collections
    8. -
    9. One Dot Per Line
    10. -
    11. Don't Abbreviate
    12. -
    13. Keep All Entities Small
    14. -
    15. No Classes With More Than Two Instance Variables
    16. -
    17. No Getters/Setters/Properties
    18. -
    -
    -

    Read more: -http://williamdurand.fr/2013/06/03/object-calisthenics/.

    -
    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    - - -



    - -
    -
    -

    Notes

    -
    - -
    -
    -
    - - - -
    @@ -9305,7 +8413,7 @@

    The Symfony2 DependencyInjection Component

    -

    Next Week:
    Web Security 101

    +

    Next Week:
    Web Security 101

    @@ -9324,7 +8432,7 @@

    The Symfony2 DependencyInjection Component

    @@ -9354,7 +8462,7 @@

    The Symfony2 DependencyInjection Component

    @@ -10336,137 +9444,17 @@

    Table of Contents

    - Writing Better Code + Next Week:
    Web Security 101 162 - Agenda + The End. 163 - - Coding Standards - 164 - - - - - PHP Coding Standards Fixer - 165 - - - - - Programming To The Interface - 166 - - - - - Dependency Inversion Principle (DIP) - 167 - - - - - Dependency Injection (DI) - 168 - - - - - Dependency Injection (Anti) Pattern - 169 - - - - - Dependency Injection Patterns - 170 - - - - - Dependency Injection Patterns - 171 - - - - - Dependency Injection Patterns - 172 - - - - - Inversion of Control (IoC) - 173 - - - - - Dependency Injection Container (DIC) - 174 - - - - - PHP Implementations - 175 - - - - - PHP Implementations - 176 - - - - - Component Driven Development - 177 - - - - - From STUPID to SOLID code! (1/2) - 178 - - - - - From STUPID to SOLID code! (2/2) - 179 - - - - - Object Calisthenics - 180 - - - - - - - 181 - - - - - Next Week:
    Web Security 101
    - 182 - - - - - The End. - 183 - - - From 75287b8ea53b88ef7de91ab03e54bd6252e6f0fc Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 14 May 2015 11:17:19 +0200 Subject: [PATCH 62/71] Publish slides (Thu May 14 11:17:19 CEST 2015) --- extended.html | 652 ++++++++++++++++++++++++++++---------------------- 1 file changed, 364 insertions(+), 288 deletions(-) diff --git a/extended.html b/extended.html index dd14725..6018235 100644 --- a/extended.html +++ b/extended.html @@ -1214,7 +1214,7 @@ @@ -1244,7 +1244,7 @@ @@ -1274,7 +1274,7 @@ @@ -1326,7 +1326,7 @@ @@ -1356,7 +1356,7 @@ @@ -1386,7 +1386,7 @@ @@ -1432,7 +1432,7 @@ @@ -1476,7 +1476,7 @@ @@ -1506,7 +1506,7 @@ @@ -1550,7 +1550,7 @@ @@ -1580,7 +1580,7 @@ @@ -1610,7 +1610,7 @@ @@ -1631,7 +1631,7 @@
  • Best Practices.
  • -

    It has been written by ~900 developers.

    +

    It has been written by ~1290 developers.

    Open Source, MIT licensed.

    @@ -1650,7 +1650,7 @@ @@ -1668,10 +1668,10 @@

    They are the foundation of the Symfony full-stack framework, but they can also be used standalone even if you don't use the framework as they don't have any mandatory dependencies.

    -

    There are ~26 components, including:

    +

    There are ~30 components, including:

    BrowserKit              EventDispatcher     OptionsResolver     Translation
    -ClassLoader             ExpressionLanguage  Process             Yaml
    -Config                  Filesystem          PropertyAccess
    +ClassLoader             ExpressionLanguage  Process             VarDumper
    +Config                  Filesystem          PropertyAccess      Yaml
     Console                 Finder              Routing
     CssSelector             Form                Security
     Debug                   HttpFoundation      Serializer
    @@ -1696,7 +1696,7 @@
                 
                 
                 
               
             
    @@ -1710,11 +1710,11 @@

    Getting Ready With Components

    -

    Assuming you want to play with YAML files, start by requiring the symfony/yaml +

    Say you want to play with YAML files, start by requiring the symfony/yaml component into your composer.json file:

    {
         "require": {
    -        "symfony/yaml": "~2.4"
    +        "symfony/yaml": "~2.6"
         }
     }
     
    @@ -1747,7 +1747,7 @@ @@ -1792,7 +1792,7 @@ @@ -1822,7 +1822,7 @@ @@ -1876,7 +1876,7 @@ @@ -1928,7 +1928,7 @@ @@ -1977,7 +1977,7 @@ @@ -2011,7 +2011,7 @@ @@ -2059,7 +2059,7 @@ @@ -2107,7 +2107,7 @@ @@ -2159,7 +2159,7 @@ @@ -2214,7 +2214,7 @@ @@ -2255,7 +2255,7 @@ @@ -2305,7 +2305,7 @@ @@ -2354,7 +2354,7 @@ @@ -2406,7 +2406,7 @@ @@ -2459,7 +2459,7 @@ @@ -2510,7 +2510,7 @@ @@ -2560,7 +2560,7 @@ @@ -2611,7 +2611,7 @@ @@ -2692,7 +2692,7 @@ @@ -2747,7 +2747,7 @@ @@ -2797,7 +2797,7 @@ @@ -2840,7 +2840,37 @@ + + + + + +
    +
    +
    + +

    Read The Best Practices!

    + + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -2870,7 +2900,7 @@
    @@ -2915,7 +2945,7 @@ @@ -2968,7 +2998,7 @@

    Controller Implementation

    @@ -3013,7 +3043,7 @@

    Controller Implementation

    @@ -3067,7 +3097,7 @@

    Controller Implementation

    @@ -3114,7 +3144,7 @@

    Controller Implementation

    @@ -3166,7 +3196,7 @@

    Rendering Templates

    @@ -3215,7 +3245,7 @@

    Rendering Templates

    @@ -3245,7 +3275,7 @@

    Rendering Templates

    @@ -3291,7 +3321,7 @@

    Rendering Templates

    @@ -3332,7 +3362,7 @@

    Rendering Templates

    @@ -3372,7 +3402,7 @@

    Rendering Templates

    @@ -3421,7 +3451,7 @@

    HTTP Method Requirements

    @@ -3470,7 +3500,7 @@

    Prefixing Imported Routes

    @@ -3522,7 +3552,7 @@

    Query String

    @@ -3552,7 +3582,7 @@

    Query String

    @@ -3582,7 +3612,7 @@

    Query String

    @@ -3634,7 +3664,7 @@

    After

    @@ -3675,7 +3705,7 @@

    After

    @@ -3727,7 +3757,7 @@

    After

    @@ -3778,7 +3808,7 @@

    Loops

    @@ -3827,7 +3857,7 @@

    Loops

    @@ -3880,7 +3910,7 @@

    Example

    @@ -3935,7 +3965,7 @@

    Example

    @@ -3986,7 +4016,7 @@

    Example

    @@ -4031,7 +4061,7 @@

    Example

    @@ -4078,7 +4108,7 @@

    Example

    @@ -4119,7 +4149,7 @@

    Example

    @@ -4153,7 +4183,7 @@

    Example

    @@ -4202,7 +4232,7 @@

    Example

    @@ -4232,7 +4262,7 @@

    Example

    @@ -4283,7 +4313,7 @@

    Using the Templating Service

    @@ -4336,7 +4366,7 @@

    Using the Templating Service

    @@ -4388,7 +4418,7 @@

    Cache Busting

    @@ -4440,7 +4470,7 @@

    Cache Busting

    @@ -4479,7 +4509,7 @@

    Cache Busting

    @@ -4509,7 +4539,7 @@

    Cache Busting

    @@ -4547,7 +4577,7 @@

    Cache Busting

    @@ -4583,7 +4613,7 @@

    Cache Busting

    @@ -4638,7 +4668,7 @@

    Cache Busting

    @@ -4688,7 +4718,7 @@

    Cache Busting

    @@ -4743,7 +4773,7 @@

    Optional Dependencies: Setter Injection

    @@ -4789,7 +4819,7 @@

    Container Extensions

    @@ -4843,7 +4873,7 @@

    Container Extensions

    @@ -4895,7 +4925,7 @@

    Container Extensions

    @@ -4942,7 +4972,7 @@

    Container Extensions

    @@ -4997,7 +5027,7 @@

    Container Extensions

    @@ -5046,7 +5076,7 @@

    Container Extensions

    @@ -5096,7 +5126,7 @@

    Debugging Services

    @@ -5126,7 +5156,7 @@

    Debugging Services

    @@ -5177,7 +5207,7 @@

    Global Options

    @@ -5234,7 +5264,7 @@

    Global Options

    @@ -5290,7 +5320,7 @@

    Global Options

    @@ -5344,7 +5374,7 @@

    Usage

    @@ -5398,7 +5428,7 @@

    Usage

    @@ -5450,7 +5480,7 @@

    Usage

    @@ -5505,7 +5535,7 @@

    Calling an existing Command

    @@ -5535,7 +5565,7 @@

    Calling an existing Command

    @@ -5582,7 +5612,7 @@

    Calling an existing Command

    @@ -5623,7 +5653,7 @@

    Calling an existing Command

    @@ -5672,7 +5702,7 @@

    Calling an existing Command

    @@ -5722,7 +5752,7 @@

    Calling an existing Command

    @@ -5755,7 +5785,7 @@

    Calling an existing Command

    @@ -5814,7 +5844,7 @@

    Calling an existing Command

    @@ -5863,7 +5893,7 @@

    Calling an existing Command

    @@ -5916,7 +5946,7 @@

    Calling an existing Command

    @@ -5969,7 +5999,7 @@

    Calling an existing Command

    @@ -6010,7 +6040,7 @@

    Calling an existing Command

    @@ -6060,7 +6090,7 @@

    Calling an existing Command

    @@ -6110,7 +6140,7 @@

    Calling an existing Command

    @@ -6140,7 +6170,7 @@

    Calling an existing Command

    @@ -6178,7 +6208,7 @@

    Calling an existing Command

    @@ -6229,7 +6259,7 @@

    Example

    @@ -6281,7 +6311,7 @@

    Example

    @@ -6316,7 +6346,7 @@

    Example

    @@ -6364,7 +6394,7 @@

    Classes

    @@ -6414,7 +6444,7 @@

    Classes

    @@ -6463,7 +6493,7 @@

    Example

    @@ -6504,7 +6534,7 @@

    Example

    @@ -6556,7 +6586,7 @@

    Example

    @@ -6608,7 +6638,7 @@

    Example

    @@ -6638,7 +6668,7 @@

    Example

    @@ -6679,7 +6709,7 @@

    Localization

    @@ -6731,7 +6761,7 @@

    Message Placeholders

    @@ -6781,7 +6811,7 @@

    Message Placeholders

    @@ -6826,7 +6856,7 @@

    Message Placeholders

    @@ -6873,7 +6903,7 @@

    Message Placeholders

    @@ -6922,7 +6952,7 @@

    Message Placeholders

    @@ -6980,7 +7010,7 @@

    Message Placeholders

    @@ -7010,7 +7040,7 @@

    Message Placeholders

    @@ -7047,7 +7077,7 @@

    Message Placeholders

    @@ -7089,7 +7119,7 @@

    HTTP Cache

    @@ -7128,7 +7158,7 @@

    Edge Side Includes

    @@ -7172,7 +7202,7 @@

    Edge Side Includes

    @@ -7216,7 +7246,7 @@

    Edge Side Includes

    @@ -7254,7 +7284,7 @@

    Edge Side Includes

    @@ -7298,7 +7328,7 @@

    Edge Side Includes

    @@ -7342,7 +7372,7 @@

    Edge Side Includes

    @@ -7382,7 +7412,7 @@

    Edge Side Includes

    @@ -7420,7 +7450,7 @@

    Edge Side Includes

    @@ -7468,7 +7498,7 @@

    Edge Side Includes

    @@ -7513,7 +7543,7 @@

    Edge Side Includes

    @@ -7552,7 +7582,7 @@

    Edge Side Includes

    @@ -7602,7 +7632,7 @@

    Edge Side Includes

    @@ -7639,7 +7669,7 @@

    Edge Side Includes

    @@ -7694,7 +7724,7 @@

    Edge Side Includes

    @@ -7733,7 +7763,7 @@

    Edge Side Includes

    @@ -7763,7 +7793,7 @@

    Edge Side Includes

    @@ -7798,7 +7828,7 @@

    Edge Side Includes

    @@ -7835,7 +7865,7 @@

    Edge Side Includes

    @@ -7893,7 +7923,7 @@

    Edge Side Includes

    @@ -7923,7 +7953,7 @@

    Edge Side Includes

    @@ -7966,7 +7996,7 @@

    Edge Side Includes

    @@ -7989,6 +8019,8 @@

    Edge Side Includes

    generics, collections, and nullable.

    +

    It also provides built-in asynchronous +programming.

    Official website: hacklang.org

    @@ -8009,7 +8041,7 @@

    Edge Side Includes

    @@ -8059,7 +8091,7 @@

    Example

    @@ -8067,13 +8099,30 @@

    Example

    -
    +

    Type Annotations

    -

    ...

    +
    <?hh
    +
    +class AnnotatedClass {
    +    public int $x;
    +    private string $s;
    +    protected array $arr;
    +    public AnotherClass $ac;
    +
    +    public function bar(string $str, bool $b): float {
    +        if ($b && $str === "Hi") {
    +            return 3.2;
    +        }
    +
    +        return 0.3;
    +    }
    +}
    +
    +

    http://docs.hhvm.com/manual/en/hack.annotations.php

    @@ -8094,7 +8143,7 @@

    Example

    @@ -8102,13 +8151,23 @@

    Example

    -
    +

    Generics

    -

    ...

    +
    <?hh
    +
    +class Box<T> {
    +    public T $value;
    +
    +    public function __construct(T $v) {
    +        $this->value = $v;
    +    }
    +}
    +
    +

    http://docs.hhvm.com/manual/en/hack.generics.php

    @@ -8129,7 +8188,7 @@

    Example

    @@ -8143,7 +8202,7 @@

    Example

    Collections

    -

    ...

    +

    Hack provides a unified collections framework including: Vector, Map, Set, Pair.

    http://docs.hhvm.com/manual/en/hack.collections.php

    @@ -8164,7 +8223,7 @@

    Example

    @@ -8172,13 +8231,24 @@

    Example

    -
    +

    Nullable Types

    -

    ...

    +

    Nullable allows any type to have null assigned and checked on it:

    +
    <?hh
    +
    +function check_not_null(?int $x): int {
    +    if ($x === null) {
    +        return -1;
    +    } else {
    +        return $x;
    +    }
    +}
    +
    +

    http://docs.hhvm.com/manual/en/hack.nullable.php

    @@ -8199,7 +8269,7 @@

    Example

    @@ -8229,7 +8299,7 @@

    Example

    @@ -8467,541 +8537,541 @@

    Table of Contents

    - Controllers + Read The Best Practices! 38 - Request, Controller, Response + Controllers 39 - The Simplest Page Ever + Request, Controller, Response 40 - Controller Naming Pattern + The Simplest Page Ever 41 - Route Params as Controller Args + Controller Naming Pattern 42 - The Request as a Controller Argument + Route Params as Controller Args 43 - The Base Controller Class + The Request as a Controller Argument 44 - The Response + The Base Controller Class 45 - Routing + The Response 46 - Basic Route Configuration + Routing 47 - Routing with Placeholders (1/2) + Basic Route Configuration 48 - Routing with Placeholders (2/2) + Routing with Placeholders (1/2) 49 - Requirements + Routing with Placeholders (2/2) 50 - Including External Routing Resources + Requirements 51 - Generating URLs + Including External Routing Resources 52 - Templating + Generating URLs 53 - + Templating 54 - Why Twig? + 55 - Getting Familiar With Twig + Why Twig? 56 - Accessing Variables + Getting Familiar With Twig 57 - Control Structure + Accessing Variables 58 - Filters + Control Structure 59 - Including Other Templates + Filters 60 - Template Inheritance (1/2) + Including Other Templates 61 - Template Inheritance (2/2) + Template Inheritance (1/2) 62 - Template Naming and Locations (1/2) + Template Inheritance (2/2) 63 - Template Naming and Locations (2/2) + Template Naming and Locations (1/2) 64 - Overriding Bundle Templates + Template Naming and Locations (2/2) 65 - Overriding Core Templates + Overriding Bundle Templates 66 - The Three-Level Approach + Overriding Core Templates 67 - Twig Into Symfony2 + The Three-Level Approach 68 - Rendering A Template + Twig Into Symfony2 69 - Linking to Pages + Rendering A Template 70 - Linking to Assets + Linking to Pages 71 - Linking To Pages In JavaScript + Linking to Assets 72 - Global Template Variables + Linking To Pages In JavaScript 73 - Service Container + Global Template Variables 74 - What Is A Service? + Service Container 75 - What Is A Service Container? + What Is A Service? 76 - Creating A Service + What Is A Service Container? 77 - Service Parameters + Creating A Service 78 - Injecting Services + Service Parameters 79 - Importing Configuration Resources + Injecting Services 80 - Creating an Extension Class + Importing Configuration Resources 81 - Dealing With Configuration (1/2) + Creating an Extension Class 82 - Dealing With Configuration (2/2) + Dealing With Configuration (1/2) 83 - The Configuration Class (1/2) + Dealing With Configuration (2/2) 84 - The Configuration Class (2/2) + The Configuration Class (1/2) 85 - More On The Service Container + The Configuration Class (2/2) 86 - Symfony2 Commands + More On The Service Container 87 - Built-in Commands (1/2) + Symfony2 Commands 88 - Built-in Commands (2/2) + Built-in Commands (1/2) 89 - Creating Commands + Built-in Commands (2/2) 90 - Command Arguments + Creating Commands 91 - Command Options (1/2) + Command Arguments 92 - Command Options (2/2) + Command Options (1/2) 93 - More On Commands + Command Options (2/2) 94 - Forms + More On Commands 95 - Building Your First Form + Forms 96 - Rendering The Form + Building Your First Form 97 - Handling Forms: The Right Way + Rendering The Form 98 - Handling Form Submissions + Handling Forms: The Right Way 99 - Built-in Form Types + Handling Form Submissions 100 - Creating A Custom Type (Form Class) + Built-in Form Types 101 - Dealing With Objects + Creating A Custom Type (Form Class) 102 - The processForm() Method (1/2) + Dealing With Objects 103 - The processForm() Method (2/2) + The processForm() Method (1/2) 104 - Cross-Site Request Forgery Protection + The processForm() Method (2/2) 105 - Rendering a Form in a Template (1/2) + Cross-Site Request Forgery Protection 106 - Rendering a Form in a Template (2/2) + Rendering a Form in a Template (1/2) 107 - Validation + Rendering a Form in a Template (2/2) 108 - About Form Validation + Validation 109 - The Validator Component + About Form Validation 110 - Using the validator Service + The Validator Component 111 - Constraints + Using the validator Service 112 - Constraint Targets (1/2) + Constraints 113 - Constraint Targets (2/2) + Constraint Targets (1/2) 114 - Validation Groups (1/2) + Constraint Targets (2/2) 115 - Validation Groups (2/2) + Validation Groups (1/2) 116 - Using Validation Groups In Forms + Validation Groups (2/2) 117 - Validating Values and Arrays + Using Validation Groups In Forms 118 - Translations + Validating Values and Arrays 119 - Definitions + Translations 120 - Using the translator Service + Definitions 121 - The Translation Process + Using the translator Service 122 - Locations and Naming Conventions + The Translation Process 123 - Pluralization + Locations and Naming Conventions 124 - Explicit Interval Pluralization + Pluralization 125 - BazingaJsTranslationBundle + Explicit Interval Pluralization 126 - HTTP Cache + BazingaJsTranslationBundle 127 @@ -9013,133 +9083,133 @@

    Table of Contents

    - Terminology (1/2) + HTTP Cache 129 - Terminology (2/2) + Terminology (1/2) 130 - Caching with a Gateway Cache + Terminology (2/2) 131 - Types of Caches + Caching with a Gateway Cache 132 - HTTP Caching + Types of Caches 133 - Public vs Private Responses + HTTP Caching 134 - Safe Methods + Public vs Private Responses 135 - Expiration + Safe Methods 136 - The Cache-Control Header (1/2) + Expiration 137 - The Cache-Control Header (2/2) + The Cache-Control Header (1/2) 138 - The Expires Header + The Cache-Control Header (2/2) 139 - Validation + The Expires Header 140 - The ETag Header + Validation 141 - The Last-Modified Header (1/2) + The ETag Header 142 - The Last-Modified Header (2/2) + The Last-Modified Header (1/2) 143 - Edge Side Includes (ESI) + The Last-Modified Header (2/2) 144 - Stack PHP + Edge Side Includes (ESI) 145 - HttpKernel + Stack PHP 146 - What Is Stack? + HttpKernel 147 - Implementation + What Is Stack? 148 - Hack + Implementation 149 - What Is Hack? + Hack 150 @@ -9151,41 +9221,47 @@

    Table of Contents

    - Getting Started + What Is Hack? 152 - Type Annotations + Getting Started 153 - Generics + Type Annotations 154 - Collections + Generics 155 - Nullable Types + Collections 156 - The End. + Nullable Types 157 + + The End. + 158 + + +
    From 09e0febab3e16ea018a41731816826643f345249 Mon Sep 17 00:00:00 2001 From: William Durand Date: Tue, 19 May 2015 09:37:05 +0200 Subject: [PATCH 63/71] Publish slides (Tue May 19 09:37:05 CEST 2015) --- extended.html | 110 +++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/extended.html b/extended.html index 6018235..a6e5d9a 100644 --- a/extended.html +++ b/extended.html @@ -1517,18 +1517,18 @@
    -

    What Is Symfony2?

    +

    What Is Symfony?

    First of all:

    -

    Symfony2 is a reusable set of standalone, decoupled, and cohesive PHP +

    Symfony is a reusable set of standalone, decoupled, and cohesive PHP components that solve common web development problems.

    Then, based on these components:

    -

    Symfony2 is also a full-stack web framework.

    +

    Symfony is also a full-stack web framework.

    Fabien Potencier, @@ -1561,7 +1561,7 @@

    -

    Is Symfony2 A MVC Framework?

    +

    Is Symfony A MVC Framework?

    @@ -1621,10 +1621,10 @@
    -

    Why You Should Use Symfony2

    +

    Why You Should Use Symfony

    -

    Symfony2 is built on powerful concepts:

    +

    Symfony is built on powerful concepts:

    • Separation of Concerns;
    • Pragmatism;
    • @@ -1661,7 +1661,7 @@
      -

      The Symfony2 Components

      +

      The Symfony Components

      The Components implement common features needed to develop websites.

      @@ -1761,7 +1761,7 @@

      Full-Stack Framework

      -

      The Symfony2 Framework accomplishes two distinct tasks:

      +

      The Symfony Framework accomplishes two distinct tasks:

      • Provides a selection of components;
      • Provides sensible configuration and a "glue" library that ties all of these @@ -1769,8 +1769,8 @@

      The goal of the framework is to integrate many independent tools in order to provide a consistent experience for the developer. Even the framework itself is -a Symfony2 bundle (i.e. a plugin) that can be configured or replaced entirely.

      -

      Symfony2 provides a powerful set of tools for rapidly developing web +a Symfony bundle (i.e. a plugin) that can be configured or replaced entirely.

      +

      Symfony provides a powerful set of tools for rapidly developing web applications without imposing on your application.

      http://symfony.com/doc/current/book/index.html

      @@ -1833,7 +1833,7 @@
      -

      The Symfony2 Request

      +

      The Symfony Request

      use Symfony\Component\HttpFoundation\Request;
      @@ -1887,7 +1887,7 @@
               
      -

      The Symfony2 Response

      +

      The Symfony Response

      use Symfony\Component\HttpFoundation\Response;
      @@ -2073,7 +2073,7 @@
                   

      Your First Controller

      -

      In Symfony2, a method in a controller is called an action. The convention is +

      In Symfony, a method in a controller is called an action. The convention is to suffix each method with Action.

      Also, each controller should be suffixed with Controller.

      // src/Acme/DemoBundle/Controller/MainController.php
      @@ -2118,10 +2118,10 @@
               
      -

      A Symfony2 Project

      +

      A Symfony Project

      -

      Recommended structure of a Symfony2 project:

      +

      Recommended structure of a Symfony project:

      path/to/project/
           app/
               cache/
      @@ -2235,7 +2235,7 @@
       

      By default, the main configuration file lives in the app/config/ directory and is called either config.yml, config.xml or config.php depending on which format you prefer.

      -

      Symfony2 is all about configuring everything, and you can do pretty much +

      Symfony is all about configuring everything, and you can do pretty much everything you want. That's why people agreed on some conventions, but then again, a convention is just A way to do things, not THE way to do them.

      @@ -2475,7 +2475,7 @@

      An application can run in various environments. The different environments share the same PHP code, but use different configuration.

      -

      A Symfony2 project generally uses three environments: dev, test and prod.

      +

      A Symfony project generally uses three environments: dev, test and prod.

      // web/app.php
       
       // ...
      @@ -2528,7 +2528,7 @@
       JavaScripts, images, ...) that implement a single feature (a blog, a forum,
       etc).

      It should be reusable, so that you don't reinvent the wheel each time you -need a common feature. In Symfony2, (almost) everything lives inside a bundle.

      +need a common feature. In Symfony, (almost) everything lives inside a bundle.

      In order to use a bundle in your application, you need to register it in the AppKernel, using the registerBundles() method:

      public function registerBundles()
      @@ -2777,7 +2777,7 @@
       

      The front controller file (app.php in this example) is the actual PHP file -that's executed when using a Symfony2 application and its job is to use a +that's executed when using a Symfony application and its job is to use a Kernel class, AppKernel, to bootstrap the application, for a given environment.

      @@ -2816,7 +2816,7 @@

      Each project contains just a few main directories: web/ (web assets and the front controllers), app/ (configuration), src/ (your bundles), and vendor/ (third-party code).

      -

      Each feature in Symfony2 (including the Symfony2 framework core) is organized +

      Each feature in Symfony (including the Symfony framework core) is organized into a bundle, which is a structured set of files for that feature.

      The configuration for each bundle lives in the Resources/config directory of the bundle and can be specified in YAML, XML or PHP.

      @@ -2916,7 +2916,7 @@

      A controller is a PHP function you create that takes information from the HTTP request and constructs and returns an HTTP response.

      -

      Every request handled by a Symfony2 project goes through the same lifecycle:

      +

      Every request handled by a Symfony project goes through the same lifecycle:

      1. Each request is handled by a single front controller file (e.g. app.php or app_dev.php) that bootstraps the application;
      2. @@ -3158,7 +3158,7 @@

        Controller Implementation

        The Base Controller Class

        -

        Symfony2 comes with a base Controller class that assists with some of the most +

        Symfony comes with a base Controller class that assists with some of the most common controller tasks and gives your controller class access to any resource it might need:

        use Symfony\Bundle\FrameworkBundle\Controller\Controller
        @@ -3289,10 +3289,10 @@ 

        Rendering Templates

        Basic Route Configuration

        -

        The Symfony2 router lets you define URLs that you map to different areas of +

        The Symfony router lets you define URLs that you map to different areas of your application.

        A route is a map from a URL path to a controller. Each route is named, and -maps a pattern (or path as of Symfony2.2) to a _controller:

        +maps a pattern (or path as of Symfony.2) to a _controller:

        # app/config/routing.yml
         homepage:
             pattern:  /
        @@ -4038,7 +4038,7 @@ 

        Example

      3. path/to/bundle/Resources/views/: Each bundle houses its templates in its Resources/views directory (and subdirectories).
    -

    Symfony2 uses a bundle:controller:template string syntax for templates.

    +

    Symfony uses a bundle:controller:template string syntax for templates.

    You can skip the controller string: bundle::template. The template file would live in Resources/views/.

    You can also skip the bundle string. It refers to an application-wide base @@ -4124,7 +4124,7 @@

    Example

    Once you use a third-party bundle, you'll likely need to override and customize one or more of its templates.

    -

    When the FooBarBundle:Bar:index.html.twig is rendered, Symfony2 actually +

    When the FooBarBundle:Bar:index.html.twig is rendered, Symfony actually looks in two different locations for the template:

    • app/Resources/FooBarBundle/views/Bar/index.html.twig;
    • @@ -4243,7 +4243,7 @@

      Example

      -

      Twig Into Symfony2

      +

      Twig Into Symfony

      @@ -4435,7 +4435,7 @@

      Cache Busting

      The FOSJsRoutingBundle allows you to expose your routing in your JavaScript code. That means you'll be able to generate URL with given parameters like you can do with the Router -component provided by Symfony2.

      +component provided by Symfony.

      # app/config/routing.yml
       my_route_to_expose:
           pattern:  /foo/{id}/bar
      @@ -4556,7 +4556,7 @@ 

      Cache Busting

      A Service is a generic term for any PHP object that performs a specific task.

      A service is usually used globally, such as a database connection object or an object that delivers email messages.

      -

      In Symfony2, services are often configured and retrieved from the service +

      In Symfony, services are often configured and retrieved from the service container.

      An application that has many decoupled services is said to follow a Service-Oriented Architecture (SOA).

      @@ -5137,7 +5137,7 @@

      Debugging Services

      -

      Symfony2 Commands

      +

      Symfony Commands

      @@ -6185,7 +6185,7 @@

      Calling an existing Command

      In the previous section, you learned how a form can be submitted with valid or -invalid data. In Symfony2, validation is applied to the underlying object.

      +invalid data. In Symfony, validation is applied to the underlying object.

      In other words, the question isn't whether the "form" is valid, but whether the object is valid after the form has applied the submitted data to it.

      Calling $form->isValid() is a shortcut that asks the object whether it has @@ -6364,7 +6364,7 @@

      Example

      (e.g. getFullName()). The first is the most common and easy to use, but the second allows you to specify more complex validation rules.

      Properties

      -

      Validating class properties is the most basic validation technique. Symfony2 +

      Validating class properties is the most basic validation technique. Symfony allows you to validate private, protected or public properties.

      # src/Acme/DemoBundle/Resources/config/validation.yml
       Acme\DemoBundle\Entity\Author:
      @@ -6409,7 +6409,7 @@ 

      Classes

      Getters

      -

      Constraints can also be applied to the return value of a method. Symfony2 +

      Constraints can also be applied to the return value of a method. Symfony allows you to add a constraint to any public method whose name starts with get or is.

      # src/Acme/DemoBundle/Resources/config/validation.yml
      @@ -6724,17 +6724,17 @@ 

      Localization

      # messages.fr.yml
      -Symfony2 is great: J'aime Symfony2
      +Symfony is great: J'aime Symfony
       'Hello %name%': Bonjour %name%
       
      -

      When the following code is executed, Symfony2 will attempt to translate the -message Symfony2 is great based on the locale of the user:

      -
      echo $this->get('translator')->trans('Symfony2 is great');
      +

      When the following code is executed, Symfony will attempt to translate the +message Symfony is great based on the locale of the user:

      +
      echo $this->get('translator')->trans('Symfony is great');
       

      Now, if the language of the user's locale is French (e.g. fr_FR or fr_BE), -the message will be translated into J'aime Symfony2.

      +the message will be translated into J'aime Symfony.

      Message Placeholders

      echo $this->get('translator')->trans('Hello %name%', [
           '%name%' => 'Will'
      @@ -6775,7 +6775,7 @@ 

      Message Placeholders

      The Translation Process

      -

      To translate the message, Symfony2 uses a simple process:

      +

      To translate the message, Symfony uses a simple process:

      1. The locale of the current user, which is stored on the request (or stored as @@ -6792,7 +6792,7 @@

        Message Placeholders

        the translator returns the original message.

      -

      When using the trans() method, Symfony2 looks for the exact string inside the +

      When using the trans() method, Symfony looks for the exact string inside the appropriate message catalog and returns it (if it exists).

      @@ -6825,19 +6825,19 @@

      Message Placeholders

      Locations and Naming Conventions

      -

      Symfony2 looks for message files (i.e. translations) in the following locations:

      +

      Symfony looks for message files (i.e. translations) in the following locations:

      • the <kernel root directory>/Resources/translations directory;
      • the <kernel root directory>/Resources/<bundle name>/translations directory;
      • the Resources/translations/ directory of the bundle.
      -

      The filename of the translations is also important as Symfony2 uses a convention +

      The filename of the translations is also important as Symfony uses a convention to determine details about the translations. Each message file must be named according to the following path: domain.locale.loader:

      • domain: an optional way to organize messages into groups;
      • locale: the locale that the translations are for (en_GB, en, etc);
      • -
      • loader: how Symfony2 should load and parse the file (xliff, php or yml).
      • +
      • loader: how Symfony should load and parse the file (xliff, php or yml).
      @@ -7096,11 +7096,11 @@

      Message Placeholders

      front of your application.

      The reverse proxy caches responses as they are returned from your application and answers requests with cached responses before they hit your application.

      -

      Symfony2 provides its own reverse proxy, but any reverse proxy can be used.

      +

      Symfony provides its own reverse proxy, but any reverse proxy can be used.

      HTTP Cache

      HTTP cache headers are used to communicate with the gateway cache and any other caches between your application and the client.

      -

      Symfony2 provides sensible defaults and a powerful interface for interacting +

      Symfony provides sensible defaults and a powerful interface for interacting with the cache headers.

      @@ -7183,7 +7183,7 @@

      Edge Side Includes

      If the same resource is requested again, the cache sends the cached response to the client, ignoring your application entirely.

      This type of cache is known as a HTTP gateway cache and many exist such as -Varnish, Squid in reverse proxy mode, and the Symfony2 reverse +Varnish, Squid in reverse proxy mode, and the Symfony reverse proxy.

      @@ -8369,13 +8369,13 @@

      Table of Contents

      - What Is Symfony2? + What Is Symfony? 10 - Is Symfony2 A MVC Framework? + Is Symfony A MVC Framework? 11 @@ -8387,13 +8387,13 @@

      Table of Contents

      - Why You Should Use Symfony2 + Why You Should Use Symfony 13 - The Symfony2 Components + The Symfony Components 14 @@ -8417,13 +8417,13 @@

      Table of Contents

      - The Symfony2 Request + The Symfony Request 18 - The Symfony2 Response + The Symfony Response 19 @@ -8453,7 +8453,7 @@

      Table of Contents

      - A Symfony2 Project + A Symfony Project 24 @@ -8723,7 +8723,7 @@

      Table of Contents

      - Twig Into Symfony2 + Twig Into Symfony 69 @@ -8837,7 +8837,7 @@

      Table of Contents

      - Symfony2 Commands + Symfony Commands 88 From 7643c7edbc77c85d28e1e3fffc94ad1de4a04b28 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 4 Jan 2016 10:46:17 +0100 Subject: [PATCH 64/71] Publish slides (Mon Jan 4 10:46:17 CET 2016) --- extended.html | 6 +- index.html | 1183 ++++++++++++++++++++++++++++++------------------- isima.html | 945 +++++++++++++++++++++++++-------------- 3 files changed, 1342 insertions(+), 792 deletions(-) diff --git a/extended.html b/extended.html index a6e5d9a..7bb2793 100644 --- a/extended.html +++ b/extended.html @@ -1288,10 +1288,10 @@

      William DURAND

      -

      PhD student at Michelin / LIMOS

      -

      Graduated from IUT and ISIMA

      -

      Worked at:

      +

      PhD student / CTO TailorDev

      +

      Graduated from IUT and ISIMA. Worked at:

        +
      • Michelin (Clermont-Fd, France);
      • Nelmio (Zürich, Switzerland);
      • e-TF1 (Paris, France);
      • Prizee.com (Clermont-Fd, France).
      • diff --git a/index.html b/index.html index e9f80f8..bd325f4 100644 --- a/index.html +++ b/index.html @@ -1214,7 +1214,7 @@
      @@ -1244,7 +1244,7 @@
      @@ -1258,10 +1258,10 @@

      William DURAND

      -

      PhD student at Michelin / LIMOS

      -

      Graduated from IUT and ISIMA

      -

      Worked at:

      +

      PhD student / CTO TailorDev

      +

      Graduated from IUT and ISIMA. Worked at:

        +
      • Michelin (Clermont-Fd, France);
      • Nelmio (Zürich, Switzerland);
      • e-TF1 (Paris, France);
      • Prizee.com (Clermont-Fd, France).
      • @@ -1296,7 +1296,7 @@
      @@ -1326,7 +1326,7 @@
    @@ -1356,7 +1356,7 @@
    @@ -1397,7 +1397,7 @@

    Week #4

    @@ -1427,7 +1427,7 @@

    Week #4

    @@ -1443,9 +1443,10 @@

    Week #4

    • Created by Rasmus Lerdorf
    • -
    • 6th language in the world (TIOBE December 2013)
    • +
    • 6th language in the world +(TIOBE January 2016)
    • 1st language for web development
    • -
    • Running on 75% of all web servers
    • +
    • Running on +75% of all web servers
    @@ -1464,7 +1465,7 @@

    Week #4

    @@ -1502,7 +1503,7 @@

    Week #4

    @@ -1517,6 +1518,11 @@

    Week #4

    Mac OS X

    +
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 7.0
    +
    + +

    +
    $ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6
     
    @@ -1540,7 +1546,7 @@

    Week #4

    @@ -1557,7 +1563,7 @@

    Week #4

    Windows

    -

    http://www.php.net/manual/en/install.windows.installer.msi.php

    +

    http://php.net/manual/en/install.windows.installer.msi.php

    @@ -1576,7 +1582,7 @@

    Week #4

    @@ -1594,7 +1600,7 @@

    Week #4

    HHVM uses a just-in-time compilation approach to achieve superior performance.

    -

    http://www.hhvm.com

    +

    http://hhvm.com

    @@ -1613,7 +1619,7 @@

    Week #4

    @@ -1624,7 +1630,7 @@

    Week #4

    @@ -1643,7 +1649,7 @@

    Week #4

    @@ -1673,7 +1679,7 @@

    Week #4

    @@ -1694,7 +1700,7 @@

    Week #4

    Note: most of these types have aliases. E.g. double for float.

    Read more about the PHP primitive types: -http://www.php.net/manual/en/language.types.intro.php.

    +http://php.net/manual/en/language.types.intro.php.

    @@ -1713,7 +1719,7 @@

    Week #4

    @@ -1767,7 +1773,7 @@

    Timing Attack Safe String Comparison

    @@ -1825,7 +1831,55 @@

    Timing Attack Safe String Comparison

    + + + + + +
    +
    +
    + +

    New Operators in PHP 7.0

    + + +

    Null Coalescing Operator: ??

    +
    // Fetches the value of $_GET['user'] and returns 'nobody'
    +// if it does not exist.
    +$username = $_GET['user'] ?? 'nobody';
    +
    +// This is equivalent to:
    +$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
    +
    + +

    Spaceship Operator: <=>

    +

    Returns -1, 0 or 1 when $a is respectively less than, equal to, or +greater than $b:

    +
    echo 1 <=> 1; // 0
    +echo 1 <=> 2; // -1
    +echo 2 <=> 1; // 1
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -1836,7 +1890,7 @@

    Timing Attack Safe String Comparison

    -

    Classes (1/2)

    +

    Classes (1/3)

    Simple class definition

    @@ -1870,7 +1924,7 @@

    Abstract class definition

    @@ -1881,7 +1935,7 @@

    Abstract class definition

    -

    Classes (2/2)

    +

    Classes (2/3)

    Creating an instance:

    @@ -1905,7 +1959,7 @@

    Abstract class definition

    -

    http://www.php.net/manual/en/language.oop5.basic.php

    +

    http://php.net/manual/en/language.oop5.basic.php

    @@ -1924,7 +1978,60 @@

    Abstract class definition

    + + + + + +
    +
    +
    + +

    Classes (3/3)

    + + +

    Anonymous Classes (PHP >= 7.0)

    +
    new class {
    +    public function foo() {
    +        return 'foo';
    +    }
    +}
    +
    + +

    Anonymous classes behave as traditional classes:

    +
    interface Logger {
    +    public function log($msg);
    +}
    +
    +$logger = new class implements Logger {
    +    public function log($msg) {
    +        // ...
    +    }
    +}
    +
    +$logger->log('Hello, Anonymous Class');
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -1965,7 +2072,7 @@

    The Rules

    @@ -2025,7 +2132,7 @@

    The Rules

    @@ -2036,7 +2143,7 @@

    The Rules

    -

    Methods (1/3)

    +

    Methods (1/4)

    class Foo
    @@ -2048,8 +2155,8 @@ 

    The Rules

    Type Hinting

    -

    Works with classes, interfaces, arrays, callable, and Closure. You can't use -scalar types such as int or string:

    +

    Works with classes, interfaces, arrays, callable, and Closure. You cannot +use scalar types such as int or string with PHP < 7.0:

    public function doSomething(Foo $foo);
     
     public function doSomething(Traversable $iterator);
    @@ -2078,7 +2185,52 @@ 

    Type Hinting

    + +
    +
    + + +
    +
    +
    + +

    Methods (2/4)

    + + +

    PHP 7 \o/

    +

    Scalar Type Declarations

    +

    Works with int, float, string, and bool:

    +
    function sumOfInts(int ...$ints) {
    +    return array_sum($ints);
    +}
    +
    + +

    Return Type Declarations

    +
    function sumOfInts(int ...$ints) : int {
    +    return array_sum($ints);
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -2089,7 +2241,7 @@

    Type Hinting

    -

    Methods (2/3)

    +

    Methods (3/4)

    The -> operator is used to call methods on objects.

    @@ -2125,7 +2277,7 @@

    Usage

    @@ -2136,7 +2288,7 @@

    Usage

    -

    Methods (3/3)

    +

    Methods (4/4)

    public function doSomething()
    @@ -2175,7 +2327,7 @@ 

    Usage

    @@ -2203,9 +2355,9 @@

    Usage

    }
    -

    Warning: the static keyword can also be used to define static +

    Warning: the static keyword can also be used to define static variables -and for late static +and for late static bindings. This is different!

    @@ -2225,7 +2377,7 @@

    Usage

    @@ -2286,7 +2438,7 @@

    Usage

    @@ -2332,7 +2484,7 @@

    Usage

    @@ -2379,7 +2531,7 @@

    Argument Unpacking

    @@ -2433,7 +2585,7 @@

    Usage

    @@ -2444,7 +2596,7 @@

    Usage

    -

    Namespaces

    +

    Namespaces (1/2)

    Namespaces prevent naming collisions with identifiers such as function, class, @@ -2460,7 +2612,7 @@

    Usage

    PSR-0

    -

    PSR-0 describes a set of rules related to +

    PSR-0 describes a set of rules related to namespaces for autoloader interoperability:

    \ns\package\Class_Name      => vendor/ns/package/Class/Name.php
     \ns\package_name\Class_Name => vendor/ns/package_name/Class/Name.php
    @@ -2483,7 +2635,62 @@ 

    PSR-0

    + +
    +
    + + +
    +
    +
    + +

    Namespaces (2/2)

    + + +

    Classes, functions, and constants have to be imported with the use +statement:

    +
    namespace My\Namespace;
    +
    +// Pre PHP 7 code
    +use some\namespace\ClassA;
    +use some\namespace\ClassB;
    +
    +use function some\namespace\fn_a;
    +use function some\namespace\fn_b;
    +
    +// PHP 7+ code
    +use some\namespace\{ClassA, ClassB};
    +
    +use function some\namespace\{fn_a, fn_b};
    +
    +class MyClass
    +{
    +    public function __construct(ClassA $a, ClassB $b) {
    +        // ...
    +    }
    +}
    +
    +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + +
    @@ -2513,7 +2720,7 @@

    PSR-0

    Read more about the class keyword: -http://www.php.net/manual/en/language.oop5.basic.php.

    +http://php.net/manual/en/language.oop5.basic.php.

    @@ -2532,7 +2739,7 @@

    PSR-0

    @@ -2567,7 +2774,7 @@

    PSR-0

    Read more about traits: -http://www.php.net/manual/en/language.oop5.traits.php.

    +http://php.net/manual/en/language.oop5.traits.php.

    @@ -2586,7 +2793,7 @@

    PSR-0

    @@ -2612,7 +2819,7 @@

    PSR-0

    Read more about anonymous functions: -http://www.php.net/manual/en/functions.anonymous.php.

    +http://php.net/manual/en/functions.anonymous.php.

    @@ -2631,7 +2838,7 @@

    PSR-0

    @@ -2679,7 +2886,7 @@

    PSR-0

    @@ -2724,7 +2931,7 @@

    PSR-0

    @@ -2744,7 +2951,7 @@

    PSR-0

    Read more about generators:

    @@ -5237,7 +5271,7 @@

    SPL Functions

    @@ -5267,7 +5301,7 @@

    SPL Functions

    @@ -5313,7 +5347,7 @@

    SPL Functions

    @@ -5365,7 +5399,7 @@

    SPL Functions

    @@ -5411,7 +5445,7 @@

    SPL Functions

    @@ -5441,7 +5475,7 @@

    SPL Functions

    @@ -5474,7 +5508,7 @@

    SPL Functions

    @@ -5524,7 +5558,7 @@

    SPL Functions

    @@ -5579,7 +5613,7 @@

    SPL Functions

    @@ -5628,7 +5662,7 @@

    Usage

    @@ -5679,7 +5713,7 @@

    Usage

    @@ -5733,7 +5767,7 @@

    Usage

    @@ -5778,7 +5812,7 @@

    Centralized Declaration

    @@ -5813,7 +5847,7 @@

    Centralized Declaration

    @@ -5843,7 +5877,7 @@

    Centralized Declaration

    @@ -5881,7 +5915,7 @@

    Centralized Declaration

    @@ -5918,7 +5952,7 @@

    Centralized Declaration

    @@ -5961,7 +5995,7 @@

    Centralized Declaration

    @@ -5991,7 +6025,7 @@

    Centralized Declaration

    @@ -6048,7 +6082,7 @@

    Centralized Declaration

    @@ -6096,7 +6130,7 @@

    Centralized Declaration

    @@ -6145,7 +6179,7 @@

    Centralized Declaration

    @@ -6175,7 +6209,7 @@

    Centralized Declaration

    @@ -6225,7 +6259,7 @@

    CRUD

    @@ -6274,7 +6308,7 @@

    CRUD

    @@ -6324,7 +6358,7 @@

    CRUD

    @@ -6378,7 +6412,7 @@

    CRUD

    @@ -6425,7 +6459,7 @@

    CRUD

    @@ -6474,7 +6508,7 @@

    CRUD

    @@ -6504,7 +6538,7 @@

    CRUD

    @@ -6553,7 +6587,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6610,7 +6644,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6640,7 +6674,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6695,7 +6729,7 @@

    Active Record = Row Data Gateway + Domain Logic

    @@ -6742,7 +6776,7 @@

    Remove

    @@ -6772,7 +6806,7 @@

    Remove

    @@ -6821,7 +6855,7 @@

    Remove

    @@ -6851,7 +6885,7 @@

    Remove

    @@ -6896,7 +6930,7 @@

    PHP Data Object (PDO)

    @@ -6947,7 +6981,7 @@

    Usage

    @@ -7003,7 +7037,7 @@

    Usage

    @@ -7052,7 +7086,7 @@

    Usage

    @@ -7082,7 +7116,7 @@

    Usage

    @@ -7121,7 +7155,7 @@

    Usage

    @@ -7159,7 +7193,7 @@

    Code Snippet

    @@ -7197,7 +7231,7 @@

    Code Snippet

    @@ -7241,7 +7275,7 @@

    Code Snippet

    @@ -7283,7 +7317,7 @@

    Doctrine2 ORM

    @@ -7313,7 +7347,7 @@

    Doctrine2 ORM

    @@ -7369,7 +7403,7 @@

    Doctrine2 ORM

    @@ -7426,7 +7460,7 @@

    Doctrine2 ORM

    @@ -7456,7 +7490,7 @@

    Doctrine2 ORM

    @@ -7507,7 +7541,7 @@

    Doctrine2 ORM

    @@ -7548,7 +7582,7 @@

    Doctrine2 ORM

    @@ -7578,7 +7612,7 @@

    Doctrine2 ORM

    @@ -7636,7 +7670,7 @@

    Doctrine2 ORM

    @@ -7684,7 +7718,7 @@

    Usage

    @@ -7745,7 +7779,7 @@

    Usage

    @@ -7803,7 +7837,7 @@

    Usage

    @@ -7853,7 +7887,7 @@

    Usage

    @@ -7883,7 +7917,7 @@

    Usage

    @@ -7928,7 +7962,7 @@

    A few use cases:

    @@ -7979,7 +8013,7 @@

    A few use cases:

    @@ -8025,7 +8059,7 @@

    Workarounds

    @@ -8079,7 +8113,7 @@

    Workarounds

    @@ -8109,7 +8143,7 @@

    Workarounds

    @@ -8144,7 +8178,7 @@

    Workarounds

    @@ -8177,7 +8211,7 @@

    Workarounds

    @@ -8220,7 +8254,7 @@

    Event Dispatcher

    @@ -8270,7 +8304,7 @@

    Event Dispatcher

    @@ -8324,7 +8358,7 @@

    Event Dispatcher

    @@ -8370,7 +8404,7 @@

    Event Dispatcher

    @@ -8412,7 +8446,7 @@

    Event Dispatcher

    @@ -8471,7 +8505,7 @@

    Event Dispatcher

    @@ -8504,7 +8538,7 @@

    Event Dispatcher

    @@ -8563,7 +8597,7 @@

    Event Dispatcher

    @@ -8601,7 +8635,7 @@

    WSSE Username Token

    @@ -8647,7 +8681,7 @@

    WSSE Username Token

    @@ -8677,7 +8711,7 @@

    WSSE Username Token

    @@ -8707,7 +8741,7 @@

    WSSE Username Token

    @@ -8789,7 +8823,7 @@

    Table of Contents

    - Getting Started + 12 @@ -8807,499 +8841,499 @@

    Table of Contents

    - HHVM + Getting Started 15 - RTFM: http://php.net + HHVM 16 - The PHP Syntax + RTFM: http://php.net 17 - Primitive Types + The PHP Syntax 18 - Comparison Operators + Primitive Types 19 - Operators + Comparison Operators 20 - New Operators in PHP 7.0 + Operators 21 - Classes (1/3) + New Operators in PHP 7.0 22 - Classes (2/3) + Classes (1/3) 23 - Classes (3/3) + Classes (2/3) 24 - Visibility + Classes (3/3) 25 - Properties + Visibility 26 - Methods (1/4) + Properties 27 - Methods (2/4) + Methods (1/4) 28 - Methods (3/4) + Methods (2/4) 29 - Methods (4/4) + Methods (3/4) 30 - Static Keyword + Methods (4/4) 31 - Late Static Bindings + Static Keyword 32 - Static Keyword + Late Static Bindings 33 - Variadic Functions + Static Keyword 34 - Interfaces + Variadic Functions 35 - Namespaces (1/2) + Interfaces 36 - Namespaces (2/2) + Namespaces (1/2) 37 - The class Keyword + Namespaces (2/2) 38 - Traits + The class Keyword 39 - Anonymous Functions + Traits 40 - Closures + Anonymous Functions 41 - Magic Methods + Closures 42 - Generators + Magic Methods 43 - Errors in PHP 7 + Generators 44 - The PHP Command Line + Errors in PHP 7 45 - The PHP Command Line (1/2) + The PHP Command Line 46 - The PHP Command Line (2/2) + The PHP Command Line (1/2) 47 - Writing a CLI program + The PHP Command Line (2/2) 48 - Client/Server + Writing a CLI program 49 - Client/Server Basics + Client/Server 50 - Unified Resource Identifier (URI) + Client/Server Basics 51 - HTTP Request + Unified Resource Identifier (URI) 52 - HTTP Verbs + HTTP Request 53 - HTTP Response + HTTP Verbs 54 - Status Codes (1/2) + HTTP Response 55 - Status Codes (2/2) + Status Codes (1/2) 56 - HTTP Parameters (1/2) + Status Codes (2/2) 57 - HTTP Parameters (2/2) + HTTP Parameters (1/2) 58 - REST + HTTP Parameters (2/2) 59 - REpresentational State Transfer + REST 60 - Richardson Maturity Model + REpresentational State Transfer 61 - Level 0 - The Swamp of POX + Richardson Maturity Model 62 - Level 1 - Resources + Level 0 - The Swamp of POX 63 - Level 2 - HTTP Verbs + Level 1 - Resources 64 - Level 3 - Hypermedia Controls + Level 2 - HTTP Verbs 65 - Level 3 = Content Negotiation + HATEOAS + Level 3 - Hypermedia Controls 66 - Media Types + Level 3 = Content Negotiation + HATEOAS 67 - Content Type Negotiation + Media Types 68 - HATEOAS + Content Type Negotiation 69 - PHP Autoloading + HATEOAS 70 - Why Is It Necessary? + PHP Autoloading 71 - The require() Way + Why Is It Necessary? 72 - The require_once() Way + The require() Way 73 - Working With Multiple Files + The require_once() Way 74 - Rethinking The Way You Load Classes + Working With Multiple Files 75 - Examples + Rethinking The Way You Load Classes 76 - Under The Hood + Examples 77 - PSR-0 vs PSR-4 + Under The Hood 78 - Leveraging PHP APIs + PSR-0 vs PSR-4 79 - Built-in Interfaces + Leveraging PHP APIs 80 - The Reflection API (1/2) + Built-in Interfaces 81 - The Reflection API (2/2) + The Reflection API (1/2) 82 - The Standard PHP Library (SPL) + The Reflection API (2/2) 83 - Observer Pattern (1/2) + The Standard PHP Library (SPL) 84 - Observer Pattern (2/2) + Observer Pattern (1/2) 85 - Exceptions (1/2) + Observer Pattern (2/2) 86 - Exceptions (2/2) + Exceptions (1/2) 87 - Password Hashing + Exceptions (2/2) 88 - PHP Archive (PHAR) + Password Hashing 89 - Dependency Management + PHP Archive (PHAR) 90 - Composer + Dependency Management 91 - composer install + Composer 92 - Composer Autoloader + composer install 93 - Model View Controller + Composer Autoloader 94 - MVC Overview + Model View Controller 95 - The Model + MVC Overview 96 - The View + The Model 97 @@ -9317,55 +9351,55 @@

    Table of Contents

    - The Controller + The View 100 - Routing + The Controller 101 - Front Controller Pattern + Routing 102 - Databases + Front Controller Pattern 103 - Agenda + Databases 104 - Quick note + Agenda 105 - Database Design Patterns + Quick note 106 - Row Data Gateway + Database Design Patterns 107 - Row Data Gateway + Row Data Gateway 108 @@ -9383,13 +9417,13 @@

    Table of Contents

    - Table Data Gateway + Row Data Gateway 111 - Table Data Gateway + Table Data Gateway 112 @@ -9425,13 +9459,13 @@

    Table of Contents

    - Active Record + Table Data Gateway 118 - Active Record + Active Record 119 @@ -9443,13 +9477,13 @@

    Table of Contents

    - Data Mapper + Active Record 121 - Data Mapper + Data Mapper 122 @@ -9461,31 +9495,31 @@

    Table of Contents

    - Identity Map + Data Mapper 124 - Identity Map + Identity Map 125 - Data Access Layer + Identity Map 126 - Data Access Layer / Data Source Name + Data Access Layer 127 - Data Access Layer + Data Access Layer / Data Source Name 128 @@ -9503,67 +9537,67 @@

    Table of Contents

    - Object Relational Mapping + Data Access Layer 131 - Object Relational Mapping (1/4) + Object Relational Mapping 132 - Object Relational Mapping (2/4) + Object Relational Mapping (1/4) 133 - Object Relational Mapping (3/4) + Object Relational Mapping (2/4) 134 - Object Relational Mapping (4/4) + Object Relational Mapping (3/4) 135 - Existing Components + Object Relational Mapping (4/4) 136 - A Note About
    Domain-Driven Design
    + Existing Components 137 - Entities + A Note About
    Domain-Driven Design
    138 - Value Objects + Entities 139 - The Repository Pattern + Value Objects 140 - The Repository Pattern + The Repository Pattern 141 @@ -9575,25 +9609,25 @@

    Table of Contents

    - The Specification Pattern + The Repository Pattern 143 - The Specification Pattern + The Specification Pattern 144 - Repository ♥ Specification + The Specification Pattern 145 - Combine Them! + Repository ♥ Specification 146 @@ -9605,131 +9639,137 @@

    Table of Contents

    - Specification For Business Rules + Combine Them! 148 - Sessions + Specification For Business Rules 149 - Overview + Sessions 150 - Code Please + Overview 151 - Security Concerns + Code Please 152 - Session Configuration + Security Concerns 153 - Authentication + Session Configuration 154 - What You Have Right Now + Authentication 155 - The Big Picture + What You Have Right Now 156 - The Interceptor Pattern + The Big Picture 157 - Introducing the Event Dispatcher + The Interceptor Pattern 158 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 159 - The Firewall (1/2) + Using the EventDispatcherTrait 160 - The Firewall (2/2) + The Firewall (1/2) 161 - Implementing The Firewall + The Firewall (2/2) 162 - Authentication Mechanism + Implementing The Firewall 163 - Adding New Routes + Authentication Mechanism 164 - Stateless Authentication + Adding New Routes 165 - Basic Security Thinking + Stateless Authentication 166 - Next Week:
    Web Security 101 + Basic Security Thinking 167 - The End. + Next Week:
    Web Security 101 168 + + The End. + 169 + + + From 61d88c34eaeab39427b5da5cde177901f023f273 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 4 Jan 2016 11:09:47 +0100 Subject: [PATCH 66/71] Publish slides (Mon Jan 4 11:09:47 CET 2016) --- index.html | 2 +- isima.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 71bb873..fa98da4 100644 --- a/index.html +++ b/index.html @@ -1980,7 +1980,7 @@

    Abstract class definition

    $foo = new $class(); -

    Getting the classname of an instance:

    +

    Getting the class name of an instance:

    echo get_class($foo);
     => Foo
     
    diff --git a/isima.html b/isima.html index cd8ec67..49423f9 100644 --- a/isima.html +++ b/isima.html @@ -2157,7 +2157,7 @@

    Abstract class definition

    $foo = new $class(); -

    Getting the classname of an instance:

    +

    Getting the class name of an instance:

    echo get_class($foo);
     => Foo
     
    From b0a8c960559d1f9148854fa9cd66daaa309ec186 Mon Sep 17 00:00:00 2001 From: William Durand Date: Tue, 5 Jan 2016 11:25:17 +0100 Subject: [PATCH 67/71] Publish slides (Tue Jan 5 11:25:17 CET 2016) --- index.html | 2 +- isima.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index fa98da4..8f2a114 100644 --- a/index.html +++ b/index.html @@ -2042,7 +2042,7 @@

    Abstract class definition

    public function log($msg) { // ... } -} +}; $logger->log('Hello, Anonymous Class'); diff --git a/isima.html b/isima.html index 49423f9..d9ca992 100644 --- a/isima.html +++ b/isima.html @@ -2219,7 +2219,7 @@

    Abstract class definition

    public function log($msg) { // ... } -} +}; $logger->log('Hello, Anonymous Class'); From db0c5e82aaf9af66c61de0bc95133b08b822c802 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 25 Jan 2016 17:56:05 +0100 Subject: [PATCH 68/71] Publish slides (Mon Jan 25 17:56:05 CET 2016) --- index.html | 627 ++++++++++++++++++++++++++++------------------------- isima.html | 415 +++++++++++++++++++---------------- 2 files changed, 558 insertions(+), 484 deletions(-) diff --git a/index.html b/index.html index 8f2a114..8c8fd68 100644 --- a/index.html +++ b/index.html @@ -1214,7 +1214,7 @@ @@ -1244,7 +1244,7 @@ @@ -1296,7 +1296,7 @@ @@ -1326,7 +1326,7 @@ @@ -1356,7 +1356,7 @@ @@ -1397,7 +1397,7 @@

    Week #4

    @@ -1427,7 +1427,7 @@

    Week #4

    @@ -1468,7 +1468,7 @@

    Week #4

    @@ -1498,7 +1498,7 @@

    Week #4

    @@ -1536,7 +1536,7 @@

    Week #4

    @@ -1579,7 +1579,7 @@

    Week #4

    @@ -1615,7 +1615,7 @@

    Week #4

    @@ -1652,7 +1652,7 @@

    Week #4

    @@ -1682,7 +1682,7 @@

    Week #4

    @@ -1712,7 +1712,7 @@

    Week #4

    @@ -1752,7 +1752,7 @@

    Week #4

    @@ -1806,7 +1806,7 @@

    Timing Attack Safe String Comparison

    @@ -1864,7 +1864,7 @@

    Timing Attack Safe String Comparison

    @@ -1912,7 +1912,7 @@

    Spaceship Operator: <=>

    @@ -1957,7 +1957,7 @@

    Abstract class definition

    @@ -2011,7 +2011,7 @@

    Abstract class definition

    @@ -2064,7 +2064,7 @@

    Abstract class definition

    @@ -2105,7 +2105,7 @@

    The Rules

    @@ -2165,7 +2165,7 @@

    The Rules

    @@ -2218,7 +2218,7 @@

    Type Hinting

    @@ -2263,7 +2263,7 @@

    Return Type Declarations

    @@ -2310,7 +2310,7 @@

    Usage

    @@ -2360,7 +2360,7 @@

    Usage

    @@ -2410,7 +2410,7 @@

    Usage

    @@ -2471,7 +2471,7 @@

    Usage

    @@ -2517,7 +2517,7 @@

    Usage

    @@ -2564,7 +2564,7 @@

    Argument Unpacking

    @@ -2618,7 +2618,7 @@

    Usage

    @@ -2668,7 +2668,7 @@

    PSR-0

    @@ -2723,7 +2723,7 @@

    PSR-0

    @@ -2772,7 +2772,7 @@

    PSR-0

    @@ -2826,7 +2826,7 @@

    PSR-0

    @@ -2871,7 +2871,7 @@

    PSR-0

    @@ -2919,7 +2919,7 @@

    PSR-0

    @@ -2964,7 +2964,7 @@

    PSR-0

    @@ -3007,7 +3007,7 @@

    PSR-0

    @@ -3045,7 +3045,7 @@

    PSR-0

    @@ -3075,7 +3075,7 @@

    PSR-0

    @@ -3129,7 +3129,7 @@

    PSR-0

    @@ -3179,7 +3179,7 @@

    PSR-0

    @@ -3233,7 +3233,7 @@

    PSR-0

    @@ -3263,7 +3263,7 @@

    PSR-0

    @@ -3305,7 +3305,7 @@

    PSR-0

    @@ -3351,7 +3351,7 @@

    Collections

    @@ -3398,7 +3398,7 @@

    Collections

    @@ -3440,7 +3440,7 @@

    Collections

    @@ -3492,7 +3492,7 @@

    Collections

    @@ -3539,7 +3539,7 @@

    3xx Redirections

    @@ -3563,6 +3563,7 @@

    3xx Redirections

  • 406 Not Acceptable
  • 409 Conflict
  • 415 Unsupported Media Type
  • +
  • 451 Unavailable For Legal Reasons
  • 5xx Server Error

    5xx Server Error

      @@ -3762,7 +3763,7 @@

      5xx Server Error

      @@ -3809,7 +3810,7 @@

      5xx Server Error

      @@ -3861,7 +3862,7 @@

      5xx Server Error

      @@ -3891,7 +3892,7 @@

      5xx Server Error

      @@ -3934,7 +3935,7 @@

      5xx Server Error

      @@ -3968,7 +3969,7 @@

      5xx Server Error

      @@ -4007,7 +4008,7 @@

      5xx Server Error

      @@ -4046,7 +4047,7 @@

      5xx Server Error

      @@ -4085,7 +4086,7 @@

      5xx Server Error

      @@ -4123,7 +4124,7 @@

      5xx Server Error

      @@ -4153,7 +4154,7 @@

      5xx Server Error

      @@ -4207,7 +4208,7 @@

      Hyper Media Types

      @@ -4261,7 +4262,7 @@

      Hyper Media Types

      @@ -4315,7 +4316,7 @@

      Hyper Media Types

      @@ -4345,7 +4346,7 @@

      Hyper Media Types

      @@ -4396,7 +4397,7 @@

      Hyper Media Types

      @@ -4448,7 +4449,7 @@

      Hyper Media Types

      @@ -4497,7 +4498,7 @@

      Hyper Media Types

      @@ -4548,7 +4549,7 @@

      Hyper Media Types

      @@ -4589,7 +4590,7 @@

      spl_autoload_functions()

      @@ -4640,7 +4641,7 @@

      spl_autoload_unregister()

      @@ -4697,7 +4698,7 @@

      spl_autoload_unregister()

      @@ -4746,7 +4747,7 @@

      PSR-4

      @@ -4776,7 +4777,7 @@

      PSR-4

      @@ -4823,7 +4824,7 @@

      Traversable

      @@ -4876,7 +4877,7 @@

      Traversable

      @@ -4929,7 +4930,7 @@

      Traversable

      @@ -4973,7 +4974,7 @@

      SPL Functions

      @@ -5028,7 +5029,7 @@

      SPL Functions

      @@ -5079,7 +5080,7 @@

      SPL Functions

      @@ -5131,7 +5132,7 @@

      SPL Functions

      @@ -5173,7 +5174,7 @@

      SPL Functions

      @@ -5226,7 +5227,7 @@

      SPL Functions

      @@ -5271,7 +5272,7 @@

      SPL Functions

      @@ -5301,7 +5302,7 @@

      SPL Functions

      @@ -5347,7 +5348,7 @@

      SPL Functions

      @@ -5399,7 +5400,7 @@

      SPL Functions

      @@ -5445,7 +5446,7 @@

      SPL Functions

      @@ -5475,7 +5476,7 @@

      SPL Functions

      @@ -5508,7 +5509,7 @@

      SPL Functions

      @@ -5558,7 +5559,7 @@

      SPL Functions

      @@ -5613,7 +5614,7 @@

      SPL Functions

      @@ -5662,7 +5663,7 @@

      Usage

      @@ -5713,7 +5714,7 @@

      Usage

      @@ -5767,7 +5768,7 @@

      Usage

      @@ -5812,7 +5813,7 @@

      Centralized Declaration

      @@ -5847,7 +5848,7 @@

      Centralized Declaration

      @@ -5877,7 +5878,7 @@

      Centralized Declaration

      @@ -5915,7 +5916,7 @@

      Centralized Declaration

      @@ -5952,7 +5953,7 @@

      Centralized Declaration

      @@ -5995,7 +5996,7 @@

      Centralized Declaration

      @@ -6025,7 +6026,7 @@

      Centralized Declaration

      @@ -6082,7 +6083,7 @@

      Centralized Declaration

      @@ -6130,7 +6131,7 @@

      Centralized Declaration

      @@ -6179,7 +6180,7 @@

      Centralized Declaration

      @@ -6209,7 +6210,7 @@

      Centralized Declaration

      @@ -6259,7 +6260,7 @@

      CRUD

      @@ -6308,7 +6309,7 @@

      CRUD

      @@ -6358,7 +6359,7 @@

      CRUD

      @@ -6412,7 +6413,7 @@

      CRUD

      @@ -6459,7 +6460,7 @@

      CRUD

      @@ -6508,7 +6509,7 @@

      CRUD

      @@ -6538,7 +6539,7 @@

      CRUD

      @@ -6587,7 +6588,7 @@

      Active Record = Row Data Gateway + Domain Logic

      @@ -6644,7 +6645,7 @@

      Active Record = Row Data Gateway + Domain Logic

      @@ -6674,7 +6675,7 @@

      Active Record = Row Data Gateway + Domain Logic

      @@ -6729,7 +6730,7 @@

      Active Record = Row Data Gateway + Domain Logic

      @@ -6776,7 +6777,7 @@

      Remove

      @@ -6806,7 +6807,7 @@

      Remove

      @@ -6855,7 +6856,7 @@

      Remove

      @@ -6885,7 +6886,7 @@

      Remove

      @@ -6930,7 +6931,7 @@

      PHP Data Object (PDO)

      @@ -6981,7 +6982,7 @@

      Usage

      @@ -7037,7 +7038,7 @@

      Usage

      @@ -7086,7 +7087,7 @@

      Usage

      @@ -7116,7 +7117,7 @@

      Usage

      @@ -7155,7 +7156,7 @@

      Usage

      @@ -7193,7 +7194,7 @@

      Code Snippet

      @@ -7231,7 +7232,7 @@

      Code Snippet

      @@ -7275,7 +7276,7 @@

      Code Snippet

      @@ -7317,7 +7318,7 @@

      Doctrine2 ORM

      @@ -7347,7 +7348,7 @@

      Doctrine2 ORM

      @@ -7403,7 +7404,7 @@

      Doctrine2 ORM

      @@ -7460,7 +7461,7 @@

      Doctrine2 ORM

      @@ -7490,7 +7491,7 @@

      Doctrine2 ORM

      @@ -7541,7 +7542,7 @@

      Doctrine2 ORM

      @@ -7582,7 +7583,7 @@

      Doctrine2 ORM

      @@ -7612,7 +7613,7 @@

      Doctrine2 ORM

      @@ -7670,7 +7671,7 @@

      Doctrine2 ORM

      @@ -7718,7 +7719,7 @@

      Usage

      @@ -7779,7 +7780,7 @@

      Usage

      @@ -7837,7 +7838,7 @@

      Usage

      @@ -7887,7 +7888,37 @@

      Usage

      + + + + + +
      +
      +
      + +

      Checkout: RulerZ

      + + +
      +
      +

      Notes

      +
      + +
      +
      +
      + + + +
      @@ -7917,7 +7948,7 @@

      Usage

      @@ -7962,7 +7993,7 @@

      A few use cases:

      @@ -8013,7 +8044,7 @@

      A few use cases:

      @@ -8059,7 +8090,7 @@

      Workarounds

      @@ -8113,7 +8144,7 @@

      Workarounds

      @@ -8143,7 +8174,7 @@

      Workarounds

      @@ -8178,7 +8209,7 @@

      Workarounds

      @@ -8211,7 +8242,7 @@

      Workarounds

      @@ -8254,7 +8285,7 @@

      Event Dispatcher

      @@ -8304,7 +8335,7 @@

      Event Dispatcher

      @@ -8358,7 +8389,7 @@

      Event Dispatcher

      @@ -8404,7 +8435,7 @@

      Event Dispatcher

      @@ -8446,7 +8477,7 @@

      Event Dispatcher

      @@ -8505,7 +8536,7 @@

      Event Dispatcher

      @@ -8538,7 +8569,7 @@

      Event Dispatcher

      @@ -8597,7 +8628,7 @@

      Event Dispatcher

      @@ -8635,7 +8666,7 @@

      WSSE Username Token

      @@ -8681,7 +8712,7 @@

      WSSE Username Token

      @@ -8711,7 +8742,7 @@

      WSSE Username Token

      @@ -8741,7 +8772,7 @@

      WSSE Username Token

      @@ -9651,125 +9682,131 @@

      Table of Contents

      - Sessions + Checkout: RulerZ 150 - Overview + Sessions 151 - Code Please + Overview 152 - Security Concerns + Code Please 153 - Session Configuration + Security Concerns 154 - Authentication + Session Configuration 155 - What You Have Right Now + Authentication 156 - The Big Picture + What You Have Right Now 157 - The Interceptor Pattern + The Big Picture 158 - Introducing the Event Dispatcher + The Interceptor Pattern 159 - Using the EventDispatcherTrait + Introducing the Event Dispatcher 160 - The Firewall (1/2) + Using the EventDispatcherTrait 161 - The Firewall (2/2) + The Firewall (1/2) 162 - Implementing The Firewall + The Firewall (2/2) 163 - Authentication Mechanism + Implementing The Firewall 164 - Adding New Routes + Authentication Mechanism 165 - Stateless Authentication + Adding New Routes 166 - Basic Security Thinking + Stateless Authentication 167 - Next Week:
      Web Security 101 + Basic Security Thinking 168 - The End. + Next Week:
      Web Security 101 169 + + The End. + 170 + + + From 57ae14b2b72696a78820175d4d3b6358b8f96ab5 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 9 May 2016 11:44:15 +0200 Subject: [PATCH 69/71] Publish slides (Mon May 9 11:44:15 CEST 2016) --- extended.html | 485 ++++++++++++++++++++++++-------------------------- index.html | 4 +- isima.html | 4 +- 3 files changed, 240 insertions(+), 253 deletions(-) diff --git a/extended.html b/extended.html index 7bb2793..0659b69 100644 --- a/extended.html +++ b/extended.html @@ -1288,8 +1288,8 @@

      William DURAND

      -

      PhD student / CTO TailorDev

      -

      Graduated from IUT and ISIMA. Worked at:

      +

      PhD / CTO TailorDev

      +

      Graduated from IUT, ISIMA, Blaise Pascal University. Worked at:

      @@ -1630,8 +1630,8 @@
    • Pragmatism;
    • Best Practices.
    -

    -

    It has been written by ~1290 developers.

    +

    +

    It has been written by ~1502 developers.

    Open Source, MIT licensed.

    @@ -1669,14 +1669,14 @@ also be used standalone even if you don't use the framework as they don't have any mandatory dependencies.

    There are ~30 components, including:

    -
    BrowserKit              EventDispatcher     OptionsResolver     Translation
    -ClassLoader             ExpressionLanguage  Process             VarDumper
    -Config                  Filesystem          PropertyAccess      Yaml
    -Console                 Finder              Routing
    -CssSelector             Form                Security
    -Debug                   HttpFoundation      Serializer
    -DependencyInjection     HttpKernel          Stopwatch
    -DomCrawler              Intl                Templating
    +
    BrowserKit              EventDispatcher     OptionsResolver     Templating
    +ClassLoader             ExpressionLanguage  Process             Translation
    +Config                  Filesystem          PropertyAccess      VarDumper
    +Console                 Finder              PropertyInfo        Yaml
    +CssSelector             Form                Routing
    +Debug                   HttpFoundation      Security
    +DependencyInjection     HttpKernel          Serializer
    +DomCrawler              Intl                Stopwatch
     
    @@ -1714,7 +1714,7 @@ component into your composer.json file:

    {
         "require": {
    -        "symfony/yaml": "~2.6"
    +        "symfony/yaml": "~3.0"
         }
     }
     
    @@ -1949,7 +1949,7 @@ $request = Request::createFromGlobals(); $path = $request->getPathInfo(); -if (in_array($path, array('', '/'))) { +if (in_array($path, ['', '/'])) { $response = new Response('Welcome to the homepage.'); } elseif ('/hello' === $path) { $response = new Response('hello, World!'); @@ -2030,10 +2030,10 @@
    # app/config/routing.yml
     hello:
         pattern:  /hello
    -    defaults: { _controller: AcmeDemoBundle:Main:hello }
    +    defaults: { _controller: AppBundle:Main:hello }
     
    -

    The AcmeDemoBundle:Main:hello string is a short syntax that points to a +

    The AppBundle:Main:hello string is a short syntax that points to a specific PHP method named helloAction() inside a class called MainController.

    @@ -2076,8 +2076,8 @@

    In Symfony, a method in a controller is called an action. The convention is to suffix each method with Action.

    Also, each controller should be suffixed with Controller.

    -
    // src/Acme/DemoBundle/Controller/MainController.php
    -namespace Acme\DemoBundle\Controller;
    +
    // src/AppBundle/Controller/MainController.php
    +namespace AppBundle\Controller;
     
     use Symfony\Component\HttpFoundation\Response;
     
    @@ -2118,27 +2118,69 @@
             
    -

    A Symfony Project

    +

    A Symfony Project (1/2)

    -

    Recommended structure of a Symfony project:

    +

    Recommended structure of a Symfony (3.x) project:

    path/to/project/
         app/
    -        cache/
             config/
    -        logs/
    +        Resources/
    +            views/
    +    bin/
    +        console
         src/
             ...
    +    tests/
    +        ...
    +    var/
    +        cache/
    +        logs/
    +        sessions/
         vendor/
             ...
         web/
             app.php
             ...
     
    - +
    + +
    +
    +

    Notes

    +
    + +
    +
    +
    + + + + +
    +
    +
    + + +
    +
    +
    + +

    A Symfony Project (2/2)

    + + +

    Each directory has its own purpose (and set of files):

      -
    • app/ contains the application kernel, and the configuration;
    • +
    • app/ contains the application kernel, views, and the configuration;
    • src/ contains your bundles;
    • +
    • tests/ contains your tests;
    • +
    • var/ contains files that change often (like in Unix systems);
    • vendor/ contains your dependencies;
    • web/ contains your front controllers and your assets.
    @@ -2159,7 +2201,7 @@
    @@ -2181,12 +2223,12 @@ { public function registerBundles() { - $bundles = array( + $bundles = [ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), // ... - ); + ]; - if (in_array($this->getEnvironment(), array('dev', 'test'))) { + if (in_array($this->getEnvironment(), ['dev', 'test'])) { $bundles[] = // dev bundle; } @@ -2214,7 +2256,7 @@
    @@ -2255,7 +2297,7 @@
    @@ -2276,14 +2318,14 @@ - { resource: security.yml } framework: - secret: "%secret%" - router: { resource: "%kernel.root_dir%/config/routing.yml" } + secret: '%secret%' + router: { resource: '%kernel.root_dir%/config/routing.yml' } # ... # Twig Configuration twig: - debug: "%kernel.debug%" - strict_variables: "%kernel.debug%" + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' # ...
    @@ -2305,7 +2347,7 @@
    @@ -2354,7 +2396,7 @@ @@ -2372,19 +2414,19 @@
    $this->import('parameters.yml');
     $this->import('security.yml');
     
    -$container->loadFromExtension('framework', array(
    +$container->loadFromExtension('framework', [
         'secret' => '%secret%',
    -    'router' => array(
    +    'router' => [
             'resource' => '%kernel.root_dir%/config/routing.php'
    -    ),
    +    ],
         // ...
    -));
    +]);
     
     // Twig Configuration
    -$container->loadFromExtension('twig', array(
    +$container->loadFromExtension('twig', [
         'debug'            => '%kernel.debug%',
         'strict_variables' => '%kernel.debug%',
    -));
    +]);
     
     // ...
     
    @@ -2406,7 +2448,7 @@ @@ -2424,21 +2466,21 @@
    # app/config/config.yml
     # ...
     twig:
    -    debug:            "%kernel.debug%"
    -    strict_variables: "%kernel.debug%"
    +    debug:            '%kernel.debug%'
    +    strict_variables: '%kernel.debug%'
     

    The routing definition MUST be written in YAML:

    # app/config/routing.yml
     hello:
         pattern:  /hello
    -    defaults: { _controller: AcmeDemoBundle:Main:hello }
    +    defaults: { _controller: AppBundle:Main:hello }
     

    The DI Container configuration MUST be written in XML:

    <services>
         <service id="acme_demo.controllers.main"
    -        class="Acme\DemoBundle\MainController" />
    +        class="AppBundle\MainController" />
     </services>
     
    @@ -2459,7 +2501,7 @@ @@ -2510,7 +2552,7 @@ @@ -2560,7 +2602,7 @@ @@ -2580,8 +2622,6 @@ DemoBundle.php Controller/ Resources/ - meta/ - LICENSE config/ doc/ index.rst @@ -2589,9 +2629,10 @@ views/ public/ Tests/ + LICENSE -

    The DemoBundle class is mandatory, and both Resources/meta/LICENSE and +

    The DemoBundle class is mandatory, and both LICENSE and Resources/doc/index.rst files should be present.

    The XXX directory(ies) reflects the namespace structure of the bundle.

    @@ -2611,7 +2652,7 @@ @@ -2692,7 +2733,7 @@ @@ -2747,7 +2788,7 @@ @@ -2797,7 +2838,7 @@ @@ -2840,7 +2881,7 @@ @@ -2851,7 +2892,7 @@
    -

    Read The Best Practices!

    +

    Read The Best Practices!

    @@ -2870,7 +2911,7 @@
    @@ -2900,7 +2941,7 @@ @@ -2945,7 +2986,7 @@ @@ -2963,12 +3004,12 @@
    # app/config/routing.yml
     homepage:
         pattern:  /
    -    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +    defaults: { _controller: AppBundle:Hello:index }
     

    Controller Implementation

    -
    // src/Acme/DemoBundle/Controller/HelloController.php
    -namespace Acme\DemoBundle\Controller;
    +
    // src/AppBundle/Controller/HelloController.php
    +namespace AppBundle\Controller;
     
     use Symfony\Component\HttpFoundation\Response;
     
    @@ -2998,7 +3039,7 @@ 

    Controller Implementation

    @@ -3015,9 +3056,7 @@

    Controller Implementation

    Every route must have a _controller parameter, which dictates which controller should be executed when that route is matched.

    This parameter uses a simple string pattern called the logical controller name. -The pattern has three parts, each separated by a colon:

    -
    bundle:controller:action
    -
    +The pattern has three parts, each separated by a colon: bundle:controller:action.

    For example, a _controller value of AcmeBlogBundle:Blog:show means:

    • Bundle: AcmeBlogBundle;
    • @@ -3043,7 +3082,7 @@

      Controller Implementation

    @@ -3058,16 +3097,16 @@

    Controller Implementation

    Routing Definition

    -
    # src/Acme/DemoBundle/Resources/config/routing.yml
    +
    # src/AppBundle/Resources/config/routing.yml
     acme_demo.hello_hello:
         pattern:  /hello/{name}
    -    defaults: { _controller: AcmeDemoBundle:Hello:hello }
    +    defaults: { _controller: AppBundle:Hello:hello }
         requirements:
             _method: GET
     

    Controller Implementation

    -
    // src/Acme/DemoBundle/Controller/HelloController.php
    +
    // src/AppBundle/Controller/HelloController.php
     
     class HelloController
     {
    @@ -3097,7 +3136,7 @@ 

    Controller Implementation

    @@ -3144,7 +3183,7 @@

    Controller Implementation

    @@ -3175,7 +3214,7 @@

    Redirecting

    Rendering Templates

    return $this->render(
    -    'AcmeDemoBundle:Hello:hello.html.twig', array('name' => $name)
    +    'hello/hello.html.twig', array('name' => $name)
     );
     
    @@ -3196,7 +3235,7 @@

    Rendering Templates

    @@ -3245,7 +3284,7 @@

    Rendering Templates

    @@ -3275,7 +3314,7 @@

    Rendering Templates

    @@ -3296,11 +3335,11 @@

    Rendering Templates

    # app/config/routing.yml
     homepage:
         pattern:  /
    -    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +    defaults: { _controller: AppBundle:Hello:index }
     

    This route matches the homepage (/) and maps it to the -AcmeDemoBundle:Hello:index controller.

    +AppBundle:Hello:index controller.

    http://symfony.com/doc/master/book/routing.html

    @@ -3321,7 +3360,7 @@

    Rendering Templates

    @@ -3362,7 +3401,7 @@

    Rendering Templates

    @@ -3402,7 +3441,7 @@

    Rendering Templates

    @@ -3426,10 +3465,10 @@

    Rendering Templates

    The \d+ requirement is a regular expression that says that the value of the {page} parameter must be a digit (i.e. a number).

    HTTP Method Requirements

    -
    # src/Acme/DemoBundle/Resources/config/routing.yml
    +
    # src/AppBundle/Resources/config/routing.yml
     acme_demo.hello_hello:
         pattern:  /hello/{name}
    -    defaults: { _controller: AcmeDemoBundle:Hello:hello }
    +    defaults: { _controller: AppBundle:Hello:hello }
         methods:  [ GET ]
         # methods:  [ GET, POST ]
     
    @@ -3451,7 +3490,7 @@

    HTTP Method Requirements

    @@ -3471,14 +3510,14 @@

    HTTP Method Requirements

    located in the bundle itself, and you should just require it:

    # app/config/routing.yml
     acme_demo:
    -    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
    +    resource: '@AppBundle/Resources/config/routing.yml'
     

    Prefixing Imported Routes

    # app/config/routing.yml
     acme_demo:
    -    resource: "@AcmeDemoBundle/Resources/config/routing.yml"
    -    prefix: /demo
    +    resource: '@AppBundle/Resources/config/routing.yml'
    +    prefix:   /demo
     

    The string /demo now be prepended to the path of each route loaded from @@ -3500,7 +3539,7 @@

    Prefixing Imported Routes

    @@ -3552,7 +3591,7 @@

    Query String

    @@ -3582,7 +3621,7 @@

    Query String

    @@ -3612,7 +3651,7 @@

    Query String

    @@ -3664,7 +3703,7 @@

    After

    @@ -3705,7 +3744,7 @@

    After

    @@ -3757,7 +3796,7 @@

    After

    @@ -3808,7 +3847,7 @@

    Loops

    @@ -3857,7 +3896,7 @@

    Loops

    @@ -3910,7 +3949,7 @@

    Example

    @@ -3965,7 +4004,7 @@

    Example

    @@ -3981,8 +4020,8 @@

    Example

    The key to template inheritance is the {% extends %} tag.

    A child template might look like this:

    -
    {# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
    -{% extends '::base.html.twig' %}
    +
    {# app/Resources/views/Blog/index.html.twig #}
    +{% extends 'base.html.twig' %}
     
     {% block title %}My cool blog posts{% endblock %}
     
    @@ -3994,9 +4033,6 @@ 

    Example

    {% endblock %}
    -

    The parent template is identified by a special string syntax -(::base.html.twig) which indicates that the template lives in -app/Resources/views/.

    If you need to get the content of a block from the parent template, you can use the {{ parent() }} function.

    @@ -4016,7 +4052,7 @@

    Example

    @@ -4033,9 +4069,10 @@

    Example

    By default, templates can live in two different locations:

    • app/Resources/views/: The applications views directory can contain - application-wide base templates (i.e. your application's layouts) as well as - templates that override bundle templates;
    • -
    • path/to/bundle/Resources/views/: Each bundle houses its templates in its + application-wide base templates (i.e. your application's layouts), + templates specific to your app as well as templates that override bundle + templates;
    • +
    • path/to/bundle/Resources/views/: Each (public) bundle houses its templates in its Resources/views directory (and subdirectories).

    Symfony uses a bundle:controller:template string syntax for templates.

    @@ -4061,7 +4098,7 @@

    Example

    @@ -4108,7 +4145,7 @@

    Example

    @@ -4149,7 +4186,7 @@

    Example

    @@ -4167,55 +4204,6 @@

    Example

    overridden by copying each from the Resources/views/ directory of the TwigBundle to the app/Resources/TwigBundle/views/ directory.

    - -
    -

    Notes

    -
    - -
    -
    -
    - - - - -
    - - - - -
    -
    -
    - -

    The Three-Level Approach

    - - -
      -
    1. -

      Create a app/Resources/views/base.html.twig file that contains the main -layout for your application (like in the previous example). Internally, this -template is called ::base.html.twig.

      -
    2. -
    3. -

      Create a template for each section of your site. The AcmeBlogBundle -would have a template called AcmeBlogBundle::layout.html.twig that contains -only blog section-specific elements.

      -
    4. -
    5. -

      Create individual templates for each page and make each extend the -appropriate section template. For example, the "index" page would be called -something close to AcmeBlogBundle:Blog:index.html.twig and list the actual -blog posts.

      -
    6. -
    -

    Notes

    @@ -4281,7 +4269,7 @@

    Example

    { // ... - return $this->render('AcmeBlogBundle:Blog:index.html.twig', array( + return $this->render('blog/index.html.twig', array( 'posts' => $posts, )); } @@ -4289,7 +4277,7 @@

    Example

    Using the Templating Service

    $engine  = $this->container->get('templating');
    -$content = $engine->render('AcmeBlogBundle:Blog:index.html.twig', array(
    +$content = $engine->render('blog/index.html.twig', array(
         'posts' => $posts,
     ));
     
    @@ -4330,7 +4318,7 @@ 

    Using the Templating Service

    Assuming the following routing definition:

    homepage:
         path:     /
    -    defaults: { _controller: AcmeDemoBundle:Hello:index }
    +    defaults: { _controller: AppBundle:Hello:index }
     
     acme_blog.post_show:
         path:     /posts/{slug}
    @@ -5101,9 +5089,9 @@ 

    Container Extensions

    Twig finds all services tagged with twig.extension and automatically registers them as extensions.

    Debugging Services

    -
    $ php app/console container:debug
    +
    $ php bin/console debug:container
     
    -$ php app/console container:debug foo
    +$ php bin/console debug:container foo
     
    @@ -5170,24 +5158,24 @@

    Debugging Services

    Built-in Commands (1/2)

    -
    $ php app/console
    +            
    $ php bin/console
     

    Global Options

    You can get help information:

    -
    $ php app/console help cmd
    -$ php app/console cmd --help
    -$ php app/console cmd -h
    +
    $ php bin/console help cmd
    +$ php bin/console cmd --help
    +$ php bin/console cmd -h
     

    You can get more verbose messages:

    -
    $ php app/console cmd --verbose
    -$ php app/console cmd -v [-vv] [-vvv]
    +
    $ php bin/console cmd --verbose
    +$ php bin/console cmd -v [-vv] [-vvv]
     

    You can suppress output:

    -
    $ php app/console cmd --quiet
    -$ php app/console cmd -q
    +
    $ php bin/console cmd --quiet
    +$ php bin/console cmd -q
     
    @@ -5231,19 +5219,18 @@

    Global Options

    config:dump-reference Dumps default configuration for an extension container container:debug Displays current services for an application -init - init:acl Mounts ACL tables in the database +debug + debug:container Displays current services for an application + debug:router Displays current routes for an application router - router:debug Displays current routes for an application - router:dump-apache Dumps all routes as Apache rewrite rules router:match Helps debug routes by simulating a path info match server server:run Runs PHP built-in web server translation translation:update Updates the translation file -twig - twig:lint Lints a template and outputs encountered +lint + lint:twig Lints a template and outputs encountered errors
    @@ -5280,8 +5267,8 @@

    Global Options

    Create a Command directory inside your bundle and create a php file suffixed with Command.php for each command that you want to provide:

    -
    // src/Acme/DemoBundle/Command/GreetCommand.php
    -namespace Acme\DemoBundle\Command;
    +
    // src/AppBundle/Command/GreetCommand.php
    +namespace AppBundle\Command;
     
     use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
     use Symfony\Component\Console\Input\InputInterface;
    @@ -5404,7 +5391,7 @@ 

    Usage

    Usage

    -
    // php app/console demo:greet --yell
    +
    // php bin/console demo:greet --yell
     
     if ($input->getOption('yell')) {
         // ...
    @@ -5457,7 +5444,7 @@ 

    Usage

    Usage

    -
    // php app/console demo:greet --iterations=10
    +
    // php bin/console demo:greet --iterations=10
     
     for ($i = 0; $i < $input->getOption('iterations'); $i++) {
     }
    @@ -5587,7 +5574,7 @@ 

    Calling an existing Command

    ->add('birthday', 'date') ->getForm(); - return $this->render('AcmeDemoBundle:Default:new.html.twig', [ + return $this->render('default/new.html.twig', [ 'form' => $form->createView(), ]); } @@ -5628,7 +5615,7 @@

    Calling an existing Command


    -
    {# src/Acme/DemoBundle/Resources/views/Default/new.html.twig #}
    +
    {# src/AppBundle/Resources/views/Default/new.html.twig #}
     <form action="{{ path('acme_demo.default_new') }}" method="post">
         {{ form_widget(form) }}
     
    @@ -5816,7 +5803,7 @@ 

    Calling an existing Command

    public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults([ - 'data_class' => 'My\Person', + 'data_class' => My\Person::class, ]); } @@ -5861,7 +5848,7 @@

    Calling an existing Command

    public function newAction(Request $request)
     {
         $person = new Person();
    -    $form   = $this->createForm(new PersonType(), $person);
    +    $form   = $this->createForm(PersonType::class, $person);
     
         if ($form->handleRequest($request)->isValid()) {
             $person->save(); // insert a new `person`
    @@ -5968,7 +5955,7 @@ 

    Calling an existing Command

    */ private function processForm(Request $request, Person $person) { - $form = $this->createForm(new PersonType(), $person); + $form = $this->createForm(PersonType::class, $person); if ($form->handleRequest($request)->isValid()) { $person->save(); @@ -5976,7 +5963,7 @@

    Calling an existing Command

    return $this->redirect($this->generateUrl('success')); } - return $this->render('AcmeDemoBundle:Default:new.html.twig', [ + return $this->render('default/new.html.twig', [ 'form' => $form->createView(), ]); } @@ -6226,7 +6213,7 @@

    Calling an existing Command

    specification.

    Example

    Given the following class:

    -
    namespace Acme\DemoBundle\Entity;
    +
    namespace AppBundle\Entity;
     
     class Author
     {
    @@ -6235,8 +6222,8 @@ 

    Example

    You can configure a set of constraints on it:

    -
    # src/Acme/DemoBundle/Resources/config/validation.yml
    -Acme\DemoBundle\Entity\Author:
    +
    # src/AppBundle/Resources/config/validation.yml
    +AppBundle\Entity\Author:
         properties:
             name:
                 - NotBlank: ~
    @@ -6287,7 +6274,7 @@ 

    Example

    If the $name property is empty, you will see the following error message:

    -
    Acme\DemoBundle\Author.name:
    +
    AppBundle\Author.name:
         This value should not be blank
     
    @@ -6366,8 +6353,8 @@

    Example

    Properties

    Validating class properties is the most basic validation technique. Symfony allows you to validate private, protected or public properties.

    -
    # src/Acme/DemoBundle/Resources/config/validation.yml
    -Acme\DemoBundle\Entity\Author:
    +
    # src/AppBundle/Resources/config/validation.yml
    +AppBundle\Entity\Author:
         properties:
             firstName:
                 - NotBlank: ~
    @@ -6412,8 +6399,8 @@ 

    Classes

    Constraints can also be applied to the return value of a method. Symfony allows you to add a constraint to any public method whose name starts with get or is.

    -
    # src/Acme/DemoBundle/Resources/config/validation.yml
    -Acme\DemoBundle\Entity\Author:
    +
    # src/AppBundle/Resources/config/validation.yml
    +AppBundle\Entity\Author:
         getters:
             passwordLegal:
                 - "False":
    @@ -6463,8 +6450,8 @@ 

    Classes

    You can organize each constraint into one or more validation groups, and then apply validation against just one group of constraints.

    Example

    -
    # src/Acme/DemoBundle/Resources/config/validation.yml
    -Acme\DemoBundle\Entity\User:
    +
    # src/AppBundle/Resources/config/validation.yml
    +AppBundle\Entity\User:
         properties:
             email:
                 - Email:    { groups: [ registration ] }
    @@ -7603,7 +7590,7 @@ 

    Edge Side Includes

    determine if two versions of a resource are the same or not.

    public function indexAction()
     {
    -    $response = $this->render('MyBundle:Main:index.html.twig');
    +    $response = $this->render('main/index.html.twig');
         $response->setETag(md5($response->getContent()));
         $response->setPublic(); // make sure the response is public/cacheable
         $response->isNotModified($this->getRequest());
    @@ -7742,7 +7729,7 @@ 

    Edge Side Includes

    web content assembly at the reverse proxy level. The reverse proxy analyses the HTML code, parses ESI specific markup and assembles the final result before flushing it to the client.

    -

    +

    <esi:include src="user.php" />
     
    @@ -8453,271 +8440,271 @@

    Table of Contents

    - A Symfony Project + A Symfony Project (1/2) 24 - Application Kernel + A Symfony Project (2/2) 25 - Application Configuration + Application Kernel 26 - YAML Configuration + Application Configuration 27 - XML Configuration + YAML Configuration 28 - PHP Configuration + XML Configuration 29 - The Rules (Well... My Rules) + PHP Configuration 30 - Environments + The Rules (Well... My Rules) 31 - What Is A Bundle? + Environments 32 - Bundle: Directory Structure + What Is A Bundle? 33 - Bundle: Where To Put Your Classes? + Bundle: Directory Structure 34 - Creating a Bundle + Bundle: Where To Put Your Classes? 35 - The Web Directory + Creating a Bundle 36 - Summary + The Web Directory 37 - Read The Best Practices! + Summary 38 - Controllers + Read The Best Practices! 39 - Request, Controller, Response + Controllers 40 - The Simplest Page Ever + Request, Controller, Response 41 - Controller Naming Pattern + The Simplest Page Ever 42 - Route Params as Controller Args + Controller Naming Pattern 43 - The Request as a Controller Argument + Route Params as Controller Args 44 - The Base Controller Class + The Request as a Controller Argument 45 - The Response + The Base Controller Class 46 - Routing + The Response 47 - Basic Route Configuration + Routing 48 - Routing with Placeholders (1/2) + Basic Route Configuration 49 - Routing with Placeholders (2/2) + Routing with Placeholders (1/2) 50 - Requirements + Routing with Placeholders (2/2) 51 - Including External Routing Resources + Requirements 52 - Generating URLs + Including External Routing Resources 53 - Templating + Generating URLs 54 - + Templating 55 - Why Twig? + 56 - Getting Familiar With Twig + Why Twig? 57 - Accessing Variables + Getting Familiar With Twig 58 - Control Structure + Accessing Variables 59 - Filters + Control Structure 60 - Including Other Templates + Filters 61 - Template Inheritance (1/2) + Including Other Templates 62 - Template Inheritance (2/2) + Template Inheritance (1/2) 63 - Template Naming and Locations (1/2) + Template Inheritance (2/2) 64 - Template Naming and Locations (2/2) + Template Naming and Locations (1/2) 65 - Overriding Bundle Templates + Template Naming and Locations (2/2) 66 - Overriding Core Templates + Overriding Bundle Templates 67 - The Three-Level Approach + Overriding Core Templates 68 diff --git a/index.html b/index.html index 8c8fd68..828da72 100644 --- a/index.html +++ b/index.html @@ -1258,8 +1258,8 @@

    William DURAND

    -

    PhD student / CTO TailorDev

    -

    Graduated from IUT and ISIMA. Worked at:

    +

    PhD / CTO TailorDev

    +

    Graduated from IUT, ISIMA, Blaise Pascal University. Worked at:

    • Michelin (Clermont-Fd, France);
    • Nelmio (Zürich, Switzerland);
    • diff --git a/isima.html b/isima.html index cbb7934..cbcbe14 100644 --- a/isima.html +++ b/isima.html @@ -1436,8 +1436,8 @@

      William DURAND

      -

      PhD student / CTO TailorDev

      -

      Graduated from IUT and ISIMA. Worked at:

      +

      PhD / CTO TailorDev

      +

      Graduated from IUT, ISIMA, Blaise Pascal University. Worked at:

      • Michelin (Clermont-Fd, France);
      • Nelmio (Zürich, Switzerland);
      • From 9d96eabd861e784a36a09defda8e2711070a4097 Mon Sep 17 00:00:00 2001 From: William Durand Date: Wed, 11 May 2016 10:31:45 +0200 Subject: [PATCH 70/71] Publish slides (Wed May 11 10:31:45 CEST 2016) --- extended.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extended.html b/extended.html index 0659b69..542c6f6 100644 --- a/extended.html +++ b/extended.html @@ -3098,7 +3098,7 @@

        Controller Implementation

        Routing Definition

        # src/AppBundle/Resources/config/routing.yml
        -acme_demo.hello_hello:
        +app.hello_hello:
             pattern:  /hello/{name}
             defaults: { _controller: AppBundle:Hello:hello }
             requirements:
        @@ -3466,7 +3466,7 @@ 

        Rendering Templates

        the {page} parameter must be a digit (i.e. a number).

        HTTP Method Requirements

        # src/AppBundle/Resources/config/routing.yml
        -acme_demo.hello_hello:
        +app.hello_hello:
             pattern:  /hello/{name}
             defaults: { _controller: AppBundle:Hello:hello }
             methods:  [ GET ]
        @@ -3509,13 +3509,13 @@ 

        HTTP Method Requirements

        In order to respect the "bundle" principle, the routing configuration should be located in the bundle itself, and you should just require it:

        # app/config/routing.yml
        -acme_demo:
        +appa:
             resource: '@AppBundle/Resources/config/routing.yml'
         

        Prefixing Imported Routes

        # app/config/routing.yml
        -acme_demo:
        +app:
             resource: '@AppBundle/Resources/config/routing.yml'
             prefix:   /demo
         
        @@ -3558,17 +3558,17 @@

        Prefixing Imported Routes

        Relative URLs

        -
        $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ]);
        +
        $router->generate('app.hello_hello', [ 'name' => 'will' ]);
         // /hello/will
         

        Absolute URLs

        -
        $router->generate('acme_demo.hello_hello', [ 'name' => 'will' ], true);
        +
        $router->generate('app.hello_hello', [ 'name' => 'will' ], true);
         // http://example.com/hello/will
         

        Query String

        -
        $router->generate('acme_demo.hello_hello', [
        +
        $router->generate('app.hello_hello', [
             'name' => 'will', 'some' => 'thing'
         ]);
         // /hello/will?some=thing
        
        From 382654b9fc9f15a0d5ec6bedf9add488d86e88f3 Mon Sep 17 00:00:00 2001
        From: William Durand 
        Date: Wed, 11 May 2016 11:10:14 +0200
        Subject: [PATCH 71/71] Publish slides (Wed May 11 11:10:14 CEST 2016)
        
        ---
         extended.html | 16 ++++++++--------
         1 file changed, 8 insertions(+), 8 deletions(-)
        
        diff --git a/extended.html b/extended.html
        index 542c6f6..a4fa159 100644
        --- a/extended.html
        +++ b/extended.html
        @@ -2029,7 +2029,7 @@
         information from the request and routing configuration you've created.

        # app/config/routing.yml
         hello:
        -    pattern:  /hello
        +    path:  /hello
             defaults: { _controller: AppBundle:Main:hello }
         
        @@ -2473,7 +2473,7 @@

        The routing definition MUST be written in YAML:

        # app/config/routing.yml
         hello:
        -    pattern:  /hello
        +    path:  /hello
             defaults: { _controller: AppBundle:Main:hello }
         
        @@ -3003,7 +3003,7 @@

        Routing Definition

        # app/config/routing.yml
         homepage:
        -    pattern:  /
        +    path:  /
             defaults: { _controller: AppBundle:Hello:index }
         
        @@ -3099,7 +3099,7 @@

        Controller Implementation

        Routing Definition

        # src/AppBundle/Resources/config/routing.yml
         app.hello_hello:
        -    pattern:  /hello/{name}
        +    path:  /hello/{name}
             defaults: { _controller: AppBundle:Hello:hello }
             requirements:
                 _method: GET
        @@ -3331,10 +3331,10 @@ 

        Rendering Templates

        The Symfony router lets you define URLs that you map to different areas of your application.

        A route is a map from a URL path to a controller. Each route is named, and -maps a pattern (or path as of Symfony.2) to a _controller:

        +maps a path to a _controller:

        # app/config/routing.yml
         homepage:
        -    pattern:  /
        +    path:  /
             defaults: { _controller: AppBundle:Hello:index }
         
        @@ -3467,7 +3467,7 @@

        Rendering Templates

        HTTP Method Requirements

        # src/AppBundle/Resources/config/routing.yml
         app.hello_hello:
        -    pattern:  /hello/{name}
        +    path:  /hello/{name}
             defaults: { _controller: AppBundle:Hello:hello }
             methods:  [ GET ]
             # methods:  [ GET, POST ]
        @@ -4426,7 +4426,7 @@ 

        Cache Busting

        component provided by Symfony.

        # app/config/routing.yml
         my_route_to_expose:
        -    pattern:  /foo/{id}/bar
        +    path:  /foo/{id}/bar
             defaults: { _controller: FooBarBundle:Foo:bar }
             options:
                 expose: true