Laravel Montréal #2 - July 17th, 2014
A free, open source, MVC web-application framework
2011 (v1.0) — current (v4.2.05)
Simple to use, elegant, and expressive API
Emphasis on testability
Great documentation
Package-based dependency management
« Any time that I have to do something that is a pain... it puts a seed in my head to work it into Laravel »
- Taylor Otwell
full of static methods...
a restrictive framework
the absolute best framework
always the best solution
composer create-project laravel/laravel contacts --prefer-dist
Command line tool to make working with Laravel easier.
php artisan
php artisan serve --port 8000
vagrant box add laravel/homestead
git clone https://github.com/laravel/homestead.git Homestead
---
ip: "192.168.10.10"
memory: 2048
cpus: 1
authorize: /Users/benjamingonzalez/.ssh/id_rsa.pub
keys:
- /Users/benjamingonzalez/.ssh/id_rsa
folders:
- map: /Applications/MAMP/htdocs/contacts
to: /home/vagrant/code/contacts
sites:
- map: contacts.app
to: /home/vagrant/code/contacts/public
variables:
- key: APP_ENV
value: local
// Simple resource routing
Route::resource('/', 'ContactsController');
php artisan routes
php artisan controller:make ContactsController
Route::resource('/', 'ContactsController');
class ContactsController extends BaseController {
public function index() {} // GET /
public function create() {} // GET /create
public function store() {} // POST /
public function show($id) {} // GET /1
public function edit($id) {} // GET /1/edit
public function update($id) {} // PUT /1
public function destroy($id) {} // DELETE /1
}
php artisan routes
Out-of-the-box support for:
return array(
'default' => 'mysql',
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'contacts',
'username' => 'homestead',
'password' => 'secret'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
…
return array(
'default' => 'mysql',
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => $_ENV['MYSQL_DB'],
'username' => $_ENV['MYSQL_USER'],
'password' => $_ENV['MYSQL_PASS'],
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
…
return array(
'MYSQL_DB' => 'contacts',
'MYSQL_USER' => 'homestead',
'MYSQL_PASS' => 'secret',
);
php artisan migrate:make create_contacts_table --create="contacts"
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
public function up() { Schema::create('posts', function(Blueprint $table) { $table->increments('id'); $table->string('name', 50); $table->string('email')->nullable()->unique(); $table->string('telephone')->nullable()->unique(); $table->boolean('active')->default(true); $table->timestamps(); }); }
public function down() { Schema::drop('posts'); }
php artisan migrate
php artisan migrate:rollback
class Contact extends Eloquent {}
/**
* Display a listing of contacts
*
* @return Response
*/
public function index()
{
$contacts = Contact::all();
return View::make('contacts.index', compact('contacts'));
}
/**
* Show the form for creating a new contact
*
* @return Response
*/
public function create()
{
return View::make('contacts.create');
}
/**
* Store a newly created contact in storage.
*
* @return Response
*/
public function store()
{
$validator = Validator::make($data = Input::all(), Contact::$rules);
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput();
}
Contact::create($data);
return Redirect::route('contacts.index');
}
/**
* Display the specified contact.
*
* @param int $id
* @return Response
*/
public function show($id)
{
$contact = Contact::findOrFail($id);
return View::make('contacts.show', compact('contact'));
}
/**
* Show the form for editing the specified contact.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
$contact = Contact::find($id);
return View::make('contacts.edit', compact('contact'));
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
$contact = Contact::findOrFail($id);
$validator = Validator::make($data = Input::all(), Contact::$rules);
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput();
}
$contact->update($data);
return Redirect::route('contacts.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
Contact::destroy($id);
return Redirect::route('contacts.index');
}
}
class HelloController extends BaseController {
public function showWelcome($name='stranger')
{
return View::make('hello', array('name'=>$name) );
}
}
class HelloController extends BaseController {
public function showWelcome($name='stranger')
{
return View::make('hello', compact('name') );
}
}
<html>
<body>
<p>Hello, <?php echo e($name); ?>!</p>
</body>
</html>
<html>
<body>
<p>Hello, {{{ $name }}}!</p>
</body>
</html>
<html>
<body>
@include('header') {{-- app/views/header.blade.php --}}
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content', 'Default content')
</div>
</body>
</html>
@extends('layouts.master')
@section('sidebar')
@parent
This is appended to the master sidebar.
@stop
@section('content')
This is my body content.
@stop
{{ Form::open() }}
{{ Form::label('name') }}
{{ Form::text('name', 'default', array('class'=>'form-control') }}
{{ Form::label('email') }}
{{ Form::email('email') }}
{{ Form::label('phone') }}
{{ Form::email('phone') }}
{{ Form::checkbox('is_active', 1, null, array('tabindex'=> 4 ) }}
{{ Form::label('is_active', 'Yes') }}
{{ Form::submit('Send it!')}}
{{ Form::close() }}
Creating a contact
{{ Form::open(['method' => 'POST', 'route' => ['store' => $contact->id]]) }}
@include('contacts.partials.form')
{{ Form::close() }}
Updating a contact
{{ Form::open(['method' => 'PATCH', 'route' => ['update' => $contact->id]]) }}
@include('contacts.partials.form')
{{ Form::close() }}
$contact = Contact::findOrFail($id);
return View::make('contacts.edit', compact('contact'));
{{ Form::model($contact, array('route'=>array('update', $contact->id), 'method'=>'PUT') ) }}
@include('contacts.partials.form')
{{ Form::close() }}
$validator = Validator::make( $data, $rules );
if ( $validator->fails() ) // ->passes()
{
$messages = $validator->messages();
…
}
if ( $messages->has('email') )
{
echo $messages->first('email', ':message
');
}
$messages->get('field');
$messages->all();
$validator = Validator::make( $data, Contact::$rules );
public static $rules = array(...);
$data = array(
'contact' => 'Benjamin Gonzalez',
'email' => 'benjamin.rosell@gmail.com',
));
$rules = array(
'contact' => 'required|min:5',
'email' => 'required|email'
);
$rules = array(
'firstname' => 'required',
'lastname' => 'alpha',
'email' => 'email',
'age' => 'integer|between:18,65',
'agree' => array('required','accepted'),
'website' => 'url',
'password' => 'confirmed', // implies matching 'password_confirmation' data
'company_id' => 'exists:companies,id',
'gender' => 'in:male,female',
'photo' => 'mimes:jpeg,png|max:100', // kilobytes
'postalcode' => 'regex:^[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]$'
);