Laravel: Bắt đầu


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Giới thiệu

Laravel tích hợp Eloquent, một trình ánh xạ quan hệ đối tượng (ORM) làm cho việc tương tác với cơ sở dữ liệu của bạn trở nên thú vị hơn. Khi sử dụng Eloquent, mỗi bảng cơ sở dữ liệu sẽ có một "Model" tương ứng được sử dụng để tương tác với bảng đó. Ngoài việc truy xuất các bản ghi từ bảng cơ sở dữ liệu, Eloquent cho phép bạn chèn, cập nhật và xóa các bản ghi khỏi bảng.

Trước khi bắt đầu, hãy đảm bảo định cấu hình kết nối cơ sở dữ liệu trong config/database.phptệp cấu hình ứng dụng của bạn . Để biết thêm thông tin về cách định cấu hình cơ sở dữ liệu của bạn, hãy xem tài liệu cấu hình cơ sở dữ liệu.

Tạo lớp Model

Để bắt đầu, hãy tạo một model Eloquent. Model thường nằm trong thư mục app\Models và mở rộng từ lớp Illuminate\Database\Eloquent\Model. Bạn có thể sử dụng lệnh Artisan make:model để tạo một model mới.

Ví dụ:

php artisan make:model Flight

Nếu bạn muốn tạo database migration khi tạo model, bạn có thể sử dụng tùy chọn --migration hoặc -m.

Ví dụ:

php artisan make:model Flight --migration

Bạn có thể tạo nhiều loại lớp khác nhau khi tạo model, chẳng hạn như factory, seeder hay controller. Ngoài ra, các tùy chọn này có thể được kết hợp để tạo nhiều lớp cùng một lúc.

Ví dụ:

# tạo model và lớp FlightFactory
php artisan make:model Flight --factory
php artisan make:model Flight -f

# tạo model và lớp FlightSeeder
php artisan make:model Flight --seed
php artisan make:model Flight -s

# tạo model và lớp FlightController
php artisan make:model Flight --controller
php artisan make:model Flight -c

# tạo model và các migration, factory, seeder, controller
php artisan make:model Flight -mfsc

Quy ước về model Eloquent

Model được tạo bằng lệnh make:model sẽ được đặt trong thư mục app/Models. Hãy xét một lớp model cơ bản sau đây:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    //
}

Tên bảng

Ở ví dụ trên, bạn có thể nhận thấy rằng ta đã không cho Eloquent biết bảng cơ sở dữ liệu nào tương ứng với model Flight của ta. Theo quy ước thì tên số nhiều của lớp sẽ được sử dụng làm tên bảng trừ khi một tên khác ta chỉ định. Vì vậy, trong trường hợp này, Eloquent sẽ giả sử model Flight lưu trữ các bản ghi trong bảng flights, còn model AirTrafficController chẳng hạn sẽ lưu trữ các bản ghi trong bảng air_traffic_controllers.

Nếu bảng tương ứng của model không phù hợp với quy ước này, thì ta có thể chỉ định tên bảng của model theo cách thủ công bằng cách tạo thuộc tính $table trên model.

Ví dụ:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected $table = 'my_flights';
}

Khóa chính (Primary Key - PK)

Eloquent cũng sẽ giả định rằng bảng cơ sở dữ liệu tương ứng của mỗi model có một cột khóa chính được đặt tên id. Nếu cần, bạn có thể tạo thuộc tính protected $primaryKey model để chỉ định một cột khác đóng vai trò là khóa chính của model.

Ví dụ:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected $primaryKey = 'flight_id';
}

Ngoài ra, Eloquent giả định rằng khóa chính là một giá trị số nguyên tăng dần, có nghĩa là Eloquent sẽ tự động chuyển giá trị khóa chính thành một số nguyên. Nếu bạn muốn sử dụng khóa chính không tăng hoặc không phải số, bạn phải tạo thuộc tính public $incrementing và đặt giá trị thành false.

Ví dụ:

<?php

class Flight extends Model
{
    public $incrementing = false;
}

Nếu khóa chính của model không phải là số nguyên, bạn cần đặt thuộc tính protected $keyType thành string.

Ví dụ:

<?php

class Flight extends Model
{
    protected $keyType = 'string';
}

Khóa chính đặt trên nhiều cột

Eloquent yêu cầu mỗi model phải có ít nhất một "ID" nhận dạng duy nhất có thể dùng làm khóa chính. Nếu khóa chính đặt trên nhiều cột thì sẽ không được Eloquent hỗ trợ. Tuy nhiên, bạn có thể tự do thêm vào bảng các chỉ mục duy nhất trên nhiều cột.

Timestamps

Theo mặc định thì Eloquent mong muốn có các cột created_at và updated_at ở trong bảng. Eloquent sẽ tự động đặt các giá trị cho các cột này khi model được tạo hoặc cập nhật. Nếu bạn không muốn các cột này được quản lý tự động bởi Eloquent, thì bạn nên đặt thuộc tính $timestamps thành false.

Ví dụ:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    public $timestamps = false;
}

Nếu bạn cần tùy chỉnh định dạng timestamps thì bạn hãy đặt giá trị cho thuộc tính $dateFormat. Thuộc tính này sẽ xác định cách các thuộc tính ngày tháng được lưu trữ trong cơ sở dữ liệu cũng như định dạng của chúng khi model được tuần tự hóa thành một mảng hoặc JSON:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected $dateFormat = 'U';
}

Nếu bạn cần tùy chỉnh tên của các cột được sử dụng để lưu trữ dấu thời gian, thì bạn có thể định nghĩa các hằng CREATED_AT và UPDATED_AT trên model như sau:

<?php

class Flight extends Model
{
    const CREATED_AT = 'creation_date';
    const UPDATED_AT = 'updated_date';
}

Kết nối cơ sở dữ liệu

Theo mặc định, tất cả các model Eloquent sẽ sử dụng kết nối cơ sở dữ liệu mặc định được cấu hình cho ứng dụng của bạn. Nếu bạn muốn chỉ định một kết nối khác sẽ được sử dụng khi tương tác với một model cụ thể thì bạn định nghĩa thuộc tính $connection như sau:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected $connection = 'sqlite';
}

Giá trị thuộc tính mặc định

Theo mặc định thì khi một model mới được tạo sẽ không chứa bất kỳ giá trị thuộc tính nào. Nếu bạn muốn tạo các giá trị mặc định cho một số thuộc tính của model thì bạn có thể sử dụng thuộc tính $attributes như sau:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    protected $attributes = [
        'delayed' => false,
    ];
}

Truy xuất model

Khi bạn đã tạo được model thì bạn có thể bắt đầu truy xuất dữ liệu từ cơ sở dữ liệu. Bạn có thể coi mỗi model Eloquent như là một trình tạo truy vấn (query builder) cho phép bạn truy vấn các bảng cơ sở dữ liệu được liên kết với model. Phương thức all của model sẽ truy xuất tất cả các bản ghi từ bảng cơ sở dữ liệu liên quan.

Ví dụ:

use App\Models\Flight;

foreach (Flight::all() as $flight) {
    echo $flight->name;
}

Xây dựng các truy vấn

Phương thức Eloquent all sẽ trả về tất cả các kết quả trong bảng của model. Tuy nhiên, vì mỗi model Eloquent đóng vai trò như một query builder, nên bạn có thể thêm các ràng buộc bổ sung vào các truy vấn và sau đó gọi phương thức get để truy xuất kết quả.

Ví dụ:

$flights = Flight::where('active', 1)
               ->orderBy('name')
               ->take(10)
               ->get();

Vì model Eloquent là trình tạo truy vấn (query builder), nên bạn nên xem lại tất cả các phương thức được cung cấp bởi trình tạo truy vấn của Laravel. Bạn có thể sử dụng bất kỳ phương thức nào trong số những phương thức này khi viết các truy vấn Eloquent.

Làm mới model

Bạn có thể làm mới model bằng cách sử dụng các phương thức fresh và refresh. Phương thức fresh truy xuất lại model từ cơ sở dữ liệu.

Ví dụ:

$flight = Flight::where('number', 'FR 900')->first();

$freshFlight = $flight->fresh();

Phương thức refresh sẽ làm mới lại model. Ngoài ra, tất cả các quan hệ đã tải của nó cũng sẽ được làm mới.

Ví dụ:

$flight = Flight::where('number', 'FR 900')->first();

$flight->number = 'FR 456';

$flight->refresh();

$flight->number; // "FR 900"

Collection

Các phương thức Eloquent như allvà get truy xuất nhiều bản ghi từ cơ sở dữ liệu. Tuy nhiên, các phương thức này không trả về một mảng PHP thuần túy. Thay vào đó, các phương thức này sẽ trả về một thể hiện của lớp Illuminate\Database\Eloquent\Collection.

Lớp Collection mở rộng từ lớp cơ sở Illuminate\Support\Collection, lớp này cung cấp nhiều phương thức hữu ích để tương tác với dữ liệu.

Ví dụ như phương thức reject có thể được sử dụng để xóa các model khỏi collection dựa trên kết quả của một lần gọi:

$flights = Flight::where('destination', 'Paris')->get();

$flights = $flights->reject(function ($flight) {
    return $flight->cancelled;
});

Ngoài ra, lớp Eloquent Collection còn cung cấp một số phương thức bổ sung dành riêng cho việc tương tác với các model Eloquent.

Vì tất cả các bộ sưu tập của Laravel đều triển khai các giao diện có thể lặp lại của PHP, nên bạn có thể lặp lại các bộ sưu tập như thể chúng là một mảng.

Ví dụ:

foreach ($flights as $flight) {
    echo $flight->name;
}

 

Phương thức chunk và chunkById

Ứng dụng của bạn có thể hết bộ nhớ nếu bạn cố gắng tải hàng chục nghìn bản ghi Eloquent thông qua các phương thức all hoặc get. Vì vậy, thay vì sử dụng các phương thức này thì bạn có thể sử dụng phương thức chunk để xử lý số lượng lớn các model được hiệu quả hơn.

Phương thức chunk sẽ lấy một tập hợp con của các model rồi truyền chúng tới closure (bao đóng - hàm) để xử lý. Vì chỉ một phần hiện tại của các model Eloquent được truy xuất tại một thời điểm, nên phương thức chunk sẽ giảm đáng kể mức sử dụng bộ nhớ khi làm việc với một số lượng lớn các model.

Ví dụ:

use App\Models\Flight;

Flight::chunk(200, function ($flights) {
    foreach ($flights as $flight) {
        //
    }
});

Đối số đầu tiên được truyền cho chunk là số lượng bản ghi bạn muốn nhận trên mỗi "đoạn". Bao đóng sẽ được gọi cho mỗi đoạn được truy xuất từ ​​cơ sở dữ liệu. Một truy vấn cơ sở dữ liệu sẽ được thực hiện để truy xuất từng đoạn bản ghi được chuyển đến bao đóng.

Nếu bạn đang lọc các kết quả của phương thức chunk dựa trên một cột mà bạn cũng sẽ cập nhật trong khi lặp lại các kết quả, thì bạn nên sử dụng phương thức chunkById bởi vì nếu sử dụng chunk trong tình huống này có thể dẫn đến kết quả không mong muốn và không nhất quán.

Phương thức chunkById sẽ luôn truy xuất model có cột id lớn hơn model cuối cùng trong đoạn trước:

Flight::where('departed', true)
        ->chunkById(200, function ($flights) {
            $flights->each->update(['departed' => false]);
        }, $column = 'id');

Phương thức cursor

Tương tự như phương thức chunk, phương thức cursor có thể được sử dụng để giảm đáng kể mức tiêu thụ bộ nhớ của ứng dụng khi lấy được hàng chục nghìn bản ghi.

cursor sẽ chỉ thực hiện một truy vấn cơ sở dữ liệu duy nhất; tuy nhiên, các model Eloquent riêng lẻ sẽ không bị phân rã cho đến khi chúng thực sự được lặp lại. Do đó, chỉ có một model Eloquent được lưu trong bộ nhớ tại bất kỳ thời điểm nào trong khi lặp qua con trỏ. cursor sử dụng trình tạo PHP để triển khai chức năng này:

use App\Models\Flight;

foreach (Flight::where('destination', 'Zurich')->cursor() as $flight) {
    //
}

cursor sẽ trả về một thể hiện Illuminate\Support\LazyCollectionLazyCollection cho phép bạn sử dụng nhiều phương thức có sẵn trong khi chỉ tải một model duy nhất vào bộ nhớ tại một thời điểm.

Ví dụ:

use App\Models\User;

$users = User::cursor()->filter(function ($user) {
    return $user->id > 500;
});

foreach ($users as $user) {
    echo $user->id;
}

zzzTruy vấn con nâng cao

Lựa chọn truy vấn con

Eloquent cũng cung cấp hỗ trợ truy vấn con nâng cao, cho phép bạn lấy thông tin từ các bảng liên quan trong một truy vấn duy nhất. Ví dụ, hãy tưởng tượng rằng chúng ta có một bảng các chuyến bay destinationsvà một bảng các flightsđiểm đến. Các flightsbảng chứa một arrived_atcột mà chỉ khi chuyến bay đến địa điểm đến.

Sử dụng chức năng truy vấn phụ có sẵn cho phương thức selectvà trình tạo truy vấn addSelect, chúng tôi có thể chọn tất cả destinationsvà tên của chuyến bay đã đến điểm đến đó gần đây nhất bằng cách sử dụng một truy vấn:

use App\Models\Destination;
use App\Models\Flight;

return Destination::addSelect(['last_flight' => Flight::select('name')
    ->whereColumn('destination_id', 'destinations.id')
    ->orderByDesc('arrived_at')
    ->limit(1)
])->get();

 

Đặt hàng truy vấn con

Ngoài ra, orderBychức năng của trình tạo truy vấn hỗ trợ các truy vấn con. Tiếp tục sử dụng ví dụ về chuyến bay của chúng tôi, chúng tôi có thể sử dụng chức năng này để sắp xếp tất cả các điểm đến dựa trên thời điểm chuyến bay cuối cùng đến điểm đến đó. Một lần nữa, điều này có thể được thực hiện trong khi thực hiện một truy vấn cơ sở dữ liệu duy nhất:

return Destination::orderByDesc(
    Flight::select('arrived_at')
        ->whereColumn('destination_id', 'destinations.id')
        ->orderByDesc('arrived_at')
        ->limit(1)
)->get();

 

Truy xuất Mô hình Đơn lẻ / Tổng hợp

Ngoài lấy tất cả các hồ sơ phù hợp với một truy vấn cụ thể, bạn cũng có thể lấy hồ sơ đơn sử dụng findfirsthoặc firstWherephương pháp. Thay vì trả về một tập hợp các mô hình, các phương thức này trả về một cá thể mô hình duy nhất:

use App\Models\Flight;

// Retrieve a model by its primary key...
$flight = Flight::find(1);

// Retrieve the first model matching the query constraints...
$flight = Flight::where('active', 1)->first();

// Alternative to retrieving the first model matching the query constraints...
$flight = Flight::firstWhere('active', 1);

Đôi khi bạn có thể muốn lấy kết quả đầu tiên của một truy vấn hoặc thực hiện một số hành động khác nếu không tìm thấy kết quả nào. Các firstOrphương pháp sẽ trả lại kết quả phù hợp đầu tiên truy vấn hoặc, nếu không có kết quả được tìm thấy, thực hiện việc đóng cửa nhất định. Giá trị được trả về bởi bao đóng sẽ được coi là kết quả của firstOrphương thức:

$model = Flight::where('legs', '>', 3)->firstOr(function () {
    // ...
});

 

Không tìm thấy ngoại lệ

Đôi khi bạn có thể muốn đưa ra một ngoại lệ nếu không tìm thấy một mô hình. Điều này đặc biệt hữu ích trong các tuyến đường hoặc bộ điều khiển. Các phương thức findOrFailvà firstOrFailsẽ truy xuất kết quả đầu tiên của truy vấn; tuy nhiên, nếu không tìm thấy kết quả nào, một Illuminate\Database\Eloquent\ModelNotFoundExceptionsẽ được ném ra:

$flight = Flight::findOrFail(1);

$flight = Flight::where('legs', '>', 3)->firstOrFail();

Nếu ModelNotFoundExceptionkhông bắt được, một phản hồi HTTP 404 sẽ tự động được gửi lại cho máy khách:

use App\Models\Flight;

Route::get('/api/flights/{id}', function ($id) {
    return Flight::findOrFail($id);
});

 

Lấy hoặc tạo mô hình

Các firstOrCreatephương pháp sẽ cố gắng xác định vị trí một kỷ lục cơ sở dữ liệu bằng cách sử dụng cặp cột / giá trị nhất định. Nếu không thể tìm thấy mô hình trong cơ sở dữ liệu, một bản ghi sẽ được chèn với các thuộc tính do hợp nhất đối số mảng đầu tiên với đối số mảng thứ hai tùy chọn:

Các firstOrNewphương pháp, như firstOrCreate, sẽ cố gắng xác định vị trí một kỷ lục trong cơ sở dữ liệu phù hợp với các thuộc tính nhất định. Tuy nhiên, nếu một mô hình không được tìm thấy, một phiên bản mô hình mới sẽ được trả về. Lưu ý rằng mô hình được trả về firstOrNewvẫn chưa được lưu vào cơ sở dữ liệu. Bạn sẽ cần phải gọi savephương thức theo cách thủ công để duy trì nó:

use App\Models\Flight;

// Retrieve flight by name or create it if it doesn't exist...
$flight = Flight::firstOrCreate([
    'name' => 'London to Paris'
]);

// Retrieve flight by name or create it with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrCreate(
    ['name' => 'London to Paris'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

// Retrieve flight by name or instantiate a new Flight instance...
$flight = Flight::firstOrNew([
    'name' => 'London to Paris'
]);

// Retrieve flight by name or instantiate with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrNew(
    ['name' => 'Tokyo to Sydney'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

 

Lấy tổng hợp

Khi tương tác với các mô hình hùng hồn, bạn cũng có thể sử dụng countsummax, và các phương pháp tổng hợp được cung cấp bởi các Laravel xây dựng truy vấn . Như bạn có thể mong đợi, các phương thức này trả về một giá trị vô hướng thay vì một phiên bản mô hình Eloquent:

$count = Flight::where('active', 1)->count();

$max = Flight::where('active', 1)->max('price');

 

Chèn & Cập nhật Mô hình

 

Chèn

Tất nhiên, khi sử dụng Eloquent, chúng ta không chỉ cần lấy các mô hình từ cơ sở dữ liệu. Chúng tôi cũng cần phải chèn các bản ghi mới. Rất may, Eloquent làm cho nó trở nên đơn giản. Để chèn một bản ghi mới vào cơ sở dữ liệu, bạn nên khởi tạo một phiên bản mô hình mới và thiết lập các thuộc tính trên mô hình. Sau đó, gọi savephương thức trên cá thể mô hình:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Flight;
use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * Store a new flight in the database.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // Validate the request...

        $flight = new Flight;

        $flight->name = $request->name;

        $flight->save();
    }
}

Trong ví dụ này, chúng tôi gán nametrường từ yêu cầu HTTP đến cho namethuộc tính của App\Models\Flightcá thể mô hình. Khi chúng ta gọi savephương thức, một bản ghi sẽ được chèn vào cơ sở dữ liệu. Dấu thời gian created_atvà của mô hình updated_atsẽ tự động được đặt khi savephương thức được gọi, vì vậy không cần đặt chúng theo cách thủ công.

Ngoài ra, bạn có thể sử dụng createphương pháp này để "lưu" một mô hình mới bằng cách sử dụng một câu lệnh PHP. Phiên bản mô hình được chèn sẽ được trả lại cho bạn theo createphương thức:

use App\Models\Flight;

$flight = Flight::create([
    'name' => 'London to Paris',
]);

Tuy nhiên, trước khi sử dụng createphương thức, bạn sẽ cần chỉ định một fillablehoặc thuộc guardedtính trên lớp mô hình của mình. Các thuộc tính này là bắt buộc vì tất cả các mô hình Eloquent được bảo vệ khỏi các lỗ hổng phân công hàng loạt theo mặc định. Để tìm hiểu thêm về bài tập khối lượng, mời các bạn tham khảo tài liệu bài tập khối lượng lớn .

 

Cập nhật

Các savephương pháp cũng có thể được sử dụng để mô hình cập nhật đã tồn tại trong cơ sở dữ liệu. Để cập nhật một mô hình, bạn nên truy xuất mô hình đó và đặt bất kỳ thuộc tính nào bạn muốn cập nhật. Sau đó, bạn nên gọi savephương thức của mô hình . Một lần nữa, updated_atdấu thời gian sẽ tự động được cập nhật, vì vậy không cần phải đặt giá trị của nó theo cách thủ công:

use App\Models\Flight;

$flight = Flight::find(1);

$flight->name = 'Paris to London';

$flight->save();

 

Cập nhật hàng loạt

Cập nhật cũng có thể được thực hiện đối với các mô hình phù hợp với một truy vấn nhất định. Trong ví dụ này, tất cả các chuyến bay được activevà có một destinationsố San Diegosẽ được đánh dấu là bị trì hoãn:

Flight::where('active', 1)
      ->where('destination', 'San Diego')
      ->update(['delayed' => 1]);

Các updatephương pháp dự đoán một mảng của các cặp cột và giá trị đại diện cho các cột cần được cập nhật.

 

Khi phát hành một bản cập nhật hàng loạt qua hùng hồn, những savingsavedupdating, và updatedcác sự kiện mô hình sẽ không được sa thải vì các mô hình được cập nhật. Điều này là do các mô hình không bao giờ thực sự được truy xuất khi phát hành một bản cập nhật hàng loạt.

 

 

Kiểm tra các thay đổi thuộc tính

Hùng hồn cung cấp isDirtyisCleanvà wasChangedcác phương pháp để kiểm tra trạng thái nội tại của mô hình của bạn và xác định cách thuộc tính của nó đã thay đổi từ khi mô hình được lấy ra ban đầu.

Các isDirtyphương pháp xác định nếu có các thuộc tính của mô hình đã được thay đổi kể từ khi mô hình đã được lấy ra. Bạn có thể chuyển một tên thuộc tính cụ thể cho isDirtyphương thức để xác định xem một thuộc tính cụ thể có bị bẩn hay không. Điều isCleannày sẽ xác định xem một thuộc tính vẫn không thay đổi kể từ khi mô hình được truy xuất. Phương thức này cũng chấp nhận một đối số thuộc tính tùy chọn:

use App\Models\User;

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false

$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true

$user->save();

$user->isDirty(); // false
$user->isClean(); // true

Các wasChangedphương pháp xác định nếu có các thuộc tính đã được thay đổi khi mô hình được lưu cuối cùng trong chu kỳ yêu cầu hiện tại. Nếu cần, bạn có thể chuyển một tên thuộc tính để xem liệu một thuộc tính cụ thể có bị thay đổi hay không:

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->save();

$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged('first_name'); // false

Các getOriginalphương thức trả về một mảng chứa các thuộc tính ban đầu của mô hình không phụ thuộc bất kỳ thay đổi mô hình vì nó đã được lấy ra. Nếu cần, bạn có thể chuyển một tên thuộc tính cụ thể để nhận giá trị ban đầu của một thuộc tính cụ thể:

$user = User::find(1);

$user->name; // John
$user->email; // john@example.com

$user->name = "Jack";
$user->name; // Jack

$user->getOriginal('name'); // John
$user->getOriginal(); // Array of original attributes...

 

Phân công hàng loạt

Bạn có thể sử dụng createphương pháp này để "lưu" một mô hình mới bằng cách sử dụng một câu lệnh PHP. Phiên bản mô hình được chèn sẽ được trả lại cho bạn theo phương thức:

use App\Models\Flight;

$flight = Flight::create([
    'name' => 'London to Paris',
]);

Tuy nhiên, trước khi sử dụng createphương thức, bạn sẽ cần chỉ định một fillablehoặc thuộc guardedtính trên lớp mô hình của mình. Các thuộc tính này là bắt buộc vì tất cả các mô hình Eloquent được bảo vệ khỏi các lỗ hổng phân công hàng loạt theo mặc định.

