aft-php-silex-slides



aft-php-silex-slides

0 1


aft-php-silex-slides

Slides for the AFT PHP Silex workshop.

On Github 2dotstwice / aft-php-silex-slides

Introduction to Silex

  • Kristof Coomans
  • Bert Ramakers
  • De Hoorn, Leuven

What will we learn?

  • Managing dependencies with Composer
  • Handling incoming requests
  • Sending responses
  • Adding additional behavior with middlewares
  • Using shared services to reduce code duplication
  • Storing session data
  • Storing data on the filesystem
  • Using Twig to render templates

What will we not learn today?

  • HTML, CSS, JavaScript
  • Databases
  • Caching
  • Version control (Git, SVN)
  • ...

Composer

Dependency management made easy

  • Use code written by other developers
  • Automatically downloads subdependencies
{
    "require": {
        "silex/silex": "~1.3",
        "twig/twig": "^1.22"
    }
}

Composer install

Packagist

App store for Composer

Silex

  • Lightweight micro-framework
  • Minimal dependencies
  • Liberal in how you structure your code
  • Suitable from small applications to large web services
  • Open-Source

Basic setup

<?php

require_once __DIR__ . '/../vendor/autoload.php';

$app = new Silex\Application();

// Handle requests ...

$app->run();

Request handling

Hello world

GET http://<your-url>/hello
$app->get(
    '/hello',
    function (Request $request) {
        return new Response('Hello world!');
    }
);

Request handling

Variable parameters in the URL

GET http://<your-url>/hello/AFT
$app->get(
    '/hello/{name}',
    function (Request $request, $name) {
        return new Response('Hello ' . $name . '!');
    }
);

Request handling

HTTP status codes

$app->get(
    '/blog/{postId}',
    function (Request $request, $postId) {
        $posts = [
            1 => 'Just another Silex blog.',
            2 => 'My thoughts on PHP.',
            5 => 'AFT workshop review.',
        ];

        if (!isset($posts[$postId])) {
            return new Response('Not found.', 404);
        } else {
            return new Response($posts[$postId], 200);
        }
    }
);

Request handling

Query parameters

GET http://<your-url>/search?name=...
$app->get('/search', function (Request $request) {
    $filter = $request->query->get('name');
    $names = ['Bill Gates', 'Steve Jobs', 'Steve Wozniak'];

    $matches = [];
    foreach ($names as $name) {
        if (stripos($name, $filter) !== false) {
            $matches[] = $name;
        }
    }

    return new Response(
        count($matches) . ' result(s): ' . implode(', ', $matches)
    );
});

Request handling

Posting data

POST http://<your-url>/contact
$app->post(
    '/contact',
    function (Request $request) {
        $filename = __DIR__ . '/files/contact-' . time() . '.txt';
        $content = $request->getContent();

        file_put_contents($filename, $content);

        return new Response($filename);
    }
);

Middlewares

Perform additional actions on each route...

$app->after(function (Request $request, Response $response) {
    $response->headers->set('X-Generated-By', 'Silex');
});

... or on specific routes

$app->get(...)
    ->after(
        function (Request $request, Response $response) {
            $response->headers->set('X-Generated-By', 'Silex');
        }
    );

Available middlewares

$app->before(
    function (Request $request) {
        // Modify $request before it is handled...
    }
);
$app->after(
    function (Request $request, Response $response) {
        // Modify $response before it is sent back... 
    }
);
$app->finish(
    function (Request $request, Response $response) {
        // Additional actions such as logging...
        // Changes to $request or $response will be ignored here.
    }
);

Services

Write your own service instantiation function ...

$app['twitter'] = $app->share(
    function() {
        return new TwitterClient();
    }
);

// ...

$app['twitter']->getTweets(...);

... or use an existing ServiceProvider

$app->register(new Silex\Provider\SessionServiceProvider());

// ...

$app['session']->set(...);
$app['session']->get(...);

Session data

Storing data

POST http://<your-url>/login
$app->register(new Silex\Provider\SessionServiceProvider());

$app->post(
    '/login',
    function (Request $request) use ($app) {
        $username = $request->request->get('username');
        $password = $request->request->get('password');

        if ($username == 'john.doe' && $password == 'secret') {
            $app['session']->set('username', $username);
            return new Response('Logged in.', 200);
        } else {
            return new Response('Access denied.', 403);
        }
    }
);

Session data

Retrieving stored data

GET http://<your-url>/user
$app->get(
    '/user',
    function (Request $request) use ($app) {
        $username = $app['session']->get('username');

        if (!empty($username)) {
            return new Response('Logged in as ' . $username);
        } else {
            return new Response('Not logged in.');
        }
    }
);

Filesystem

Storing data

file_put_contents($filename, $contents);

Retrieving data

$contents = file_get_contents($filename);

Filesystem

Storing data as JSON

$users = [
    'john.doe' => [
        'password' => '662azd',
        'bio' => '...',
    ],
    'an0n' => [
        'password' => 'aazf959',
        'bio' => '...',
    ],
];

$json = json_encode($users);
file_put_contents('users.json', $json);

Filesystem

Reading JSON data

$json = file_get_contents('users.json');
$users = json_decode($json);
[
    'john.doe' => [
        'password' => '662azd',
        'bio' => '...',
    ],
    'an0n' => [
        'password' => 'aazf959',
        'bio' => '...',
    ],
];

Twig templates

$app->register(
    new Silex\Provider\TwigServiceProvider(),
    ['twig.path' => __DIR__ . '/../templates']
);
$app->get(
    'blog',
    function(Request $request) use ($app) {
        $posts = [
            1 => 'Just another Silex blog.',
            2 => 'My thoughts on PHP.',
            5 => 'AFT workshop review.',
        ];

        $html = $app['twig']->render('blog.twig', [
            'title' => 'My awesome blog.',
            'posts' => $posts,
        ]);

        return new Response($html);
    }
);
<h1>{{ title }}</h1>
<ul>
    {% for id, post in posts %}
        <li><a href="/blog/{{ id }}">{{ post }}</a></li>
    {% endfor %}
</ul>

Additional reading

Break time!

Introduction to Silex