Maison >développement back-end >tutoriel php >Comment écrire du code en utilisant la classe Laravel Collections

Comment écrire du code en utilisant la classe Laravel Collections

不言
不言original
2018-07-10 14:02:341320parcourir

Cet article présente principalement comment écrire du code à l'aide de la classe Laravel Collections. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Laravel fournit des composants impressionnants. à mon avis, c'est celui qui offre le meilleur support de composants parmi tous les frameworks Web actuels. Il fournit non seulement des vues prêtes à l'emploi, l'authentification, les sessions, la mise en cache, Eloquent, les files d'attente, la validation des données et d'autres composants. Il existe même des outils de développement fournis (Valet et Homestead).

Cependant, l'une des fonctionnalités les plus puissantes de ce framework est souvent négligée par les nouveaux arrivants : la classe Collection . Dans cet article, nous verrons comment utiliser les collections pour améliorer l'efficacité du codage, les lignes de code lisibles et écrire du code plus simple.

Aperçu

L'exposition initiale à l'utilisation de collections est venue de développeurs utilisant Eloquent pour exécuter des requêtes de base de données et utilisant l'instruction foreach pour parcourir la collection de modèles à partir des données renvoyées.

Cependant, les débutants ne remarqueront peut-être pas que les collections fournissent plus de 90 méthodes pour manipuler les données sous-jacentes. Ce qui est encore mieux, c'est que presque toutes les méthodes prennent en charge les opérations de chaînage, ce qui rend votre code lu comme de la prose. Cela rend votre code plus facile à lire, tant pour vous que pour les autres utilisateurs.

Vous n’arrivez toujours pas à aller droit au but ? Bon, passons en revue un simple extrait de code et voyons comment nous pouvons utiliser les collections pour écrire du code épais, rapide et puissant.

Exemple de code

Construisons un monde réel. Supposons que nous interrogeons certaines interfaces API et obtenions l'ensemble de résultats suivant enregistré dans un tableau :

