Permulaan cepat
- Definisi model Elok model
- Nama jadual data
- Kunci utama
- Timestamp
- Atribut lalai Dapatkan koleksi
- Hasil potongan
- Dapatkan model/koleksi tunggal menggunakan kursor Pengecualian "Tidak dijumpai"
- Kemas kini kelompok
- Penugasan kelompok
- Lindungi atribut
- Kaedah penciptaan lain
- .
- Sertakan model yang dipadam lembut
- Dapatkan semula model yang dipadam lembut Batalkan skop global
- Gunakan skop tempatan
- Skop dinamik
- Perbandingan model
- Acara
- Fasih: Bermula del Retrieval
- Koleksi
- Result Chunking
- Sisip & Kemas kini model
- Kaedah penciptaan lain
- Perbandingan model introduction
- laravel's fasih orm menyediakan pelaksanaan Activerecord yang indah dan ringkas untuk berinteraksi dengan interaksi pangkalan data. Setiap jadual pangkalan data mempunyai "model" yang sepadan yang digunakan untuk berinteraksi dengan jadual. Anda boleh menanyakan data dalam jadual data melalui model dan memasukkan rekod baharu ke dalam jadual data.
- Sebelum anda bermula, pastikan anda mengkonfigurasi sambungan pangkalan data dalam
- Definisi Model Mula-mula, cipta model Fasih. Model biasanya berada dalam direktori
php artisan make:model Flight
Jika anda ingin menjana migrasi pangkalan data semasa menjana model, anda boleh menggunakan--migration
atau-m
Pilihan:php artisan make:model Flight --migration php artisan make:model Flight -m
- < h3>Konvensyen model yang fasih Sekarang, mari lihat contoh model
Penerbangan
, yang akan kami gunakan untuk mendapatkan dan menyimpan maklumat data daripada pangkalan datapenerbangan
meja:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ // }
Nama jadual data
Sila ambil perhatian bahawa kami tidak memberitahu Eloquent jadual data yang hendak digunakan untuk model
Penerbangan kami. Melainkan nama lain dinyatakan secara eksplisit, bentuk jamak kelas, "ular", akan digunakan sebagai nama jadual. Oleh itu, dalam kes ini, Eloquent akan menganggap bahawa model Flight
menyimpan data daripada jadual dataflights
. Anda boleh menentukan jadual data tersuai dengan mentakrifkan atributtable
pada model:Flight
模型使用哪个数据表。 除非明确地指定了其它名称,否则将使用类的复数形式「蛇形命名」来作为表名。因此,在这种情况下,Eloquent 将假设Flight
模型存储的是flights
数据表中的数据。你可以通过在模型上定义table
属性来指定自定义数据表:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 与模型关联的表名 * * @var string */ protected $table = 'my_flights'; }
主键
Eloquent 也会假设每个数据表都有一个名为
id
的主键列。你可以定义一个受保护的$primaryKey
属性来重写约定。此外,Eloquent 假设主键是一个自增的整数值,这意味着默认情况下主键会自动转换为
int
类型。如果您希望使用非递增或非数字的主键则需要设置公共的$incrementing
属性设置为false
。如果你的主键不是一个整数,你需要将模型上受保护的$keyType
属性设置为string
。时间戳
默认情况下,Eloquent 预期你的数据表中存在
created_at
和updated_at
。如果你不想让 Eloquent 自动管理这两个列, 请将模型中的$timestamps
属性设置为false
:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 指示模型是否自动维护时间戳 * * @var bool */ public $timestamps = false; }
如果需要自定义时间戳的格式,在你的模型中设置
$dateFormat
属性。这个属性决定日期属性在数据库的存储方式,以及模型序列化为数组或者 JSON 的格式:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型日期列的存储格式。 * * @var string */ protected $dateFormat = 'U'; }
如果你需要自定义存储时间戳的字段名,可以在模型中设置
CREATED_AT
和UPDATED_AT
常量的值来实现:<?php class Flight extends Model{ const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update'; }
数据库连接
默认情况下,Eloquent 模型将使用你的应用程序配置的默认数据库连接。如果你想为模型指定一个不同的连接,设置
$connection
属性:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型的连接名称 * * @var string */ protected $connection = 'connection-name'; }
默认属性值
如果要为模型的某些属性定义默认值,可以在模型上定义
$attributes
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型的默认属性值。 * * @var array */ protected $attributes = [ 'delayed' => false, ]; }
Kunci utamaEloquent juga akan menganggap bahawa setiap Setiap jadual data mempunyai lajur kunci utama bernama
id
. Anda boleh mengatasi konvensyen dengan mentakrifkan atribut$primaryKey
yang dilindungi.Selain itu, Eloquent menganggap bahawa kunci utama ialah nilai integer yang meningkat secara automatik, yang bermaksud bahawa kunci utama ditukar secara automatik kepada jenisint
secara lalai. Jika anda ingin menggunakan kunci utama bukan penambahan atau bukan angka, anda perlu menetapkan harta$incrementing
awam kepadafalse
. Jika kunci utama anda bukan integer, anda perlu menetapkan sifat$keyType
yang dilindungi pada model kepadastring
.TimestampSecara lalai, Eloquent mengharapkancreated_at
danupdated_at
. Jika anda tidak mahu Eloquent mengurus kedua-dua lajur ini secara automatik, sila tetapkan atribut$timestamps
dalam model kepadafalse
:Jika anda perlu menyesuaikan format cap waktu , Tetapkan sifat<?php $flights = App\Flight::all(); foreach ($flights as $flight) { echo $flight->name; }
$dateFormat
dalam model anda. Atribut ini menentukan cara atribut tarikh disimpan dalam pangkalan data dan format model disiri ke dalam tatasusunan atau JSON: 🎜$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();
🎜 Jika anda perlu menyesuaikan nama medan untuk menyimpan cap masa, anda boleh menetapkanCREATED_AT
dalam model dan nilai pemalarUPDATED_AT
: 🎜$flight = App\Flight::where('number', 'FR 900')->first(); $freshFlight = $flight->fresh();
🎜🎜Sambungan pangkalan data🎜🎜Secara lalai, Eloquent model akan digunakan oleh aplikasi anda Sambungan pangkalan data lalai yang dikonfigurasikan. Jika anda ingin menentukan sambungan lain untuk model, tetapkan atribut$connection
: 🎜$flight = App\Flight::where('number', 'FR 900')->first(); $flight->number = 'FR 456';$flight->refresh(); $flight->number; // "FR 900"
🎜🎜🎜🎜Nilai atribut lalai
🎜Jika anda ingin mentakrifkan nilai lalai untuk sesetengah atribut model, anda boleh mentakrifkan atribut$attributes
pada model: 🎜$flights = $flights->reject(function ($flight) { return $flight->cancelled; });
🎜🎜🎜 🎜🎜🎜🎜Model Retrieval🎜🎜Selepas mencipta model dan jadual pangkalan data yang berkaitan, anda boleh bertanya data daripada pangkalan data. Fikirkan setiap model Eloquent sebagai pembina pertanyaan yang berkuasa yang boleh anda gunakan untuk menanyakan jadual data yang berkaitan dengan lebih cepat. Contohnya: 🎜foreach ($flights as $flight) { echo $flight->name; }
🎜🎜Kekangan tambahan
Kaedah
semua
Eloquent akan mengembalikan semua hasil dalam model. Memandangkan setiap model Eloquent bertindak sebagai pembina pertanyaan, anda juga boleh menambah syarat pertanyaan dan kemudian menggunakan kaedahget
untuk mendapatkan hasil pertanyaan:all
方法会返回模型中所有的结果。由于每个 Eloquent 模型都充当一个查询构造器,所以你也可以添加查询条件,然后使用get
方法获取查询结果:Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // } });
{tip} 因为 Eloquent 模型也是查询构造器,所以你也应当阅读 查询构造器可用的所有方法。你可以在 Eloquent 查询中使用这些方法。
重新加载模型
你可以使用
fresh
和refresh
方法重新加载模型。fresh
方法会重新从数据库中检索模型。现有的模型实例不受影响:foreach (Flight::where('foo', 'bar')->cursor() as $flight) { // }
refresh
方法使用数据库中的新数据重新赋值现有模型。此外,已经加载的关系会被重新加载:// 通过主键检索一个模型... $flight = App\Flight::find(1); // 检索符合查询限制的第一个模型... $flight = App\Flight::where('active', 1)->first();
集合
对于 Eloquent 中的
all
和get
方法可以查询多个结果,返回一个IlluminateDatabaseEloquentCollection
实例。Collection
类提供了 很多辅助函数 来处理 Eloquent 结果:$flights = App\Flight::find([1, 2, 3]);
你可以像数组一样遍历集合:
$model = App\Flight::findOrFail(1); $model = App\Flight::where('legs', '>', 100)->firstOrFail();
分块结果
如果你需要处理数以千计的 Eloquent 结果,使用
chunk
命令。chunk
方法会检索 Eloquent 模型中的『分块』将他们提供给指定的Closure
处理。在处理大型结果集时,使用chunk
方法可以节省内存:Route::get('/api/flights/{id}', function ($id) { return App\Flight::findOrFail($id); });
传递到方法的第一个参数是希望每个『分块』接收的数据量。闭包作为第二个参数传递,它在每次从数据库中检索分块的时候调用。它将执行数据库查询把检索分块的结果传递给闭包方法。
使用游标
cursor
方法允许你使用游标遍历数据库,它只执行一次查询。处理大量的数据时,cursor
方法可以大大减少内存的使用量:$count = App\Flight::where('active', 1)->count(); $max = App\Flight::where('active', 1)->max('price');
检索单个模型 / 集合
除了从指定的数据表检索所有记录外,你可以使用
find
或first
方法来检索单条记录。这些方法返回单个模型实例,而不是返回模型集合:<?php namespace App\Http\Controllers; use App\Flight;use Illuminate\Http\Request; use App\Http\Controllers\Controller; class FlightController extends Controller{ /** * 创建一个新的航班实例 * * @param Request $request * @return Response */ public function store(Request $request) { // 校验请求... $flight = new Flight; $flight->name = $request->name; $flight->save(); } }
你也可以使用主键数组作为参数调用
find
$flight = App\Flight::find(1); $flight->name = 'New Flight Name';$flight->save();
{tip} Kerana model Eloquent juga merupakan pertanyaan pembina pembina, jadi anda juga harus membaca tentang semua kaedah yang tersedia untuk pembina pertanyaan. Anda boleh menggunakan kaedah ini dalam pertanyaan Eloquent.
🎜Muat semula model🎜🎜Anda boleh memuat semula menggunakan kaedahfresh
danrefresh
Model. Kaedahfresh
mendapatkan semula model daripada pangkalan data sekali lagi. Contoh model sedia ada tidak terjejas: 🎜App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);
🎜 Kaedahrefresh
menetapkan semula model sedia ada dengan data baharu daripada pangkalan data. Selain itu, perhubungan yang telah dimuatkan akan dimuat semula: 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 可以被批量赋值的属性。 * * @var array */ protected $fillable = ['name']; }
🎜🎜🎜Koleksi
🎜 Kaedahsemua
danget
dalam Eloquent boleh menanyakan berbilang hasil dan mengembalikan contohIlluminateDatabaseEloquentCollection
. KelasCollection
menyediakan beberapa fungsi pembantu untuk mengendalikan hasil Eloquent: 🎜$flight = App\Flight::create(['name' => 'Flight 10']);
🎜Anda boleh mengulangi koleksi seperti tatasusunan: 🎜$flight->fill(['name' => 'Flight 22']);
🎜🎜🎜Hasil potongan
🎜Jika anda perlu memproses beribu hasil Eloquent, gunakan perintahchunk
. Kaedahchunk
mendapatkan semula "chunks" dalam model Eloquent dan memberikannya kepadaClosure
yang ditentukan untuk diproses. Apabila memproses set hasil yang besar, gunakan kaedahchunk
untuk menjimatkan memori: 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 不可批量赋值的属性。 * * @var array */ protected $guarded = ['price']; }
🎜Parameter pertama yang dihantar kepada kaedah ialah jumlah data yang anda mahu setiap "chunk" terima. Penutupan diluluskan sebagai parameter kedua dan dipanggil setiap kali ketulan diambil daripada pangkalan data. Ia akan melaksanakan pertanyaan pangkalan data dan menghantar hasil potongan yang diambil kepada kaedah penutupan. 🎜🎜🎜Menggunakan Kursor🎜🎜Kaedahkursor membolehkan anda melintasi pangkalan data menggunakan kursor, yang hanya melakukan pertanyaan. Apabila memproses sejumlah besar data, kaedah kursor
boleh mengurangkan penggunaan memori dengan ketara: 🎜/** * 不可以批量赋值的属性。 * * @var array */ protected $guarded = [];
🎜🎜🎜Dapatkan semula model/koleksi tunggal
🎜Selain mendapatkan semula semua rekod daripada jadual data yang ditentukan, anda boleh menggunakancari
ataukaedah< /code> pertama untuk mendapatkan semula satu rekod. Kaedah ini mengembalikan contoh model tunggal dan bukannya koleksi model: 🎜
// 通过 name 来查找航班,不存在则创建... $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); // 通过 name 查找航班,不存在则使用 name 和 delayed 属性创建... $flight = App\Flight::firstOrCreate(['name' => 'Flight 10'], ['delayed' => 1]); // 通过 name 查找航班,不存在则创建一个实例... $flight = App\Flight::firstOrNew(['name' => 'Flight 10']); // 通过 name 查找航班,不存在则使用 name 和 delayed 属性创建一个实例... $flight = App\Flight::firstOrNew(['name' => 'Flight 10'], ['delayed' => 1]);
🎜 Anda juga boleh memanggil kaedahcari
dengan tatasusunan kunci utama sebagai argumen, yang akan mengembalikan koleksi rekod yang sepadan: 🎜// 如果有从奥克兰到圣地亚哥的航班,则价格定为99美元。 // 如果没匹配到存在的模型,则创建一个。 $flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );
🎜🎜『Tidak Ditemui』Pengecualian
Kadangkala anda ingin membuang pengecualian apabila model tidak ditemui. Ini sangat berguna dalam pengawal dan penghalaan. Kaedah
findOrFail
danfirstOrFail
akan mendapatkan semula hasil pertama pertanyaan Jika tidak ditemui,IlluminateDatabaseEloquentModelNotFoundException
akan dilemparkan:findOrFail
和firstOrFail
方法会检索查询的第一个结果,如果未找到,将抛出IlluminateDatabaseEloquentModelNotFoundException
异常:$flight = App\Flight::find(1); $flight->delete();
如果没有捕获异常,则会自动返回
404
响应给用户。也就是说,使用这些方法时,没有必要再写个检查来返回404
响应::App\Flight::destroy(1); App\Flight::destroy(1, 2, 3); App\Flight::destroy([1, 2, 3]); App\Flight::destroy(collect([1, 2, 3]));
检索集合
你还可以使用 查询构造器 提供的
count
,sum
,max
, 和其他的聚合函数。这些方法只会返回适当的标量值而不是一个模型实例:$deletedRows = App\Flight::where('active', 0)->delete();
插入 & 更新模型
插入
要往数据库新增一条记录,先创建新模型实例,给实例设置属性,然后调用
save
方法:<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Flight extends Model{ use SoftDeletes; }
在这个示例中,我们将 HTTP 请求参数
name
赋值给了AppFlight
模型实例的name
属性。当调用save
方法时,将会插入一条新记录。created_at
和updated_at
时间戳将会自动设置,不需要手动赋值。更新
save
方法也可以用来更新数据库已经存在的模型。更新模型,你需要先检索出来,设置要更新的属性,然后调用save
方法。同样,updated_at
时间戳会自动更新,所以也不需要手动赋值:Schema::table('flights', function (Blueprint $table) { $table->softDeletes(); });
批量更新
也可以更新匹配查询条件的多个模型。在这个示例中,所有的
active
和destination
为San Diego
的航班会标记为延误:if ($flight->trashed()) { // }
update
方法接受一个键为字段名称数据为值的数组。{note} 通过 Eloquent 批量更新时, 更新的模型不会触发
saved
和updated
$flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();
Jika tidak ditangkap Pengecualian, respons404
akan dikembalikan secara automatik kepada pengguna. Iaitu, apabila menggunakan kaedah ini, tidak perlu menulis cek untuk mengembalikan respons404
: :$flight->history()->withTrashed()->get();
Dapatkan koleksi
Anda juga boleh menggunakancount
,sum
,maks yang disediakan oleh pembina pertanyaan
dan fungsi agregat lain. Kaedah ini hanya akan mengembalikan nilai skalar yang sesuai dan bukannya contoh model:$flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();
🎜🎜🎜🎜Sisipkan & Kemas Kini Model
🎜🎜🎜🎜Sisipkan
🎜Pergi ke To tambah rekod baharu pada pangkalan data, mula-mula buat contoh model baharu, tetapkan sifat untuk contoh itu, dan kemudian panggil kaedahsimpan: 🎜 $flight->restore();
🎜Dalam contoh ini, kami menukar parameter permintaan HTTPnama Ditugaskan kepada atribut name
contoh modelAppFlight
. Apabila kaedahsave
dipanggil, rekod baharu akan dimasukkan. Cap waktucreated_at
danupdated_at
akan ditetapkan secara automatik dan tidak memerlukan tugasan manual. 🎜🎜🎜🎜🎜kemas kini
🎜simpan kaedah juga boleh digunakan Kemas kini model sedia ada dalam pangkalan data. Untuk mengemas kini model, anda perlu mendapatkannya dahulu, tetapkan sifat untuk dikemas kini dan kemudian panggil kaedah simpan
. Begitu juga, cap waktuupdated_at
akan dikemas kini secara automatik, jadi tidak perlu menetapkan nilai secara manual: 🎜App\Flight::withTrashed() ->where('airline_id', 1) ->restore();
🎜🎜Kemas kini kelompok🎜 🎜Anda juga boleh mengemas kini padanan Pelbagai model untuk syarat pertanyaan. Dalam contoh ini, semua penerbangan denganaktif
dandestination
keSan Diego
akan ditandakan sebagai tertunda: 🎜$flight->history()->restore();
🎜kemas kini
menerima tatasusunan yang kuncinya ialah nama medan dan data ialah nilai. 🎜🎜{note} Apabila kumpulan mengemas kini melalui Eloquent, model yang dikemas kini tidak akan mencetuskan acara
disimpan
dandikemas kini
. Kerana semasa kemas kini kelompok, model tidak pernah diambil. 🎜🎜🎜🎜🎜🎜🎜🎜Penugasan kelompok
Anda juga boleh menggunakan kaedah
create
untuk menyimpan model baharu Kaedah ini akan mengembalikan contoh model. Walau bagaimanapun, sebelum menggunakannya, anda perlu menentukan atributfillable
atauguarded
pada model, kerana semua model Eloquent tidak boleh ditetapkan secara kelompok secara lalai.create
方法来保存新模型,此方法会返回模型实例。不过,在使用之前,你需要在模型上指定fillable
或guarded
属性,因为所有的 Eloquent 模型都默认不可进行批量赋值。当用户通过 HTTP 请求传入一个意外的参数,并且该参数更改了数据库中你不需要更改的字段时。比如:恶意用户可能会通过 HTTP 请求传入
is_admin
参数,然后将其传给create
方法,此操作能让用户将自己升级成管理员。所以,在开始之前,你应该定义好模型上的哪些属性是可以被批量赋值的。你可以通过模型上的
$fillable
属性来实现。 例如:让Flight
模型的name
属性可以被批量赋值:// 单个模型实例的永久删除... $flight->forceDelete(); // 关联模型的永久删除... $flight->history()->forceDelete();
一旦我们设置好了可以批量赋值的属性,就可以通过
create
方法插入新数据到数据库中了。create
方法将返回保存的模型实例:<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class AgeScope implements Scope{ /** * 把约束加到 Eloquent 查询构造中。 * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { $builder->where('age', '>', 200); } }
如果你已经有一个模型实例,你可以传递一个数组给
fill
方法来赋值:<?php namespace App;use App\Scopes\AgeScope; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 模型的 「启动」 方法. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope(new AgeScope); } }
保护属性
$fillable
可以看作批量赋值的「白名单」, 你也可以使用$guarded
属性来实现。$guarded
属性包含的是不允许批量赋值的数组。也就是说,$guarded
从功能上将更像是一个「黑名单」。注意:你只能使用$fillable
或$guarded
二者中的一个,不可同时使用。下面这个例子中,除了price
属性,其他的属性都可以批量赋值:select * from `users` where `age` > 200
如果你想让所有属性都可以批量赋值, 你可以将
$guarded
定义成一个空数组:<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class User extends Model{ /** *模型的「启动」方法. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope('age', function (Builder $builder) { $builder->where('age', '>', 200); }); } }
其他创建方法
firstOrCreate
/firstOrNew
这里有两个你可能用来批量赋值的方法:
firstOrCreate
和firstOrNew
。firstOrCreate
方法会通过给定的 列 / 值 来匹配数据库中的数据。如果在数据库中找不到对应的模型, 则会从第一个参数的属性乃至第二个参数的属性中创建一条记录插入到数据库。
Apabila pengguna menghantar parameter yang tidak dijangka melalui permintaan HTTP, dan parameter itu menukar medan dalam pangkalan data yang anda tidak perlu ubah. Sebagai contoh: pengguna berniat jahat boleh menghantar parameterfirstOrNew
方法像firstOrCreate
方法一样尝试通过给定的属性查找数据库中的记录。不同的是,如果firstOrNew
方法找不到对应的模型,会返回一个新的模型实例。注意firstOrNew
返回的模型实例尚未保存到数据库中,你需要手动调用save
is_admin
melalui permintaan HTTP, dan kemudian menghantarnya kepada kaedahcreate
Operasi ini membolehkan pengguna menaik taraf dirinya kepada kaedah pentadbir. Jadi, sebelum anda mula, anda harus menentukan atribut pada model yang boleh diberikan kelompok. Anda boleh melakukan ini melalui atribut$fillable
pada model. Contohnya: biarkan atributname
modelFlight
ditetapkan secara kelompok: 🎜User::withoutGlobalScope(AgeScope::class)->get();
🎜Setelah kami menyediakan atribut yang boleh ditetapkan secara kelompok, kami boleh lulus Kaedahcreate code> memasukkan data baharu ke dalam pangkalan data. Kaedah
create
akan mengembalikan contoh model yang disimpan: 🎜User::withoutGlobalScope('age')->get();
🎜Jika anda sudah mempunyai contoh model, anda boleh menghantar tatasusunan kepada kaedahfill
untuk menetapkan nilai: 🎜// 取消所有的全局作用域... User::withoutGlobalScopes()->get(); // 取消部分全局作用域... User::withoutGlobalScopes([ FirstScope::class, SecondScope::class ])->get();
🎜Atribut yang dilindungi
🎜$fillable
boleh dianggap sebagai "senarai putih" untuk tugasan kelompok, anda juga boleh gunakan atribut$guarded
untuk mencapai ini. Atribut$guarded
mengandungi tatasusunan yang tidak membenarkan penugasan kelompok. Dengan kata lain,$guarded
akan berfungsi lebih seperti "senarai hitam". Nota: Anda hanya boleh menggunakan salah satu daripada$fillable
atau$guarded
, bukan kedua-duanya pada masa yang sama. Dalam contoh berikut, kecuali untuk atributprice
, semua atribut lain boleh diberikan nilai dalam kelompok: 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 只查询受欢迎的用户的作用域. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopePopular($query) { return $query->where('votes', '>', 100); } /** * 只查询 active 用户的作用域. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('active', 1); } }
🎜 Jika anda mahu semua atribut diberikan nilai dalam kelompok, anda boleh menukar$guarded
ditakrifkan sebagai tatasusunan kosong: 🎜$users = App\User::popular()->active()->orderBy('created_at')->get();
🎜🎜🎜🎜 Kaedah penciptaan lain🎜🎜
🎜Berikut ialah dua daripada anda Kaedah yang mungkin untuk penugasan kelompok:firstOrCreate
/firstOrNew
firstOrCreate
danfirstOrNew
. KaedahfirstOrCreate
akan memadankan data dalam pangkalan data dengan lajur/nilai yang diberikan. Jika model yang sepadan tidak dapat ditemui dalam pangkalan data, rekod akan dibuat daripada atribut parameter pertama dan juga atribut parameter kedua dan dimasukkan ke dalam pangkalan data. 🎜🎜KaedahfirstOrNew
, seperti kaedahfirstOrCreate
, cuba mencari rekod dalam pangkalan data mengikut atribut yang diberikan. Perbezaannya ialah jika kaedahfirstOrNew
tidak dapat mencari model yang sepadan, ia akan mengembalikan contoh model baharu. Ambil perhatian bahawa contoh model yang dikembalikan olehfirstOrNew
belum disimpan ke pangkalan data, anda perlu memanggil kaedahsave
secara manual untuk menyimpan: 🎜$users = App\User::popular()->orWhere(function (Builder $query) { $query->active(); })->get();
🎜🎜updateOrCreate
updateOrCreate
你还可能遇到希望更新现有模型或在不存在的情况下则创建新的模型的情景。 Laravel 提供了
updateOrCreate
方法仅一个步骤就可以实现。跟firstOrCreate
方法一样,updateOrCreate
匹配到对应模型,所以不需要调用save()
方法:$users = App\User::popular()->orWhere->active()->get();
删除模型
可以在模型实例上调用
delete
方法来删除实例:<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 将查询作用域限制为仅包含给定类型的用户。 * * @param \Illuminate\Database\Eloquent\Builder $query * @param mixed $type * @return \Illuminate\Database\Eloquent\Builder */ public function scopeOfType($query, $type) { return $query->where('type', $type); } }
通过主键删除模型
在上面的例子中,在调用
delete
之前需要先去数据库中查找对应的模型。事实上,如果你知道了模型的主键,你可以直接使用destroy
方法来删除模型,而不用先去数据库中查找。destroy
方法除了接受单个主键作为参数之外,还接受多个主键,或者使用数组,集合来保存多个主键:$users = App\User::ofType('admin')->get();
通过查询删除模型
你也可以在模型上运行删除语句。在这个例子中,我们将删除所有标记为非活跃的航班。与批量更新一样,批量删除不会为删除的模型启动任何模型事件:
if ($post->is($anotherPost)) { // }
{note} 通过 Eloquent 执行批量删除语句时,不会触发
deleting
和deleted
模型事件。因此,在执行删除语句时,从不检索模型示例。软删除
除了真实删除数据库记录, Eloquent 也可以「软删除」模型。软删除的模型并不是真的从数据库中删除了。事实上,是在模型上设置了
deleted_at
属性并将其值写入数据库。如果deleted_at
值非空,代表这个模型已被软删除。如果要开启模型软删除功能,你需要在模型上使用IlluminateDatabaseEloquentSoftDeletes
trait:<?php namespace App; use App\Events\UserSaved; use App\Events\UserDeleted; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ use Notifiable; /** * 为模型事件。 * * @var array */ protected $dispatchesEvents = [ 'saved' => UserSaved::class, 'deleted' => UserDeleted::class, ]; }
{tip}
SoftDeletes
trait 会自动将deleted_at
属性转换成DateTime
/Carbon
实例当然,你需要把
deleted_at
字段添加到数据表中。 Laravel 的 数据库迁移 有创建这个字段的方法:php artisan make:observer UserObserver --model=User
那现在,当你在模型实例上使用
delete
方法, 当前日期时间会写入deleted_at
字段。同时,查询出来的结果也会自动排除已被软删除的记录。你可以使用
trashed
Anda juga mungkin menghadapi situasi di mana anda ingin mengemas kini model sedia ada atau mencipta model baharu jika ia tidak wujud. Laravel menyediakan kaedahupdateOrCreate
yang boleh dilaksanakan dalam satu langkah sahaja. Seperti kaedahfirstOrCreate
,updateOrCreate
sepadan dengan model yang sepadan, jadi tidak perlu memanggil kaedahsave()
:<?php namespace App\Observers; use App\User; class UserObserver{ /** * 处理 User 「新建」事件。 * * @param \App\User $user * @return void */ public function created(User $user) { // } /** * 处理 User 「更新」 事件。 * * @param \App\User $user * @return void */ public function updated(User $user) { // } /** * 处理 User 「删除」 事件。 * * @param \App\User $user * @return void */ public function deleted(User $user) { // } }
Delete model
Anda boleh memanggil kaedahdelete
pada contoh model untuk memadamkan contoh :<?php namespace App\Providers; use App\User;use App\Observers\UserObserver; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * 启动应用服务。 * * @return void */ public function boot() { User::observe(UserObserver::class); } /** * 注册服务提供者。 * * @return void */ public function register() { // } }
Padam model dengan kunci utamaDalam contoh di atas, anda perlu pergi ke pangkalan data sebelum memanggilrrreeedelete
Cari model yang sepadan dalam . Malah, jika anda mengetahui kunci utama model, anda boleh terus menggunakan kaedahmusnah
untuk memadamkan model tanpa melihatnya terlebih dahulu dalam pangkalan data. Selain menerima satu kunci utama sebagai parameter, kaedahmusnah
juga menerima berbilang kunci utama, atau menggunakan tatasusunan atau koleksi untuk menyimpan berbilang kunci utama:🎜🎜Padam model melalui pertanyaan🎜Anda juga boleh menjalankan kenyataan padam pada model. Dalam contoh ini, kami akan memadamkan semua penerbangan yang ditandakan sebagai tidak aktif. Seperti kemas kini kelompok, pemadaman kelompok tidak akan mencetuskan sebarang peristiwa model untuk model yang dipadamkan: 🎜rrreee🎜{note} Apabila melaksanakan pernyataan padam kelompok melalui Eloquent,
🎜🎜🎜memadam dan tidak akan dicetuskan.
acara model. Oleh itu, apabila melaksanakan kenyataan padam, contoh model tidak pernah diambil. 🎜🎜🎜Soft delete🎜🎜Selain benar-benar memadamkan rekod pangkalan data, Eloquent juga boleh model "padam lembut" Padam. Model yang dipadam lembut sebenarnya tidak dipadamkan daripada pangkalan data. Sebenarnya, atributdeleted_at
ditetapkan pada model dan nilainya ditulis pada pangkalan data. Jika nilaideleted_at
tidak kosong, ini bermakna model tersebut telah dipadamkan secara lembut. Jika anda ingin mendayakan fungsi pemadaman lembut model, anda perlu menggunakan ciriIlluminateDatabaseEloquentSoftDeletes
pada model: 🎜rrreee🎜{tip} Sifat
🎜Sudah tentu, anda perlu menambahSoftDeletes
akan secara automatik padam atributdeleted_at< /code> ditukar menjadi contoh
DateTime
/Carbon
🎜medan deleted_at
ke jadual data. Penghijrahan pangkalan data Laravel mempunyai kaedah untuk mencipta medan ini: 🎜rrreee🎜Sekarang, apabila anda menggunakan kaedahdelete
pada contoh model, tarikh dan masa semasa akan ditulis padadeleted_at kod> medan. Pada masa yang sama, hasil pertanyaan akan mengecualikan rekod yang telah dipadam lembut secara automatik. 🎜🎜Anda boleh menggunakan kaedah
untuk mengesahkan sama ada model semasa dipadam lembut: 🎜rrreee🎜🎜🎜🎜🎜🎜🎜Soal model yang dipadam lembut🎜🎜🎜dibuang Termasuk model yang dipadam lembut
Seperti yang dinyatakan sebelum ini, hasil pertanyaan akan mengecualikan hasil yang dipadam lembut secara automatik. Sudah tentu, anda boleh menggunakan kaedah
rrreeewithTrashed
untuk mendapatkan model termasuk model yang dipadam lembut:withTrashed
方法来获取包括软删除模型在内的模型:
rrreeewithTrashed
方法也可以用在 关联 查询:检索软删除模型
rrreeeonlyTrashed
方法 只 获取已软删除的模型:恢复软删除模型
有时会对软删除模型进行 「撤销」,在已软删除的数据上使用
rrreeerestore
方法即可恢复到有效状态:你也可以在查询中使用
rrreeerestore
方法,从而快速恢复多个模型。和其他批量」操作一样,这个操作不会触发模型的任何事件:类似
rrreeewithTrashed
方法,restore
方法也用在 关联上:永久删除
要真实删除数据时,使用
rrreeeforceDelete
方法即可:查询作用域
全局作用域
全局作用域可以给模型的查询都添加上约束。Laravel 的 软删除 功能就是利用此特性从数据库中获取 「未删除」的模型。 你可以编写你自己的全局作用域,很简单、方便的为每个模型查询都加上约束条件:
编写全局作用域
编写全局作用域很简单。定义一个实现
rrreeeIlluminateDatabaseEloquentScope
接口的类,并实现apply
这个方法。 根据你的需求,在apply
方法中加入查询的where
条件:{tip} 如果需要在 select 语句里添加字段,应使用
addSelect
方法,而不是select
方法。 这将有效防止无意中替换现有 select 语句的情况。应用全局作用域
要将全局作用域分配给模型,需要重写模型的
rrreeeboot
方法并使用addGlobalScope
方法:添加作用域后,对
User::all()
rrreeewithTrashed
Kaedah ini juga boleh digunakan dalam pertanyaan berkaitan:rrreeeDapatkan semula model yang dipadam lembut
rrreeehanya Disampah kaedah sahaja Dapatkan model yang dipadam lembut:Pulihkan model yang dipadam lembut🎜🎜Kadangkala model yang dipadam lembut "dibuat asal", dan anda boleh menggunakan kaedahrestore
pada data yang dipadam lembut untuk pulihkannya kepada status Sah: 🎜rrreee🎜Anda juga boleh menggunakan kaedahrestore
dalam pertanyaan untuk memulihkan berbilang model dengan cepat. Seperti operasi kelompok lain, operasi ini tidak akan mencetuskan sebarang peristiwa dalam model: 🎜rrreee🎜Serupa dengan kaedahwithTrashed
, kaedahrestore
juga digunakan pada persatuan: 🎜rrreee🎜🎜Pemadaman kekal🎜🎜Untuk memadam data sebenarnya, gunakan kaedahforceDelete
: 🎜rreee🎜🎜🎜Skop pertanyaan
🎜🎜🎜 Skop global
🎜Skop global boleh menambah kekangan pada pertanyaan model. Fungsi pemadaman lembut Laravel menggunakan ciri ini untuk mendapatkan model "tidak dipadam" daripada pangkalan data. Anda boleh menulis skop global anda sendiri dan menambah kekangan pada setiap pertanyaan model dengan sangat ringkas dan mudah: 🎜🎜🎜Tulis skop global🎜🎜 Menulis skop global adalah mudah. Tentukan kelas yang melaksanakan antara mukaIlluminateDatabaseEloquentScope
dan melaksanakan kaedahapply
. Mengikut keperluan anda, tambahkan syaratwhere
pertanyaan dalam kaedahapply
: 🎜rrreee🎜{tip} Jika anda perlu menambah medan dalam pernyataan pilih , anda harus menggunakan kaedah < code>addSelect, bukan kaedah
select
. Ini akan menghalang penyataan pilihan sedia ada daripada diganti secara tidak sengaja. 🎜🎜🎜Gunakan skop global🎜🎜Untuk menetapkan skop global kepada model, anda perlu mengatasiboot
model kaedah dan gunakan kaedahaddGlobalScope
: 🎜rrreee🎜Selepas menambah skop, pertanyaan untukUser::all()
akan menjana pernyataan pertanyaan SQL berikut: 🎜rrreee🎜🎜 🎜Skop Global Tanpa Nama 🎜🎜Eloquent juga membenarkan penggunaan penutupan untuk menentukan skop global, jadi tidak perlu menulis kelas berasingan untuk skop mudah: 🎜rrreee🎜🎜Batalkan skop global
Jika anda perlu membatalkan skop global untuk pertanyaan semasa, anda perlu menggunakan kaedah
rrreeetanpaGlobalScope
. Kaedah ini hanya menerima nama kelas skop global sebagai satu-satunya parameternya:withoutGlobalScope
方法。 该方法仅接受全局作用域类名作为它唯一的参数:或者,如果使用闭包定义全局作用域的话:
rrreee如果你需要取消部分或者全部的全局作用域的话,需要使用
rrreeewithoutGlobalScopes
方法:本地作用域
本地作用域允许定义通用的约束集合以便在应用程序中重复使用。例如,你可能经常需要获取所有 「流行」的用户。 要定义这样一个范围,只需要在对应的 Eloquent 模型方法前添加
scope
前缀:作用域总是返回一个查询构造器实例:
rrreee使用本地作用域
一旦定义了作用域,就可以在查询该模型时调用作用域方法。不过,在调用这些方法时不必包含
rrreeescope
前缀。甚至可以链式调用多个作用域,例如:借助
rrreeeor
查询运行符整合多个 Eloquent 模型,可能需要使用闭包回调:因为这样可能会有点麻烦,Laravel 提供了「高阶的」
rrreeeorWhere
方法,它允许你在链式调用作用域时不使用闭包:动态作用域
有时可能地希望定义一个可以接受参数的作用域。把额外参数传递给作用域就可以达到此目的。作用域参数要放在
rrreee$query
参数之后:这样就可以在调用作用域时传递参数了:
rrreee模型比较
有时可能需要判断两个模型是否「相同」。
Atau, jika penutupan digunakan untuk menentukan skop global:is
rrreeerrreee Jika anda perlu membatalkan sebahagian atau semua skop global, anda perlu menggunakan
tanpaSkopGlobal Kaedah: rrreee🎜Skop tempatan
🎜 Skop setempat membolehkan anda menentukan set kekangan biasa untuk digunakan semula merentas aplikasi. Sebagai contoh, anda mungkin sering perlu mendapatkan semua pengguna "popular". Untuk mentakrifkan skop sedemikian, cuma tambahkan awalanskop sebelum kaedah model Eloquent yang sepadan: 🎜🎜Skop sentiasa mengembalikan contoh pembina pertanyaan: 🎜rrreee 🎜🎜Gunakan skop tempatan🎜🎜Setelah skop ditakrifkan, kaedah skop boleh dipanggil apabila menanyakan model tersebut. Walau bagaimanapun, anda tidak perlu memasukkan awalanskop
semasa memanggil kaedah ini. Anda juga boleh membuat panggilan bersambung ke berbilang skop, contohnya: 🎜rrreee🎜Gunakan pelari pertanyaanatau
untuk menyepadukan berbilang model Eloquent Anda mungkin perlu menggunakan panggilan balik penutupan: 🎜rrreee🎜Kerana ini mungkin sedikit. menyusahkan, Laravel menyediakan kaedahorWhere
"perintah lebih tinggi", yang membolehkan anda merantai skop panggilan tanpa menggunakan penutupan: 🎜rrreee🎜🎜 Skop Dinamik🎜🎜 Kadangkala anda mungkin mahu menentukan skop yang menerima parameter. Ini boleh dicapai dengan menghantar parameter tambahan kepada skop. Parameter skop hendaklah diletakkan selepas parameterrrreee🎜 mentakrifkan dan memetakan peristiwa Eloquent, anda boleh menggunakan pendengar acara untuk mengendalikan acara ini. 🎜🎜🎜🎜$query
: 🎜rrreee🎜 Dengan cara ini anda boleh lulus parameter semasa memanggil skop: 🎜rrreee🎜🎜🎜🎜 Perbandingan model
🎜Kadangkala mungkin perlu untuk menentukan sama ada dua model adalah "sama". Kaedahis
boleh digunakan untuk mengesahkan dengan cepat sama ada dua model mempunyai kunci utama, jadual dan sambungan pangkalan data yang sama: 🎜rrreee🎜🎜🎜🎜🎜🎜Events
Model Eloquent mencetuskan beberapa peristiwa, membolehkan anda menyambung ke nod berikut bagi kitaran hayat model:
diambil
,mencipta
,dicipta
,kemas kini, dikemas kini, simpan, disimpan, memadam, dipadamkan< /code>, memulihkan
dandipulihkan
. Acara membolehkan anda melaksanakan kod apabila model tertentu disimpan atau dikemas kini dalam pangkalan data. Setiap peristiwa menerima contoh model melalui pembinanya. Acararetrieved
、creating
、created
、updating
、updated
、saving
、saved
、deleting
、deleted
、restoring
和restored
。事件允许你每当特定模型保存或更新数据库时执行代码。每个事件通过其构造器接受模型实例。retrieved
事件在现有模型从数据库中查找数据时触发。当新模型每一次保存时,creating
和created
事件被触发。如果数据库中已经存在模型并且调用了save
方法,updating
/updated
事件被触发。这些情况下,saving
/saved
事件也被触发。{note} 通过 Eloquent 进行批量更新时,被更新模型的
saved
和updated
事件不会被触发。这是因为批量更新时,并没有真的获取模型。首先,在 Eloquent 模型上定义一个
rrreee$dispatchesEvents
属性,将 Eloquent 模型生命周期的几个节点映射到你自己的 event 类 :定义并且映射了 Eloquent 事件,就可以使用 event 监听器 listeners 处理这些事件了。
观察者
定义观察者
如果在一个模型上监听了多个事件,可以使用观察者来将这些监听器组织到一个单独的类中。观察者类的方法名映射到你希望监听的 Eloquent 事件。 这些方法都以模型作为其唯一参数。
rrreeemake:observer
Artisan 命令可以快速建立新的观察者类:此命令将在
rrreeeApp/Observers
文件夹放置新的观察者类。如果这个目录不存在,Artisan 将替你创建。使用如下方式开启观察者:在你希望观察的模型上使用
observe
方法注册观察者。也可以在服务提供者的boot
方法注册观察者。下面是在AppServiceProvider
diambil dicetuskan apabila model sedia ada mencari data daripada pangkalan data. Setiap kali model baharu disimpan, peristiwa membuat
danmembuat
dicetuskan. Jika model sudah wujud dalam pangkalan data dan kaedahsave
dipanggil, peristiwakemas kini
/updated
akan dicetuskan. Dalam kes ini, peristiwasimpan
/simpan
juga dicetuskan. Mula-mula, tentukan atribut$dispatchesEvents
pada model Eloquent untuk memetakan beberapa nod kitaran hayat model Eloquent ke kelas acara anda sendiri:🎜Pemerhati
🎜Tentukan Pemerhati
🎜Jika anda mendengar berbilang acara pada model, anda boleh menggunakan pemerhati untuk menyusun pendengar ini ke dalam kelas yang berasingan. Nama kaedah kelas pemerhati memetakan kepada peristiwa Eloquent yang anda ingin dengar. Kaedah ini semua mengambil model sebagai satu-satunya parameter mereka.make:observer
Perintah Artisan boleh mencipta kelas pemerhati baharu dengan pantas: 🎜rrreee🎜Arahan ini akan meletakkan kelas pemerhati baharu dalam folderApp/Observers
. Jika direktori ini tidak wujud, Artisan akan menciptanya untuk anda. Gunakan kaedah berikut untuk membolehkan pemerhati: 🎜rrreee🎜Gunakan kaedahobserve
untuk mendaftarkan pemerhati pada model yang ingin anda perhatikan. Pemerhati juga boleh didaftarkan dalam kaedahboot
pembekal perkhidmatan. Berikut ialah contoh mendaftarkan pemerhati dalamAppServiceProvider
: 🎜rrreee🎜Artikel ini mula-mula muncul di tapak web 🎜LearnKu.com🎜. 🎜🎜Laman web PHP Cina
config/database.php
. Untuk maklumat lanjut tentang konfigurasi pangkalan data, lihat dokumentasi.app
, tetapi anda boleh meletakkannya di mana-mana sahaja di mana ia boleh dimuatkan secara automatik berdasarkan failcomposer.json
. Semua model Eloquent mewarisi daripada kelasIlluminateDatabaseEloquentModel
. Cara paling mudah untuk mencipta model ialah menggunakan perintahmake:model
Artisan:
- Sambungan pangkalan data