Artikel ini akan membolehkan anda bercakap tentang generik dalam PHP Pertama, mari kita memahami pengetahuan asas tentang generik PHP Dalam artikel berikut, kami akan memberi anda pemahaman yang mendalam tentang generik !
Generik dalam PHP. Saya tahu inilah yang saya mahukan. Saya tahu ramai pembangun mahu ini menggunakan jenis ini. Sebaliknya, mungkin terdapat sekumpulan besar pengaturcara PHP yang tidak tahu apa itu generik, atau mengapa mereka mempunyai jenis ini.
Saya akan membuat satu siri di blog ini tentang generik dan PHP. Mari kita mulakan pada permulaan dan tidak lama lagi kita akan sampai ke topik yang lebih kompleks. Kami akan membincangkan apakah generik itu, sebab PHP tidak menyokongnya dan perkara yang mungkin berlaku pada masa hadapan.
Mari mulakan.
Setiap bahasa pengaturcaraan mempunyai beberapa jenis sistem. Sesetengah bahasa sangat ketat dalam pelaksanaannya, manakala yang lain - dan PHP termasuk dalam kategori ini - jauh lebih longgar
Kini, terdapat banyak sebab untuk menggunakan sistem jenis. Yang paling jelas ialah pengesahan jenis.
Andaikan kita mempunyai fungsi yang mengambil dua nombor, dua integer dan melakukan beberapa matematik padanya:
function add($a, $b) { return $a + $b; }
PHP membolehkan anda menghantar sebarang jenis data ke fungsi , nombor, rentetan, nilai Boolean tidak penting. PHP akan melakukan yang terbaik untuk mengubah pembolehubah apabila ia masuk akal, seperti menambahkannya bersama-sama.
add('1', '2');
Tetapi penukaran ini — juggling jenis — selalunya membawa kepada hasil yang tidak dijangka, atau sebaliknya: ralat dan ranap sistem.
add([], true); // ?
Kini, kami boleh menulis kod secara manual untuk menyemak operasi penambahan matematik kami, yang akan digunakan untuk sebarang input yang diberikan
function add($a, $b) { if (!is_int($a) || !is_int($b)) { return null; } return $a + $b; }
Sebagai alternatif, kami boleh menggunakan PHPS terbina dalam Petua Jenis – Ini ialah trengkas terbina dalam untuk perkara yang kami lakukan secara manual:
function add(int $a, int $b): int { return $a + $b; }
Ramai pembangun dalam komuniti PHP mengatakan mereka tidak begitu mengambil berat tentang pembayang jenis ini kerana mereka tahu ia hanya perlu lulus. integer kepada Fungsi ini - mereka sendiri yang menulisnya.
Walau bagaimanapun, alasan ini cepat rosak: anda selalunya bukan satu-satunya yang bekerja dalam pangkalan kod itu, dan anda menggunakan kod yang anda tidak tulis sendiri - fikirkan sejauh mana anda memperkenalkan Beg Komposer. Jadi, walaupun contoh terpencil ini tidak kelihatan seperti masalah besar, semakan jenis berguna apabila kod anda mula berkembang.
Selain itu, menambah petunjuk jenis bukan sahaja menghalang keadaan tidak sah, tetapi juga menjelaskan jenis input nilai yang kami perlukan oleh pengaturcara. Menentukan jenis biasanya menghilangkan keperluan untuk membaca dokumentasi luaran kerana kebanyakan fungsi fungsi sudah dirangkumkan oleh definisi jenisnya.
IDE banyak menggunakan prinsip ini: mereka boleh memberitahu pengaturcara jenis input nilai yang diharapkan oleh fungsi, atau medan dan kaedah yang tersedia pada objek - kerana ia tergolong dalam kelas. IDE menjadikan kami menulis kod dengan lebih cekap, sebahagian besarnya kerana mereka boleh menganalisis petunjuk jenis secara statik dalam pangkalan kod kami.
Ingat perkataan ini: Analisis Statik - ini akan menjadi sangat penting kemudian dalam siri ini. Ini bermakna program, IDE atau jenis "penganalisis statik" yang lain boleh melihat kod kami dan memberitahu kami sama ada ia akan berfungsi tanpa menjalankannya - sekurang-kurangnya pada tahap tertentu. Jika kami menghantar rentetan kepada fungsi kami yang hanya menerima integer, IDE kami akan memberitahu kami apa yang kami lakukan salah - yang akan menyebabkan program ranap pada masa jalan tetapi IDE kami boleh memberitahu kami tanpa menjalankan kod tersebut.
Sebaliknya, sistem jenis juga mempunyai hadnya. Contoh biasa ialah "senarai item":
class Collection extends ArrayObject { public function offsetGet(mixed $key): mixed { /* … */ } public function filter(Closure $fn): self { /* … */ } public function map(Closure $fn): self { /* … */ } }
Koleksi mempunyai banyak cara untuk mengendalikan sebarang jenis input: gelung, penapisan, pemetaan, dsb.; rentetan Atau integer.
Tetapi mari kita lihat dari perspektif orang luar. Apa yang berlaku jika kita ingin memastikan bahawa satu koleksi hanya mengandungi rentetan dan koleksi lain hanya mengandungi objek "pengguna". Koleksi itu sendiri tidak peduli apabila mengulangi items
nya, tetapi kami melakukannya. Kami ingin tahu sama ada item dalam gelung ialah pengguna atau rentetan - itu berbeza sama sekali. Tetapi tanpa maklumat jenis yang betul, IDE kami akan berjalan dalam keadaan yang tidak diketahui.
$users = new Collection(); // … foreach ($users as $user) { $user-> // ? }
Kini kita boleh mencipta pelaksanaan berasingan untuk setiap koleksi: satu yang hanya berfungsi dengan rentetan dan satu lagi yang hanya berfungsi dengan User
objek:
class StringCollection extends Collection { public function offsetGet(mixed $key): string { /* … */ } } class UserCollection extends Collection { public function offsetGet(mixed $key): User { /* … */ } }
Tetapi bagaimana jika kita memerlukan pelaksanaan ketiga? Yang keempat? Mungkin 10 atau 20. Menguruskan kod ini akan menjadi sangat sukar.
Di sinilah generik masuk.
Untuk menjelaskan: PHP tidak mempunyai generik. Ia adalah pernyataan berani yang memerlukan beberapa lencongan, yang akan kita bincangkan kemudian dalam siri ini. Tetapi sekarang saya boleh mengatakan bahawa apa yang saya akan tunjukkan kepada anda tidak wujud dalam PHP. Tetapi ia wujud dalam bahasa pengaturcaraan lain.
Banyak bahasa pengaturcaraan membenarkan pembangun mentakrifkan "generik" pada kelas koleksi, dan bukannya perlu melaksanakan pelaksanaan berasingan untuk setiap jenis yang mungkin:
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视频教程》
Atas ialah kandungan terperinci Mari kita bercakap tentang pengetahuan asas generik dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!