Démarrage rapide
Eloquent : Démarrage
- Introduction
- Définition du modèle
- Récupération du modèle
- Récupérer un seul modèle/collection
- Insérer et mettre à jour le modèle
- Insérer
- Mettre à jour
- Autres méthodes de création "Supprimer le modèle" scope Domaine
- Introduction L'ORM éloquent de Laravel fournit une implémentation ActiveRecord belle et concise pour interagir avec l'interaction de la base de données. Chaque table de base de données possède un « modèle » correspondant utilisé pour interagir avec la table. Vous pouvez interroger les données de la table de données via le modèle et insérer de nouveaux enregistrements dans la table de données.
Avant de commencer, assurez-vous de configurer la connexion à la base de données dans - Définition du modèle
- Tout d'abord, créez un modèle Eloquent. Les modèles se trouvent généralement dans le répertoire
- Le moyen le plus simple de créer un modèle est d'utiliser la commande
make:model
Artisan :php artisan make:model Flight
Si vous souhaitez générer une migration de base de données lors de la génération du modèle, vous pouvez utiliser
app
, mais vous pouvez les placer n'importe où où ils peuvent être automatiquement chargés en fonction du fichiercomposer.json
. Tous les modèles Eloquent héritent de la classeIlluminateDatabaseEloquentModel
.--migration< /code> ou
-m
Options :php artisan make:model Flight --migration php artisan make:model Flight -m
- Le moyen le plus simple de créer un modèle est d'utiliser la commande
config/database.php
. Pour plus d'informations sur la configuration de la base de données, consultez la documentation. Conventions de modèle éloquentes
Maintenant, regardons un exemple du modèleFlight
, que nous utiliserons pour récupérer et stocker les informations de données de la table de base de données flights
: <?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ // }
Nom de la table de données
Veuillez noter que nous n'indiquons pas à Eloquent quelle table de données utiliser pour notre modèle Flight
. Sauf si un autre nom est explicitement spécifié, le pluriel de la classe, « serpents », sera utilisé comme nom de table. Par conséquent, dans ce cas, Eloquent supposera que le modèle Flight
stocke les données de la table de données flights
. Vous pouvez spécifier une table de données personnalisée en définissant l'attribut table
sur le modèle : 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, ]; }
Clé primaireEloquent assumera également que chaque table de données a une colonne de clé primaire nommée id
. Vous pouvez remplacer la convention en définissant un attribut $primaryKey
protégé.
int
par défaut. Si vous souhaitez utiliser une clé primaire non incrémentée ou non numérique, vous devez définir la propriété publique $incrementing
sur false
. Si votre clé primaire n'est pas un entier, vous devez définir la propriété protégée $keyType
sur le modèle sur string
. created_at
et updated_at
. Si vous ne souhaitez pas qu'Eloquent gère automatiquement ces deux colonnes, veuillez définir l'attribut $timestamps
dans le modèle sur false
: <?php $flights = App\Flight::all(); foreach ($flights as $flight) { echo $flight->name; }
$dateFormat
dans votre modèle. Cet attribut détermine comment l'attribut date est stocké dans la base de données et le format dans lequel le modèle est sérialisé dans un tableau ou JSON : 🎜$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();🎜 Si vous devez personnaliser le nom du champ pour stocker les horodatages, vous pouvez définir
CREATED_AT
dans le modèle et la valeur de la constante UPDATED_AT
: 🎜$flight = App\Flight::where('number', 'FR 900')->first(); $freshFlight = $flight->fresh();
$connection
: 🎜$flight = App\Flight::where('number', 'FR 900')->first(); $flight->number = 'FR 456';$flight->refresh(); $flight->number; // "FR 900"🎜🎜🎜
Valeurs d'attribut par défaut
🎜Si vous souhaitez définir des valeurs par défaut pour certains attributs du modèle, vous pouvez définir l'attribut$attributes
sur le modèle : 🎜$flights = $flights->reject(function ($flight) { return $flight->cancelled; });🎜🎜🎜 🎜🎜🎜🎜Récupération du modèle🎜🎜Après avoir créé le modèle et sa table de base de données associée, vous pouvez interroger les données de la base de données. Considérez chaque modèle Eloquent comme un puissant générateur de requêtes que vous pouvez utiliser pour interroger plus rapidement la table de données associée. Par exemple : 🎜
foreach ($flights as $flight) { echo $flight->name; }🎜🎜
Contraintes supplémentaires
La méthode all
d'Eloquent renverra tous les résultats du modèle. Puisque chaque modèle Eloquent agit comme un constructeur de requêtes, vous pouvez également ajouter des conditions de requête, puis utiliser la méthode get
pour obtenir les résultats de la requête : 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} Parce que les modèles Eloquent sont également des requêtes constructors constructeur, vous devriez donc également lire toutes les méthodes disponibles pour le générateur de requêtes. Vous pouvez utiliser ces méthodes dans les requêtes Eloquent.🎜Recharger le modèle🎜🎜Vous pouvez recharger en utilisant les méthodesfresh
etrefresh
Modèle. La méthodefresh
récupère à nouveau le modèle de la base de données. Les instances de modèle existantes ne sont pas affectées : 🎜App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);🎜 La méthoderefresh
réaffecte un modèle existant avec de nouvelles données de la base de données. De plus, les relations déjà chargées seront rechargées : 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 可以被批量赋值的属性。 * * @var array */ protected $fillable = ['name']; }🎜🎜🎜Collections
🎜 Les méthodesall
etget
dans Eloquent peuvent interroger plusieurs résultats et renvoyer une instanceIlluminateDatabaseEloquentCollection
. La classeCollection
fournit un certain nombre de fonctions d'assistance pour gérer les résultats Eloquent : 🎜$flight = App\Flight::create(['name' => 'Flight 10']);🎜Vous pouvez parcourir la collection comme un tableau : 🎜$flight->fill(['name' => 'Flight 22']);🎜🎜🎜Chunk results
🎜Si vous devez traiter des milliers de résultats Eloquent, utilisez la commandechunk
. La méthodechunk
récupère les "morceaux" dans le modèle Eloquent et les fournit auClosure
spécifié pour traitement. Lors du traitement de grands ensembles de résultats, utilisez la méthodechunk
pour économiser de la mémoire : 🎜<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 不可批量赋值的属性。 * * @var array */ protected $guarded = ['price']; }🎜Le premier paramètre transmis à la méthode est la quantité de données que vous souhaitez que chaque "chunk" reçoive. La fermeture est passée en deuxième paramètre et est appelée chaque fois qu'un morceau est récupéré de la base de données. Il exécutera la requête de base de données et transmettra les résultats fragmentés récupérés à la méthode de fermeture. 🎜🎜🎜Utilisation des curseurs🎜🎜La méthodecursor
permet de parcourir la base de données à l'aide d'un curseur, qui effectue uniquement une requête. Lors du traitement de grandes quantités de données, la méthodecursor
peut réduire considérablement l'utilisation de la mémoire : 🎜/** * 不可以批量赋值的属性。 * * @var array */ protected $guarded = [];🎜🎜🎜Récupérer un seul modèle/collection
🎜En plus de récupérer tous les enregistrements d'une table de données spécifiée, vous pouvez utiliserfind
oufirst< /code> méthode pour récupérer un seul enregistrement. Ces méthodes renvoient une seule instance de modèle au lieu d'une collection de modèles : 🎜
// 通过 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]);🎜 Vous pouvez également appeler la méthodefind
avec un tableau de clés primaires comme argument, qui renverra une collection d'enregistrements correspondants : 🎜// 如果有从奥克兰到圣地亚哥的航班,则价格定为99美元。 // 如果没匹配到存在的模型,则创建一个。 $flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99] );🎜🎜『Not Found』Exception
Parfois, vous souhaitez lever une exception lorsqu'un modèle n'est pas trouvé. Ceci est très utile dans les contrôleurs et le routage. Les méthodes
findOrFail
etfirstOrFail
récupéreront le premier résultat de la requête. S'il n'est pas trouvé,IlluminateDatabaseEloquentModelNotFoundException
sera levée :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();If. Si aucune exception n'est détectée, une réponse404
sera automatiquement renvoyée à l'utilisateur. Autrement dit, lorsque vous utilisez ces méthodes, il n'est pas nécessaire d'écrire un chèque pour renvoyer une réponse404
:$flight->history()->withTrashed()->get();Récupérer une collection
Vous pouvez également utiliser lecount
, lasum
, lemax fournis par le générateur de requêtes
et d'autres fonctions d'agrégation. Ces méthodes renverront simplement la valeur scalaire appropriée plutôt qu'une instance de modèle :$flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();🎜🎜🎜🎜Insérer et mettre à jour le modèle
🎜🎜🎜🎜Insérer
🎜Aller à ajoutez un nouvel enregistrement à la base de données, créez d'abord une nouvelle instance de modèle, définissez les propriétés de l'instance, puis appelez la méthodesave
: 🎜$flight->restore();🎜Dans cet exemple, nous modifions le paramètre de requête HTTPname
Attribué à l'attributname
de l'instance de modèleAppFlight
. Lorsque la méthodesave
est appelée, un nouvel enregistrement sera inséré. Les horodatagescreated_at
etupdated_at
seront définis automatiquement et ne nécessiteront pas d'affectation manuelle. 🎜🎜🎜🎜🎜update
🎜save
peut également être utilisée Mettez à jour un modèle qui existe déjà dans la base de données. Pour mettre à jour le modèle, vous devez d'abord le récupérer, définir les propriétés à mettre à jour, puis appeler la méthodesave
. De même, l'horodatageupdated_at
sera mis à jour automatiquement, il n'est donc pas nécessaire d'attribuer manuellement la valeur : 🎜App\Flight::withTrashed() ->where('airline_id', 1) ->restore();🎜🎜Mise à jour par lots🎜 🎜Vous pouvez également mettre à jour la correspondance de plusieurs modèles pour les conditions de requête. Dans cet exemple, tous les vols avecactif
etdestination
versSan Diego
seront marqués comme retardés : 🎜$flight->history()->restore();🎜update
accepte un tableau dont les clés sont des noms de champs et les données sont des valeurs. 🎜🎜{note} Lors de la mise à jour par lots via Eloquent, le modèle mis à jour ne déclenchera pas les événementssaved
etmis à jour
. Car lors des mises à jour batch, le modèle n’est jamais récupéré. 🎜🎜🎜🎜🎜🎜🎜🎜Affectation par lots
Vous pouvez également utiliser la méthode
create
pour enregistrer un nouveau modèle, qui renverra une instance de modèle. Cependant, avant de l'utiliser, vous devez spécifier l'attributfillable
ouguarded
sur le modèle, car tous les modèles Eloquent ne peuvent pas être attribués par lot par défaut.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
方法会通过给定的 列 / 值 来匹配数据库中的数据。如果在数据库中找不到对应的模型, 则会从第一个参数的属性乃至第二个参数的属性中创建一条记录插入到数据库。Lorsque l'utilisateur transmet un paramètre inattendu via une requête HTTP et que ce paramètre modifie un champ de la base de données que vous n'avez pas besoin de modifier. Par exemple : un utilisateur malveillant peut transmettre le paramètre
firstOrNew
方法像firstOrCreate
方法一样尝试通过给定的属性查找数据库中的记录。不同的是,如果firstOrNew
方法找不到对应的模型,会返回一个新的模型实例。注意firstOrNew
返回的模型实例尚未保存到数据库中,你需要手动调用save
is_admin
via une requête HTTP, puis le transmettre à la méthodecreate
. Cette opération permet à l'utilisateur de se mettre à niveau vers un. administrateur. Donc, avant de commencer, vous devez définir quels attributs du modèle peuvent être attribués par lots. Vous pouvez le faire via l'attribut$fillable
sur le modèle. Par exemple : laissez l'attributname
du modèleFlight
être attribué par lots : 🎜User::withoutGlobalScope(AgeScope::class)->get();🎜Une fois que nous avons configuré les attributs pouvant être attribués par lots, nous pouvons transmettre La méthodecreate code> insère de nouvelles données dans la base de données. La méthode
create
renverra l'instance de modèle enregistrée : 🎜User::withoutGlobalScope('age')->get();🎜Si vous disposez déjà d'une instance de modèle, vous pouvez transmettre un tableau à la méthodefill
pour attribuer des valeurs : 🎜// 取消所有的全局作用域... User::withoutGlobalScopes()->get(); // 取消部分全局作用域... User::withoutGlobalScopes([ FirstScope::class, SecondScope::class ])->get();🎜Attributs protégés
🎜$fillable
peut être considéré comme une "liste blanche" pour l'affectation par lots, vous pouvez également utilisez l'attribut$guarded
pour y parvenir. L'attribut$guarded
contient un tableau qui n'autorise pas l'affectation par lots. En d'autres termes,$guarded
fonctionnera davantage comme une « liste noire ». Remarque : Vous ne pouvez utiliser qu'un seul élément parmi$fillable
ou$guarded
, pas les deux en même temps. Dans l'exemple suivant, à l'exception de l'attributprice
, tous les autres attributs peuvent se voir attribuer des valeurs par lots : 🎜<?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); } }🎜 Si vous souhaitez que tous les attributs se voient attribuer des valeurs par lots, vous pouvez modifier$guarded
comme étant un tableau vide : 🎜$users = App\User::popular()->active()->orderBy('created_at')->get();🎜🎜🎜🎜 Autres méthodes de création🎜🎜🎜Voici deux méthodes possibles pour l'affectation par lots :
firstOrCreate
/firstOrNew
firstOrCreate
etfirstOrNew
. La méthodefirstOrCreate
fera correspondre les données de la base de données avec la colonne/valeur donnée. Si le modèle correspondant est introuvable dans la base de données, un enregistrement sera créé à partir des attributs du premier paramètre et même des attributs du deuxième paramètre et inséré dans la base de données. 🎜🎜La méthodefirstOrNew
, comme la méthodefirstOrCreate
, tente de trouver un enregistrement dans la base de données par l'attribut donné. La différence est que si la méthodefirstOrNew
ne trouve pas le modèle correspondant, elle renverra une nouvelle instance de modèle. Notez que l'instance de modèle renvoyée parfirstOrNew
n'a pas été enregistrée dans la base de données, vous devez appeler manuellement la méthodesave
pour enregistrer : 🎜$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
Vous pouvez également rencontrer des situations dans lesquelles vous souhaitez mettre à jour un modèle existant ou créer un nouveau modèle s'il n'existe pas. Laravel fournit la méthodeupdateOrCreate
qui peut être implémentée en une seule étape. Comme la méthodefirstOrCreate
,updateOrCreate
correspond au modèle correspondant, il n'est donc pas nécessaire d'appeler la méthodesave()
:<?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) { // } }Supprimer le modèle
Vous pouvez appeler la méthodedelete
sur l'instance du modèle pour supprimer l'instance :<?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() { // } }Supprimer le modèle par clé primaireDans l'exemple ci-dessus, vous devez accéder à la base de données avant Appel àrrreeedelete
Trouver le modèle correspondant dans . En fait, si vous connaissez la clé primaire d'un modèle, vous pouvez directement utiliser la méthodedestroy
pour supprimer le modèle sans le rechercher au préalable dans la base de données. En plus d'accepter une seule clé primaire comme paramètre, la méthodedestroy
accepte également plusieurs clés primaires, ou utilise un tableau ou une collection pour enregistrer plusieurs clés primaires :🎜🎜Supprimer le modèle via une requête🎜Vous pouvez également exécuter des instructions de suppression sur le modèle. Dans cet exemple, nous supprimerons tous les vols marqués comme inactifs. Comme la mise à jour par lots, la suppression par lots ne déclenchera aucun événement de modèle pour le modèle supprimé : 🎜rrreee🎜{note} Lors de l'exécution d'une instruction de suppression par lots via Eloquent, la🎜🎜🎜suppression
et lene seront pas déclenché. événement de modèle supprimé
. Par conséquent, lors de l’exécution d’une instruction delete, les exemples de modèles ne sont jamais récupérés. 🎜🎜🎜Suppression logicielle🎜🎜En plus de supprimer réellement les enregistrements de la base de données, Eloquent peut également Modèle "suppression logicielle" Supprimer ". Un modèle supprimé de manière réversible n’est pas réellement supprimé de la base de données. En fait, l'attributdeleted_at
est défini sur le modèle et sa valeur est écrite dans la base de données. Si la valeurdeleted_at
n'est pas vide, cela signifie que le modèle a été supprimé de manière logicielle. Si vous souhaitez activer la fonction de suppression logicielle du modèle, vous devez utiliser le traitIlluminateDatabaseEloquentSoftDeletes
sur le modèle : 🎜rrreee🎜{tip} Le trait🎜Bien sûr, vous devez ajouter leSoftDeletes
sera automatiquement supprimer l'attributdeleted_at< /code> est converti en une instance
DateTime
/Carbon
🎜champ delete_at
à la table de données. La migration de la base de données de Laravel a une méthode pour créer ce champ : 🎜rrreee🎜Maintenant, lorsque vous utilisez la méthodedelete
sur l'instance du modèle, la date et l'heure actuelles seront écrites dans ledeleted_at champ code>. Dans le même temps, les résultats de la requête excluront automatiquement les enregistrements qui ont été supprimés de manière logicielle. 🎜🎜Vous pouvez utiliser la méthode
trashed
pour vérifier si le modèle actuel est supprimé de manière logicielle : 🎜rrreee🎜🎜🎜🎜🎜🎜🎜Interrogez le modèle supprimé de manière logicielle🎜🎜🎜Y compris les modèles supprimés de manière logicielle
Comme mentionné précédemment, les résultats de la requête excluront automatiquement les résultats supprimés de manière logicielle. Bien sûr, vous pouvez utiliser la méthode
rrreeewithTrashed
pour obtenir des modèles incluant des modèles supprimés de manière logicielle :withTrashed
方法来获取包括软删除模型在内的模型:rrreee
withTrashed
方法也可以用在 关联 查询:检索软删除模型
rrreee
onlyTrashed
方法 只 获取已软删除的模型:恢复软删除模型
有时会对软删除模型进行 「撤销」,在已软删除的数据上使用
rrreeerestore
方法即可恢复到有效状态:你也可以在查询中使用
rrreeerestore
方法,从而快速恢复多个模型。和其他批量」操作一样,这个操作不会触发模型的任何事件:类似
rrreeewithTrashed
方法,restore
方法也用在 关联上:永久删除
要真实删除数据时,使用
rrreeeforceDelete
方法即可:查询作用域
全局作用域
全局作用域可以给模型的查询都添加上约束。Laravel 的 软删除 功能就是利用此特性从数据库中获取 「未删除」的模型。 你可以编写你自己的全局作用域,很简单、方便的为每个模型查询都加上约束条件:
编写全局作用域
编写全局作用域很简单。定义一个实现
rrreeeIlluminateDatabaseEloquentScope
接口的类,并实现apply
这个方法。 根据你的需求,在apply
方法中加入查询的where
条件:{tip} 如果需要在 select 语句里添加字段,应使用
addSelect
方法,而不是select
方法。 这将有效防止无意中替换现有 select 语句的情况。应用全局作用域
要将全局作用域分配给模型,需要重写模型的
rrreeeboot
方法并使用addGlobalScope
方法:添加作用域后,对
La méthodeUser::all()
rrreeewithTrashed
peut également être utilisée dans des requêtes associées :rrreeeRécupérer les modèles supprimés de manière logicielle
rrreee
onlyTrashed
Méthode uniquement Récupérer les modèles supprimés de manière logicielle :Restaurer le modèle supprimé de manière logicielle🎜🎜Parfois, le modèle supprimé de manière logicielle est "annulé", et vous pouvez utiliser la méthoderestaurer
sur les données supprimées de manière logicielle pour restaurez-le à l'état valide : 🎜rrreee🎜Vous pouvez également utiliser la méthoderestore
dans une requête pour restaurer rapidement plusieurs modèles. Comme les autres opérations batch, cette opération ne déclenchera aucun événement dans le modèle : 🎜rrreee🎜Similaire à la méthodewithTrashed
, la méthoderestore
est également utilisée sur les associations : 🎜rrreee🎜🎜Suppression permanente🎜🎜Pour supprimer réellement des données, utilisez la méthodeforceDelete
: 🎜rrreee🎜🎜🎜Portée de la requête
🎜🎜🎜Portée globale
🎜La portée globale peut ajouter des contraintes aux requêtes de modèle. La fonction de suppression logicielle de Laravel utilise cette fonctionnalité pour obtenir des modèles "non supprimés" de la base de données. Vous pouvez écrire votre propre portée globale et ajouter des contraintes à chaque requête de modèle très simplement et facilement : 🎜🎜🎜Écrire une portée globale🎜🎜 Écrire une portée globale est facile. Définissez une classe qui implémente l'interfaceIlluminateDatabaseEloquentScope
et implémentez la méthodeapply
. Selon vos besoins, ajoutez la conditionwhere
de la requête dans la méthodeapply
: 🎜rrreee🎜{tip} Si vous devez ajouter des champs dans l'instruction select , vous devez utiliser la méthode < code>addSelect, et non la méthodeselect
. Cela empêchera efficacement le remplacement par inadvertance des instructions select existantes. 🎜🎜🎜Appliquer la portée globale🎜🎜Pour attribuer la portée globale à un modèle, vous devez remplacer leboot
du modèle. et utilisez la méthodeaddGlobalScope
: 🎜rrreee🎜Après avoir ajouté la portée, la requête pourUser::all()
générera l'instruction de requête SQL suivante : 🎜rrreee🎜🎜 🎜Portée globale anonyme 🎜🎜Eloquent permet également l'utilisation de fermetures pour définir des portées globales, il n'est donc pas nécessaire d'écrire une classe distincte pour une portée simple : 🎜rrreee🎜🎜Annuler la portée globale
Si vous devez annuler la portée globale de la requête actuelle, vous devez utiliser la méthode
rrreeesansGlobalScope
. Cette méthode n'accepte que le nom de classe de portée globale comme seul paramètre :withoutGlobalScope
方法。 该方法仅接受全局作用域类名作为它唯一的参数:或者,如果使用闭包定义全局作用域的话:
rrreee如果你需要取消部分或者全部的全局作用域的话,需要使用
rrreeewithoutGlobalScopes
方法:本地作用域
本地作用域允许定义通用的约束集合以便在应用程序中重复使用。例如,你可能经常需要获取所有 「流行」的用户。 要定义这样一个范围,只需要在对应的 Eloquent 模型方法前添加
scope
前缀:作用域总是返回一个查询构造器实例:
rrreee使用本地作用域
一旦定义了作用域,就可以在查询该模型时调用作用域方法。不过,在调用这些方法时不必包含
rrreeescope
前缀。甚至可以链式调用多个作用域,例如:借助
rrreeeor
查询运行符整合多个 Eloquent 模型,可能需要使用闭包回调:因为这样可能会有点麻烦,Laravel 提供了「高阶的」
rrreeeorWhere
方法,它允许你在链式调用作用域时不使用闭包:动态作用域
有时可能地希望定义一个可以接受参数的作用域。把额外参数传递给作用域就可以达到此目的。作用域参数要放在
rrreee$query
参数之后:这样就可以在调用作用域时传递参数了:
rrreee模型比较
有时可能需要判断两个模型是否「相同」。
Ou, si une fermeture est utilisée pour définir la portée globale :is
rrreeerrreee Si vous devez annuler une partie ou la totalité de la portée globale, vous devez utiliser Méthode
withoutGlobalScopes
: rrreee🎜Portées locales
🎜 La portée locale vous permet de définir un ensemble commun de contraintes à réutiliser dans une application. Par exemple, vous devrez peut-être souvent obtenir tous les utilisateurs « populaires ». Pour définir une telle portée, ajoutez simplement le préfixescope
avant la méthode du modèle Eloquent correspondante : 🎜🎜Scope renvoie toujours une instance du générateur de requêtes : 🎜rrreee🎜🎜Utiliser des portées locales🎜🎜Une fois qu'une portée est définie, les méthodes de portée peuvent être appelées lors de l'interrogation de ce modèle. Cependant, il n'est pas nécessaire d'inclure le préfixescope
lors de l'appel de ces méthodes. Vous pouvez même chaîner des appels vers plusieurs portées, par exemple : 🎜rrreee🎜Utilisez l'exécuteur de requêtesou
pour intégrer plusieurs modèles Eloquent. Vous devrez peut-être utiliser des rappels de fermeture : 🎜rrreee🎜Parce que cela peut être un peu. gênant, Laravel fournit la méthodeorWhere
"d'ordre supérieur", qui vous permet d'enchaîner les portées d'appel sans utiliser de fermetures : 🎜rrreee🎜🎜 Portée dynamique🎜🎜Parfois, vous souhaiterez peut-être définir une portée qui accepte des paramètres. Ceci peut être réalisé en transmettant des paramètres supplémentaires à la portée. Les paramètres de scope doivent être placés après le paramètre$query
: 🎜rrreee🎜 De cette façon, vous pouvez transmettre des paramètres lors de l'appel du scope : 🎜rrreee🎜🎜🎜🎜rrreee🎜 définit et mappe les événements Eloquent, vous peut utiliser des écouteurs d'événements pour gérer ces événements. 🎜🎜🎜🎜Comparaison de modèles
🎜Parfois, il peut être nécessaire de déterminer si deux modèles sont "identiques". La méthodeis
peut être utilisée pour vérifier rapidement si deux modèles ont les mêmes clés primaires, tables et connexions à la base de données : 🎜rrreee🎜🎜🎜🎜🎜🎜Événements
Le modèle Eloquent déclenche plusieurs événements, vous permettant de vous connecter aux nœuds suivants du cycle de vie du modèle :
récupéré
,création
,créé
,mise à jour
,mis à jour
,enregistrement
,enregistré
,suppression
,supprimé< /code>,
restauration
etrestauré
. Les événements vous permettent d'exécuter du code chaque fois qu'un modèle spécifique est enregistré ou mis à jour dans la base de données. Chaque événement accepte une instance de modèle via son constructeur. L'événementretrieved
、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
retrieved
est déclenché lorsqu'un modèle existant recherche des données dans la base de données. Chaque fois qu'un nouveau modèle est enregistré, les événementscreating
etcreated
sont déclenchés. Si le modèle existe déjà dans la base de données et que la méthodesave
est appelée, les événementsupdating
/updated
sont déclenchés. Dans ces cas, les événementssave
/saved
sont également déclenchés. Tout d'abord, définissez un attribut$dispatchesEvents
sur le modèle Eloquent pour mapper plusieurs nœuds du cycle de vie du modèle Eloquent à votre propre classe d'événements :🎜Observateurs
🎜Définir les observateurs
🎜Si vous écoutez plusieurs événements sur un modèle, vous pouvez utiliser des observateurs pour organiser ces auditeurs dans une classe distincte. Les noms de méthode de la classe d'observateur correspondent aux événements Eloquent que vous souhaitez écouter. Ces méthodes prennent toutes le modèle comme seul paramètre.make:observer
La commande Artisan peut créer rapidement une nouvelle classe d'observateur : 🎜rrreee🎜Cette commande placera une nouvelle classe d'observateur dans le dossierApp/Observers
. Si ce répertoire n'existe pas, Artisan le créera pour vous. Utilisez la méthode suivante pour activer un observateur : 🎜rrreee🎜Utilisez la méthodeobserver
pour enregistrer un observateur sur le modèle que vous souhaitez observer. Les observateurs peuvent également être enregistrés dans la méthodeboot
du fournisseur de services. Voici un exemple d'enregistrement d'un observateur dansAppServiceProvider
: 🎜rrreee🎜Cet article est apparu pour la première fois sur le site Web 🎜LearnKu.com🎜. 🎜🎜