Maison > Article > développement back-end > Parlons des connaissances de base des génériques en PHP
Cet article vous permettra de parler des génériques en PHP. Tout d'abord, comprenons les connaissances de base des génériques PHP. Dans les articles suivants, nous vous amènerons à comprendre les génériques en profondeur.
Génériques en PHP. Je savais que c'était ce que je voulais. Je sais que beaucoup de développeurs souhaitent que ce type soit utilisé. D'un autre côté, il peut y avoir un grand groupe de programmeurs PHP qui ne savent pas ce que sont les génériques, ni pourquoi ils ont ce type.
Je ferai une série sur les génériques et PHP sur ce blog. Commençons par le début et nous aborderons bientôt des sujets plus complexes. Nous discuterons de ce que sont les génériques, pourquoi PHP ne les prend pas en charge et de ce qui pourrait arriver à l'avenir.
Commençons.
Chaque langage de programmation possède un certain type de système. Certains langages sont très stricts dans leur implémentation, tandis que d'autres - et PHP entre dans cette catégorie - sont beaucoup plus souples
Maintenant, il existe de nombreuses raisons d'utiliser un système de types. Le plus évident est la vérification de type.
Supposons que nous ayons une fonction qui prend deux nombres, deux entiers ; et fait des calculs dessus :
function add($a, $b) { return $a + $b; }
PHP vous permet de transmettre n'importe quel type de données à la fonction, les nombres, les chaînes, les booléens n'ont pas d'importance. PHP fera de son mieux pour transformer les variables lorsque cela a du sens, par exemple en les additionnant.
add('1', '2');
Mais ces conversions - jonglerie de types - conduisent souvent à des résultats inattendus, ou plutôt : des erreurs et des plantages.
add([], true); // ?
Maintenant, nous pouvons écrire manuellement du code pour vérifier que notre opération d'addition mathématique sera utilisée pour une entrée donnée
function add($a, $b) { if (!is_int($a) || !is_int($b)) { return null; } return $a + $b; }
Alternativement, nous pouvons utiliser des astuces de type intégrées à PHPS - c'est le raccourci intégré que nous devons faire l'opération manuellement :
function add(int $a, int $b): int { return $a + $b; }
De nombreux développeurs de la communauté PHP disent qu'ils ne se soucient pas vraiment de ces astuces de type car ils savent qu'ils ne doivent transmettre que des entiers à cette fonction - ils l'ont écrit eux-mêmes après tout.
Cependant, ce raisonnement s'effondre rapidement : vous n'êtes souvent pas le seul à travailler dans cette base de code et vous utilisez du code que vous n'avez pas écrit vous-même - pensez au nombre de packages que vous récupérez avec Composer. Ainsi, même si cet exemple isolé ne semble pas très grave, la vérification de type s'avère utile une fois que votre code commence à se développer.
Au-delà de cela, l'ajout d'indices de type empêche non seulement les états invalides, mais également clarifiele type d'entrée de valeur dont nous, les programmeurs, avons besoin. La définition d'un type élimine généralement le besoin de lire une documentation externe car la plupart des fonctionnalités d'une fonction sont déjà encapsulées par sa définition de type.
Les IDE font un usage intensif de ce principe : ils peuvent indiquer au programmeur quel type de valeur d'entrée une fonction attend, ou quels champs et méthodes sont disponibles sur un objet - parce qu'il appartient à une classe. Les IDE nous permettent d'écrire du code plus efficacement, en grande partie parce qu'ils peuvent analyser statiquement les indices de type dans notre base de code.
Souvenez-vous de ce mot : Analyse statique - Ce sera très important plus tard dans cette série. Cela signifie qu'un programme, un IDE ou un autre type "d'analyseur statique" peut examiner notre code et nous dire s'il fonctionnera sans l'exécuter - du moins dans une certaine mesure. Si nous transmettons à notre fonction une chaîne qui n'accepte que des entiers, notre IDE nous dira ce que nous faisons de mal - ce qui entraînera un crash du programme au moment de l'exécution, mais notre IDE peut nous le dire sans réellement exécuter le code.
D'un autre côté, le système de typage a aussi ses limites. Un exemple courant est une "liste d'éléments" :
class Collection extends ArrayObject { public function offsetGet(mixed $key): mixed { /* … */ } public function filter(Closure $fn): self { /* … */ } public function map(Closure $fn): self { /* … */ } }
Une collection a de nombreuses façons de gérer tout type d'entrée : boucle, filtrage, mappage, etc. ; l'implémentation de la collection ne doit pas se soucier de savoir si elle gère des chaînes ou des entiers.
Mais regardons les choses d’un point de vue extérieur. Que se passe-t-il si nous voulons nous assurer qu'une collection ne contient que des chaînes et qu'une autre collection ne contient que des objets "utilisateur". La collection elle-même ne se soucie pas de parcourir ses items
, mais nous le faisons. Nous voulons savoir si l'élément dans la boucle est un utilisateur ou une chaîne - c'est complètement différent. Mais sans les informations de type correctes, notre IDE fonctionnera dans des circonstances inconnues. items
时并不关心,但我们关心。我们想知道循环中的这个项目是用户还是字符串 —— 这是完全不同的。但是如果没有正确的类型信息,我们的 IDE 就会在未知情况中运行。
$users = new Collection(); // … foreach ($users as $user) { $user-> // ? }
现在,我们可以为每个集合创建单独的实现:一个只适用于字符串的实现,另一个只适用于 User
class StringCollection extends Collection { public function offsetGet(mixed $key): string { /* … */ } } class UserCollection extends Collection { public function offsetGet(mixed $key): User { /* … */ } }Maintenant, nous pouvons créer des implémentations distinctes pour chaque collection : une qui ne fonctionne qu'avec des chaînes et une autre qui ne fonctionne qu'avec des objets
User
: class Collection<Type> extends ArrayObject { public function offsetGet(mixed $key): Type { /* … */ } // … }Mais que se passe-t-il si nous avons besoin d'un troisième accomplissement ? Le quatrième ? Peut-être 10 ou 20. La gestion de ces codes deviendra très difficile. C'est là qu'interviennent les génériques. Pour clarifier : PHP n'a pas de génériques. C’est une déclaration audacieuse qui nécessite de nombreux détours, dont nous parlerons plus tard dans cette série. Mais maintenant je peux dire que ce que je vais vous montrer n'existe pas en PHP. Mais il existe dans d'autres langages de programmation. De nombreux langages de programmation permettent aux développeurs de définir des « génériques » sur les classes de collection, plutôt que d'avoir à implémenter des implémentations distinctes pour chaque type possible : 🎜
class Collection<Type> extends ArrayObject { public function offsetGet(mixed $key): Type { /* … */ } // … }
基本上我们说的是集合类的实现适用于任何类型的输入,但是当我们创建集合的实例时,我们应该指定一个类型。它是一个泛型实现,需要根据程序员的需求来特定:
$users = new Collection<User>(); $slugs = new Collection<string>();
添加类型似乎是一件小事。但这种类型本身就开启了一个充满可能性的世界。 我们的 IDE 现在知道了集合中的数据类型,它可以告诉我们是否添加了错误类型的项;它可以告诉我们在迭代集合时可以对项执行什么操作;它可以告诉我们是否将集合传递给知道如何处理这些特定项的函数。
虽然我们可以通过手动为我们需要的每种类型实现一个集合,在技术上实现同样的效果;对于编写和维护代码的开发人员来说,通用实现将是一项重大改进。
那么,我们为什么不在 PHP 中使用泛型呢?除了无聊的收藏,我们还能用它们做什么?我们能为他们增加支持吗?我们将在这个系列中回答所有这些问题。首先需要澄清的是:我在本系列文章中的目标是教你关于泛型的知识,但同样重要的是,我想让大家意识到我们是如何误解 PHP 的。我想改变这种状况。
英文原文地址:https://stitcher.io/blog/generics-in-php-1
推荐:《PHP视频教程》
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!