Lỗ hổng phân công hàng loạt xảy ra khi người dùng chuyển một trường yêu cầu HTTP không mong muốn và trường đó thay đổi một cột trong cơ sở dữ liệu của bạn mà bạn không mong đợi. Ví dụ: một người dùng độc hại có thể gửi một is_admintham số thông qua một yêu cầu HTTP, sau đó được chuyển đến createphương thức của mô hình của bạn , cho phép người dùng tự báo cáo cho quản trị viên.

Vì vậy, để bắt đầu, bạn nên xác định thuộc tính mô hình nào bạn muốn để có thể gán hàng loạt. Bạn có thể làm điều này bằng cách sử dụng thuộc $fillabletính trên mô hình. Ví dụ: hãy làm cho namethuộc tính của Flightkhối lượng mô hình của chúng ta có thể gán được:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name'];
}

Khi bạn đã chỉ định thuộc tính nào có thể gán hàng loạt, bạn có thể sử dụng createphương pháp này để chèn một bản ghi mới vào cơ sở dữ liệu. Các createphương thức trả về trường hợp mô hình mới được tạo ra:

$flight = Flight::create(['name' => 'London to Paris']);

Nếu bạn đã có một phiên bản mô hình, bạn có thể sử dụng fillphương thức để điền vào nó một mảng thuộc tính:

$flight->fill(['name' => 'Amsterdam to Frankfurt']);

 

Chuyển nhượng hàng loạt & các cột JSON

Khi gán các cột JSON, khóa có thể gán khối lượng của mỗi cột phải được chỉ định trong $fillablemảng của mô hình của bạn . Để bảo mật, Laravel không hỗ trợ cập nhật các thuộc tính JSON lồng nhau khi sử dụng thuộc guardedtính:

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'options->enabled',
];

 

Cho phép phân công hàng loạt

Nếu bạn muốn gán hàng loạt các thuộc tính của mình, bạn có thể xác định thuộc tính của mô hình $guardedlà một mảng trống. Nếu bạn chọn để unguard mô hình của bạn, bạn nên chăm sóc đặc biệt để luôn tay nghề các mảng truyền cho hùng biện của fillcreatevà updatephương pháp:

/**
 * The attributes that aren't mass assignable.
 *
 * @var array
 */
protected $guarded = [];

 

Cảnh báo

Đôi khi, bạn có thể cần cập nhật một mô hình hiện có hoặc tạo một mô hình mới nếu không có mô hình phù hợp nào tồn tại. Giống như firstOrCreatephương thức, updateOrCreatephương thức vẫn tồn tại mô hình, vì vậy không cần phải gọi savephương thức theo cách thủ công .

Trong ví dụ dưới đây, nếu một chuyến bay tồn tại với departurevị trí của Oaklandvà destinationvị trí của San Diego, các cột pricevà của nó discountedsẽ được cập nhật. Nếu không có chuyến bay nào như vậy tồn tại, một chuyến bay mới sẽ được tạo với các thuộc tính là kết quả của việc hợp nhất mảng đối số đầu tiên với mảng đối số thứ hai:

$flight = Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99, 'discounted' => 1]
);

Nếu bạn muốn thực hiện nhiều "cảnh báo" trong một truy vấn, thì bạn nên sử dụng upsertphương pháp này để thay thế. Đối số đầu tiên của phương thức bao gồm các giá trị để chèn hoặc cập nhật, trong khi đối số thứ hai liệt kê (các) cột xác định duy nhất các bản ghi trong bảng được liên kết. Đối số thứ ba và cuối cùng của phương thức là một mảng các cột cần được cập nhật nếu một bản ghi phù hợp đã tồn tại trong cơ sở dữ liệu. Các upsertphương pháp sẽ tự động đặt created_atvà updated_attimestamps nếu timestamps được bật trên mô hình:

Flight::upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);

 

Tất cả các hệ thống cơ sở dữ liệu ngoại trừ SQL Server yêu cầu các cột trong đối số thứ hai được cung cấp cho upsertphương thức phải có chỉ mục "chính" hoặc "duy nhất".

 

 

Xóa mô hình

Để xóa một mô hình, bạn có thể gọi deletephương thức trên phiên bản mô hình:

use App\Models\Flight;

$flight = Flight::find(1);

$flight->delete();

Bạn có thể gọi truncatephương thức để xóa tất cả các bản ghi cơ sở dữ liệu liên quan của mô hình. Các truncatehoạt động cũng sẽ thiết lập lại bất kỳ ID tự động incrementing trên bàn liên quan của mô hình:

Flight::truncate();

 

Xóa một mô hình hiện có bằng khóa chính của nó

Trong ví dụ trên, chúng tôi đang truy xuất mô hình từ cơ sở dữ liệu trước khi gọi deletephương thức. Tuy nhiên, nếu bạn biết khóa chính của mô hình, bạn có thể xóa mô hình mà không cần truy xuất rõ ràng bằng cách gọi destroyphương thức. Ngoài việc chấp nhận một khóa chính, destroyphương thức sẽ chấp nhận nhiều khóa chính, một mảng khóa chính hoặc một tập hợp các khóa chính:

Flight::destroy(1);

Flight::destroy(1, 2, 3);

Flight::destroy([1, 2, 3]);

Flight::destroy(collect([1, 2, 3]));

 

Các destroyphương pháp tải mỗi mô hình độc lập và gọi deletephương pháp sao cho deletingvà deletedsự kiện được gửi đi đúng cho mỗi mô hình.

 

 

Xóa mô hình bằng truy vấn

Tất nhiên, bạn có thể tạo một truy vấn Eloquent để xóa tất cả các mô hình phù hợp với tiêu chí truy vấn của bạn. Trong ví dụ này, chúng tôi sẽ xóa tất cả các chuyến bay được đánh dấu là không hoạt động. Giống như cập nhật hàng loạt, xóa hàng loạt sẽ không gửi các sự kiện mô hình cho các mô hình bị xóa:

$deletedRows = Flight::where('active', 0)->delete();

 

