3. Compare Apples to Apples
Which of these is your favorite Doctor?
Chris Roberts @thechrisroberts Caddis Interactive
3
4. Apples to Apples
Chris Roberts @thechrisroberts Caddis Interactive
4
5. Choosing Your Environment
In some ways, it doesn’t matter
• Pick what fits you and learn it inside and out.
• Always be ready to try new things.
• Find the right tool for the job.
Chris Roberts @thechrisroberts Caddis Interactive
5
6. Choosing Your Environment
When it matters
• What does your server environment support?
• Will your chosen framework scale up when your work goes viral?
• Are your developers familiar with the tools?
• How is the community support?
• Does it have the third-party utilities you need?
Chris Roberts @thechrisroberts Caddis Interactive
6
7. Language Overview
Looking at the details: Language Syntax
• Ruby is generally considered more human-readable
• Python is more script-like and white space significant
• PHP uses a C-style syntax
Chris Roberts @thechrisroberts Caddis Interactive
7
8. Language Overview
Looking at the details: Language Syntax
• Each language supports closures
• Ruby: blocks, procs, and lambdas
• Python and PHP: nested functions
• PHP closures introduced in PHP 5.3
Chris Roberts @thechrisroberts Caddis Interactive
8
9. Language Overview
Looking at the details: Object Oriented
• Each language supports OO code.
• PHP is not what it used to be.
• Namespaces, inheritance, autoloading
• PSR standards
Chris Roberts @thechrisroberts Caddis Interactive
9
10. Unit Testing
Find your bugs before your users find them
• Each framework has options for unit testing
• Django uses Python’s unittest
• Rails has unit testing baked in
• Laravel has out-of-the-box support for PHPUnit with the ability to
run assertions on your routes
Chris Roberts @thechrisroberts Caddis Interactive
10
11. Language Overview
Looking at the details: Third-party Packages
• Ruby: gem packages
• Python: pip (official support in Python 3.4)
• PHP: composer
Chris Roberts @thechrisroberts Caddis Interactive
11
12. Language Overview
Who uses it
• Ruby: Github (Rails and Erlang), original Twitter
• Python: Disqus, Instagram
• PHP: Wikipedia, many CMS’s, Facebook uses their own variant
Chris Roberts @thechrisroberts Caddis Interactive
12
13. Framework Overview
Rails, Django, and Laravel
• Numerous frameworks per language
• Rails and Django are the most popular for their languages
• PHP has many contenders: Yii, Zend, CakePHP, CodeIgniter,
Symfony, Aura, Slim, Silex, numerous others.
• Pick the one that fits your project
Chris Roberts @thechrisroberts Caddis Interactive
13
14. Laravel for PHP
The PHP Framework for Web Artisans
• Follows PSR-0/PSR-4 for namespacing and autoloading
• Flexible configuration system with multiple environment support
• Powerful ORM tied to a comprehensive query builder
• Highly extensible through service providers
• MVC design pattern in Laravel 4
• Excellent documentation
Chris Roberts @thechrisroberts Caddis Interactive
14
15. DWRM
(Doctor Who Relationship Management)
Chris Roberts @thechrisroberts Caddis Interactive
15
16. Getting up and running
Chris Roberts @thechrisroberts Caddis Interactive
16
17. Pieces for a DWRM
Setting things up
• Models: doctors, companions, enemies, episodes
• Also prepare for users, comments, and ratings
• Need pivot tables to track relationships
• Set up migrations to easily create and update our data structure
• Add seed data for testing
Chris Roberts @thechrisroberts Caddis Interactive
17
18. Migrations
Building out your database in code
• Laravel Migrations: versionable table schemas.
• Puts your schema inside source control
• Easily built out with Laravel’s command line utility: artisan
Chris Roberts @thechrisroberts Caddis Interactive
18
19. Laravel Artisan
This command line tool provides numerous helpers from
generating classes to running migrations to seeding data.
Chris Roberts @thechrisroberts Caddis Interactive
19
20. use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateDoctorsTable extends Migration {
public function up()
{
Schema::create('doctors', function($table) {
$table->increments('id')
->integer('number')
->string('image')
->text('description')
->timestamps();
});
}
public function down()
{
Schema::drop('doctors');
Chris Roberts @thechrisroberts Caddis Interactive
}
}
20
21. use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class ModifyDoctorsTable extends Migration {
public function up()
{
Schema::table('doctors', function($table) {
$table->string('name');
});
}
public function down()
{
Schema::table('doctors', function($table) {
$table->dropColumn('name');
});
Chris Roberts @thechrisroberts Caddis Interactive
}
}
21
22. Run the Migration
Chris Roberts @thechrisroberts Caddis Interactive
22
23. Rails Migration
Rails provides a similar mechanism for setting up your data
structure
class CreateDoctors < ActiveRecord::Migration
def change
create_table :doctors do |t|
t.integer :number
t.string :name
t.string :image
t.text :description
t.timestamps
end
end
end
Chris Roberts @thechrisroberts Caddis Interactive
23
24. Django Migration
Django also provides migrations, though they work a bit
differently than Rails or Laravel
• Changes are made on the model class file
• Migrations are automatically generated based on model changes
Chris Roberts @thechrisroberts Caddis Interactive
24
25. Loading test data
Laravel data seeding makes it easy to bootstrap your website
or load data for testing.
• Laravel seeding makes use of its ORM methods to easily create
and store model data.
• The query builder can also be used to manipulate data directly.
• DB seeds are run using Artisan.
Chris Roberts @thechrisroberts Caddis Interactive
25
27. class CompanionTableSeeder extends Seeder {
public function run()
{
Companion::delete();
$doctorNine = Doctor::where('number', 9)->first();
$doctorTen = Doctor::where('number', 10)->first();
Companion::create(array(‘name' => 'Rose Tyler',
'description' => '...',
'image' => '...'
))
->doctors()
->attach(array($doctorNine->id, $doctorTen->id));
Chris Roberts @thechrisroberts Caddis Interactive
}
}
27
28. Running php artisan db:seed
Chris Roberts @thechrisroberts Caddis Interactive
28
29. Django and Rails
Other ways to do the same
• Similar in Rails
Doctor.create(name: "David Tennant", number: 10, description: "...")
• Different in Django
• Can import from structured data (XML, JSON, etc)
• Primarily imported via data migration
Chris Roberts @thechrisroberts Caddis Interactive
29
30. Data Model
Writing code that represents “things”
• Class that provides additional abstraction between you and data
• A model represents an object in the database
• The framework provides ways to manipulate those models
• Laravel, Rails, and Django each follow the Active Record pattern
Chris Roberts @thechrisroberts Caddis Interactive
30
31. Model relationships
Connecting related pieces
• Laravel’s ORM (called Eloquent) makes it easy to connect related
models.
• In our demo, each doctor has a companion, each episode a
doctor, companion, and enemy, etc.
• We also have comments and ratings that can attach to any of
these.
Chris Roberts @thechrisroberts Caddis Interactive
31
32. Modeling the Doctor
class Doctor extends Eloquent {
public function companions()
{
return $this->belongsToMany('Companion');
}
public function enemies()
{
return $this->belongsToMany('Enemy');
}
public function episodes()
{
return $this->belongsToMany('Episode');
Chris Roberts @thechrisroberts Caddis Interactive
}
}
32
33. Modeling the Companion
class Companion extends Eloquent {
public function doctors()
{
return $this->belongsToMany('Doctor');
}
public function episodes()
{
return $this->belongsToMany('Episode');
Chris Roberts @thechrisroberts Caddis Interactive
}
}
33
34. Relationships
There are many ways
models might relate to
each other. Laravel
provides methods for
interacting with each
option. This includes
nested relations, ie,
accessing a grandparent
model through a child.
• one-to-one
• hasOne(…)
• belongsTo(…)
• one-to-many
• hasMany(…)
• belongsTo(…)
• many-to-many
• belongsToMany(…)
Chris Roberts @thechrisroberts Caddis Interactive
34
35. Stepping back
Reviewing the state of our application
• Our tables are defined and created
• We’ve loaded seed data
• We have pieced together our models and their relations
• Time to get something on screen
• First step: connecting the URL to our code
Chris Roberts @thechrisroberts Caddis Interactive
35
36. Laravel Routing
Provides a powerful interface to direct users based on their
url path and depending on your defined filters
• Routing is finding out where a user once to go and directing
them to the appropriate place in your code.
• Laravel provides several ways to define your application routes.
• It also provides filters to allow you to lock routes based on
certain situations, ie, keep guests away from routes requiring
authentication.
Chris Roberts @thechrisroberts Caddis Interactive
36
37. Routing the Doctor
Route::get('/', 'IndexController@index');
Route::get('/doctors', 'DoctorController@index');
Route::get('/companions', 'CompanionController@index');
Route::get('/enemies', 'EnemyController@index');
Route::get('/episodes', 'EpisodeController@index');
Route::get('/doctor/{id}', 'DoctorController@get');
Route::get('/companion/{id}', 'CompanionController@get');
Route::get('/enemy/{id}', 'EnemyController@get');
Route::get('/episode/{season}/{show}', 'EpisodeController@get');
Route::post('/comment', 'CommentController@post');
Chris Roberts @thechrisroberts Caddis Interactive
37
38. Django Routing
• Django handles routes via a URL dispatcher which matches
routs through regular expressions.
• Does not match against GET, POST, etc.
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^doctors/$', views.list_doctors)
url(r'^doctor/(d+)$', views.view_doctor)
Chris Roberts @thechrisroberts Caddis Interactive
)
38
39. Rails Routing
• Routes defined in application routes.db
• Out of the box, no route filtering
• Able to define specific routes to specific controller methods
• Able to automatically route to controllers and methods
Rails.application.routes.draw do
root 'index#index'
get 'doctors' => 'doctor#index'
get 'doctor/:id' => 'doctor#get'
resources :enemy
end
Chris Roberts @thechrisroberts Caddis Interactive
39
40. Laravel Controllers
Mediating between your model and view
• Performs data validation
• Interacts with necessary models
• Generates views
• Returns responses to the client or redirects to an alternate route
Chris Roberts @thechrisroberts Caddis Interactive
40
41. DoctorController.php
class DoctorController extends BaseController {
public function index()
{
$doctors = Doctor::orderBy('number')->get();
return View::make('doctors', array(‘doctors' => $doctors));
}
public function get($id)
{
$doctor = Doctor::with(array(‘companions', ‘episodes'))->find($id);
$ratings = RatingController::getRating('doctor', $id);
$comments = Comment::where('item_id', $id)
->where('item_type', 'doctor')
->with('user')
->orderBy('created_at', 'desc')
->get();
return View::make('items.doctor', array( 'doctor' => $doctor,
'ratings' => $ratings,
'comments' => $comments ));
Chris Roberts @thechrisroberts Caddis Interactive
}
}
41
42. Blade Tempting
@extends('layouts.structure')
@section('content')
<h1>The Modern Doctor</h1>
<div class="row doctor">
@foreach ($doctors as $doctor)
<div class="item">
<a href="/doctor/{{ $doctor->id }}">
<img src="{{ $doctor->image }}">
<h3>{{ $doctor->name }}</h3>
</a>
</div>
@endforeach
</div>
Chris Roberts @thechrisroberts Caddis Interactive
@stop
42
43. Blade Tempting
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
@if (isset($title)) {{ $title }} | @endif
The Doctor
</title>
<link rel="stylesheet" href="/assets/css/style.css">
</head>
<body>
<header class="container">
<h1 class="site"><a href="/">The Island of Doctor Who</a></h1>
</header>
<div class="container">
@yield('content')
</div>
</body>
<script src="/assets/js/script.min.js"></script>
Chris Roberts @thechrisroberts Caddis Interactive
</html>
43
44. Blade Tempting
@extends('layouts.structure')
@section('content')
<h1>The Modern Doctor</h1>
<div class="row doctor">
@foreach ($doctors as $doctor)
<div class="item">
<a href="/doctor/{{ $doctor->id }}">
<img src="{{ $doctor->image }}">
<h3>{{ $doctor->name }}</h3>
</a>
</div>
@endforeach
</div>
Chris Roberts @thechrisroberts Caddis Interactive
@stop
44
48. Retrieving individual models
Laravel makes it easy to retrieve a model, any related data,
and pass it to a view for presentation.
public function get($id)
{
$doctor = Doctor::with(array(‘companions', ‘episodes’))->find($id);
$ratings = Rating::getRating('doctor', $id);
$comments = Comment::where('item_id', $id)
->where('item_type', 'doctor')
->with('user')
->orderBy('created_at', 'desc')
->get();
return View::make('items.doctor', array('doctor' => $doctor,
'ratings' => $ratings,
'comments' => $comments ));
Chris Roberts @thechrisroberts Caddis Interactive
}
48
49. @extends('layouts.structure')
@section('content')
<h1 class="title">{{ $doctor['name'] }}</h1>
<div class="hero">
<img src="{{ $doctor['image'] }}">
</div>
<div class="rating">
Rated {{ $ratings['rating'] }} out of 5 with
{{ $ratings['numRatings'] }} votes
</div>
<p class="description">
{{ $doctor['description'] }}
</p>
Chris Roberts @thechrisroberts Caddis Interactive
49
52. CSRF Protection
Laravel comes with filters to help protect you and your users
from CSRF attacks
class BaseController extends Controller {
public function __construct()
{
$this->beforeFilter('csrf', array('on' => 'post'));
Chris Roberts @thechrisroberts Caddis Interactive
}
}
52
53. Validation
Once user data is received, Laravel provides tools to simplify
validation and storage.
$validator = Validator::make(
Input::all(),
array(
'type' => 'in:doctor,companion,enemy,episode',
'title' => 'required|min:5',
'email' => 'required|email',
'content' => 'required',
Chris Roberts @thechrisroberts Caddis Interactive
));
53
54. When the test fails
if ($validator->fails()) {
return Redirect::to(URL::previous() . '#comments')
->withErrors($validator)
->withInput();
Chris Roberts @thechrisroberts Caddis Interactive
}
54
58. Fin
From start to end, Laravel provides a full-featured framework
to make your development elegant and efficient
• Laravel provides a powerful, flexible framework for application
development.
• Based on PHP, Laravel has broad support from most hosts.
• Language features and framework methods are on par with or
better than other popular frameworks.
Chris Roberts @thechrisroberts Caddis Interactive
58
59. Recommended Resources
• Laracasts: https://laracasts.com/
• Laravel Podcast and Forums: http://laravel.io/forum
• Code Bright by Dayle Rees
• #Laravel on Freenode
• https://github.com/JeffreyWay/Laravel-Generators
• Homestead: http://laravel.com/docs/homestead
Chris Roberts @thechrisroberts Caddis Interactive
59
60. Thank you!
Chris Roberts
chris@caddis.co
@thechrisroberts
Caddis is hiring let’s talk
Chris Roberts @thechrisroberts Caddis Interactive
60