<?php
// API 请求返回的结果
$data = [
    [&#39;first_name&#39; => 'John', 'last_name' => 'Doe', 'age' => 'twenties'],
    ['first_name' => 'Fred', 'last_name' => 'Ali', 'age' => 'thirties'],
    ['first_name' => 'Alex', 'last_name' => 'Cho', 'age' => 'thirties'],
];

Nous voyons que le tableau contient le prénom, le nom et la tranche d'âge. Maintenant, nous supposons que nous obtenons un utilisateur dont âge (age) est 30 ans (trentaine) à partir de l'enregistrement, puis procédons en fonction du nom de famille (nom nom) 🎜> Trier . Enfin, nous espérons également que le résultat renvoyé soit une chaîne (chaîne unique) , afin que chaque utilisateur dispose d'une ligne (nouvelle ligne) exclusive . Enfin, nous espérons également que le résultat renvoyé est

Cette exigence ne semble pas difficile à réaliser. Voyons maintenant comment implémenter cette fonction en utilisant PHP :

// 依据姓氏排序
usort($data, function ($item1, $item2) {
    return $item1['last_name'] <=> $item2['last_name'];
});

// 依据年龄范围分组
$new_data = [];

foreach ($data as $key => $item) {
    $new_data[$item['age']][$key] = $item;
}

ksort($new_data, SORT_NUMERIC);

// 从年龄为 30 岁组里获取用户全名
$result = array_map(function($item) {
    return $item['first_name'].' '.$item['last_name'];
}, $new_data['thirties']);

// 将数组转换为字符串并以行分隔符分隔
$final = implode("\n", $result);

// 译注:原文是 $final = implode($results, "\n"); implode函数接收两种顺序的参数,为了保持与文档一致所以我这边做了调整。
Notre code d'implémentation dépasse. 20 lignes, et très inélégant. Supprimez les commentaires et le code lié à la nouvelle ligne, et ce code deviendra difficile à lire. De plus, nous devons également utiliser des variables temporaires et la méthode de tri peu conviviale intégrée à PHP.

Maintenant, voyons à quel point c'est simple avec la classe Collection :

collection($data)->where('age', 'thirties')
                 ->sortBy('last_name')
                 ->map(function($item){
                    return $item['first_name'].' '.$item['last_name'];
                 })
                 ->implode("\n");
Wow ! Notre code est passé de 20 lignes à 6 lignes. Non seulement le code fonctionne désormais beaucoup plus facilement, mais les méthodes sont implémentées sans avoir besoin de commentaires pour nous indiquer à quel problème elles sont confrontées.

Cependant, il y a un problème qui empêche notre code d'être aussi parfait qu'il l'était... et c'est la méthode

map pour comparer le prénom et le nom. Franchement, ce n'est pas vraiment grave, mais cela donne de la motivation pour explorer le concept de macro.

Extension des collections

La classe Collection, comme les autres composants Laravel, prend en charge les macros, ce qui signifie que vous pouvez y ajouter des méthodes et les utiliser plus tard.

Conseil : Si vous souhaitez que de nouvelles méthodes soient disponibles partout, vous devez les ajouter au fournisseur de services. J'aime créer un MacroServiceProvider pour implémenter cette fonctionnalité, comme vous le souhaitez.
Ajoutons une méthode qui concaténera n'importe quel nombre de champs fournis par le tableau et renverra un résultat de chaîne :

Collection::macro('toConcatenatedString', function ($fields = [], $separator = ' ') {
    return $this->map(function($item) use ($fields, $separator) {
        return implode($separator, array_map(function ($el) use ($item) {
                return $item[$el];
            }, $fields)
        );
    })->implode("\n");
});
Après avoir ajouté cette méthode, notre code est fondamentalement parfait :

collect($data)->where('age', 'thirties')
              ->sortBy('last_name')
              ->toConcatenatedString(['first_name', 'last_name']);
Notre code a été rationalisé de plus de 20 lignes chaotiques à 3 lignes. Le code est propre et bien rangé et comporte des fonctions claires que tout le monde peut comprendre immédiatement.

Un autre exemple

Regardons maintenant le deuxième exemple, en supposant que nous ayons une liste d'utilisateurs, nous devons les filtrer en fonction de leur rôle, puis plus loin si leur durée d'inscription est de 5 ans. ou supérieur et

nom de famille commence par les lettres A-M n'obtient que le premier utilisateur.

Les données sont similaires à celles-ci :

<?php
// API 请求返回的结果
$users = [
    [&#39;name&#39; => 'John Doe', 'role' => 'vip', 'years' => 7],
    ['name' => 'Fred Ali', 'role' => 'vip', 'years' => 3],
    ['name' => 'Alex Cho', 'role' => 'user', 'years' => 9],
];
Si nous utilisons l'implémentation PHP, notre code ressemble à ceci :

$subset = [];
foreach ($users as $user) {
    if ($user['role'] === 'vip' && $user['years'] >= 5) {
        if (preg_match('/\s[A-Z]/', $user['name'])) {
            $subset[] = $user;
        }
    }
}
return reset($subset)
Remarque : Vous pouvez déplacer la deuxième instruction if à l'intérieur de la première, mais personnellement, j'aime ne pas utiliser plus de deux conditions dans une seule instruction if car je pense que plus de 2 conditions ne sont pas un bon code Difficile à lire.
Ce code n'est pas trop mauvais, mais nous devons quand même utiliser des variables temporaires, et nous devons également utiliser la fonction

reset pour réinitialiser le pointeur vers le premier utilisateur. Notre code comporte également quatre niveaux d'indentation, ce qui rend l'analyse du code plus difficile.

Regardons plutôt comment les collections gèrent ce problème :

collect($users)->where('role', 'vip')
              ->map(function($user) {
                  return preg_match('/\s[A-Z]/', $user['name']);
              })
              ->firstWhere('years', '>=', '5');

我们将代码简化到了之前的一般左右,每一步过滤处理清晰明了,并且我们不需要引入临时变量。

遗憾的是目前集合还不支持正则匹配,所以我们使用 map 方法,不过我们可以为这个功能创建一个宏:

Collection::macro('whereRegex', function($expression, $field) {
    return $this->map(function ($item) use ($expression, $field) {
        return preg_match($expression, $item[$field]);
    })
});

得益于宏方法,我们的代码现在看起来如下:

collect($users) -> where('role', 'vip')
                -> whereRegex('/\s[A-Z]/', 'name')
                -> firstWhere('years', '>=', 5);
注意:  为了简单起见,我们的红仅仅适用于数组集合。如果你计划让它们可以在 Eloquent 集合上使用,你需要在此场景下做相应的代码处理才行。

不同的视角

我们可以继续列出无数的示例,但仍然无法涵盖所有可用的集合方法,并且这从来都不是本文的真正目的。

需要注意的是,通过使用 Collection 类,您不仅可以获得一个方法库来简化编程工作,还可以选择一种从根本上改善代码的方法。

你会情不自禁的将你的代码结构从代码块重构简化成一行,同时减少代码的缩进,临时变量的使用和技巧性方法,另外你还可以使用链式编程方法,这让你的代码更加便于阅读和解析,此外最重要的是减少了编码工作!

查看官方文档获取更多这个迷人的类库的使用细节:https://laravel.com/docs/coll...

提示: 你还可以获取这个 Collection 类独立安装包,在使用非 laravel 项目是会非常有帮助。感谢 Tighten Co 团队做出的努力 https://github.com/tightenco/...。

感谢阅读,快乐编码!

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于Laravel的Eloquent ORM的解析

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn