Laravel advance tips and trick sheet

→ Laravel Advance Tips Sheet ←

Routing:

// routes/web.php
Route::get('/url', 'Controller@method');

// Route with parameters
Route::get('/user/{id}', 'UserController@show');

// Named routes
Route::get('/profile', 'UserController@profile')->name('user.profile');

// Route groups
Route::prefix('admin')->group(function () {
    Route::get('dashboard', 'AdminController@dashboard');
    Route::get('users', 'AdminController@users');
});

 

→ Controllers:

# Create a controller
php artisan make:controller MyController

# Resourceful controller
php artisan make:controller MyResourceController --resource

Invoke controller: Define a controller's __invoke() method to handle the request.


→ Models:

# Create a model
php artisan make:model MyModel

# Create a model with migration
php artisan make:model MyModel -m

Mass assignment: Define protected $fillable or protected $guarded in the model.


→ Migrations:

# Run migrations
php artisan migrate

# Create a migration
php artisan make:migration create_table_name

# Rollback last batch of migrations
php artisan migrate:rollback

# Refresh the database
php artisan migrate:refresh


→ Eloquent ORM:

// Retrieve all records
MyModel::all();

// Find a record by primary key
MyModel::find($id);

// Query builder
MyModel::where('column', 'value')->get();

// Create a new record
$model = new MyModel(['column' => 'value']);
$model->save();

// Update a record
$model = MyModel::find($id);
$model->update(['column' => 'value']);

// Delete a record
$model = MyModel::find($id);
$model->delete();


→ Views:

Blade templates: Use @ to denote Blade directives like @if, @foreach, etc.
Include a view: @include('partials.header')
Conditionals: @if, @else, @elseif, @unless, @isset, @empty
Loops: @for, @foreach, @while

<!-- Blade templates -->
<!-- Escaped output -->
{{ $variable }}

<!-- Unescaped output -->
{!! $variable !!}

<!-- Comments -->
{{-- This is a comment --}}

<!-- Inline if statement -->
{{ $var ? 'Yes' : 'No' }}

<!-- Directives -->
@extends('layouts.app')
@section('content')
    <p>This is the content.</p>
@endsection
@include('partials.header')


→ Blade Templating:

Escaped output: {{ $variable }}
Unescaped output: {!! $variable !!}
Comments: {{-- This is a comment --}}
Inline if statement: {{ $var ? 'Yes' : 'No' }}
Directives: @extends, @section, @yield, @include, @stack

<!-- Blade templates -->
<!-- Escaped output -->
{{ $variable }}

<!-- Unescaped output -->
{!! $variable !!}

<!-- Comments -->
{{-- This is a comment --}}

<!-- Inline if statement -->
{{ $var ? 'Yes' : 'No' }}

<!-- Directives -->
@extends('layouts.app')
@section('content')
    <p>This is the content.</p>
@endsection
@include('partials.header')


→ Middleware:

# Create a middleware
php artisan make:middleware MyMiddleware

Apply middleware in route definition: Route::get('/admin', 'AdminController@index')->middleware('auth');


→ Validation:

// Manually validate
$request->validate([
    'name' => 'required|max:255',
    'email' => 'required|email|unique:users',
]);

// Validation in controller method
public function store(Request $request)
{
    $validatedData = $request->validate([
        'name' => 'required|max:255',
        'email' => 'required|email|unique:users',
    ]);
}
  • Validation in controller method: $this->validate($request, [...]);


→ Authentication:

# Install Laravel UI
composer require laravel/ui

# Generate auth scaffolding
php artisan ui bootstrap --auth


→ Artisan commands:

# Clear cache
php artisan cache:clear

# Create a controller
php artisan make:controller MyController

# Create a model
php artisan make:model MyModel

# Create a migration
php artisan make:migration create_table_name

# Create a seeder
php artisan make:seeder MySeeder


→ Database Seeding:

# Run all seeders
php artisan db:seed

# Run a specific seeder
php artisan db:seed --class=MySeeder

# Refresh the database and run all seeders
php artisan migrate:refresh --seed


→ Tinker (Interactive Shell):

Access Tinker: php artisan tinker
Create and save a model: $model = new MyModel; $model->column = 'value'; $model->save();
Eloquent queries: MyModel::where('column', 'value')->get();


→ Testing:

# Run tests
php artisan test

# Generate a test
php artisan make:test MyTest

Test methods: setUp, tearDown, test*


→ Miscellaneous:

// Environment variables
$apiKey = env('API_KEY', 'default-value');
$apiKey = config('app.api_key');

// Service Providers
// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(MyService::class, function ($app) {
        return new MyService();
    });
}

// Dependency Injection
// app/Http/Controllers/MyController.php
use App\Services\MyService;

public function __construct(MyService $myService)
{
    $this->myService = $myService;
}

 

→ Eloquent Relationships:

// Define relationships in the model

// One-to-One
class User extends Model
{
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

// One-to-Many
class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

// Many-to-Many
class User extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

 

→ Eager Loading:

// Reduce database queries by eager loading related data

// Lazy Loading (N+1 problem)
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name;
}

// Eager Loading
$posts = Post::with('user')->get();
foreach ($posts as $post) {
    echo $post->user->name;
}

 

→ Collections:

// Additional methods for working with collections

$collection = collect([1, 2, 3, 4, 5]);

// Map
$result = $collection->map(function ($item) {
    return $item * 2;
}); // [2, 4, 6, 8, 10]

// Filter
$result = $collection->filter(function ($item) {
    return $item % 2 === 0;
}); // [2, 4]

// Reduce
$total = $collection->reduce(function ($carry, $item) {
    return $carry + $item;
}); // 15

// Pluck
$collection = collect([
    ['name' => 'John', 'age' => 25],
    ['name' => 'Jane', 'age' => 30],
]);
$ages = $collection->pluck('age'); // [25, 30]

 

→ Blade Components:

// Create reusable Blade components

// Components
// resources/views/components/alert.blade.php
<div class="alert">
    {{ $slot }}
</div>

// Use the component
<x-alert>
    This is an alert message.
</x-alert>

 

→ Queues:

// Offload time-consuming tasks to queues

// Create a job
php artisan make:job MyJob

// Dispatch the job
MyJob::dispatch($data);

 

→ Events and Listeners:

// Implement event-driven behavior

// Create an event
php artisan make:event MyEvent

// Create a listener
php artisan make:listener MyListener --event=MyEvent

// Dispatch the event
event(new MyEvent($data));

 

→ Service Providers:

// Register custom service providers

// Create a service provider
php artisan make:provider MyServiceProvider

// Register the service provider in config/app.php
'MyServiceProvider' => App\Providers\MyServiceProvider::class,

 

→ Custom Helper Functions:

// Create custom helper functions

// Create a new file: app/Helpers/my_helper.php
// Define your functions in this file

// Include the helper file in composer.json autoload section
"autoload": {
    "files": [
        "app/Helpers/my_helper.php"
    ]
}

// Run composer dump-autoload to load the helper file

 

→ Events and Broadcasting:

// Use events and broadcasting to create real-time updates

// Event listeners
Event::listen(MyEvent::class, function ($event) {
    // Handle the event
});

// Broadcasting
// Configure broadcasting driver in config/broadcasting.php
Broadcast::channel('user.{id}', function ($user, $id) {
    return $user->id === (int) $id;
});

 

→ Policies and Gates:

// Define authorization policies and gates

// Create a policy
php artisan make:policy PostPolicy --model=Post

// Define gates
Gate::define('update-post', function ($user, $post) {
    return $user->id === $post->user_id;
});

 

→ Package Development:

# Create a new package
composer create-project --prefer-dist laravel/laravel my-package

# Create a new package

 

→ Eloquent Subqueries:

// Perform subqueries using Eloquent

$users = User::where('created_at', '>', function ($query) {
    $query->select('created_at')
          ->from('orders')
          ->whereColumn('user_id', 'users.id')
          ->orderByDesc('created_at')
          ->limit(1);
})->get();

 

→ Model Factories:

// Generate fake data for testing

// Define a model factory
$factory->define(App\Post::class, function (Faker\Generator $faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->paragraph,
    ];
});

// Generate fake data using the factory
$posts = factory(App\Post::class, 10)->create();

 

Observer Pattern:

// Implement the Observer pattern using Eloquent events

// Create an observer
php artisan make:observer MyObserver --model=User

// Register the observer in the boot method of the model
protected static function boot()
{
    parent::boot();

    static::observe(MyObserver::class);
}

 

Model Caching:

// Cache model queries for improved performance

// Cache a model query
$users = Cache::remember('users', $minutes, function () {
    return User::all();
});

 

→ API Authentication with Sanctum:

# Install Laravel Sanctum
composer require laravel/sanctum

# Publish the Sanctum configuration
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

# Configure your API routes
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

 

