Maison  >  Article  >  cadre php  >  Compétences pratiques essentielles de Laravel Eloquent couramment utilisées

Compétences pratiques essentielles de Laravel Eloquent couramment utilisées

Guanhui
Guanhuiavant
2020-06-13 18:24:442600parcourir

Compétences pratiques essentielles de Laravel Eloquent couramment utilisées

L'ORM éloquent semble être un mécanisme simple, mais sous le capot, il y a de nombreuses fonctions semi-cachées et des moyens peu connus pour obtenir plus de fonctionnalités. Dans cet article, je vais vous montrer quelques conseils.

1. Incrémenter et décrémenter

Pour remplacer l'implémentation suivante :

$article = Article::find($article_id);
$article->read_count++;
$article->save();
Vous pouvez faire ceci :

$article = Article::find($article_id);
$article->increment('read_count');
Les méthodes suivantes peuvent également être implémentées :

Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1
2. Exécuter la méthode Si la méthode X ne parvient pas à s'exécuter, la méthode Y sera exécutée."

Exemple 1 --

:

Pour remplacer l'implémentation du code suivant : findOrFail()

$user = User::find($id);
if (!$user) { abort (404); }
Vous pouvez écrire comme ceci :

$user = User::findOrFail($id);
Exemple 2 --

:

Pour remplacer l'implémentation du code suivant : firstOrCreate()

$user = User::where('email', $email)->first();
if (!$user) {
  User::create([
    'email' => $email
  ]);
}
Écrivez simplement ceci :

$user = User::firstOrCreate(['email' => $email]);
3 La méthode boot() du modèle

Dans un modèle Eloquent, il existe un endroit magique appelé

, où vous pouvez remplacer le comportement par défaut :

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // 写点日志啥的
            // 覆盖一些属性,类似这样 $model->something = transform($something);
        });
    }
}

Définissez la valeur de certains champs lors de la création de l'objet modèle, probablement le plus One des exemples populaires. Voyons ce que vous devez faire si vous souhaitez générer un champ UUID lors de la création d'un objet modèle.

public static function boot()
{
  parent::boot();
  self::creating(function ($model) {
    $model->uuid = (string)Uuid::generate();
  });
}
boot()4. Association avec conditions et tri

Manière générale de définir l'association :

public function users() {
    return $this->hasMany('App\User');
}

Le savez-vous ? Vous pouvez également ajouter

ou

?

sur la base de ce qui précède. Par exemple, si vous souhaitez associer certains types d'utilisateurs et utiliser le champ email pour trier, vous pouvez faire ceci :

.

public function approvedUsers() {
    return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
}
where5. Caractéristiques du modèle : heure, ajout, etc. orderBy
Certains paramètres du modèle Eloquent se présentent sous la forme d'attributs de classe. Les plus couramment utilisés sont :
class User extends Model {
    protected $table = 'users';
    protected $fillable = ['email', 'password']; // 可以被批量赋值字段,如 User::create() 新增时,可使用字段
    protected $dates = ['created_at', 'deleted_at']; // 需要被Carbon维护的字段名
    protected $appends = ['field1', 'field2']; // json返回时,附加的字段
}

Non seulement ceux-ci, mais aussi :

protected $primaryKey = 'uuid'; // 更换主键
public $incrementing = false; // 设置 不自增长
protected $perPage = 25; // 定义分页每页显示数量(默认15)
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at'; //重写 时间字段名
public $timestamps = false; // 设置不需要维护时间字段

et plus encore. Pour plus de détails, reportez-vous au résumé du document Model class pour apprendre. toutes les fonctionnalités.

6. Interrogez plusieurs enregistrements par ID

Tout le monde connaît la méthode

, n'est-ce pas ?

$user = User::find(1);

Je suis très surpris que peu de gens sachent que cette méthode peut accepter des tableaux de plusieurs identifiants comme paramètres :

$users = User::find([1,2,3]);
find()7 WhereX

Il existe une manière élégante de procéder. type de code :

$users = User::where('approved', 1)->get();

est converti en ce type de code :

$users = User::whereApproved(1)->get();

Oui, vous avez bien lu, utilisez le nom du champ comme suffixe et ajoutez-le à l'arrière de

, et il fonctionnera par la méthode magique .

De plus, il existe quelques méthodes prédéfinies liées au temps dans Eloquent :

User::whereDate('created_at', date('Y-m-d'));
User::whereDay('created_at', date('d'));
User::whereMonth('created_at', date('m'));
User::whereYear('created_at', date('Y'));
where8. Tri par relation

Une "technique" plus compliquée. Voulez-vous trier les sujets du forum par derniers messages ? C'est une exigence courante d'avoir les sujets les plus récemment mis à jour dans un forum en haut, n'est-ce pas ?

Tout d'abord, définissez une relation distincte pour le dernier message du sujet :

public function latestPost()
{
    return $this->hasOne(\App\Post::class)->latest();
}

Ensuite, dans le contrôleur, nous pouvons implémenter cette "magie" :

$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');

9. :when() -- Plus besoin d'utiliser if-else

Beaucoup de gens aiment utiliser "if-else" pour écrire des conditions de requête, comme ceci :

if (request('filter_by') == 'likes') {
    $query->where('likes', '>', request('likes_amount', 0));
}
if (request('filter_by') == 'date') {
    $query->orderBy('created_at', request('ordering_rule', 'desc'));
}

Il existe une meilleure méthode Méthode- -Utiliser

