Validation

Validation

01.08.2024
Author: ADMIN

# Laravel Validation

Laravel cung cấp một hệ thống kiểm tra dữ liệu mạnh mẽ và dễ sử dụng. Bạn có thể thực hiện kiểm tra dữ liệu (validation) trong các controller, form request, hoặc thậm chí là trực tiếp trong các model. Dưới đây là hướng dẫn cơ bản về cách sử dụng hệ thống kiểm tra dữ liệu của Laravel.

1. Validation trong Controller

Bạn có thể thực hiện kiểm tra dữ liệu trực tiếp trong các phương thức của controller bằng cách sử dụng phương thức validate:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // User::create($validatedData);

        return response('User created successfully.');
    }
}
  • name phải có giá trị và không được vượt quá 255 ký tự.
  • email phải là một địa chỉ email hợp lệ và duy nhất trong bảng users.
  • password phải có ít nhất 8 ký tự và được xác nhận (có một trường password_confirmation khớp với password).

2. Validation trong Form Request

Bạn có thể tách logic kiểm tra dữ liệu ra khỏi controller bằng cách sử dụng Form Request. Điều này giúp mã nguồn của bạn sạch hơn và dễ bảo trì hơn.

Tạo một Form Request:

php artisan make:request StoreUserRequest

Sử dụng Form Request:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ];
    }
}

Sử dụng Form Request trong Controller:

namespace App\Http\Controllers;

use App\Http\Requests\StoreUserRequest;

class UserController extends Controller
{
    public function store(StoreUserRequest $request)
    {
        $validatedData = $request->validated();

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // User::create($validatedData);

        return response('User created successfully.');
    }
}

3. Custom Messages

Bạn có thể tùy chỉnh các thông báo lỗi kiểm tra dữ liệu bằng cách sử dụng phương thức messages trong Form Request hoặc bằng cách truyền mảng thứ ba vào phương thức validate.

Tùy chỉnh thông báo lỗi trong Form Request:
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ];
    }

    public function messages()
    {
        return [
            'name.required' => 'Vui lòng nhập tên.',
            'email.required' => 'Vui lòng nhập địa chỉ email.',
            'email.email' => 'Địa chỉ email không hợp lệ.',
            'email.unique' => 'Địa chỉ email đã tồn tại.',
            'password.required' => 'Vui lòng nhập mật khẩu.',
            'password.min' => 'Mật khẩu phải có ít nhất 8 ký tự.',
            'password.confirmed' => 'Xác nhận mật khẩu không khớp.',
        ];
    }
}

Tùy chỉnh thông báo lỗi trong Controller:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ], [
            'name.required' => 'Vui lòng nhập tên.',
            'email.required' => 'Vui lòng nhập địa chỉ email.',
            'email.email' => 'Địa chỉ email không hợp lệ.',
            'email.unique' => 'Địa chỉ email đã tồn tại.',
            'password.required' => 'Vui lòng nhập mật khẩu.',
            'password.min' => 'Mật khẩu phải có ít nhất 8 ký tự.',
            'password.confirmed' => 'Xác nhận mật khẩu không khớp.',
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // User::create($validatedData);

        return response('User created successfully.');
    }
}

4. Custom Validation Rules

Bạn có thể tạo các quy tắc kiểm tra dữ liệu tùy chỉnh nếu cần.

Tạo Custom Validation Rule:
php artisan make:rule Uppercase

Sử dụng Custom Validation Rule:

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

Sử dụng Custom Validation Rule trong Controller hoặc Form Request:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use App\Rules\Uppercase;

class StoreUserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => ['required', 'max:255', new Uppercase],
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ];
    }
}

# ValidateWithBag

Trong Laravel, khi thực hiện kiểm tra dữ liệu (validation), đôi khi bạn muốn tách biệt các thông báo lỗi thành nhiều túi (bag) khác nhau. Điều này có thể hữu ích khi bạn có nhiều form trên cùng một trang và bạn muốn quản lý thông báo lỗi riêng biệt cho từng form. Laravel cung cấp phương thức validateWithBag để thực hiện điều này.

Sử dụng validateWithBag

Phương thức validateWithBag cho phép bạn chỉ định một túi lỗi cụ thể cho các lỗi kiểm tra dữ liệu. Đây là cách sử dụng cơ bản:

Controller:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validateWithBag('storeUser', [
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8|confirmed',
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // User::create($validatedData);

        return response('User created successfully.');
    }

    public function update(Request $request, $id)
    {
        $validatedData = $request->validateWithBag('updateUser', [
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users,email,' . $id,
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // User::find($id)->update($validatedData);

        return response('User updated successfully.');
    }
}

Trong ví dụ trên, phương thức validateWithBag được sử dụng với túi lỗi storeUser cho phương thức store và túi lỗi updateUser cho phương thức update.

Hiển thị lỗi trong Blade

Để hiển thị các thông báo lỗi cho từng túi lỗi riêng biệt trong Blade, bạn có thể sử dụng phương thức hasBaggetBag của đối tượng $errors.

Ví dụ trong Blade template:
<!-- Form tạo người dùng mới -->
<form action="{{ route('user.store') }}" method="POST">
    @csrf
    <div>
        <label for="name">Name</label>
        <input type="text" id="name" name="name">
        @if ($errors->storeUser->has('name'))
            <div>{{ $errors->storeUser->first('name') }}</div>
        @endif
    </div>
    <div>
        <label for="email">Email</label>
        <input type="email" id="email" name="email">
        @if ($errors->storeUser->has('email'))
            <div>{{ $errors->storeUser->first('email') }}</div>
        @endif
    </div>
    <div>
        <label for="password">Password</label>
        <input type="password" id="password" name="password">
        @if ($errors->storeUser->has('password'))
            <div>{{ $errors->storeUser->first('password') }}</div>
        @endif
    </div>
    <button type="submit">Create User</button>
</form>

<!-- Form cập nhật người dùng -->
<form action="{{ route('user.update', ['id' => 1]) }}" method="POST">
    @csrf
    @method('PUT')
    <div>
        <label for="name">Name</label>
        <input type="text" id="name" name="name">
        @if ($errors->updateUser->has('name'))
            <div>{{ $errors->updateUser->first('name') }}</div>
        @endif
    </div>
    <div>
        <label for="email">Email</label>
        <input type="email" id="email" name="email">
        @if ($errors->updateUser->has('email'))
            <div>{{ $errors->updateUser->first('email') }}</div>
        @endif
    </div>
    <button type="submit">Update User</button>
</form>

Trong ví dụ trên, các thông báo lỗi cho từng form được hiển thị riêng biệt dựa trên túi lỗi tương ứng (storeUserupdateUser).

Kết luận

Phương thức validateWithBag của Laravel giúp bạn dễ dàng tách biệt và quản lý các thông báo lỗi cho nhiều form trên cùng một trang. Bằng cách sử dụng túi lỗi riêng biệt, bạn có thể đảm bảo rằng mỗi form chỉ hiển thị các thông báo lỗi liên quan, giúp giao diện người dùng trở nên rõ ràng và dễ hiểu hơn.

# Dừng Lại Khi Gặp Lỗi Đầu Tiên

Trong Laravel, để dừng kiểm tra dữ liệu khi gặp lỗi đầu tiên, bạn có thể sử dụng quy tắc bail. Quy tắc này sẽ yêu cầu Laravel dừng quá trình kiểm tra dữ liệu đối với thuộc tính cụ thể ngay khi phát hiện ra lỗi đầu tiên.

Sử Dụng Quy Tắc bail

Bạn có thể gán quy tắc bail cho thuộc tính cần kiểm tra. Khi một thuộc tính có quy tắc bail và Laravel phát hiện ra lỗi đầu tiên trên thuộc tính đó, các quy tắc kiểm tra còn lại sẽ không được thực thi.

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

Ngoài ra, bạn có thể sử dụng method stopOnFirstFailure 

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}

# Lưu Ý Về Các Thuộc Tính Lồng Nhau

Trong Laravel, khi yêu cầu HTTP chứa dữ liệu trường "lồng nhau", bạn có thể chỉ định các trường này trong các quy tắc kiểm tra dữ liệu (validation rules) bằng cú pháp "dot". Ngoài ra, nếu tên trường của bạn chứa một dấu chấm thực sự, bạn có thể ngăn chặn việc này bị hiểu sai thành cú pháp "dot" bằng cách sử dụng dấu gạch chéo ngược để thoát khỏi dấu chấm.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'title' => 'required|unique:posts|max:255',
            'author.name' => 'required',
            'author.description' => 'required',
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // Post::create($validatedData);

        return response('Post created successfully.');
    }
}
  • title là một trường thông thường với các quy tắc required, unique:posts, và max:255.
  • author.nameauthor.description là các thuộc tính lồng nhau trong trường author.

Tránh Nhầm Lẫn Với Tên Trường Chứa Dấu Chấm Thực Sự

Nếu tên trường của bạn chứa một dấu chấm thực sự, bạn có thể ngăn chặn việc này bị hiểu sai thành cú pháp "dot" bằng cách sử dụng dấu gạch chéo ngược để thoát khỏi dấu chấm. Điều này hữu ích khi bạn có các phiên bản hoặc các tên trường đặc biệt.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class VersionController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'title' => 'required|unique:posts|max:255',
            'v1\.0' => 'required',
        ]);

        // Nếu dữ liệu hợp lệ, bạn có thể tiếp tục xử lý dữ liệu ở đây.
        // Version::create($validatedData);

        return response('Version created successfully.');
    }
}
  • title là một trường thông thường với các quy tắc required, unique:posts, và max:255.
  • v1\.0 là một tên trường chứa dấu chấm thực sự và được thoát bằng dấu gạch chéo ngược.

Tham khảo
# Available Validation Rules

# Tái Tạo Dữ Liệu Cho Form

Trong Laravel, việc tái tạo dữ liệu cho các form rất quan trọng để giữ lại thông tin đã nhập vào khi có lỗi xảy ra hoặc khi cần hiển thị lại dữ liệu đã lưu trước đó. Laravel cung cấp nhiều cách để thực hiện việc này một cách dễ dàng và hiệu quả.

Sử Dụng old() Helper

Khi một yêu cầu HTTP POST không thành công do lỗi kiểm tra dữ liệu, Laravel sẽ tự động chuyển hướng người dùng trở lại trang trước đó với dữ liệu cũ (old input) và các thông báo lỗi. Bạn có thể sử dụng helper old() để lấy lại dữ liệu này và hiển thị trong form.

<form action="{{ route('post.store') }}" method="POST">
    @csrf
    <div>
        <label for="title">Title</label>
        <input type="text" id="title" name="title" value="{{ old('title') }}">
        @error('title')
            <div class="error">{{ $message }}</div>
        @enderror
    </div>
    <div>
        <label for="content">Content</label>
        <textarea id="content" name="content">{{ old('content') }}</textarea>
        @error('content')
            <div class="error">{{ $message }}</div>
        @enderror
    </div>
    <button type="submit">Submit</button>
