Laravel Overview
Installation
sudo composer create-project laravel/laravel newwebsite --prefer-dist
sudo mkdir -m 777 app/storage/cache app/storage/logs app/storage/meta app/storage/sessions app/storage/views
Dependencies
- composer
- PHP 5.4+
- mcrypt (PHP extension)
- php5-json (depending on OS)
- Apache/alternative (support also for nginx)
- MySQL/alternative (support also for Postgres, SQLite, and SQL Server)
Controllers
<?php
class ProductsController extends AppController
{
public function engine_index
{
$this->Paginator->settings = array(
'order' => 'Product.name ASC'
);
$items = $this->Paginator->paginate('Product');
$this->set(compact('items'));
}
public function engine_add()
{
if (!empty($this->request->data)) {
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash('The product has been saved.', 'success');
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The product could not be saved. Please see the errors below.', 'error');
}
}
$categories = $this->Product->Category->find('list');
$this->set(compact('categories'));
}
public function engine_edit($id)
{
if (!empty($this->request->data)) {
$this->Product->id = $id;
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash('The product has been saved.', 'success');
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The product could not be saved. Please see the errors below.', 'error');
}
}
$this->request->data = $this->Product->read(null, $id);
$categories = $this->Product->Category->find('list');
$this->set(compact('categories'));
}
public function engine_delete($id)
{
if ($this->Product->delete($id)) {
$this->Session->setFlash('The product has been deleted.', 'success');
} else {
$this->Session->setFlash('The product could not be deleted.', 'error');
}
return $this->redirect(array('action' => 'index'));
}
}
CakePHP Example
Laravel Example
<?php
class ProductsController extends \BaseController
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$products = Product::orderBy('name', 'ASC')->paginate(15);
return View::make('engine::products.index')->with(array('products' => $products));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function add()
{
$product = new Product();
if (Request::getMethod() == 'POST') {
$product->fill(Input::except(array('_token')));
$product->slug = Str::slug($product->name);
$product->save();
return Redirect::route('engine.products.index')->with('success', 'The product has been saved.');
}
$getCategories = Category::get();
$categories = array();
foreach ($getCategories as $category) {
$categories[$category->id] = $category->name;
}
return View::make('engine::products.add')->with(array('product' => $product, 'categories' => $categories));
}
/**
* Store a newly created resource in storage.
*
* @param int $id
*
* @return Response
*/
public function edit($id)
{
$product = Product::find($id);
if (Request::getMethod() == 'POST') {
$product->fill(Input::except(array('_token')));
$product->slug = Str::slug($product->name);
$product->save();
return Redirect::route('engine.products.index')->with('success', 'The product has been saved.');
}
$getCategories = Category::get();
$categories = array();
foreach ($getCategories as $category) {
$categories[$category->id] = $category->name;
}
return View::make('engine::products.edit')->with(array('product' => $product, 'categories' => $categories));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
*
* @return Response
*/
public function delete($id)
{
Product::find($id)->delete();
return Redirect::route('engine.products.index')->with('success', 'The product has been deleted.');
}
}
Resource Controllers
php artisan controller:make PhotoController
Route::resource('photo', 'PhotoController');
<?php
class PhotoController extends \BaseController
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
}
<?php
class Product extends AppModels
{
public $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id',
)
);
public function getFullName()
{
return $this->data['Product']['name'] . ' ' . $this->data['Product']['code'];
}
}
Models
CakePHP Example
Laravel Example
<?php
class Product extends Eloquent
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'products';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array();
protected $guarded = array('id');
public function category()
{
return $this->belongsTo('Category');
}
public function getFullName()
{
// Name and code are database field.
return $this->name . ' ' . $this->code;
}
}
Views
Forms
@extends('layouts.base')
@section('title')
Add Product
@stop
@section('content')
{{ Form::model($product, array('method' => 'put', 'route' => array('admin.products.edit', 'product' => $product->id), 'class' => 'col-md-5')) }}
<div class="form-group">
{{ Form::label('name', 'Name') }}
{{ Form::text('name', Input::get('name'), array('class' => 'form-control')) }}
</div>
<div class="form-group">
{{ Form::label('active', 'Active') }}
{{ Form::checkbox('active', 1, Input::get('active')) }}
</div>
<div class="form-group">
{{ Form::label('description', 'Description') }}
{{ Form::text('description', Input::get('description'), array('class' => 'form-control')) }}
</div>
<div class="form-group">
{{ Form::label('category_id', 'Category') }}
{{ Form::select('category_id', $categories, Input::get('category_id'), array('class' => 'form-control')) }}
</div>
<div class="form-group">
{{ Form::submit('Submit', array('class' => 'btn btn-primary')) }}
</div>
{{ Form::close() }}
@stop
Blade
@if(!empty($variable)
Hello
@else
Goodbye
@endif
@foreach($product in $products)
{{ $product->name }}<br />
@endforeach
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
{{ $product->active ? 'Yes' : 'No' }}
{{ time() }}
@include('product.header', array('product' => $product))
Routing
Basic Routing
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::get('/', array('as' => 'home', 'uses' => 'BaseController@home'));
Route::group(array('prefix' => 'engine'), function()
{
Route::resource('products', 'ProductsController');
Route::get('products/delete/{id}', array(
'as' => 'admin.products.delete',
'uses' => 'ProductsController@delete'
));
});
Route Filters
<?php
// Sample route group with auth requirement
Route::group(array('before' => 'auth', 'prefix' => 'engine'), function() {
Route::resource('products', 'ProductsController');
Route::get('products/delete/{id}', array(
'as' => 'admin.products.delete',
'uses' => 'ProductsController@delete'
));
});
// Sample route that requires the user to have a field "activated_email" that has a value,
// otherwise redirected to a page notifying them to confirm their email.
Router::filter('activated_email', function () {
if (!Auth::user()->activated_email) {
return Redirect::to('activate_email');
}
});
Route::get('dashboard', array(
'before' => 'auth|activated_email',
'uses' => 'UsersController@dashboard'
));
Querying
Fetching Associations
<?php
// This method will optimize the associations. Rather than doing
// a lot of joins like cake would, it will do an IN statement.
$product = Product::with('category')->get();
// Getting the category name
$category_name = Product::find(1)->category()->name;
Query Scopes
<?php
class Product extends Eloquent
{
// Method call is always prepended by "scope"
public function scopeRecent($query)
{
// This query is returning the most recent 5 items created in the last 5 minutes.
// We use Carbon to easily figure out the value to plug in.
return $query
->where('created_at', '<=', Carbon::now()->subMinutes(5))
->orderBy('created_at', 'desc')
->limit(5);
}
}
// In your controller
$products = Product::recent()->get();
Extras
- Workbench
- Queues
- 3rd Party Support
Migrations
<?php
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (!Schema::hasTable('products')) {
Schema::create('products', function ($table) {
$table->increments('id');
$table->string('name');
$table->boolean('active')->index();
$table->text('description');
$table->integer('category_id')->index();
$table->timestamps();
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
sudo php artisan migrate:make create_products_table
Pros / Cons
Pros
- Widely used, well liked by the PHP community.
- Easy to get into, compared to others.
- Strong composer support
- Documentation / troubleshooting
- Modern PHP code/standards
- Querying is really nice and easy
Cons
- Fascades usage is controversial, some love it, some think it's a bad practice.
- Form validation in the controller.
- New major releases often.
- Workbench tricky at first.
laravel
By Charlie Page
laravel
- 807