Advanced learning
Laravel Advanced learning
☕ Scheduler
1,Configuration Scheduler
Open the app/Console/Kernel.php file, you will see the schedule method, this is where the tasks are defined:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*/
protected function schedule(Schedule $schedule): void
{
// Execute the report:daily command at 8 am every day
//$schedule->command('report:daily')->dailyAt('08:00');
$schedule->command('report:daily')->everyMinute();
}
/**
* Register the commands for the application.
*/
protected function commands(): void
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
2,SendDailyReport
php artisan make:command SendDailyReport
<?php
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
class SendDailyReport extends Command
{
// Command Signature
protected $signature = 'report:daily';
// Command Description
protected $description = 'Send daily report email to all users';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->info('Starting to send daily report emails');
// Retrieve all users
$users = User::all();
$this->info('Number of users found: ' . $users->count());
if ($users->isEmpty()) {
$this->error('No users found.');
return;
}
foreach ($users as $user) {
try
{
Mail::raw('Here is your daily report content', function ($message) use ($user) {
$message->to($user->email)
->from(config('services.mail.mail_gmail'), config('services.mail.mail_name'))
->subject('Daily Report');
});
$this->info('Email successfully sent to: ' . $user->email);
}
catch (\Exception $e)
{
$this->error('Failed to send email to ' . $user->email . ': ' . $e->getMessage());
}
}
$this->info('Daily report emails sent successfully.');
}
}
3,ENV Setting
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ex_sh
DB_USERNAME=root
DB_PASSWORD=
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=11db8c1f10c50d
MAIL_PASSWORD=667fe814a795e7
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=HooBusiness@example.com
MAIL_FROM_NAME=Hoo
4,php artisan migrate
Create User
5,start up Scheduler
php artisan schedule:run
Automatically execute php artisan report:daily
In Windows environment, you can use Task Scheduler to set up scheduled tasks.
Setting steps:
-
Open Task Scheduler: Press
Win + Rkeys, entertaskschd.mscand press Enter. -
Create a basic task:
-
Click "Create Basic Task" on the right.
-
Enter a task name, such as "Laravel Report Daily".
-
-
Set Trigger:
-
On the Trigger page, select "Daily" or other desired frequency.
-
Specify the start time, such as
08:00.
-
-
Set Action:
-
On the Action page, select "Start Program".
-
Program or Script Path Enter your PHP executable file path, such as
D:\php-8.3.10\php.exe. -
Enter in the Add Parameters section
artisan report:daily, for example:
D:\Code\Laravel P\example-app2\artisan report:daily -
-
Save and Finish
☕ Event & Listener
Scenario: Send a welcome email after user registration
When a new user registers, we trigger an event UserRegistered, and then the listener SendWelcomeEmail will capture the event and send a welcome email.
1. Installation
php artisan make:event UserRegistered
php artisan make:listener SendWelcomeEmail --event=UserRegistered
2. Define event and listener logic
Open app/Events/UserRegistered.php and edit the following:
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class UserRegistered
{
use Dispatchable, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
3. Write the logic of sending emails in the listener file
Open the app/Listeners/SendWelcomeEmail.php file and add the following code:
namespace App\Listeners;
use App\Events\UserRegistered;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
class SendWelcomeEmail implements ShouldQueue
{
use InteractsWithQueue;
public function __construct()
{
// Optional: perform initialization in the constructor
}
public function handle(UserRegistered $event)
{
$user = $event->user;
Mail::raw('Welcome to our website!', function ($message) use ($user) {
$message->to($user->email)
->subject('Welcome!');
});
}
}
4. Register events and listeners
Open app/Providers/EventServiceProvider.php and register events and listeners in the $listen array:
namespace App\Providers;
use App\Events\UserRegistered;
use App\Listeners\SendWelcomeEmail;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
UserRegistered::class => [
SendWelcomeEmail::class,
],
];
public function boot()
{
parent::boot();
}
}
- Trigger events
Trigger the UserRegistered event in the user registration logic. For example, add the following code to the user controller:
php artisan make:controller UserController
<?php
namespace App\Http\Controllers;
use App\Events\UserRegistered;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function register(Request $request)
{
$user = User::create($request->only('name', 'email', 'password'));
event(new UserRegistered($user));
return response()->json(['message' => 'Registration successful!']);
}
}
api.php
Route::post('register', [\App\Http\Controllers\UserController::class, 'register']);
Test the registration request through Postman or the command line to confirm that you received the welcome email.
☕ Authorization Policies
Using authorization policies in Laravel can help you better manage user permissions. Below are detailed steps and code to create and use policies.
1. Installation
php artisan make:policy PostPolicy
This will create a PostPolicy.php file in the app/Policies directory.
2. Define policy methods
Open app/Policies/PostPolicy.php and define the user permission logic in the policy. The following example shows checking whether the user has the permission to update and delete a specific Post:
<?php
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
/**
* Determine whether the user can update the post
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
/**
* Determine whether the user can delete the post
*/
public function delete(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
3. Register policies
Open the AuthServiceProvider file (app/Providers/AuthServiceProvider.php) and register PostPolicy in the $policies array:
<?php
namespace App\Providers;
use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Post::class => PostPolicy::class,
];
public function boot()
{
$this->registerPolicies();
}
}
4. Use policies for authorization checks
In the controller, you can use policies to check user permissions.
For example, use the authorize method in PostController:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function update(Request $request, Post $post)
{
// Check if the user has permission to update the post
$this->authorize('update', $post);
// Perform the update operation
$post->update($request->all());
return response()->json(['message' => 'Post updated successfully']);
}
public function delete(Post $post)
{
// Check if the user has permission to delete the post
$this->authorize('delete', $post);
// Perform the delete operation
$post->delete();
return response()->json(['message' => 'Post deleted successfully']);
}
}
5. Use policies in Blade templates
You can use the @can directive in Blade templates to check policy permissions:
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}">Edit a post</a>
@endcan
@can('delete', $post)
<form action="{{ route('posts.destroy', $post) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Delete a post</button>
</form>
@endcan
☕ Real-time event broadcasting x
In Laravel, real-time event broadcasting can broadcast server-side events to the front-end, allowing the client to receive and respond to events in real time. This is very useful for implementing real-time update functions (such as notifications, chats, etc.). The following are detailed steps and codes for implementing real-time event broadcasting using Laravel Broadcasting.
Real-time event broadcasting is a mechanism that allows Laravel applications to notify client applications, such as web pages or mobile applications, of events in real time. This allows for features such as real-time chat and push notifications without the client constantly polling the server for updates. Pusher is a very commonly used third-party service that makes it easier for Laravel to implement event broadcasting.
Pusher registration is required
1. Install
npm install
npm install vite --save-dev
composer require pusher/pusher-php-server
php artisan make:model Message -m
Edit the Message model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
use HasFactory;
protected $fillable = ['user_id', 'content'];
public function user()
{
return $this->belongsTo(User::class);
}
}
In this model, user_id indicates the sender of the message, and content is the message content. You can customize the fields as needed.
Create a migration file for the Messages table
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->text('content');
$table->timestamps();
});
}
php artisan migrate
2, Configuring the Broadcast Driver
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
3,Set up broadcast events
php artisan make:event MessageSent
In the generated event class (e.g. app/Events/MessageSent.php), implement the ShouldBroadcast interface:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
use App\Models\Message;
class MessageSent implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public $message;
public function __construct(Message $message)
{
$this->message = $message;
}
public function broadcastOn()
{
return new Channel('chat');
}
public function broadcastAs()
{
return 'message.sent';
}
}
4. Trigger an event
Call event(new MessageSent($message)) where you need to trigger an event. For example, trigger an event when a new message is sent in MessageController:
php artisan make:controller MessageController
<?php
namespace App\Http\Controllers;
use App\Events\MessageSent;
use App\Models\Message;
use Illuminate\Http\Request;
class MessageController extends Controller
{
public function send(Request $request)
{
$message = Message::create([
'user_id' => $request->user()->id,
'content' => $request->input('content'),
]);
// Broadcast Events
event(new MessageSent($message));
return response()->json(['message' => 'Message sent successfully!']);
}
}
5. Listen for broadcast events on the front end
Use Laravel Echo and Pusher to receive broadcast events on the front end. First install Laravel Echo and Pusher JavaScript SDK:
npm install --save laravel-echo pusher-js
Initialize Echo in the front-end JavaScript file and listen for events. For example, in resources/js/app.js:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
wsHost: window.location.hostname,
wsPort: 6001,
forceTLS: false,
disableStats: true,
});
window.Echo.channel('chat')
.listen('.message.sent', (e) => {
console.log('News:', e.message);
});
6. Run the broadcast service
npm run dev
npm install --save laravel-echo pusher-js
.env
VITE_PUSHER_APP_KEY=your-app-key
VITE_PUSHER_APP_CLUSTER=your-app-cluster
cmd
composer require beyondcode/laravel-websockets --with-all-dependencies
php artisan websockets:serve
php artisan serve
☕ OAuth 2.0 / Laravel Passport
Yes, Laravel Passport does provide a createToken method that allows the creation of access tokens in an OAuth 2.0 implementation. This method is ideal for generating "Personal Access Tokens" for users, which are often used for API authentication.
1. Installation
composer require laravel/passport
2. Configuration Passport
php artisan migrate
Generate encryption key: Generates the encryption key required by Passport.
php artisan passport:install
3. Add Passport service provider
Add to the providers array in the config/app.php file:
Laravel\Passport\PassportServiceProvider::class,
4. Configure Auth
In the config/auth.php file, set the api authentication driver to passport:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
5. Set up the User model
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens;
// Other model codes...
}
6. Define routes
In routes/api.php, define the Passport route:
use Laravel\Passport\RouteRegistrar;
Route::group(['middleware' => ['auth:api']], function () {
// Routes that require authentication
});
Route::post('register', 'AuthController@register');
Route::post('login', 'AuthController@login');
7. Create an authentication controller
Create a controller to handle registration and login:
php artisan make:controller AuthController
Then implement the registration and login logic in AuthController:
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
]);
if ($validator->fails()) {
throw new ValidationException($validator);
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
return response()->json(['user' => $user], 201);
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (!auth()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$user = auth()->user();
$token = $user->createToken('Personal Access Token')->accessToken;
return response()->json(['token' => $token]);
}
}
8. Test the API
You can use Postman or any API client to test the registration and login APIs:
Register:
- Request type: POST
- URL:
http://your-domain/api/register - Request body:
{
"name": "Your Name",
"email": "your-email@example.com",
"password": "your-password",
"password_confirmation": "your-password"
}
Login:
- Request type: POST
- URL:
http://your-domain/api/login - Request body:
{
"email": "your-email@example.com",
"password": "your-password"
}
The returned JSON will contain a token, which you can use for authentication.
9. Protect routes
Add the auth:api middleware to the routes that need to be protected. For example:
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
});
☕ Task Queues
Time-consuming tasks (such as sending emails) can be pushed into queues and processed asynchronously to improve application performance.
With these steps, you can create and use task queues in Laravel. Asynchronous processing of tasks can significantly improve the responsiveness of the system while maintaining the efficiency of background tasks.
1. Configure queue drivers
In the config/queue.php file, Laravel provides a variety of queue drivers, including database, Redis, Beanstalkd, etc. The database driver is commonly used in the development environment. Make sure the appropriate driver is set in the .env file, for example:
QUEUE_CONNECTION=database
2. Create a queue table
If you use the database driver, please generate a queue table first:
php artisan queue:table
php artisan migrate
The generated table jobs will store the information of the queue tasks.
3. Create a queue task
Use the Artisan command to create a queue task class. For example, here is a task for sending emails:
php artisan make:job SendEmailJob
This command will generate the SendEmailJob.php file in the app/Jobs/ directory.
4. Write the queue task logic
In the generated SendEmailJob class, write the task logic. Suppose we want to send an email, we can use the following code:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
class SendEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function handle()
{
Mail::to($this->user->email)->send(new \App\Mail\WelcomeEmail($this->user));
}
}
In this code, the handle method defines the specific logic of task execution. Here we use Laravel's email sending function to send a welcome email to the user.
5. Dispatch queue tasks
When using tasks in an application, you can push tasks to the queue through the dispatch method. For example, send a welcome email after the user registers:
use App\Jobs\SendEmailJob;
use App\Models\User;
$user = User::find(1); // Example User
SendEmailJob::dispatch($user);
6. Run queue tasks
Use the queue:work command to start a queue worker to process queue tasks:
php artisan queue:work
The queue:work command will listen to the queue and process the tasks in the queue.
7. Set up task failure retries (optional)
If you need to automatically retry when a task fails, you can define the $tries and $timeout properties in the task class:
class SendEmailJob implements ShouldQueue
{
public $tries = 3; // Maximum number of attempts
public $timeout = 120; // Timeout (seconds)
// ...
}
8. Failed task processing (optional)
You can use queue:failed-table to create a database table for failed tasks:
php artisan queue:failed-table
php artisan migrate
☕ Middleware
Used to filter HTTP requests, such as authentication, cross-site request forgery (CSRF) protection, etc.
Laravel middleware provides flexible control over requests, allowing you to insert custom logic during request processing, such as authentication, logging, cross-site request protection, etc. Through middleware, Laravel can effectively enhance the security and maintainability of applications.
1. Create middleware
php artisan make:middleware CheckAdmin
This command will generate the CheckAdmin.php file in the app/Http/Middleware directory.
2. Write middleware logic
In the generated CheckAdmin.php file, write the logic of the middleware. This example will check whether the user is an administrator and return a 403 error if not.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CheckAdmin
{
public function handle(Request $request, Closure $next)
{
// Check if the user is logged in and is an administrator
if (!Auth::check() || !Auth::user()->is_admin) {
// If not an administrator, return a 403 error
return response()->json(['error' => 'Unauthorized'], 403);
}
// If the user is an administrator, continue with the request
return $next($request);
}
}
Schema::table('users', function (Blueprint $table) {
$table->boolean('is_admin')->default(false); // Not an administrator by default
});
3. Register middleware
Open the app/Http/Kernel.php file and register the middleware as routing middleware. Add to the $routeMiddleware array:
protected $routeMiddleware = [
// Other middleware
'admin' => \App\Http\Middleware\CheckAdmin::class,
];
This way you can use admin as a middleware alias to call CheckAdmin in the route.
4. Apply middleware to routes
Middleware can be applied to a single route or a route group. For example, apply the admin middleware in routes/web.php:
use Illuminate\Support\Facades\Route;
Route::middleware(['admin'])->group(function () {
Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
Route::get('/admin/settings', [AdminController::class, 'settings']);
});
Or apply the middleware to a single route:
Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->middleware('admin');
5. Global middleware (optional)
If you need to apply middleware on all requests, you can add the middleware to the $middleware array in the app/Http/Kernel.php file:
protected $middleware = [
// Global Middleware
\App\Http\Middleware\CheckAdmin::class,
];
In this way, each request will be checked by CheckAdmin first.
☕ API Resources
API resources provide a flexible JSON format for model data, define the structure through the toArray method, and can attach additional metadata. API resources can make your API clearer and more standardized.
1. Create API resources
Use the make:resource command to generate an API resource class. For example, create an API resource for the User model:
php artisan make:resource UserResource
This command will generate the UserResource.php file in the app/Http/Resources/ directory.
2. Define the API resource format
In the generated UserResource.php file, use the toArray method to define the output format of the API resource. You can choose to return specific fields or a custom format. For example:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}
In this example, only the id, name, email, and created_at fields are returned. If you have sensitive fields, such as passwords, make sure not to include them here.
3. Use API resources to return data
Use API resources in controllers to return model data. For example, in UserController, return data for a single user:
use App\Http\Resources\UserResource;
use App\Models\User;
class UserController extends Controller
{
public function show($id)
{
$user = User::findOrFail($id);
return new UserResource($user);
}
}
If you would like to return a collection of users, you may use the UserResource::collection method:
public function index()
{
$users = User::all();
return UserResource::collection($users);
}
4. Customize resource collection format (optional)
Laravel also supports creating dedicated resource collection classes. You can use the following command to generate resource collection classes:
php artisan make:resource UserCollection
In UserCollection.php, you can customize the collection return format.
5. Add additional metadata (optional)
You can add additional metadata to the resource, such as status information or pagination data. You can use the with method in the resource class:
public function with($request)
{
return [
'status' => 'success',
'code' => 200,
];
}
Complete Example
After creating UserResource, the API will return JSON in the following format:
{
"data": {
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com",
"created_at": "2024-10-31 12:34:56"
},
"status": "success",
"code": 200
}
☕ Seeder and Factories
Laravel's Seeder and Factories can be used to generate fake data and populate database data during development and testing. The following are detailed steps and complete code examples for using Seeder and Factories.
1. Factories: Create and define factories
Factories are used to create fake data for models, which is suitable for generating different test data when the database is populated.
Use the make:factory command to generate factories. For example, to generate a factory for the User model:
php artisan make:factory UserFactory
The generated factory file will be located in the database/factories/ directory.
2. Define fake data for Factory
In the generated UserFactory.php file, use the Faker library to define fake data for the model. The following is an example of UserFactory:
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => bcrypt('password'), // Default Password
'remember_token' => Str::random(10),
];
}
}
In this example, the factory generates fake data for fields such as name and email for the User model.
3. Seeder: Create and define data population
Seeder is used to insert batches of test data into the database.
Generate Seeder using Artisan commands, such as generating UserSeeder:
php artisan make:seeder UserSeeder
The generated Seeder file will be located in the database/seeders/ directory.
4. Define Seeder data population logic
In UserSeeder.php, call the factory to generate multiple user records:
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class UserSeeder extends Seeder
{
public function run()
{
// Use the factory to generate 10 users
User::factory()->count(10)->create();
}
}
This code will create 10 user records using UserFactory.
5. Run Seeder
In DatabaseSeeder.php, register UserSeeder to the run method so that it will be called when running database population:
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UserSeeder::class);
}
}
Then, run the db:seed command to execute the Seeder and populate the data:
php artisan db:seed
You can also run a specific Seeder separately:
php artisan db:seed --class=UserSeeder
6. Use Tinker to test Factory (optional)
Laravel provides the Tinker tool, which can be used to quickly generate data. Enter the Tinker environment:
php artisan tinker
Then run the following command to generate a single user:
User::factory()->create();
Or generate multiple users:
User::factory()->count(5)->create();
☕ Caching
Laravel's cache system provides multiple cache driver support, which can use methods such as put, get, and remember to operate the cache and improve application performance.
Laravel's cache system supports multiple drivers (such as Redis, Memcached, files, etc.), which can effectively improve the performance of the application. The following are detailed steps and code examples for using cache.
1. Configure cache driver
Laravel uses file cache by default. You can change the driver type in the .env file. For example, change the cache driver to Redis:
CACHE_DRIVER=redis
Confirm that the Redis configuration in the .env file is correct. The default Redis configuration is as follows:
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
Make sure Redis is running on the server. If you use other drivers (such as Memcached), install the driver and configure the corresponding .env settings.
2. Using Cache in Laravel
Laravel provides multiple cache methods to easily operate the cache.
Example: Store Data in Cache
Use the following code in a controller or service to store data in the cache:
use Illuminate\Support\Facades\Cache;
// Store data in the cache with a validity period of 60 minutes
Cache::put('key', 'value', 60);
Cache::put('key', 'value', null); // Permanent Cache
Cache::forever('key', 'value'); // Permanent Cache
You can use the remember method to cache data for a period of time. If the cache does not exist, execute the given callback and cache the result:
Cache::remember('key', 60, function () {
return 'value';
});
Example: Get data from cache
Use the get method to get data from cache:
$value = Cache::get('key');
// If key does not exist, return the default value
$value = Cache::get('key', 'default');
Example: Delete cache
Use the forget method to delete cache items:
Cache::forget('key');
3. Cache collection data
Caching collection data such as query results can effectively reduce database queries. For example:
$users = Cache::remember('users', 60, function () {
return \App\Models\User::all();
});
The above example caches all user data for 60 minutes, and subsequent requests will directly retrieve data from the cache.
4. Redis specific cache operations
If you use the Redis driver, you can access the Redis instance to perform operations:
use Illuminate\Support\Facades\Redis;
// Storing Values
Redis::set('key', 'value');
// Get Value
$value = Redis::get('key');
5. Clear the cache
Use the Artisan command to clear all caches:
php artisan cache:clear
☕RabbitMQ
RabbitMQ is a message broker that can be used for task queues, messaging, and asynchronous processing in distributed systems. Here are the complete steps and code examples on how to configure and use RabbitMQ in Laravel.
1. Install the RabbitMQ client library
Laravel does not have built-in support for RabbitMQ, so you need to use a community-provided package, such as the vladimir-yuldashev/laravel-queue-rabbitmq package. First, install the package:
composer require vladimir-yuldashev/laravel-queue-rabbitmq
2. Configure the queue connection
After the installation is complete, configure the config/queue.php file and add the RabbitMQ configuration in connections:
'connections' => [
'rabbitmq' => [
'driver' => 'rabbitmq',
'queue' => 'default', // Default queue name
'connection' => 'default',
'hosts' => [
[
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
'user' => env('RABBITMQ_USER', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'vhost' => env('RABBITMQ_VHOST', '/'),
],
],
'options' => [
'ssl_options' => [
'cafile' => env('RABBITMQ_SSL_CAFILE', null),
'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
],
'queue' => [
'job' => \VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class,
],
],
],
],
Add the following RabbitMQ configuration items to your .env file:
RABBITMQ_HOST=127.0.0.1
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_VHOST=/
3. Create a task queue Job
You can use Laravel's Artisan command to create a Job to process tasks:
php artisan make:job ProcessMessage
In the app/Jobs/ProcessMessage.php file, define the specific execution content of the task, for example:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function handle()
{
// Process the message here
\Log::info("Processing message: " . $this->data);
}
}
4. Put the task into the queue
Where the queue is needed (such as in the controller), you can use the following code to put the task into the queue:
use App\Jobs\ProcessMessage;
Route::get('/send', function () {
$data = 'This is a message for RabbitMQ';
ProcessMessage::dispatch($data);
return 'Message sent to RabbitMQ!';
});
5. Start the queue listener
Finally, start the queue listener with the following command to process tasks in the RabbitMQ queue:
php artisan queue:work --queue=rabbitmq
By configuring the queue.php file, creating a Job, and using dispatch to send tasks to the RabbitMQ queue, you can easily use RabbitMQ as a queue driver for Laravel.
☕ Service Providers
1. Create a service provider
In development, it is often necessary to register common services, such as custom payment processing or data conversion services. Service providers can bind these service classes to the container for easy calling from various parts of the project.
php artisan make:provider CustomServiceProvider
Create CustomService.php in the app/Services/ directory to implement basic business logic:
namespace App\Services;
class CustomService
{
public function performAction()
{
return "Custom Service Action Performed!";
}
}
In the register method in CustomServiceProvider.php, bind CustomService to the container:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\CustomService;
class CustomServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(CustomService::class, function ($app) {
return new CustomService();
});
}
public function boot()
{
// You can add other startup logic here
}
}
2. Register service provider
Register service provider in config/app.php:
'providers' => [
// Other service providers
App\Providers\CustomServiceProvider::class,
],
Inject CustomService in a controller or elsewhere, and call its performAction method:
namespace App\Http\Controllers;
use App\Services\CustomService;
class ExampleController extends Controller
{
protected $customService;
public function __construct(CustomService $customService)
{
$this->customService = $customService;
}
public function index()
{
return $this->customService->performAction();
}
}
☕ Model Observers
If you use Laravel's built-in php artisan serve to run a local server during development, the information will be displayed in the command line window where php artisan serve is started.
Model observers are used to perform specific actions when model events (such as create, update, delete, etc.) occur. Using observers can separate business logic from controllers, making the code clearer and easier to maintain. Here are the detailed steps and code examples:
1. Create Observer
Laravel provides Artisan commands to quickly generate observer files. Suppose you have a User model and want to listen to user creation and deletion events.
php artisan make:observer UserObserver --model=User
After executing this command, Laravel will generate the UserObserver.php file in the app/Observers directory and automatically associate it with the User model.
2. Define the Observer method
Open the app/Observers/UserObserver.php file and define the actions to be performed when a specific event occurs. For example, record related actions when a user is created and deleted:
<?php
namespace App\Observers;
use App\Models\User;
class UserObserver
{
// Listen to the user creation event
public function created(User $user)
{
// Logic to execute when a user is created
echo "User created with ID: " . $user->id;
}
// Listen to the user deletion event
public function deleted(User $user)
{
// Logic to execute when a user is deleted
echo "User deleted with ID: " . $user->id;
}
}
3. Register Observer in the service provider
To make the observer effective, you need to register it in AppServiceProvider or a custom service provider. In the boot method in App\Providers\AppServiceProvider, register UserObserver:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Models\User;
use App\Observers\UserObserver;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
User::observe(UserObserver::class);
}
public function register()
{
//
}
}
4. Test Observer
You can test the observer by creating or deleting users. Open Laravel Tinker or execute the following code in the controller to observe the effect:
// Create User
$user = \App\Models\User::create([
'name' => 'John Doe',
'email' => 'johndoe@example.com',
'password' => bcrypt('password')
]);
// Deleting a User
$user->delete();
The observer will trigger the created and deleted methods when the create or delete operation is performed, and output the corresponding message.
Common usage examples
In addition to creation and deletion, observers can also listen to other events, such as updated, saving, restoring, etc. You can define the corresponding methods in UserObserver as needed:
public function updated(User $user)
{
echo "User updated with ID: " . $user->id;
}
In this way, model observers can help you perform specific actions when model events are triggered, making the code logic more modular and clear.
☕ Custom Commands (Artisan Commands)
Custom Artisan commands allow you to extend Laravel's command line tools, which are very suitable for performing scheduled tasks, batch processing of data, etc. The following are detailed steps and code examples for creating custom commands:
1. Generate custom commands
Use Artisan commands to generate a new command class:
php artisan make:command CustomCommand
After running, Laravel will create a CustomCommand.php file in the app/Console/Commands directory.
2. Define the name and function of the command
Open app/Console/Commands/CustomCommand.php and modify the command name, description and processing logic:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CustomCommand extends Command
{
// Define the name of the command, used for calling it in the command line
protected $signature = 'custom:run';
// Description of the command, displayed in `php artisan list`
protected $description = 'Execute a custom command';
// The command's processing logic
public function handle()
{
// Write the actual logic of the command here
$this->info('Custom Command Executed Successfully!');
}
}
$signature: Defines the command's calling name, such ascustom:run.$description: The command's description, which can help understand the command's purpose.handlemethod: The actual processing logic of the command. You can add any required business logic here, such as querying the database, processing data, etc.
3. Register custom commands
In app/Console/Kernel.php, register the custom command to the $commands array:
protected $commands = [
\App\Console\Commands\CustomCommand::class,
];
After registration, Laravel will be able to recognize and use this custom command.
4. Execute custom commands
You can now run custom commands in the terminal with the following command:
php artisan custom:run
After execution, the terminal will output Custom Command Executed Successfully!, indicating that the command has been successfully run.
5, Another example
Another example, demonstrating how to create a custom Artisan command to get data from an API and store it in the database. Suppose we want to create a command to get user data and insert it into the users table.
5.1, Generate a custom command
First, generate a new custom command:
php artisan make:command FetchUsers
This will create a file named FetchUsers.php in the app/Console/Commands directory.
5.2, define the name and function of the command
Open the app/Console/Commands/FetchUsers.php file and modify the command name, description and processing logic:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use App\Models\User;
class FetchUsers extends Command
{
// Define the name of the command
protected $signature = 'fetch:users';
// Description of the command
protected $description = 'Fetch users from an external API and store them in the database';
// Command processing logic
public function handle()
{
// Call an external API to get user data
$response = Http::get('https://jsonplaceholder.typicode.com/users');
if ($response->successful()) {
$users = $response->json();
foreach ($users as $userData) {
// Insert user data into the database
User::updateOrCreate(
['email' => $userData['email']], // Unique identifier
[
'name' => $userData['name'],
'username' => $userData['username'],
'address' => json_encode($userData['address']),
]
);
}
$this->info('Users fetched and stored successfully!');
} else {
$this->error('Failed to fetch users from the API.');
}
}
}
Code analysis
-
$signature: defines the command call name asfetch:users. -
$description: describes the command's function. -
handlemethod -
Use Laravel's HTTP client to get user data from the specified API (here using JSONPlaceholder's sample API).
-
If the request is successful, traverse the user data and use the
updateOrCreatemethod to insert the user information into the database. If the user already exists (based on the email field), update the user's information. -
Output a success or failure message.
5.3, Register custom commands
In the app/Console/Kernel.php file, register the custom command to the $commands array:
protected $commands = [
\App\Console\Commands\FetchUsers::class,
];
5.4, Execute custom commands
You can now run custom commands in the terminal with the following command:
php artisan fetch:users
After execution, the command will fetch user data from the API and store it in the database. The terminal will display Users fetched and stored successfully! to indicate that the operation was successful.
Application scenarios
This command can be used to periodically synchronize user data from an external API to your application, such as maintaining data consistency when registering, updating information, or performing data analysis. You can set this command to run on a scheduled basis in conjunction with Laravel's task scheduler to ensure that your database is always in sync with the external data source.
☕ User avatars
Here are detailed steps and code examples for processing user avatar uploads and saving avatar images to Laravel applications.
1, Create database fields
First, make sure you have a field in your user table to store the path to the avatar. If you don't have this field yet, you can add it through migration.
Run the following command in your terminal to create a migration:
php artisan make:migration add_avatar_to_users_table --table=users
Then, add the avatar field to the generated migration file:
// database/migrations/xxxx_xx_xx_xxxxxx_add_avatar_to_users_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAvatarToUsersTable extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar')->nullable(); // Add an avatar field
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar'); // Delete the avatar field
});
}
}
Run the migration command to update the database:
php artisan migrate
2. Create an avatar upload controller
Next, create a controller to handle avatar uploads. Run in the terminal:
php artisan make:controller AvatarController
Add the following code to the generated AvatarController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class AvatarController extends Controller
{
public function upload(Request $request)
{
// Validate the file in the request
$request->validate([
'avatar' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
// Get the current user
$user = Auth::user();
// Process the uploaded avatar
if ($request->hasFile('avatar')) {
// Delete old avatar if it exists
if ($user->avatar) {
Storage::delete($user->avatar);
}
// Upload new avatar
$path = $request->file('avatar')->store('avatars'); // Stored in storage/app/avatars
// Update the user's avatar path
$user->avatar = $path;
$user->save();
}
return response()->json(['message' => 'Avatar uploaded successfully', 'avatar' => $path]);
}
public function getAvatar()
{
// Get the current user's avatar
$user = Auth::user();
return response()->json(['avatar' => $user->avatar]);
}
}
3. Routing configuration
Add the corresponding routes in routes/web.php or routes/api.php:
use App\Http\Controllers\AvatarController;
Route::middleware('auth:sanctum')->post('/upload-avatar', [AvatarController::class, 'upload']);
Route::middleware('auth:sanctum')->get('/get-avatar', [AvatarController::class, 'getAvatar']);
4. Front-end upload form example
You can use HTML form or JavaScript/Axios to upload avatars. The following is a simple HTML form example:
<form id="avatar-form" enctype="multipart/form-data">
@csrf
<input type="file" name="avatar" id="avatar" required>
<button type="submit">Upload an avatar</button>
</form>
<script>
document.getElementById('avatar-form').addEventListener('submit', function (e) {
e.preventDefault();
let formData = new FormData(this);
fetch('/upload-avatar', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}', // Laravel CSRF token
},
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
});
</script>
5. Get the avatar
To get the current user's avatar, you can call the getAvatar method:
fetch('/get-avatar', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token, // Replace with your Bearer Token
},
})
.then(response => response.json())
.then(data => {
if (data.avatar) {
console.log('User avatar path:', data.avatar);
}
});
6. Display avatar
You can display the avatar through the generated avatar path, for example:
<img src="{{ asset($user->avatar) }}" alt="User Avatar" />
Summary
The above steps show how to implement the user avatar upload function in Laravel, including database migration, controller, route configuration, and front-end code examples. With these codes, users can upload, save, and get their avatars. If needed, you can further expand this function, such as adding more verification, adjusting the storage path, etc.
☕ middleware('auth:sanctum')
middleware('auth:sanctum') is a middleware in Laravel that is used to protect your routes so that they can only be accessed by authenticated users. Specifically, sanctum is a lightweight authentication system provided by Laravel, which is particularly suitable for API development.
Verify user identity.
Log request information.
Modify the request or response.
auth:api: Suitable for applications that require complex authentication, usually used in conjunction with Passport.
auth:sanctum: For quick, simple applications, typically used in SPAs or mobile applications, using simple token authentication provided by Laravel Sanctum
Which one to choose depends on the needs and complexity of your application. If your application only needs basic user authentication, using Sanctum will be simpler and faster; if you need more complex OAuth2 functionality, you should choose Passport.
The steps for using middleware('auth:sanctum') and HasApiTokens for API authentication are as follows. This will include installing Sanctum, setting up a user model, creating tokens, and protecting routes.
1. Install Laravel Sanctum
In your Laravel project, first install Sanctum via Composer:
composer require laravel/sanctum
2. Publish Sanctum configuration
Once installed, publish Sanctum's configuration and migration files:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
3. Run database migrations
Run database migrations to create the necessary tables:
php artisan migrate
4. Configure authentication guards
In the config/auth.php file, set the API guard to use Sanctum:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'sanctum', // Set the API guard to Sanctum
'provider' => 'users',
],
],
5. Use HasApiTokens Trait in User Model
Introduce HasApiTokens feature in user model (usually App\Models\User):
namespace App\Models;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens; // Introducing the HasApiTokens trait
// Other model properties and methods
}
6. Create a user token
Create a token for the user in the controller. The following is an example controller for user login and generating a token:
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if ($user && Hash::check($request->password, $user->password)) {
// Creating a Token
$token = $user->createToken('token-name')->plainTextToken;
return response()->json(['token' => $token], 200);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
}
7. Protect routes
Use middleware('auth:sanctum') in the route file to protect routes that require authentication. For example, to protect a route that obtains user information:
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user(); // Returns the information of the currently logged in user
});
8. Make requests using API tokens
In the client (e.g., Postman or a front-end application), use the generated token to make API requests. Add the Authorization field to the request header:
Authorization: Bearer your-token-here
Revoke tokens
You can revoke a user's token in the following ways:
// Revoke all tokens
$user->tokens()->delete();
// Or revoke a specific token
$token = $user->tokens()->find($tokenId);
$token->delete();
Summary
Through the above steps, you can successfully use middleware('auth:sanctum') and the HasApiTokens feature to implement API authentication. Laravel Sanctum provides a simple and effective way to manage API tokens for single-page applications (SPA) and mobile applications.
☕ Define Model Relationships
In Laravel, if you want to define a relationship in one model with another model and connect the two models through the user_id field, you usually use the belongsTo relationship. The following are detailed codes and steps, assuming that we have a User model and a Post model, and the user_id field in the Post model points to the User model.
Step 1: Define Model Relationships
1.1. User Model
Define the relationship with Post in the User model:
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasFactory;
// Define a relationship with the Post model
public function posts()
{
return $this->hasMany(Post::class);
}
}
1.2. Post model
Define the relationship between Post and User in the Post model:
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
// Define a relationship with the User model
public function user()
{
return $this->belongsTo(User::class);
}
}
Step 2: Create database migrations
If you haven't created the posts table yet, you can create it through migrations. Run the following command to generate the migration file:
php artisan make:migration create_posts_table
Then in the generated migration file, define the structure of the posts table:
// database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade'); // Adding a user_id field
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
Step 3: Run Migrations
Run migrations to create the posts table:
php artisan migrate
Step 4: Use Relationships
Now you can use the defined relationships to get a user's posts or get a user's posts.
4.1. Get all posts for a user
use App\Models\User;
$user = User::find(1); // Get the user with ID 1
$posts = $user->posts; // Get all posts by this user
foreach ($posts as $post) {
echo $post->title; // Output the title of each post
}
4.2. Get the user of the post
use App\Models\Post;
$post = Post::find(1); // Get the post with ID 1
$user = $post->user; // Get the user of the post
echo $user->name; // Output the user name of the post
Summary
Through the above steps, you can define the relationship between User and Post in Laravel, and use the belongsTo and hasMany methods to easily perform database operations. This makes navigating between models simple and intuitive.
☕ Request
In Laravel, Request is the core component for handling HTTP requests. Using the Request class, you can easily get the requested data, validate input, manage file uploads, and more. The following is a detailed code and steps to introduce how to use the Request class.
1. Import Request class
In your controller, you can use the Request class through dependency injection or direct import.
Dependency injection
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
// Handling Requests
}
}
Using the Request facade directly
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Request;
class UserController extends Controller
{
public function store()
{
$data = Request::all(); // Get all request data
}
}
2. Get request data
You can get various data in the request through the Request instance.
public function store(Request $request)
{
$name = $request->input('name'); // Get a single input value
$email = $request->get('email'); // Get input using the get method
$allData = $request->all(); // Get all input data
}
3. Validate request data
Use Laravel's validation function to validate the request data. You can use the validate method in the controller.
public function store(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
]);
// After validation, you can use $validatedData
$user = User::create($validatedData);
}
4. Handling file uploads
Handling file uploads using Request is very simple. You can use the file method to get the uploaded file, and the store method to save the file.
public function store(Request $request)
{
$request->validate([
'avatar' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('avatars', 'public'); // Save to the storage/app/public/avatars directory
// You can save $path to the database
$user->avatar = $path;
$user->save();
}
}