Salah satu ciri bahasa yang diumumkan kembali dalam Php 5.6 adalah penambahan ... token untuk menunjukkan bahawa fungsi atau kaedah menerima panjang argumen yang berubah -ubah.
Sesuatu yang jarang saya lihat disebutkan adalah mungkin untuk menggabungkan ciri ini dengan petunjuk jenis untuk membuat array yang ditaip pada dasarnya.
Contohnya, kita boleh mempunyai kelas filem dengan kaedah untuk menetapkan pelbagai tarikh udara yang hanya menerima objek DateTimeImmutable:
kita kini boleh lulus bilangan pembolehubah objek DateTimeImmutable yang berasingan kepada kaedah setairdates ():
<span><span><?php </span></span><span> </span><span><span>class Movie { </span></span><span> <span>private $dates = []; </span></span><span> </span><span> <span>public function setAirDates(\DateTimeImmutable ...$dates) { </span></span><span> <span>$this->dates = $dates; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAirDates() { </span></span><span> <span>return $this->dates; </span></span><span> <span>} </span></span><span><span>} </span></span>
Jika kita lulus sesuatu yang lain daripada datetimeimmutable, rentetan misalnya, ralat maut akan dibuang:
<span><span><?php </span></span><span> </span><span><span>$movie = new Movie(); </span></span><span> </span><span><span>$movie->setAirDates( </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'), </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22') </span></span><span><span>); </span></span>
Selain itu, kita boleh menggunakan jenis skalar dengan cara yang sama bermula dari Php 7. Sebagai contoh, kita boleh menambah kaedah untuk menetapkan senarai penilaian sebagai terapung pada kelas filem kami:
<span><span><?php </span></span><span> </span><span><span>class Movie { </span></span><span> <span>private $dates = []; </span></span><span> </span><span> <span>public function setAirDates(\DateTimeImmutable ...$dates) { </span></span><span> <span>$this->dates = $dates; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAirDates() { </span></span><span> <span>return $this->dates; </span></span><span> <span>} </span></span><span><span>} </span></span>
Sekali lagi, ini memastikan bahawa harta penarafan akan sentiasa mengandungi terapung tanpa kita perlu gelung ke atas semua kandungan untuk mengesahkannya. Jadi sekarang kita dapat dengan mudah melakukan beberapa operasi matematik pada mereka dalam getaveragerating (), tanpa perlu bimbang tentang jenis tidak sah.
Salah satu kelemahan menggunakan ciri ini sebagai tatasusunan yang ditaip ialah kita hanya boleh menentukan satu array sedemikian setiap kaedah. Katakan kami ingin mempunyai kelas filem yang menjangkakan senarai tarikh udara bersama -sama dengan senarai penarafan dalam pembina, bukannya menetapkannya kemudian melalui kaedah pilihan. Ini mustahil dengan kaedah yang digunakan di atas.
Satu lagi masalah ialah apabila menggunakan Php 7, jenis pulangan kaedah kami () masih perlu "array", yang sering terlalu generik.
Untuk memperbaiki kedua-dua masalah, kita hanya boleh menyuntik tatasusunan yang ditaip kami di dalam kelas yang dipanggil "koleksi". Ini juga meningkatkan pemisahan kebimbangan kita, kerana kita kini boleh memindahkan kaedah pengiraan untuk penarafan purata ke kelas pengumpulan yang berkaitan:
<span><span><?php </span></span><span> </span><span><span>$movie = new Movie(); </span></span><span> </span><span><span>$movie->setAirDates( </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'), </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22') </span></span><span><span>); </span></span>
Perhatikan bagaimana kami masih menggunakan senarai argumen yang ditaip dengan panjang pembolehubah dalam pembina kami, yang menjimatkan masalah untuk melengkapkan setiap penarafan untuk memeriksa jenisnya.
Jika kita mahu keupayaan untuk menggunakan kelas koleksi ini dalam gelung foreach, kita hanya perlu melaksanakan antara muka IteratorAggregate:
<span><span><?php </span></span><span> </span><span><span>$dates = [ </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'), </span></span><span> <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22'), </span></span><span><span>]; </span></span><span> </span><span><span>$movie = new Movie(); </span></span><span><span>$movie->setAirDates(...$dates); </span></span>
bergerak, kami juga boleh membuat koleksi untuk senarai tarikh udara kami:
<span><span><?php </span></span><span> </span><span><span>declare(strict_types=1); </span></span><span> </span><span><span>class Movie { </span></span><span> <span>private $dates = []; </span></span><span> <span>private $ratings = []; </span></span><span> </span><span> <span>public function setAirDates(\DateTimeImmutable ...$dates) { /* ... */ } </span></span><span> <span>public function getAirDates() : array { /* ... */ } </span></span><span> </span><span> <span>public function setRatings(float ...$ratings) { </span></span><span> <span>$this->ratings = $ratings; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAverageRating() : float { </span></span><span> <span>if (empty($this->ratings)) { </span></span><span> <span>return 0; </span></span><span> <span>} </span></span><span> </span><span> <span>$total = 0; </span></span><span> </span><span> <span>foreach ($this->ratings as $rating) { </span></span><span> <span>$total += $rating; </span></span><span> <span>} </span></span><span> </span><span> <span>return $total / count($this->ratings); </span></span><span> <span>} </span></span><span><span>} </span></span>
Meletakkan semua kepingan teka -teki bersama -sama dalam kelas filem, kini kita boleh menyuntik dua koleksi yang ditaip secara berasingan di pembina kami. Di samping itu, kami dapat menentukan jenis pulangan yang lebih spesifik daripada "array" pada kaedah GET kami:
<span><span><?php </span></span><span> </span><span><span>declare(strict_types=1); </span></span><span> </span><span><span>class Ratings { </span></span><span> <span>private $ratings; </span></span><span> </span><span> <span>public function __construct(float ...$ratings) { </span></span><span> <span>$this->ratings = $ratings; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAverage() : float { </span></span><span> <span>if (empty($this->ratings)) { </span></span><span> <span>return 0; </span></span><span> <span>} </span></span><span> </span><span> <span>$total = 0; </span></span><span> </span><span> <span>foreach ($this->ratings as $rating) { </span></span><span> <span>$total += $rating; </span></span><span> <span>} </span></span><span> </span><span> <span>return $total / count($this->ratings); </span></span><span> <span>} </span></span><span><span>} </span></span>
Jika kami mahu menambah pengesahan tambahan kepada penarafan kami, kami masih boleh pergi satu langkah lagi, dan menentukan objek nilai penarafan dengan beberapa kekangan tersuai. Sebagai contoh, penarafan boleh dibatasi antara 0 dan 5:
<span><span><?php </span></span><span> </span><span><span>declare(strict_types=1); </span></span><span> </span><span><span>class Ratings implements IteratorAggregate { </span></span><span> <span>private $ratings; </span></span><span> </span><span> <span>public function __construct(float ...$ratings) { </span></span><span> <span>$this->ratings = $ratings; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAverage() : float { /* ... */ } </span></span><span> </span><span> <span>public function getIterator() { </span></span><span> <span>return new ArrayIterator($this->ratings); </span></span><span> <span>} </span></span><span><span>} </span></span>
Kembali dalam kelas pengumpulan penilaian kami, kami hanya perlu melakukan perubahan kecil untuk menggunakan objek nilai ini dan bukannya terapung:
<span><span><?php </span></span><span> </span><span><span>class AirDates implements IteratorAggregate { </span></span><span> <span>private $dates; </span></span><span> </span><span> <span>public function __construct(\DateTimeImmutable ...$dates) { </span></span><span> <span>$this->dates = $dates; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getIterator() { </span></span><span> <span>return new ArrayIterator($this->airdates); </span></span><span> <span>} </span></span><span><span>} </span></span>
Dengan cara ini, kami mendapat pengesahan tambahan ahli pengumpulan individu, masih tanpa perlu melayari setiap objek yang disuntik.
menaip kelas koleksi dan objek nilai yang berasingan mungkin kelihatan seperti banyak kerja, tetapi mereka mempunyai beberapa kelebihan berbanding array generik dan nilai skalar:
Pengesahan jenis mudah di satu tempat. Kami tidak perlu melayari secara manual di atas array untuk mengesahkan jenis ahli pengumpulan kami;
Walaupun kita dapat menambah kaedah untuk memudahkan pengeditan, ini dengan cepat akan menjadi rumit kerana kita perlu menduplikasi kebanyakan kaedah pada setiap koleksi untuk mengekalkan kelebihan jenis petunjuk. Sebagai contoh, kaedah Tambah () pada penarafan hanya boleh menerima objek penarafan, manakala kaedah Tambah () pada Airdates hanya boleh menerima objek DateTimeImmutable. Ini menjadikan interfacing dan/atau menggunakan semula kaedah ini sangat keras.
Sebaliknya, kita hanya dapat menyimpan koleksi dan nilai objek kita tidak berubah, dan menukarnya kepada jenis primitif mereka apabila kita perlu membuat perubahan. Selepas kami selesai membuat perubahan, kami dapat membina semula apa-apa koleksi yang diperlukan atau objek nilai dengan nilai yang dikemas kini. Setelah (semula) pembinaan semua jenis akan disahkan semula, bersama-sama dengan sebarang pengesahan tambahan yang mungkin kami tentukan.
Contohnya, kita boleh menambah kaedah ToArray () mudah untuk koleksi kami, dan membuat perubahan seperti ini:
Dengan cara ini kita juga boleh menggunakan semula fungsi array sedia ada seperti array_filter ().
<span><span><?php </span></span><span> </span><span><span>class Movie { </span></span><span> <span>private $dates = []; </span></span><span> </span><span> <span>public function setAirDates(\DateTimeImmutable ...$dates) { </span></span><span> <span>$this->dates = $dates; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAirDates() { </span></span><span> <span>return $this->dates; </span></span><span> <span>} </span></span><span><span>} </span></span>
menggunakan semula kaedah generik
Seperti yang anda perhatikan, kami masih mendapat beberapa duplikasi kod di seluruh kelas pengumpulan kami dengan melaksanakan kedua -dua Toarray () dan getIterator () pada mereka semua. Nasib baik kaedah ini cukup generik untuk berpindah ke kelas induk generik, kerana kedua -duanya hanya mengembalikan array yang disuntik:
semua yang kita akan ditinggalkan dalam kelas pengumpulan kami akan menjadi pengesahan jenis dalam pembina, dan mana -mana logik tambahan pilihan yang khusus untuk koleksi itu, seperti ini:
<span><span><?php </span></span><span> </span><span><span>class Movie { </span></span><span> <span>private $dates = []; </span></span><span> </span><span> <span>public function setAirDates(\DateTimeImmutable ...$dates) { </span></span><span> <span>$this->dates = $dates; </span></span><span> <span>} </span></span><span> </span><span> <span>public function getAirDates() { </span></span><span> <span>return $this->dates; </span></span><span> <span>} </span></span><span><span>} </span></span>
Secara pilihan kita boleh membuat final koleksi kami, untuk mengelakkan mana -mana kelas kanak -kanak daripada mengacaukan dengan nilai harta dengan cara yang boleh membatalkan pengesahan jenis kami.
Walaupun masih jauh dari sempurna, ia semakin mudah untuk bekerja dengan pengesahan jenis dalam koleksi dan objek nilai dengan siaran terkini php.
Sebaik-baiknya kita akan mendapat beberapa bentuk generik dalam versi PHP masa depan untuk memudahkan penciptaan kelas pengumpulan semula yang boleh digunakan semula.
Ciri yang akan meningkatkan penggunaan objek nilai akan menjadi keupayaan untuk membuang objek kepada jenis primitif yang berbeza, sebagai tambahan kepada rentetan. Ini dapat dengan mudah dilaksanakan dengan menambahkan kaedah sihir tambahan yang setanding dengan __toString (), seperti __toint (), __tofloat (), dan lain -lain
Nasib baik terdapat beberapa RFC yang sedang berjalan untuk melaksanakan kedua -dua ciri dalam versi kemudian, jadi jari melintasi! ?
Generik: https://wiki.php.net/rfc/generics
array generik: https://wiki.php.net/rfc/generic-arrays
objek pemutus ke skalar: https://wiki.php.net/rfc/class_casting_to_scalar
Jika anda mendapati tutorial ini berguna, sila lawati jawatan asal pada medium dan berikan beberapa ❤️. Sekiranya anda mempunyai maklum balas, soalan, atau komen, sila tinggalkannya di bawah atau sebagai respons pada jawatan asal.
Array yang ditaip ketat dalam PHP menyediakan cara untuk memastikan semua elemen dalam array adalah jenis tertentu. Ini boleh menjadi sangat berguna dalam aplikasi yang lebih besar dan lebih kompleks di mana konsistensi data adalah penting. Dengan menguatkuasakan jenis tertentu untuk semua elemen dalam array, anda boleh menghalang potensi bug dan kesilapan yang mungkin berlaku disebabkan oleh jenis data yang tidak dijangka. Ia juga menjadikan kod anda lebih mudah diramalkan dan lebih mudah untuk debug, kerana anda selalu mengetahui jenis data yang anda kerjakan. tidak menyokong array yang ditaip secara asli. Walau bagaimanapun, anda boleh membuat kelas yang menguatkuasakan pemeriksaan jenis pada unsur -unsur yang ditambahkan pada array. Kelas ini akan mempunyai kaedah untuk menambah dan mengambil unsur -unsur, dan kaedah ini akan memeriksa jenis elemen sebelum melakukan operasi. Jika jenis elemen tidak sepadan dengan jenis yang diharapkan, ralat akan dilemparkan. Anda boleh menentukan bahawa fungsi atau kaedah mengharapkan array sebagai hujah dengan menambahkan "array" sebelum nama argumen dalam perisytiharan fungsi atau kaedah. Walau bagaimanapun, ini hanya memastikan bahawa hujah adalah array, bukan bahawa semua elemen dalam array adalah jenis tertentu.
Atas ialah kandungan terperinci Mewujudkan susunan dan koleksi yang ditaip dengan ketat dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!