→ Task Scheduling with Cron:

# Add the task scheduler to your server's cron
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

 

→ Background Jobs with Supervisor:

# Install Supervisor
sudo apt-get install supervisor

# Create a Supervisor configuration file
sudo nano /etc/supervisor/conf.d/your-worker.conf

# Example configuration:
[program:your-worker]
command=php /path-to-your-project/artisan queue:work --tries=3
numprocs=1
autostart=true
autorestart=true
user=your-user
redirect_stderr=true
stdout_logfile=/path-to-your-project/storage/logs/worker.log

# Update Supervisor and start the worker
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start your-worker

 

→ Laravel Echo (WebSockets):

# Install Laravel Echo
npm install laravel-echo

# Configure broadcasting driver and other settings in config/broadcasting.php

# Initialize Echo in JavaScript
import Echo from 'laravel-echo';
window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    encrypted: true,
});

 

→ File Uploads:

// Handle file uploads using Laravel's Filesystem

// Store an uploaded file
$request->file('avatar')->store('avatars');

// Get the stored file's URL
$avatarUrl = Storage::url('avatars/filename.jpg');

 

→ Macros:

// Extend existing classes with macros

// Create a macro in a service provider
use Illuminate\Support\Str;

Str::macro('partNumber', function ($part) {
    return 'PART-' . substr($part, 0, 3);
});

// Use the macro
$partNumber = Str::partNumber('ABC123'); // Outputs "PART-ABC"

 

→ Event Broadcasting:

// Broadcast events to front-end using Laravel Echo

// Define event class
php artisan make:event OrderShipped

// Use broadcasting in the event
use Illuminate\Broadcasting\InteractsWithSockets;

class OrderShipped implements ShouldBroadcast
{
    use InteractsWithSockets;

    // ...
}

 

→ Notifications:

// Send notifications to users

// Create a notification
php artisan make:notification InvoicePaid

// Send the notification
use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));

 

→ Pagination:

// Paginate query results

$users = User::paginate(10);

@foreach ($users as $user)
    // Display user data
@endforeach

{{ $users->links() }}

 

→ Custom Artisan Commands with Arguments/Options:

// Create custom commands with arguments and options

// Create a command with arguments/options
php artisan make:command MyCustomCommand --option=name --argument=id

// Define arguments/options in the signature property
protected $signature = 'my:custom-command {--option=default} {id}';

// Access arguments/options in the handle method
public function handle()
{
    $option = $this->option('option');
    $id = $this->argument('id');
}

 

→ API Resources:

// Transform and format API responses

// Create an API resource
php artisan make:resource UserResource

// Transform data in the resource
public function toArray($request)
{
    return [
        'name' => $this->name,
        'email' => $this->email,
    ];
}

 

→ Livewire:

# Install Livewire
composer require livewire/livewire

# Use Livewire components in Blade views
<livewire:counter />

 

→ Blade Components with Slots:

// Use slots to pass content to Blade components

// Blade component with slot
<!-- resources/views/components/alert.blade.php -->
<div class="alert">
    {{ $slot }}
</div>

<!-- Using the component with a slot -->
<x-alert>
    This is an alert message.
</x-alert>

 

→ Job Timeout:

// Define a timeout for jobs

public $timeout = 60; // Timeout in seconds

public function handle()
{
    // Perform job tasks
}

 

→ Model Events:

// Listen for model events

// Listen for created event
User::created(function ($user) {
    // Do something when a user is created
});

 

→ Service Injection:

// Inject services directly into methods

use App\Services\MyService;

public function myMethod(MyService $service)
{
    $result = $service->doSomething();
}

 

→ Eloquent Touch:

// Update the updated_at timestamp of related models

$comment = Comment::find(1);
$comment->post->touch();

 

→ Route Model Binding:

// Automatically resolve route parameters using model binding

// Implicit binding in route definition
Route::get('profile/{user}', function (User $user) {
    return view('profile', compact('user'));
});

// Customizing the resolution key
public function getRouteKeyName()
{
    return 'slug';
}

 

→ Collection Partitioning:

// Partition a collection into two arrays based on a given truth test

$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

list($even, $odd) = $collection->partition(function ($value, $key) {
    return $value % 2 == 0;
});

$even->all(); // [2, 4, 6, 8, 10]
$odd->all();  // [1, 3, 5, 7, 9]

 

→ Container Binding:

// Bind an interface to an implementation in the service container

// In a service provider's register method
$this->app->bind(MyInterface::class, MyImplementation::class);