Khi thực hiện câu lệnh xóa hàng loạt qua Eloquent, các sự kiện deletingvà deletedmô hình sẽ không được gửi cho các mô hình đã xóa. Điều này là do các mô hình không bao giờ thực sự được truy xuất khi thực hiện câu lệnh xóa.

 

 

Xóa mềm

Ngoài việc thực sự xóa các bản ghi khỏi cơ sở dữ liệu của bạn, Eloquent cũng có thể thực hiện các mô hình "xóa mềm". Khi các mô hình bị xóa mềm, chúng không thực sự bị xóa khỏi cơ sở dữ liệu của bạn. Thay vào đó, một deleted_atthuộc tính được đặt trên mô hình cho biết ngày và giờ tại đó mô hình bị "xóa". Để bật tính năng xóa mềm cho một mô hình, hãy thêm Illuminate\Database\Eloquent\SoftDeletesđặc điểm vào mô hình:

<?php

namespace App\Models;

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

class Flight extends Model
{
    use SoftDeletes;
}

 

Các SoftDeletesđặc điểm sẽ tự động cast deleted_atthuộc tính cho một DateTimeCarbonVí dụ cho bạn.

 

Bạn cũng nên thêm deleted_atcột vào bảng cơ sở dữ liệu của mình. Trình tạo lược đồ Laravel chứa một phương thức trợ giúp để tạo cột này:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Facades\Schema;

Schema::table('flights', function (Blueprint $table) {
    $table->softDeletes();
});

Schema::table('flights', function (Blueprint $table) {
    $table->dropSoftDeletes();
});

Bây giờ, khi bạn gọi deletephương thức trên mô hình, deleted_atcột sẽ được đặt thành ngày và giờ hiện tại. Tuy nhiên, bản ghi cơ sở dữ liệu của mô hình sẽ được để lại trong bảng. Khi truy vấn một mô hình sử dụng tính năng xóa mềm, các mô hình đã xóa mềm sẽ tự động bị loại trừ khỏi tất cả các kết quả truy vấn.

Để xác định xem một phiên bản mô hình nhất định đã bị xóa mềm hay chưa, bạn có thể sử dụng trashedphương pháp:

if ($flight->trashed()) {
    //
}

 

Khôi phục các mô hình đã xóa mềm

Đôi khi bạn có thể muốn "hủy xóa" một mô hình đã xóa mềm. Để khôi phục một mô hình đã xóa mềm, bạn có thể gọi restorephương thức trên một phiên bản mô hình. Các restorephương pháp sẽ thiết lập của mô hình deleted_atcột để null:

$flight->restore();

Bạn cũng có thể sử dụng restorephương pháp này trong một truy vấn để khôi phục nhiều mô hình. Một lần nữa, giống như các hoạt động "hàng loạt" khác, thao tác này sẽ không gửi bất kỳ sự kiện mô hình nào cho các mô hình được khôi phục:

Flight::withTrashed()
        ->where('airline_id', 1)
        ->restore();

Các restorephương pháp cũng có thể được sử dụng khi xây dựng mối quan hệ truy vấn:

$flight->history()->restore();

 

Xóa vĩnh viễn các mô hình

Đôi khi bạn có thể cần thực sự xóa một mô hình khỏi cơ sở dữ liệu của mình. Bạn có thể sử dụng forceDeletephương pháp để xóa vĩnh viễn một mô hình đã xóa mềm khỏi bảng cơ sở dữ liệu:

$flight->forceDelete();

Bạn cũng có thể sử dụng forceDeletephương pháp này khi xây dựng các truy vấn mối quan hệ hùng hồn:

$flight->history()->forceDelete();

 

Truy vấn các mô hình đã xóa mềm

 

Bao gồm các mô hình đã xóa mềm

Như đã lưu ý ở trên, các mô hình đã xóa mềm sẽ tự động bị loại trừ khỏi kết quả truy vấn. Tuy nhiên, bạn có thể buộc các mô hình đã xóa mềm được đưa vào kết quả của truy vấn bằng cách gọi withTrashedphương thức trên truy vấn:

use App\Models\Flight;

$flights = Flight::withTrashed()
                ->where('account_id', 1)
                ->get();

Các withTrashedphương pháp cũng có thể được gọi khi xây dựng một mối quan hệ truy vấn:

$flight->history()->withTrashed()->get();

 

Chỉ truy xuất các mô hình đã xóa mềm

Các onlyTrashedphương pháp sẽ lấy chỉ mô hình xóa mềm:

$flights = Flight::onlyTrashed()
                ->where('airline_id', 1)
                ->get();

 

Nhân rộng mô hình

Bạn có thể tạo một bản sao chưa lưu của một phiên bản mô hình hiện có bằng cách sử dụng replicatephương pháp này. Phương pháp này đặc biệt hữu ích khi bạn có các phiên bản mô hình chia sẻ nhiều thuộc tính giống nhau:

use App\Models\Address;

$shipping = Address::create([
    'type' => 'shipping',
    'line_1' => '123 Example Street',
    'city' => 'Victorville',
    'state' => 'CA',
    'postcode' => '90001',
]);

$billing = $shipping->replicate()->fill([
    'type' => 'billing'
]);

$billing->save();

 

Phạm vi truy vấn

 

Phạm vi toàn cầu

Phạm vi toàn cục cho phép bạn thêm các ràng buộc vào tất cả các truy vấn cho một mô hình nhất định. Chức năng xóa mềm của riêng Laravel sử dụng phạm vi toàn cục để chỉ truy xuất các mô hình "không bị xóa" từ cơ sở dữ liệu. Viết phạm vi toàn cục của riêng bạn có thể cung cấp một cách thuận tiện, dễ dàng để đảm bảo mọi truy vấn cho một mô hình nhất định đều nhận được những ràng buộc nhất định.

 

Viết phạm vi toàn cầu

Viết phạm vi toàn cầu rất đơn giản. Đầu tiên, xác định một lớp thực thi Illuminate\Database\Eloquent\Scopegiao diện. Laravel không có một vị trí thông thường mà bạn nên đặt các lớp phạm vi, vì vậy bạn có thể tự do đặt lớp này trong bất kỳ thư mục nào bạn muốn.

Các Scopegiao diện đòi hỏi bạn phải thực hiện một phương pháp: apply. Các applyphương pháp có thể thêm wherenhững hạn chế hoặc loại khác của các điều khoản với truy vấn khi cần thiết:

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class AncientScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('created_at', '<', now()->subYears(2000));
    }
}

 

Nếu phạm vi toàn cầu của bạn đang thêm các cột vào mệnh đề chọn của truy vấn, bạn nên sử dụng addSelectphương pháp này thay vì select. Điều này sẽ ngăn việc vô tình thay thế mệnh đề lựa chọn hiện có của truy vấn.

 

 

Áp dụng phạm vi toàn cầu

Để gán phạm vi toàn cục cho một mô hình, bạn nên ghi đè bootedphương thức của mô hình và gọi addGlobalScopephương thức của mô hình . Các addGlobalScopephương pháp chấp nhận một thể hiện của phạm vi của bạn như là đối số duy nhất của nó:

<?php

namespace App\Models;

use App\Scopes\AncientScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope(new AncientScope);
    }
}

Sau khi thêm phạm vi trong ví dụ trên vào App\Models\Usermô hình, một lệnh gọi User::all()phương thức sẽ thực hiện truy vấn SQL sau:

select * from `users` where `created_at` < 0021-02-18 00:00:00

 

Phạm vi toàn cầu ẩn danh

Eloquent cũng cho phép bạn xác định phạm vi toàn cục bằng cách sử dụng các bao đóng, điều này đặc biệt hữu ích cho các phạm vi đơn giản không đảm bảo một lớp riêng của chúng. Khi xác định phạm vi toàn cục bằng cách sử dụng bao đóng, bạn nên cung cấp tên phạm vi mà bạn chọn làm đối số đầu tiên cho addGlobalScopephương thức:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::addGlobalScope('ancient', function (Builder $builder) {
            $builder->where('created_at', '<', now()->subYears(2000));
        });
    }
}

 

Xóa phạm vi toàn cầu

Nếu bạn muốn xóa phạm vi toàn cục cho một truy vấn nhất định, bạn có thể sử dụng withoutGlobalScopephương pháp này. Phương thức này chấp nhận tên lớp của phạm vi toàn cục làm đối số duy nhất của nó:

User::withoutGlobalScope(AncientScope::class)->get();

Hoặc, nếu bạn đã xác định phạm vi toàn cầu bằng cách sử dụng bao đóng, bạn nên chuyển tên chuỗi mà bạn đã gán cho phạm vi toàn cầu:

User::withoutGlobalScope('ancient')->get();

Nếu bạn muốn loại bỏ một số hoặc thậm chí tất cả các phạm vi toàn cục của truy vấn, bạn có thể sử dụng withoutGlobalScopesphương pháp:

// Remove all of the global scopes...
User::withoutGlobalScopes()->get();

// Remove some of the global scopes...
User::withoutGlobalScopes([
    FirstScope::class, SecondScope::class
])->get();

 

Phạm vi địa phương

Phạm vi cục bộ cho phép bạn xác định các bộ ràng buộc truy vấn phổ biến mà bạn có thể dễ dàng sử dụng lại trong toàn bộ ứng dụng của mình. Ví dụ: bạn có thể cần thường xuyên truy xuất tất cả người dùng được coi là "phổ biến". Để xác định phạm vi, hãy đặt trước một phương thức Eloquent model với scope.

Phạm vi phải luôn trả về một phiên bản trình tạo truy vấn:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include popular users.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    /**
     * Scope a query to only include active users.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }
}

 

Sử dụng phạm vi cục bộ

Khi phạm vi đã được xác định, bạn có thể gọi các phương thức phạm vi khi truy vấn mô hình. Tuy nhiên, bạn không nên bao gồm scopetiền tố khi gọi phương thức. Bạn thậm chí có thể chuỗi các cuộc gọi đến các phạm vi khác nhau:

use App\Models\User;

$users = User::popular()->active()->orderBy('created_at')->get();

Việc kết hợp nhiều phạm vi mô hình Eloquent thông qua ortoán tử truy vấn có thể yêu cầu sử dụng các bao đóng để đạt được nhóm logic chính xác :

$users = User::popular()->orWhere(function (Builder $query) {
    $query->active();
})->get();

Tuy nhiên, vì điều này có thể phức tạp, Laravel cung cấp một orWherephương thức "bậc cao" cho phép bạn kết nối các phạm vi chuỗi với nhau một cách trôi chảy mà không cần sử dụng các bao đóng:

$users = App\Models\User::popular()->orWhere->active()->get();

 

Phạm vi động

Đôi khi bạn có thể muốn xác định một phạm vi chấp nhận các tham số. Để bắt đầu, chỉ cần thêm các tham số bổ sung của bạn vào chữ ký của phương thức phạm vi của bạn. Tham số phạm vi phải được xác định sau $querytham số:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include users of a given type.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  mixed  $type
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeOfType($query, $type)
    {
        return $query->where('type', $type);
    }
}

Khi các đối số mong đợi đã được thêm vào chữ ký của phương thức phạm vi của bạn, bạn có thể chuyển các đối số khi gọi phạm vi:

$users = User::ofType('admin')->get();

 

So sánh các mô hình

Đôi khi bạn có thể cần phải xác định xem hai mô hình có "giống nhau" hay không. Các phương pháp isvà isNotcó thể được sử dụng để nhanh chóng xác minh hai mô hình có cùng khóa chính, bảng và kết nối cơ sở dữ liệu hay không:

if ($post->is($anotherPost)) {
    //
}

if ($post->isNot($anotherPost)) {
    //
}

Các isvà isNotphương pháp này cũng có sẵn khi sử dụng belongsTohasOnemorphTo, và morphOne các mối quan hệ . Phương pháp này đặc biệt hữu ích khi bạn muốn so sánh một mô hình có liên quan mà không đưa ra một truy vấn để truy xuất mô hình đó:

if ($post->author()->is($user)) {
    //
}

 

Sự kiện

Mô hình hùng hồn cử một số sự kiện, cho phép bạn để móc vào những khoảnh khắc sau trong vòng đời của một mô hình: retrievedcreatingcreatedupdatingupdatedsavingsaveddeletingdeletedrestoringrestored, và replicating.

Sự retrievedkiện sẽ gửi khi một mô hình hiện có được truy xuất từ ​​cơ sở dữ liệu. Khi một mô hình mới được lưu lần đầu tiên, các sự kiện creatingvà createdsẽ gửi đi. Các sự kiện updatingupdatedsẽ gửi đi khi một mô hình hiện có được sửa đổi và savephương thức được gọi. Các sự kiện savingsavedsẽ gửi đi khi một mô hình được tạo hoặc cập nhật - ngay cả khi các thuộc tính của mô hình không bị thay đổi.

Để bắt đầu lắng nghe các sự kiện mô hình, hãy xác định một thuộc $dispatchesEventstính trên mô hình Eloquent của bạn. Thuộc tính này ánh xạ các điểm khác nhau trong vòng đời của mô hình Eloquent cho các lớp sự kiện của riêng bạn . Mỗi lớp sự kiện mô hình sẽ nhận được một thể hiện của mô hình bị ảnh hưởng thông qua phương thức khởi tạo của nó:

<?php

namespace App\Models;

use App\Events\UserDeleted;
use App\Events\UserSaved;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The event map for the model.
     *
     * @var array
     */
    protected $dispatchesEvents = [
        'saved' => UserSaved::class,
        'deleted' => UserDeleted::class,
    ];
}