</form>

Trong ví dụ này, nếu kiểm tra dữ liệu không thành công, giá trị của các trường titlecontent sẽ được tái tạo lại trong form bằng cách sử dụng old('title')old('content').

Route Resource and Resourceful Controllers

Route Resource and Resourceful Controllers

01.08.2024
Author: ADMIN

# Resource Controllers

Resource Controllers trong Laravel cung cấp một cách thuận tiện để xử lý các hành động CRUD (Create, Read, Update, Delete) cho các tài nguyên của bạn. Khi bạn tạo một Resource Controller, Laravel sẽ tự động tạo ra các phương thức xử lý các hành động CRUD tiêu chuẩn. Điều này giúp bạn giảm bớt việc phải viết mã thủ công cho các hành động lặp đi lặp lại.

1. Tạo Resource Controller

Để tạo một Resource Controller, bạn sử dụng lệnh Artisan sau:

php artisan make:controller UserController --resource

Lệnh này sẽ tạo ra một controller mới tên là UserController với các phương thức mặc định cho các hành động CRUD. Đây là các phương thức được tạo ra:

  • index(): Hiển thị danh sách tài nguyên.
  • create(): Hiển thị form để tạo tài nguyên mới.
  • store(): Lưu trữ tài nguyên mới vào cơ sở dữ liệu.
  • show($id): Hiển thị chi tiết một tài nguyên cụ thể.
  • edit($id): Hiển thị form để chỉnh sửa một tài nguyên cụ thể.
  • update(Request $request, $id): Cập nhật tài nguyên cụ thể trong cơ sở dữ liệu.
  • destroy($id): Xóa một tài nguyên cụ thể khỏi cơ sở dữ liệu.

2. Route Resource

Để định tuyến đến Resource Controller, bạn có thể sử dụng phương thức Route::resource. Ví dụ:

use Illuminate\Support\Facades\Route;

Route::resource('users', UserController::class);

Lệnh này sẽ tự động tạo ra tất cả các tuyến đường cần thiết cho các hành động CRUD tương ứng với các phương thức trong UserController.

# Actions Handled by Resource Controllers

Verb URI Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

# Tùy Chỉnh Hành Vi Khi Model Không Tồn Tại với Phương Thức missing

Thường thì, một phản hồi HTTP 404 sẽ được tạo ra nếu một resource model không được tìm thấy. Tuy nhiên, bạn có thể tùy chỉnh hành vi này bằng cách gọi phương thức missing khi xác định resource route của bạn. Phương thức missing chấp nhận một closure sẽ được gọi nếu một Model được ràng buộc một cách ngầm định không thể tìm thấy cho bất kỳ resource's routes nào:

use App\Http\Controllers\UserController;
use App\Models\User;
use Illuminate\Support\Facades\Route;

Route::resource('users', UserController::class)
    ->missing(function (Request $request) {
         return response()->view('errors.custom', [], 404);
});

Trong ví dụ trên, nếu một mô hình User không được tìm thấy khi truy cập bất kỳ tuyến đường tài nguyên nào của users, Laravel sẽ trả về một view tùy chỉnh errors.custom với mã trạng thái 404.

# Soft Deleted Models

Trong Laravel, tính năng Soft Deletes cho phép bạn "xóa" các bản ghi khỏi cơ sở dữ liệu mà không thực sự xóa chúng. Thay vì bị xóa, một bản ghi sẽ được đánh dấu là đã xóa bằng cách thiết lập giá trị của cột deleted_at thành thời điểm hiện tại. Điều này giúp bạn dễ dàng khôi phục các bản ghi đã bị xóa nếu cần thiết.

1. Thiết lập Soft Deletes cho một Model

Để sử dụng Soft Deletes, bạn cần làm theo các bước sau:

Thêm cột deleted_at vào bảng

Bạn có thể sử dụng migration để thêm cột deleted_at vào bảng của bạn:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddDeletedAtToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->softDeletes();
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropSoftDeletes();
        });
    }
}
Sử dụng trait SoftDeletes trong model

Bạn cần thêm trait SoftDeletes vào model của bạn:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use SoftDeletes;

    protected $dates = ['deleted_at'];
}

2. Sử dụng Soft Deletes

Xóa mềm một bản ghi

Để xóa mềm một bản ghi, bạn chỉ cần gọi phương thức delete:

$user = User::find(1);
$user->delete();
Khôi phục một bản ghi đã bị xóa mềm

Bạn có thể khôi phục một bản ghi đã bị xóa mềm bằng phương thức restore:

$user = User::withTrashed()->find(1);
$user->restore();
Xóa vĩnh viễn một bản ghi

Để xóa vĩnh viễn một bản ghi, bạn có thể sử dụng phương thức forceDelete:

$user = User::withTrashed()->find(1);
$user->forceDelete();

3. Truy vấn với Soft Deletes

Lấy các bản ghi chưa bị xóa

Mặc định, các truy vấn Eloquent sẽ chỉ lấy các bản ghi chưa bị xóa:

$users = User::all();
Lấy tất cả các bản ghi, bao gồm cả bản ghi đã bị xóa

Bạn có thể sử dụng phương thức withTrashed để lấy tất cả các bản ghi, bao gồm cả những bản ghi đã bị xóa:

$users = User::withTrashed()->get();
Chỉ lấy các bản ghi đã bị xóa

Bạn có thể sử dụng phương thức onlyTrashed để chỉ lấy những bản ghi đã bị xóa mềm:

$users = User::onlyTrashed()->get();

4. Các phương thức bổ sung

Kiểm tra xem một bản ghi đã bị xóa hay chưa

Bạn có thể sử dụng phương thức trashed để kiểm tra xem một bản ghi đã bị xóa mềm hay chưa:

$user = User::withTrashed()->find(1);

if ($user->trashed()) {
    // Bản ghi đã bị xóa mềm
}

# Nested Resources

Nested Resources (tài nguyên lồng nhau) cho phép bạn định nghĩa các tuyến đường tài nguyên lồng nhau để biểu diễn mối quan hệ giữa các mô hình. Điều này thường được sử dụng khi một mô hình có mối quan hệ với một mô hình khác, ví dụ như PostComment.

1. Định Nghĩa Nested Resources

Bạn có thể định nghĩa các nested resources trong tệp định tuyến của mình (routes/web.php). Dưới đây là một ví dụ về cách định nghĩa nested resources cho PostComment:

use App\Http\Controllers\PostController;
use App\Http\Controllers\CommentController;
use Illuminate\Support\Facades\Route;

Route::resource('posts', PostController::class);

Route::resource('posts.comments', CommentController::class);

2. URL và Tên Định Tuyến cho Nested Resources

Khi bạn định nghĩa nested resources, Laravel sẽ tự động tạo ra các tuyến đường với các URL và tên định tuyến tương ứng.

Ví dụ URL và tên định tuyến:
  • GET /posts - posts.index
  • GET /posts/{post} - posts.show
  • GET /posts/{post}/comments - posts.comments.index
  • GET /posts/{post}/comments/{comment} - posts.comments.show

3. Sử Dụng Nested Resources trong Controller

Bạn có thể sử dụng nested resources trong controller của bạn để quản lý các hành động liên quan đến mô hình lồng nhau.

namespace App\Http\Controllers;

use App\Models\Post;
use App\Models\Comment;
use Illuminate\Http\Request;

class CommentController extends Controller
{
    public function index(Post $post)
    {
        $comments = $post->comments;
        return view('comments.index', compact('comments'));
    }

    public function show(Post $post, Comment $comment)
    {
        return view('comments.show', compact('post', 'comment'));
    }

    public function create(Post $post)
    {
        return view('comments.create', compact('post'));
    }

    public function store(Request $request, Post $post)
    {
        $validatedData = $request->validate([
            'body' => 'required|max:255',
        ]);

        $post->comments()->create($validatedData);

        return redirect()->route('posts.comments.index', $post);
    }

    public function edit(Post $post, Comment $comment)
    {
        return view('comments.edit', compact('post', 'comment'));
    }

    public function update(Request $request, Post $post, Comment $comment)
    {
        $validatedData = $request->validate([
            'body' => 'required|max:255',
        ]);

        $comment->update($validatedData);

        return redirect()->route('posts.comments.index', $post);
    }

    public function destroy(Post $post, Comment $comment)
    {
        $comment->delete();

        return redirect()->route('posts.comments.index', $post);
    }
}

4. Ràng Buộc Ngầm Định và Nested Resources

Laravel tự động ràng buộc các Model cho các nested resources. Khi bạn định nghĩa một nested resource, Laravel sẽ tự động ràng buộc các Model cha cho các tuyến đường con. Ví dụ, trong CommentController, mô hình Post sẽ tự động được ràng buộc trước khi mô hình Comment.

Nested resources cung cấp một cách rõ ràng và dễ dàng để quản lý mối quan hệ giữa các mô hình trong ứng dụng Laravel của bạn. Bằng cách sử dụng nested resources, bạn có thể tạo ra các tuyến đường và controller hành động cho các mô hình lồng nhau một cách trực quan và dễ dàng.

 

Các Mối Quan Hệ Trong Eloquent

Các Mối Quan Hệ Trong Eloquent

01.08.2024
Author: ADMIN

# Các Mối Quan Hệ Trong Eloquent

Eloquent cung cấp một hệ thống mạnh mẽ để quản lý các mối quan hệ giữa các mô hình trong cơ sở dữ liệu. Các mối quan hệ giúp bạn dễ dàng lấy dữ liệu liên quan từ các bảng khác nhau. Dưới đây là các loại mối quan hệ phổ biến trong Eloquent và cách sử dụng chúng:

1. Mối Quan Hệ Một-Một (One-to-One)

Một mối quan hệ một-một liên kết hai mô hình với nhau, với mỗi bản ghi trong bảng đầu tiên liên kết với một bản ghi trong bảng thứ hai.

Ví Dụ:

// Mô hình User
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

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

// Mô hình Profile
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Cấu Trúc Bảng:

  • users table: id, name
  • profiles table: id, user_id, bio

2. Mối Quan Hệ Một-Nhiều (One-to-Many)

Một mối quan hệ một-nhiều cho phép một bản ghi trong bảng đầu tiên liên kết với nhiều bản ghi trong bảng thứ hai.

Ví Dụ:

// Mô hình Post
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

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

// Mô hình Comment
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

Cấu Trúc Bảng:

  • posts table: id, title
  • comments table: id, post_id, content

3. Mối Quan Hệ Nhiều-Nhiều (Many-to-Many)

Mối quan hệ nhiều-nhiều cho phép nhiều bản ghi trong bảng đầu tiên liên kết với nhiều bản ghi trong bảng thứ hai thông qua bảng trung gian.

Ví Dụ:

// Mô hình Student
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    public function courses()
    {
        return $this->belongsToMany(Course::class);
    }
}

// Mô hình Course
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Course extends Model
{
    public function students()
    {
        return $this->belongsToMany(Student::class);
    }
}

Cấu Trúc Bảng:

  • students table: id, name
  • courses table: id, title
  • course_student table: student_id, course_id

4. Mối Quan Hệ Một-Một (Polymorphic)

Mối quan hệ polymorphic cho phép một mô hình liên kết với nhiều mô hình khác theo cách linh hoạt.

Ví Dụ:

// Mô hình Comment
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}

// Mô hình Post
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

// Mô hình Video
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

Cấu Trúc Bảng:

  • comments table: id, commentable_id, commentable_type, content
  • posts table: id, title
  • videos table: id, title

5. Mối Quan Hệ Một-Nhiều (Polymorphic)

 

Mối quan hệ một-nhiều polymorphic cho phép một mô hình liên kết với nhiều mô hình khác mà không cần phải tạo ra nhiều cột khóa ngoại. Điều này rất hữu ích khi bạn muốn một mô hình có thể liên kết với nhiều loại mô hình khác mà không cần tạo nhiều bảng trung gian.

Ví Dụ Cụ Thể

Giả sử bạn có một hệ thống mà người dùng có thể bình luận trên các bài viết (Post) và video (Video). Bạn có thể sử dụng mối quan hệ polymorphic để xử lý các bình luận mà không cần tạo bảng trung gian riêng cho mỗi loại mô hình.

Bước 1: Tạo Các Mô Hình và Cấu Trúc Bảng

  1. Tạo Model Comment
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Comment extends Model
    {
        /**
         * Thiết lập mối quan hệ polymorphic.
         */
        public function commentable()
        {
            return $this->morphTo();
        }
    }
    
  2. Tạo Model Post
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        /**
         * Thiết lập mối quan hệ một-nhiều polymorphic.
         */
        public function comments()
        {
            return $this->morphMany(Comment::class, 'commentable');
        }
    }
    
  3. Tạo Model Video
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Video extends Model
    {
        /**
         * Thiết lập mối quan hệ một-nhiều polymorphic.
         */
        public function comments()
        {
            return $this->morphMany(Comment::class, 'commentable');
        }
    }
    
  4. Tạo Cấu Trúc Bảng
    • Bảng comments

      Schema::create('comments', function (Blueprint $table) {
          $table->id();
          $table->text('content');
          $table->unsignedBigInteger('commentable_id');
          $table->string('commentable_type');
          $table->timestamps();
      });
      

       

      • commentable_id: ID của mô hình mà bình luận thuộc về.
      • commentable_type: Loại mô hình mà bình luận thuộc về (ví dụ: Post hoặc Video).
    • Bảng posts
      Schema::create('posts', function (Blueprint $table) {
          $table->id();
          $table->string('title');
          $table->timestamps();
      });
      
    • Bảng videos
      Schema::create('videos', function (Blueprint $table) {
          $table->id();
          $table->string('title');
          $table->timestamps();
      });
      

Bước 2: Sử Dụng Mối Quan Hệ

1. Thêm Bình Luận

use App\Models\Post;
use App\Models\Video;
use App\Models\Comment;

// Thêm bình luận cho một bài viết
$post = Post::find(1);
$post->comments()->create([
    'content' => 'Great post!',
]);

// Thêm bình luận cho một video
$video = Video::find(1);
$video->comments()->create([
    'content' => 'Amazing video!',
]);

2. Truy Xuất Bình Luận

// Truy xuất bình luận của một bài viết
$post = Post::find(1);
foreach ($post->comments as $comment) {
    echo $comment->content;
}

// Truy xuất bình luận của một video
$video = Video::find(1);
foreach ($video->comments as $comment) {
    echo $comment->content;
}

3. Lấy Mô Hình Từ Bình Luận

// Lấy mô hình mà bình luận thuộc về
$comment = Comment::find(1);
echo $comment->commentable_type; // Ví dụ: App\Models\Post hoặc App\Models\Video

6.Mối Quan Hệ Nhiều-Nhiều (Polymorphic)

Mối quan hệ nhiều-nhiều polymorphic cho phép một mô hình liên kết với nhiều mô hình khác và ngược lại thông qua một bảng trung gian duy nhất. Điều này cho phép mô hình liên kết với nhiều mô hình khác mà không cần phải tạo nhiều bảng trung gian riêng biệt.

Ví Dụ: Tagging trên Bài Viết và Video

Cấu Trúc và Mô Hình
  1. Tạo Mô Hình Tag

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Tag extends Model
    {
        /**
         * Thiết lập mối quan hệ nhiều-nhiều polymorphic.
         */
        public function taggable()
        {
            return $this->morphTo();
        }
    }
    
  2. Tạo Mô Hình Post
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        /**
         * Thiết lập mối quan hệ nhiều-nhiều polymorphic.
         */
        public function tags()
        {
            return $this->morphToMany(Tag::class, 'taggable');
        }
    }
    
  3. Tạo Mô Hình Video
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Video extends Model
    {
        /**
         * Thiết lập mối quan hệ nhiều-nhiều polymorphic.
         */
        public function tags()
        {
            return $this->morphToMany(Tag::class, 'taggable');
        }
    }
    
  4. Tạo Cấu Trúc Bảng
    Schema::create('tags', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
    
    Schema::create('taggables', function (Blueprint $table) {
        $table->unsignedBigInteger('tag_id');
        $table->unsignedBigInteger('taggable_id');
        $table->string('taggable_type');
        $table->timestamps();
    });
    
  5. Sử dụng
    // Thêm tag cho một bài viết
    $post = Post::find(1);
    $tag = Tag::find(1);
    $post->tags()->attach($tag);
    
    // Thêm tag cho một video
    $video = Video::find(1);
    $tag = Tag::find(2);
    $video->tags()->attach($tag);
    

Kết Luận

  • Một-Một (One-to-One): Liên kết mỗi bản ghi trong bảng đầu tiên với một bản ghi trong bảng thứ hai.
  • Một-Nhiều (One-to-Many): Liên kết một bản ghi trong bảng đầu tiên với nhiều bản ghi trong bảng thứ hai.
  • Nhiều-Nhiều (Many-to-Many): Liên kết nhiều bản ghi trong bảng đầu tiên với nhiều bản ghi trong bảng thứ hai thông qua bảng trung gian.
  • Polymorphic: Cho phép liên kết linh hoạt với nhiều mô hình khác.

Các mối quan hệ trong Eloquent giúp bạn dễ dàng quản lý và truy xuất dữ liệu liên quan trong ứng dụng của bạn, làm cho việc tương tác với cơ sở dữ liệu trở nên dễ dàng và trực quan hơn.

Auth Basics

Auth Basics

01.08.2024
Author: ADMIN

# Auth Basics

Laravel cung cấp một hệ thống xác thực mạnh mẽ và dễ sử dụng. Dưới đây là những bước cơ bản để thiết lập và sử dụng hệ thống xác thực trong Laravel.

Bước 1: Cài Đặt Laravel UI

Laravel UI là một package cho phép bạn cài đặt các scaffolding (bộ khung) cho xác thực, bao gồm cả giao diện Bootstrap, Vue, và React.

Đầu tiên, cài đặt Laravel UI:

composer require laravel/ui

Sau đó, bạn có thể tạo scaffolding cho xác thực:

php artisan ui bootstrap --auth

Lệnh này sẽ tạo các route, controller, view cần thiết cho hệ thống xác thực và cài đặt Bootstrap. Nếu bạn muốn sử dụng Vue hoặc React, bạn có thể thay bootstrap bằng vue hoặc react.

Tiếp theo, chạy lệnh để cài đặt các package npm và biên dịch các asset:

npm install
npm run dev

Bước 2: Chạy Migrations

Laravel UI sẽ tạo sẵn các migration cho bảng users. Bạn chỉ cần chạy lệnh migrate để tạo bảng trong database:

php artisan migrate

Bước 3: Routes

Laravel UI sẽ tự động tạo các route cần thiết cho hệ thống xác thực trong file routes/web.php:

Auth::routes();

Bạn có thể kiểm tra file này để xem các route mà Laravel đã tạo cho bạn, bao gồm login, register, logout, và password reset.

Bước 4: Middleware

Laravel cung cấp middleware để bảo vệ các route của bạn. Middleware này sẽ đảm bảo rằng chỉ có người dùng đã xác thực mới có thể truy cập các route được bảo vệ.

Ví dụ, bạn có thể bảo vệ một route bằng middleware auth như sau:

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home')->middleware('auth');

Bước 5: Views

Laravel UI sẽ tạo sẵn các view cho các trang login, register, và reset password trong thư mục resources/views/auth.

1. Login với $user

Khi bạn cần thiết lập một người dùng hiện tại làm người dùng đã xác thực, bạn có thể truyền instance của người dùng đó vào phương thức login của Facade Auth. Người dùng này phải là một implementation của interface Illuminate\Contracts\Auth\Authenticatable. Mô hình App\Models\User được bao gồm trong Laravel đã triển khai sẵn interface này. Phương pháp này hữu ích khi bạn đã có một instance người dùng hợp lệ, chẳng hạn như ngay sau khi người dùng đăng ký với ứng dụng của bạn.

use Illuminate\Support\Facades\Auth;

$user = User::find(1); // Giả sử bạn đã có instance của người dùng
Auth::login($user);

Ghi Nhớ Đăng Nhập Người Dùng

Auth::login($user, $remember = true);

Sử Dụng Guard

Nếu cần, bạn có thể chỉ định một guard xác thực trước khi gọi phương thức login:

Auth::guard('admin')->login($user);

Ngoài ra, bạn có thể tham khảo thêm về loginUsingId

2. Lấy id user đã đăng nhập

Auth::user()->id;
// or
Auth::id();

3. Extra Password Confirmation

Laravel cung cấp một tính năng gọi là "Extra Password Confirmation" (Xác nhận mật khẩu bổ sung), yêu cầu người dùng nhập lại mật khẩu của họ để xác nhận danh tính trước khi thực hiện các hành động nhạy cảm như thay đổi email, mật khẩu hoặc xóa tài khoản.

Thiết lập Extra Password Confirmation

Laravel đi kèm với các route và controller cần thiết để quản lý việc xác nhận mật khẩu bổ sung. Bạn có thể sử dụng PasswordConfirmationMiddleware để bảo vệ các route cần xác nhận mật khẩu bổ sung.

Sử Dụng Middleware

Đầu tiên, bạn cần bảo vệ các route nhạy cảm của mình bằng middleware password.confirm. Middleware này sẽ kiểm tra xem người dùng đã xác nhận mật khẩu của họ trong một khoảng thời gian nhất định (mặc định là 3 giờ).

Định Nghĩa Route

Trong file routes/web.php, bạn có thể thêm middleware password.confirm cho các route nhạy cảm của mình:

Route::get('/settings', [SettingsController::class, 'index'])->name('settings');

Route::get('/settings/security', [SettingsController::class, 'security'])->middleware(['auth', 'password.confirm'])->name('settings.security');

Trong ví dụ trên, route /settings/security sẽ yêu cầu người dùng xác nhận mật khẩu của họ trước khi truy cập.

Tạo Controller cho Xác Nhận Mật Khẩu

Laravel đã cung cấp sẵn controller và route cho việc xác nhận mật khẩu. Bạn có thể kiểm tra hoặc tùy chỉnh theo nhu cầu.

File: app/Http/Controllers/Auth/ConfirmPasswordController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ConfirmPasswordController extends Controller
{
    /**
     * Hiển thị form xác nhận mật khẩu.
     *
     * @return \Illuminate\View\View
     */
    public function showConfirmForm()
    {
        return view('auth.passwords.confirm');
    }

    /**
     * Xác nhận mật khẩu của người dùng.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function confirm(Request $request)
    {
        $request->validate([
            'password' => 'required|password',
        ]);

        $request->session()->put('auth.password_confirmed_at', time());

        return redirect()->intended();
    }
}

View cho Form Xác Nhận Mật Khẩu

Tạo một file view để hiển thị form xác nhận mật khẩu. Laravel có sẵn file confirm.blade.php cho form xác nhận mật khẩu trong thư mục resources/views/auth/passwords.

File: resources/views/auth/passwords/confirm.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Confirm Password') }}</div>

                <div class="card-body">
                    {{ __('Please confirm your password before continuing.') }}

                    <form method="POST" action="{{ route('password.confirm') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Confirm Password') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Route Cho Xác Nhận Mật Khẩu

Laravel đã định nghĩa sẵn route cho xác nhận mật khẩu. Bạn có thể tìm thấy route này trong file routes/web.php:

Route::get('password/confirm', [ConfirmPasswordController::class, 'showConfirmForm'])->name('password.confirm');
Route::post('password/confirm', [ConfirmPasswordController::class, 'confirm']);

4. Fortify Password Rules

Laravel Fortify cung cấp một cách dễ dàng để tùy chỉnh quy tắc mật khẩu cho ứng dụng của bạn. Bạn có thể định nghĩa các quy tắc mật khẩu tùy chỉnh thông qua lớp Password.

Thiết Lập Các Quy Tắc Mật Khẩu

Laravel Fortify cung cấp lớp Password để bạn có thể định nghĩa các quy tắc mật khẩu một cách linh hoạt. Bạn có thể tùy chỉnh các quy tắc này trong phương thức boot của FortifyServiceProvider.

Cấu Hình Mặc Định

Trong FortifyServiceProvider, bạn có thể định nghĩa các quy tắc mật khẩu mặc định như sau:

File: app/Providers/FortifyServiceProvider.php

<?php

namespace App\Providers;

use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use App\Actions\Fortify\UpdateUserProfileInformation;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Fortify;
use Illuminate\Validation\Rules\Password;

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Fortify::createUsersUsing(CreateNewUser::class);
        Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
        Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
        Fortify::resetUserPasswordsUsing(ResetUserPassword::class);

        // Cấu hình các quy tắc mật khẩu
        Password::defaults(function () {
            return Password::min(8)
                            ->mixedCase()
                            ->letters()
                            ->numbers()
                            ->symbols()
                            ->uncompromised();
        });
    }
}

Trong đoạn mã trên, các quy tắc mật khẩu được thiết lập như sau:

  • min(8): Mật khẩu phải có ít nhất 8 ký tự.
  • mixedCase(): Mật khẩu phải có cả chữ hoa và chữ thường.
  • letters(): Mật khẩu phải có ít nhất một chữ cái.
  • numbers(): Mật khẩu phải có ít nhất một chữ số.
  • symbols(): Mật khẩu phải có ít nhất một ký tự đặc biệt.
  • uncompromised(): Mật khẩu không được nằm trong danh sách các mật khẩu đã bị lộ.

 

 

Blade Components

Blade Components

01.08.2024
Author: ADMIN

# Blade Components

Laravel Blade Components cung cấp một cách tiện lợi để xây dựng các phần tử HTML tái sử dụng, giúp bạn tổ chức mã nguồn một cách rõ ràng và hiệu quả hơn. Blade Components cho phép bạn tách biệt logic và giao diện, giúp việc phát triển và bảo trì ứng dụng trở nên dễ dàng hơn.

1. Tạo Blade Components

Tạo Component Bằng Lệnh Artisan

Bạn có thể sử dụng lệnh Artisan để tạo một component:

php artisan make:component Alert

Lệnh này sẽ tạo hai file:

  • Một class component tại app/View/Components/Alert.php
  • Một view Blade tại resources/views/components/alert.blade.php

File Class Component

File: app/View/Components/Alert.php

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public $type;

    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct($type)
    {
        $this->type = $type;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

File View Component

File: resources/views/components/alert.blade.php

<div class="alert alert-{{ $type }}">
    {{ $slot }}
</div>

2. Sử Dụng Blade Components

Nhúng Component Trong View

Bạn có thể nhúng component trong view Blade bằng cú pháp <x-component-name>:

File: resources/views/welcome.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Welcome</title>
</head>
<body>
    <x-alert type="success">
        This is a success alert.
    </x-alert>

    <x-alert type="danger">
        This is a danger alert.
    </x-alert>
</body>
</html>

3. Truyền Dữ Liệu Cho Component

Bạn có thể truyền dữ liệu cho component thông qua các thuộc tính:

File: app/View/Components/Alert.php

public $type;

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

File: resources/views/components/alert.blade.php

<div class="alert alert-{{ $type }}">
    {{ $slot }}
</div>

File: resources/views/welcome.blade.php

<x-alert type="success">
    This is a success alert.
</x-alert>

<x-alert type="danger">
    This is a danger alert.
</x-alert>

4. Slots

Slots cho phép bạn xác định các phần nội dung động trong component. Mặc định, tất cả nội dung được truyền vào component sẽ nằm trong biến $slot.

Slots Mặc Định

File: resources/views/components/alert.blade.php

<div class="alert alert-{{ $type }}">
    {{ $slot }}
</div>

File: resources/views/welcome.blade.php

<x-alert type="success">
    This is a success alert.
</x-alert>

Named Slots

Bạn có thể tạo nhiều slots với tên khác nhau.

File: resources/views/components/alert.blade.php

<div class="alert alert-{{ $type }}">
    <div class="alert-title">{{ $title }}</div>
    {{ $slot }}
</div>

File: resources/views/welcome.blade.php

<x-alert type="success">
    <x-slot name="title">
        Success
    </x-slot>
    This is a success alert.
</x-alert>

5. Inline Components

Nếu component của bạn đơn giản và không yêu cầu logic phức tạp, bạn có thể sử dụng Inline Components mà không cần tạo file class riêng.

File: resources/views/components/button.blade.php

<button {{ $attributes->merge(['class' => 'btn btn-primary']) }}>
    {{ $slot }}
</button>

File: resources/views/welcome.blade.php

<x-button>
    Click Me
</x-button>

Tóm Tắt

  • Tạo Component: Sử dụng lệnh Artisan để tạo component.
  • Nhúng Component: Sử dụng cú pháp <x-component-name> để nhúng component trong view.
  • Truyền Dữ Liệu: Truyền dữ liệu cho component thông qua các thuộc tính.
  • Slots: Sử dụng slots để xác định nội dung động trong component.
  • Inline Components: Sử dụng Inline Components cho các component đơn giản.

Blade Components giúp mã nguồn của bạn trở nên sạch sẽ, dễ đọc và dễ bảo trì hơn. Việc tách biệt giao diện và logic giúp bạn tập trung vào từng khía cạnh riêng biệt của ứng dụng, làm cho quá trình phát triển trở nên hiệu quả hơn.

Layout: @include, @extends, @section, @yield

Layout: @include, @extends, @section, @yield

01.08.2024
Author: ADMIN

# @include, @extends, @section, và @yield

Laravel Blade cung cấp các từ khóa @include, @extends, @section, và @yield để giúp bạn tái sử dụng và tổ chức mã HTML một cách hiệu quả. Dưới đây là cách sử dụng từng từ khóa này với các ví dụ cụ thể.

@include

@include cho phép bạn nhúng một view Blade khác vào trong view hiện tại. Đây là cách tuyệt vời để tái sử dụng các phần tử HTML như header, footer, hoặc sidebar.

Ví Dụ

Giả sử bạn có một view header.blade.php:

<!-- resources/views/header.blade.php -->
<header>
    <h1>My Website Header</h1>
</header>

Bạn có thể nhúng view này vào view chính của bạn như sau:

<!-- resources/views/welcome.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Welcome</title>
</head>
<body>
    @include('header')
    <div class="content">
        <p>Welcome to the homepage!</p>
    </div>
</body>
</html>

@extends

@extends được sử dụng để chỉ định layout mà view hiện tại sẽ kế thừa. Layout này thường chứa các cấu trúc HTML cơ bản mà các view khác có thể sử dụng lại.

Ví Dụ

Giả sử bạn có một layout app.blade.php:

<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
</head>
<body>
    @include('header')
    <div class="content">
        @yield('content')
    </div>
    @include('footer')
</body>
</html>

Trong view cụ thể của bạn, bạn có thể kế thừa layout này như sau:

<!-- resources/views/home.blade.php -->
@extends('layouts.app')

@section('title', 'Home Page')

@section('content')
    <h2>Welcome to the Home Page</h2>
    <p>This is the home page content.</p>
@endsection

@section và @yield

@section được sử dụng để xác định nội dung mà view con sẽ cung cấp cho các vùng nội dung được định nghĩa trong layout bằng @yield.

Ví Dụ

Trong layout app.blade.php, bạn có thể có các vùng nội dung:

<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
</head>
<body>
    @include('header')
    <div class="content">
        @yield('content')
    </div>
    @include('footer')
</body>
</html>

Trong view con home.blade.php, bạn có thể định nghĩa các phần nội dung cho các vùng đó:

<!-- resources/views/home.blade.php -->
@extends('layouts.app')

@section('title', 'Home Page')

@section('content')
    <h2>Welcome to the Home Page</h2>
    <p>This is the home page content.</p>
@endsection

Tóm Tắt

  • @include: Nhúng một view Blade khác vào view hiện tại.
  • @extends: Kế thừa layout từ một view khác.
  • @section: Định nghĩa một phần nội dung trong view con.
  • @yield: Đánh dấu vị trí mà nội dung của view con sẽ được chèn vào trong layout.

Việc sử dụng @include, @extends, @section, và @yield giúp bạn tổ chức mã nguồn của mình một cách rõ ràng và tái sử dụng được các phần tử giao diện, làm cho việc phát triển và bảo trì ứng dụng trở nên dễ dàng hơn.