Heim > Artikel > Backend-Entwicklung > Lassen Sie uns über die Grundkenntnisse der Generika in PHP sprechen
In diesem Artikel möchten wir Sie über die Grundkenntnisse von PHP-Generika informieren. Ich hoffe, dass dies für Sie hilfreich ist.
Generika in PHP. Ich wusste, dass es das war, was ich wollte. Ich weiß, dass viele Entwickler diesen Typ verwenden möchten. Andererseits gibt es möglicherweise eine große Gruppe von PHP-Programmierern, die nicht wissen, was Generika sind oder warum sie diesen Typ haben.
Ich werde in diesem Blog eine Reihe über Generics und PHP verfassen. Beginnen wir am Anfang und schon bald kommen wir zu komplexeren Themen. Wir besprechen, was Generika sind, warum PHP sie nicht unterstützt und was in Zukunft passieren könnte.
Lass uns anfangen.
Jede Programmiersprache hat eine Art System. Einige Sprachen sind in ihrer Implementierung sehr streng, während andere – und PHP fällt in diese Kategorie – viel lockerer sind
Nun gibt es viele Gründe, ein Typsystem zu verwenden. Am offensichtlichsten ist die Typüberprüfung.
Angenommen, wir haben eine Funktion, die zwei Zahlen, zwei ganze Zahlen, annimmt und einige Berechnungen anstellt:
function add($a, $b) { return $a + $b; }
PHP ermöglicht es Ihnen, jede Art von Daten an die Funktion zu übergeben, Zahlen, Zeichenfolgen, Boolesche Werte spielen keine Rolle. PHP wird sein Bestes tun, um Variablen zu transformieren, wenn es sinnvoll ist, beispielsweise indem sie addiert werden.
add('1', '2');
Aber diese Konvertierungen – Typ-Jonglage – führen oft zu unerwarteten Ergebnissen, oder besser gesagt: Fehlern und Abstürzen.
add([], true); // ?
Jetzt können wir manuell Code schreiben, um zu überprüfen, ob unsere mathematische Additionsoperation für jede gegebene Eingabe verwendet wird
function add($a, $b) { if (!is_int($a) || !is_int($b)) { return null; } return $a + $b; }
Alternativ können wir in PHPS integrierte Typhinweise verwenden – dies ist die integrierte Abkürzung, die wir ausführen müssen die Operation manuell durchführen :
function add(int $a, int $b): int { return $a + $b; }
Viele Entwickler in der PHP-Community sagen, dass ihnen diese Typhinweise egal sind, weil sie wissen, dass sie dieser Funktion nur Ganzzahlen übergeben sollten – schließlich haben sie sie selbst geschrieben.
Diese Argumentation scheitert jedoch schnell: Sie sind oft nicht der Einzige, der in dieser Codebasis arbeitet, und Sie verwenden Code, den Sie nicht selbst geschrieben haben – denken Sie daran, wie viele Pakete Sie mit Composer abrufen. Auch wenn dieses isolierte Beispiel keine große Sache zu sein scheint, ist die Typprüfung dennoch nützlich, sobald Ihr Code zu wachsen beginnt.
Darüber hinaus verhindert das Hinzufügen von Typhinweisen nicht nur ungültige Zustände, sondern klärt auch, welche Art von Werteingabe wir Programmierer benötigen. Durch das Definieren eines Typs entfällt in der Regel das Lesen externer Dokumentation, da der Großteil der Funktionalität einer Funktion bereits durch ihre Typdefinition gekapselt ist. IDEs nutzen dieses Prinzip intensiv: Sie können dem Programmierer mitteilen, welche Art von Werteingabe eine Funktion erwartet oder welche Felder und Methoden für ein Objekt verfügbar sind – weil es zu einer Klasse gehört. Mit IDEs können wir Code effizienter schreiben, vor allem weil sie Typhinweise in unserer Codebasis statisch analysieren können.
Merken Sie sich dieses Wort:
Statische Analyse– Dies wird später in dieser Serie sehr wichtig sein. Das bedeutet, dass ein Programm, eine IDE oder ein anderer „statischer Analysator“ sich unseren Code ansehen und uns sagen kann, ob er funktioniert, ohne ihn auszuführen – zumindest bis zu einem gewissen Grad. Wenn wir unserer Funktion eine Zeichenfolge übergeben, die nur Ganzzahlen akzeptiert, teilt uns unsere IDE mit, was wir falsch machen – was dazu führt, dass das Programm zur Laufzeit abstürzt. Unsere IDE kann uns dies jedoch mitteilen, ohne den Code tatsächlich auszuführen. Andererseits hat das Typensystem auch seine Grenzen. Ein häufiges Beispiel ist eine „Liste von Elementen“:
class Collection extends ArrayObject { public function offsetGet(mixed $key): mixed { /* … */ } public function filter(Closure $fn): self { /* … */ } public function map(Closure $fn): self { /* … */ } }
Eine Sammlung hat viele Möglichkeiten, jede Art von Eingabe zu verarbeiten: Schleifen, Filtern, Zuordnen usw.; der Sammlungsimplementierung sollte es egal sein, ob sie Zeichenfolgen oder ganze Zahlen verarbeitet.
Aber betrachten wir es aus der Perspektive eines Außenstehenden. Was passiert, wenn wir sicherstellen möchten, dass eine Sammlung nur Zeichenfolgen und eine andere Sammlung nur „Benutzer“-Objekte enthält? Der Sammlung selbst ist es egal, wenn sie ihre items
durchläuft, uns aber schon. Wir wollen wissen, ob das Element in der Schleife ein Benutzer oder ein String ist – das ist etwas völlig anderes. Aber ohne die korrekten Typinformationen wird unsere IDE unter unbekannten Umständen ausgeführt.
$users = new Collection(); // … foreach ($users as $user) { $user-> // ? }
Jetzt können wir für jede Sammlung separate Implementierungen erstellen: eine, die nur mit Strings funktioniert, und eine andere, die nur mit Benutzer
-Objekten funktioniert: items
时并不关心,但我们关心。我们想知道循环中的这个项目是用户还是字符串 —— 这是完全不同的。但是如果没有正确的类型信息,我们的 IDE 就会在未知情况中运行。
class StringCollection extends Collection { public function offsetGet(mixed $key): string { /* … */ } } class UserCollection extends Collection { public function offsetGet(mixed $key): User { /* … */ } }
现在,我们可以为每个集合创建单独的实现:一个只适用于字符串的实现,另一个只适用于 User
class Collection<Type> extends ArrayObject { public function offsetGet(mixed $key): Type { /* … */ } // … }Aber was ist, wenn wir eine dritte Leistung benötigen? Der vierte? Vielleicht 10 oder 20. Die Verwaltung dieser Codes wird sehr schwierig. Hier kommen Generika ins Spiel. Zur Klarstellung: PHP hat keine Generika. Es ist eine mutige Aussage, die einige Umwege erfordert, auf die wir später in dieser Serie eingehen werden. Aber jetzt kann ich sagen, dass das, was ich Ihnen zeigen werde, in PHP nicht existiert. Aber es existiert in anderen Programmiersprachen. Viele Programmiersprachen ermöglichen es Entwicklern, „Generika“ für Sammlungsklassen zu definieren, anstatt für jeden möglichen Typ separate Implementierungen implementieren zu müssen:
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视频教程》
Das obige ist der detaillierte Inhalt vonLassen Sie uns über die Grundkenntnisse der Generika in PHP sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!