$query = Author::query();
$query->when(request('filter_by') == 'likes', function ($q) {
    return $q->where('likes', '>', request('likes_amount', 0));
});
$query->when(request('filter_by') == 'date', function ($q) {
    return $q->orderBy('created_at', request('ordering_rule', 'desc'));
});
Cela n'a peut-être pas l'air très élégant, mais sa fonction puissante est de transmettre des paramètres :

$query = User::query();
$query->when(request('role', false), function ($q, $role) {
    return $q->where('role_id', $role);
});
$authors = $query->get();
when()10 un à plusieurs renvoie l'objet modèle par défaut.

Supposons qu'il y ait une situation dans laquelle vous souhaitez afficher l'auteur de l'article, alors le code du modèle est :

{{ $post->author->name }}

Mais si les informations sur l'auteur sont supprimées ou ne sont pas définies pour une raison quelconque. Le code renverra une erreur telle que « propriété du non-objet ».

Bien sûr, vous pouvez le faire comme ceci :

{{ $post->author->name ?? '' }}

Vous pouvez le faire via la relation Eloquent :

public function author()
{
    return $this->belongsTo('App\Author')->withDefault();
}

Dans cet exemple, si le texte n'a pas d'informations sur l'auteur ,

will Renvoie un objet modèle

vide.

De plus, nous pouvons également attribuer des valeurs par défaut aux propriétés de l'objet modèle par défaut. author()

public function author()
{
    return $this->belongsTo('App\Author')->withDefault([
        'name' => 'Guest Author'
    ]);
}
AppAuthor11. Tri par fonction d'affectation

Imaginez que vous avez ce code :

function getFullNameAttribute()
{
  return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}

Maintenant, vous souhaitez trier par "nom_complet" ?

$clients = Client::orderBy('full_name')->get(); //没有效果

La solution est simple. Nous devons trier les résultats après les avoir obtenus.

$clients = Client::get()->sortBy('full_name'); // 成功!

Notez que les noms des méthodes sont différents - ce n'est pas orderBy, mais sortBy

12. Tri par défaut dans la portée globale

Et si vous souhaitez que

soit toujours trié par le champ

 ? Vous pouvez lui attribuer une portée globale. Revenons à la méthode

que nous avons mentionnée ci-dessus :

protected static function boot()
{
    parent::boot();

    // 按照 name 正序排序
    static::addGlobalScope('order', function (Builder $builder) {
        $builder->orderBy('name', 'asc');
    });
}
User::all()Portée de la requête de lecture étendue. name

13. 原生查询方法

有时候,我们需要在 Eloquent 语句中添加原生查询。 幸运的是,确实有这样的方法。

// whereRaw
$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();

// havingRaw
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();

// orderByRaw
User::where('created_at', '>', '2016-01-01')
  ->orderByRaw('(updated_at - created_at) desc')
  ->get();

14. 复制:复制一行的副本

很简单。说明不是很深入,下面是复制数据库实体(一条数据)的最佳方法:

$task = Tasks::find(1);
$newTask = $task->replicate();
$newTask->save();

15. Chunk() 方法之大块数据

与 Eloquent 不完全相关,它更多的关于 Collection (集合),但是对于处理大数据集合,仍然是很有用的。你可以使用 chunk() 将这些数据分割成小数据块

修改前:

$users = User::all();
foreach ($users as $user) {
    // ...

你可以这样做:

User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // ...
    }
});

16. 创建模型时创建额外的东西

我们都知道Artisan命令:

php artisan make:model Company

但是,你知道有三个有用的标记可以为模型生成相关文件吗?

php artisan make:model Company -mcr
  • -m 将创建一个迁移文件

  • -c 将创建一个控制器

  • -r 表示控制器应该是一个资源控制器

17. 调用 save 方法的时候指定 updated_at

你知道  ->save() 方法可以接受参数吗? 我们可以通过传入参数阻止它的默认行为:更新  updated_at  的值为当前时间戳。

$product = Product::find($id);
$product->updated_at = '2019-01-01 10:00:00';
$product->save(['timestamps' => false]);

这样,我们成功在  save  时指定了  updated_at  的值。

18. update() 的结果是什么?

你是否想知道这段代码实际上返回什么?

$result = $products->whereNull('category_id')->update(['category_id' => 2]);

我是说,更新操作是在数据库中执行的,但 $result 会包含什么?

答案是受影响的行。 因此如果你想检查多少行受影响, 你不需要额外调用其他任何内容 -- update() 方法会给你返回此数字。

19. 把括号转换成 Eloquent 查询

如果你有个 andor 混合的 SQL 查询,像这样子的:

... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)

怎么用 Eloquent 来翻译它呢? 下面是一种错误的方式:

$q->where('gender', 'Male');
$q->orWhere('age', '>=', 18);
$q->where('gender', 'Female');
$q->orWhere('age', '>=', 65);

顺序就没对。正确的打开方式稍微复杂点,使用闭包作为子查询:

$q->where(function ($query) {
    $query->where('gender', 'Male')
        ->where('age', '>=', 18);
})->orWhere(function($query) {
    $query->where('gender', 'Female')
        ->where('age', '>=', 65);
})

20. 复数参数的 orWhere

终于,你可以传递阵列参数给 orWhere()。平常的方式:

$q->where('a', 1);
$q->orWhere('b', 2);
$q->orWhere('c', 3);

你可以这样做:

$q->where('a', 1);
$q->orWhere(['b' => 2, 'c' => 3]);

我很确定还有更多隐藏的秘诀,但我希望至少上面的其中一些对你来说是新的。

推荐教程:《Laravel教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer