Slide 1

Slide 1 text

Text PHP Belfast Laravel Presentation By David Frame

Slide 2

Slide 2 text

About me Started using PHP around 1999-2000. Primarily interested in OOP, design patterns, frameworks, CMS development and R&D. Research Developer at Tibus / Simply Zesty (2003-2012). Senior Developer at Blue Cube / AV Browne (2013). Senior Developer at 31interactive (2013-present).

Slide 3

Slide 3 text

The PHP Renaissance Better internals (namespaces, closures, traits, etc). Better tools (Composer, CLI utilities). Better methodologies (OOP, TDD, DI). Better standards (PSR). Better frameworks (Symfony2, ZF2, Slim, Aura, Laravel).

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

About this presentation It's a VERY brief introduction! Covers Laravel's six main elements as I see them. Will hopefully prompt you to learn more about it. It's not a sermon!

Slide 6

Slide 6 text

So what is Laravel? A modern PHP 5.3+ full-stack framework first released in July 2011. Very loosely based off Codeigniter. Makes use of several popular and highly tested components such as Symfony's HttpKernel & HttpFoundation, Monolog, Swiftmailer, etc.

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

The six areas I'll be covering 1. Syntax. 2. Artisan command line tool. 3. Request routing. 4. Query Builder & Eloquent database layers. 5. Blade templating engine. 6. IoC container.

Slide 9

Slide 9 text

1. Syntax

Slide 10

Slide 10 text

Expressiveness $articles = Article::where('online', '=', 1) ->orderBy('date', 'desc') ->skip(10) ->take(5) ->get(); Redirect::to('login') ->with('message', 'Login failed'); Cookie::forever('remember_me', 1);

Slide 11

Slide 11 text

Facades Facades are static wrappers to instantiated objects. They provide a quick, readable way to access Laravel's various components. Big misconception: Laravel is NOT a static framework. Since these facades are syntactic sugar you can bypass them for mocks and tests! You can easily create your own facades or 'rewire' the existing ones.

Slide 12

Slide 12 text

Facades example $appName = Config::get('application.name'); $filesystem = new Filesystem(...); $fileloader = new Fileloader($filesysyem); $config = new Config($fileloader, 'dev'); $appName = $config->get('application.name');

Slide 13

Slide 13 text

2. Artisan

Slide 14

Slide 14 text

Powerful command line tool Based off Symfony's Console component. Allows a number of application management tasks to be run from the CLI (code generation, DB migrations, etc). Easily customisable - write your own tasks!

Slide 15

Slide 15 text

Text Interactive shell (Tinker)

Slide 16

Slide 16 text

Text Custom mailer command

Slide 17

Slide 17 text

3. Request routing

Slide 18

Slide 18 text

Implicit routing Route::get('news', function() { return '

News page

'; }); Route::get('news/{id}', function($id) { return '

Article with id ' . $id . '

'; })->where('id', '[0-9]+'); Route::post('enquiry/submit', function() { return 'Posted: ' . print_r($_POST, true); });

Slide 19

Slide 19 text

Routing to controllers Route::controller('news', 'NewsController'); Route::controller('login', 'LoginController'); Route::controller('admin', 'AdminController'); class NewsController { public function getIndex() { ... } public function getArticle() { ... } public function postComment() { ... } }

Slide 20

Slide 20 text

Routing to resources (REST) Route::resource('news', 'NewsController'); class NewsController { public function index() { ... } public function create() { ... } public function store() { ... } public function show() { ... } public function edit() { ... } public function update() { ... } public function destroy() { ... } }

Slide 21

Slide 21 text

Resource routes -> methods GET /news -> NewsController::index() GET /news/create -> NewsController::create() POST /news -> NewsController::store(); GET /news/{id} -> NewsController::show($id) GET /news/{id}/edit -> NewsController::edit($id) PUT/PATCH /news/{id} -> NewsController::update($id) DELETE /news/{id} -> NewsController::destroy($id) For the previous NewsController route we would have:

Slide 22

Slide 22 text

Route names & filters Route::get('news/{id}', array('as' => 'article', function() { return '

News article!

'; }}); ! Redirect::route('article', array('id' => 1)); Route::filter('auth', function() { if (Auth::guest()) { return Redirect::to('login'); } }); ! Route::get('admin', array('before' => 'auth', function() { return '

Welcome to the admin area!

'; }));

Slide 23

Slide 23 text

4. Query Builder and Eloquent

Slide 24

Slide 24 text

Query Builder A feature-rich database abstraction layer implemented using PDO. Allows you to manipulate a database using object methods calls or using raw SQL. Fluent interface (chainable methods). Clean, English-like syntax. Supports 'complicated' database operations such as joins, aggregates, unions and even caching. Comparable to Zend\Db\Sql, Pear's MDB2 package.

Slide 25

Slide 25 text

Selects and Inserts DB::table('posts')->where('online', '=', 1) ->orderBy('date', 'desc')->take(5)->get(); DB::table('posts')->where('id', '=', 15)->first(); DB::table('posts')->insert(array( 'title' => 'Test Article', 'date' => '2013-11-05', 'online' => 1 ));

Slide 26

Slide 26 text

Updates and Deletes DB::table('posts') ->where('id', '=', 15) ->update(array( 'title' => 'Updated Test Article', 'online' => 0 ) ); DB::table('posts') ->where('id', '=', 15) ->delete();

Slide 27

Slide 27 text

Other handy features DB::table('posts')->where('id', '=', 15) ->pluck('title'); DB::table('posts') ->join('categories', 'posts.category_id', '=', 'categories.id') ->where('categories.id', '=', 5) ->get(); DB::table('reviews')->avg('rating');

Slide 28

Slide 28 text

Eloquent Object Relational Mapper built on top of Query Builder - it has identical syntax! Allows database entities to be mapped to PHP code, commonly referred to as Models. A model definition can be quickly set up using an appropriately named class (no getter/setters required!) Powerful features such as relationships, eager loading, event triggers, accessors/mutators and a lot more! Comparable to Zend\Db\TableGateway, Doctrine, Propel, Redbean.

Slide 29

Slide 29 text

Model Class class Post extends Eloquent { } class Post extends Eloquent { protected $table = 'newsposts'; public function summary() { return truncate($this->content, 150); } }

Slide 30

Slide 30 text

Selects and Inserts Post::where('date', '<=', DB::raw('CURDATE()')) ->andWhere('online', '=', 1) ->get(); Post::find(5); $post = new Post(); $post->title = 'New Article'; $post->date = new DateTime(); $post->online = true; $post->save();

Slide 31

Slide 31 text

Updates, Deletes & Conversions $post = Post::find(5); $post->title = 'Updated News Article'; $post->online = false; $post->save(); Post::find(5)->delete(); // Or... Post::destroy(5); Post::all()->toArray(); Post::find(5)->toJson();

Slide 32

Slide 32 text

Relationship definition class Post extends Eloquent { public function comments() { return $this->hasMany('Comment'); } } ! ! class Comment extends Eloquent { public function post() { return $this->belongsTo('Post'); } }

Slide 33

Slide 33 text

Relationship usage $post = Post::find(5); echo '

' . $post->title . '

'; foreach ($post->comments as $comment) { echo '

' . $comment->text . '

' . $comment->author . '

'; } $comment = Comment::find(25); echo '

' . $comment->post->title . '

';

Slide 34

Slide 34 text

Quick and easy Pagination $posts = Post::paginate(10); ... Produces Bootstrap-compatible paging links! foreach ($posts as $post) { echo '

' . $post->title . '

'; echo '

' . $post->summary .

'; } ! echo $posts->links();

Slide 35

Slide 35 text

5. Blade

Slide 36

Slide 36 text

Overview Blade is a quick and relatively simple template engine for rendering your views. Features many of the core functions found in other popular engines such as Twig and Smarty. Since Blade views are PHP scripts, you can use PHP code directly in your templates (with caution!) Inheritance-driven to allow for multiple layouts, sections, etc.

Slide 37

Slide 37 text

Basic template @include('inc/header') !

{{{ $pageTitle }}}

!

{{ count($posts) }} articles to display!

! @foreach ($posts as $post)

{{{ $post->title }}}

@if ($post->summary)

{{{ $post->summary }}}

@endif @endforeach ! @include('inc/footer');

Slide 38

Slide 38 text

Rendering a view Route::get('news', function() { ! $posts = Post::all(); ! return View.make('news') ->with('pageTitle', 'News') ->with('posts', $posts); ! }); Assuming that the template on the previous slide is named 'news.blade.php' we can do the following:

Slide 39

Slide 39 text

Layouts Site header goes here!
@yield('content')
Site footer goes here! @extends('layout') @section('content')

Welcome to the website!

@stop layout.blade.php home.blade.php

Slide 40

Slide 40 text

6. IoC Container ? ? ? ? ? ? ? ? ? ? ?

Slide 41

Slide 41 text

A quick word on dependencies A dependency is when one component (typically an object) relies on another for its operation. Dependencies should be passed (injected) into an object via its constructor or setter methods and not instantiated inside it. Directly instantiating dependencies is considered bad practise as it reduces scalability and flexibility, plus it makes objects difficult to test in isolation.

Slide 42

Slide 42 text

Dependency examples class Computer { protected $processor; public function __construct() { $this->processor = new Processor\Intel\i7(); } } class Computer { protected $processor; public function __construct(ProcessorInterface $processor) { $this->processor = $processor; } } Bad Good

Slide 43

Slide 43 text

"In software engineering, inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis." - Wikipedia So... IoC?

Slide 44

Slide 44 text

Forget the jargon! App::bind('shopping_basket', function($app) { return new ShoppingBasket( new Customer(), new DeliveryService\ParcelForce() ); }); The IoC container is a way of automatically passing dependencies into your objects and/or storing them for later retrieval. $shoppingBasket = App::make('shopping_basket');

Slide 45

Slide 45 text

Singletons App::singleton('user_session', function($app) { return new UserSession($_SESSION['REMOTE_ADDR']); }); We can treat the IoC container as a registry, initialising objects once and returning them on subsequent calls. // First call to App::make() creates the object... $userSession = App::make('user_session'); ! // Second call to App::Make() just fetches it... $sameUserSession = App::make('user_session');

Slide 46

Slide 46 text

IoC automatic resolution class Computer { protected $processor; public function __construct(ProcessorInterface $processor) { $this->processor = $processor; } } If you type-hint the dependencies passed into a constructor then Laravel can do the rest! $computer = App::make('Computer'); // Has i7 processor! App::bind('ProcessorInterface', 'Processor\Intel\i7');

Slide 47

Slide 47 text

IoC container + Facades = Laravel The static classes used to control Laravel are known as Facades. Facades are nothing more than wrappers to the IoC container. Therefore, every time you use a Facade such as DB, Config, View, Route, etc, you are creating and/or fetching a pre- registered object! You can easily create your own application-specific IoC bindings and Facades.

Slide 48

Slide 48 text

Further Resources Website and documentation: http://www.laravel.com GitHub: http://www.github.com/laravel/framework Laravel Ins and Outs: http://laravel.io Laracasts: http://www.laracasts.com Laravel Cheat Sheet: http://cheats.jesse-obrien.ca Leanpub: http://www.leanpub.com Twitter: @laravel, @taylorotwell, @jeffrey_way

Slide 49

Slide 49 text

Thanks for watching! Email: [email protected] Twitter: @DaGrFr LinkedIn: http://linkedin.com/in/ dgframe Web: http://31interactive.com PHPBelfast: http://phpbelfast.com and on Twitter at @PHPBelfast