Sau khi xác định và lập bản đồ các sự kiện Eloquent của bạn, bạn có thể sử dụng trình nghe sự kiện để xử lý các sự kiện.

 

Khi phát hành một bản cập nhật tin đại chúng hoặc truy vấn xóa qua hùng hồn, những savedupdateddeleting, và deletedcác sự kiện mô hình sẽ không được gửi đi cho các mô hình bị ảnh hưởng. Điều này là do các mô hình không bao giờ thực sự được truy xuất khi thực hiện cập nhật hoặc xóa hàng loạt.

 

 

Sử dụng Closures

Thay vì sử dụng các lớp sự kiện tùy chỉnh, bạn có thể đăng ký các bao đóng thực thi khi các sự kiện mô hình khác nhau được gửi đi. Thông thường, bạn nên đăng ký các lần đóng này trong bootedphương thức của mô hình của bạn:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::created(function ($user) {
            //
        });
    }
}

Nếu cần, bạn có thể sử dụng trình nghe sự kiện ẩn danh có thể xếp hàng đợi khi đăng ký các sự kiện mô hình. Điều này sẽ hướng dẫn Laravel thực thi trình xử lý sự kiện mô hình trong nền bằng cách sử dụng hàng đợi ứng dụng của bạn :

use function Illuminate\Events\queueable;

static::created(queueable(function ($user) {
    //
}));

 

Quan sát viên

 

Xác định người quan sát

Nếu bạn đang nghe nhiều sự kiện trên một mô hình nhất định, bạn có thể sử dụng các quan sát viên để nhóm tất cả những người nghe của bạn thành một lớp duy nhất. Các lớp trình quan sát có tên phương thức phản ánh các sự kiện Eloquent mà bạn muốn lắng nghe. Mỗi phương thức này nhận mô hình bị ảnh hưởng làm đối số duy nhất của chúng. Lệnh make:observerArtisan là cách dễ nhất để tạo một lớp quan sát viên mới:

php artisan make:observer UserObserver --model=User

Lệnh này sẽ đặt trình quan sát mới trong App/Observersthư mục của bạn . Nếu thư mục này không tồn tại, Artisan sẽ tạo nó cho bạn. Người quan sát mới của bạn sẽ trông giống như sau:

<?php

namespace App\Observers;

use App\Models\User;

class UserObserver
{
    /**
     * Handle the User "created" event.
     *
     * @param  \App\Models\User  $user
     * @return void
     */
    public function created(User $user)
    {
        //
    }

    /**
     * Handle the User "updated" event.
     *
     * @param  \App\Models\User  $user
     * @return void
     */
    public function updated(User $user)
    {
        //
    }

    /**
     * Handle the User "deleted" event.
     *
     * @param  \App\Models\User  $user
     * @return void
     */
    public function deleted(User $user)
    {
        //
    }

    /**
     * Handle the User "forceDeleted" event.
     *
     * @param  \App\Models\User  $user
     * @return void
     */
    public function forceDeleted(User $user)
    {
        //
    }
}

Để đăng ký một quan sát viên, bạn cần gọi observephương thức trên mô hình mà bạn muốn quan sát. Bạn có thể đăng ký quan sát viên theo bootphương thức của App\Providers\EventServiceProvidernhà cung cấp dịch vụ ứng dụng của bạn :

use App\Models\User;
use App\Observers\UserObserver;

/**
 * Register any events for your application.
 *
 * @return void
 */
public function boot()
{
    User::observe(UserObserver::class);
}

 

Sự kiện tắt tiếng

Đôi khi, bạn có thể cần tạm thời "tắt tiếng" tất cả các sự kiện do mô hình kích hoạt. Bạn có thể đạt được điều này bằng cách sử dụng withoutEventsphương pháp này. Các withoutEventsphương pháp chấp nhận một kết thúc như là đối số duy nhất của nó. Bất kỳ mã nào được thực thi trong lần đóng này sẽ không gửi các sự kiện mô hình. Ví dụ: ví dụ sau sẽ tìm nạp và xóa một App\Models\Usercá thể mà không gửi bất kỳ sự kiện mô hình nào. Bất kỳ giá trị nào được trả về bởi quá trình đóng sẽ được trả về theo withoutEventsphương thức:

use App\Models\User;

$user = User::withoutEvents(function () use () {
    User::findOrFail(1)->delete();

    return User::find(2);
});

 

Lưu một mô hình duy nhất không có sự kiện

Đôi khi bạn có thể muốn "lưu" một mô hình nhất định mà không cần cử đi bất kỳ sự kiện nào. Bạn có thể thực hiện điều này bằng cách sử dụng saveQuietlyphương pháp:

$user = User::findOrFail(1);

$user->name = 'Victoria Faith';

$user->saveQuietly();
» Tiếp: Bắt đầu
« Trước: Di chuyển dữ liệu (Migrations)
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!