Jadi, di PHPDoc kita dapat menentukan di @var
atas deklarasi variabel anggota untuk mengisyaratkan pada tipenya. Kemudian sebuah IDE, misalnya. PHPEd, akan tahu jenis objek apa yang bekerja dengannya dan akan dapat memberikan wawasan kode untuk variabel itu.
<?php
class Test
{
/** @var SomeObj */
private $someObjInstance;
}
?>
Ini berfungsi dengan baik sampai saya perlu melakukan hal yang sama ke array objek untuk bisa mendapatkan petunjuk yang tepat ketika saya beralih melalui objek-objek itu nanti.
Jadi, apakah ada cara untuk mendeklarasikan tag PHPDoc untuk menentukan bahwa variabel anggota adalah array dari SomeObj
s? @var
array tidak cukup, dan @var array(SomeObj)
sepertinya tidak valid, misalnya.
Jawaban:
Menggunakan:
saat mengetikkan variabel sebaris, dan
untuk properti kelas.
Jawaban sebelumnya dari '09 ketika PHPDoc (dan IDE seperti Zend Studio dan Netbeans) tidak memiliki opsi itu:
Yang terbaik yang bisa Anda lakukan adalah mengatakan,
Saya sering melakukan itu di Zend Studio. Tidak tahu tentang editor lain, tetapi itu harus berhasil.
sumber
/** @var $Obj Test */
tidak berfungsi.@var Object[] $objects
mengatakan bahwa "$ object" adalah array dari instance Object.)/** @var TYPE $variable_name */
adalah sintaks yang benar; jangan membalik urutan jenis dan nama variabel (seperti yang disarankan sebelumnya dalam komentar) karena tidak akan berfungsi dalam semua kasus.Dalam IDE PhpStorm dari JetBrains, Anda dapat menggunakan
/** @var SomeObj[] */
, misalnya:The dokumentasi phpdoc merekomendasikan metode ini:
sumber
foreach(getSomeObjects() as $obj)
tidak berhasil, tetapi berhasil$objs = getSomeObjects(); foreach($objs as $obj)
@var Obj[string]
array asosiatif.Petunjuk Netbeans:
Anda mendapatkan penyelesaian kode untuk
$users[0]->
dan untuk$this->
berbagai kelas Pengguna.Anda juga dapat melihat jenis array dalam daftar anggota kelas ketika Anda selesai
$this->...
sumber
array_pop()
atau fungsi serupa karena beberapa alasan. Tampaknya Netbeans tidak menyadari fungsi-fungsi itu mengembalikan elemen tunggal dari array input.Untuk menentukan variabel adalah array objek:
Ini bekerja di Netbeans 7.2 (Saya menggunakannya)
Bekerja juga dengan:
Oleh karena itu penggunaan deklarasi di dalam
foreach
tidak diperlukan.sumber
/* @var $Obj Test */
anotasi baru setiap kali./**
2. Format yang benar adalah@var <data-type> <variable-name>
PSR-5: PHPDoc mengusulkan bentuk notasi gaya Generics.
Sintaksis
Nilai dalam Koleksi MUNGKIN bahkan menjadi array lain dan bahkan Koleksi lain.
Contohnya
Catatan: Jika Anda mengharapkan IDE untuk melakukan bantuan kode, maka itu adalah pertanyaan lain tentang apakah IDE mendukung notasi koleksi gaya generik PHPDoc.
Dari jawaban saya untuk pertanyaan ini .
sumber
Saya lebih suka membaca dan menulis kode bersih - sebagaimana diuraikan dalam "Kode Bersih" oleh Robert C. Martin. Saat mengikuti kredo Anda, Anda tidak perlu meminta pengembang (sebagai pengguna API Anda) untuk mengetahui struktur (internal) array Anda.
Pengguna API dapat bertanya: Apakah itu array dengan satu dimensi saja? Apakah objek tersebar di semua tingkatan array multi dimensi? Berapa banyak loop bersarang (foreach, dll.) Yang saya perlukan untuk mengakses semua objek? Jenis objek apa yang "disimpan" dalam array itu?
Saat Anda menguraikan Anda ingin menggunakan array itu (yang berisi objek) sebagai array satu dimensi.
Seperti yang dijelaskan oleh Nishi, Anda dapat menggunakan:
untuk itu.
Tetapi sekali lagi: waspada - ini bukan notasi docblock standar. Notasi ini diperkenalkan oleh beberapa produsen IDE.
Oke, oke, sebagai pengembang Anda tahu bahwa "[]" terikat ke sebuah array di PHP. Tapi apa arti "sesuatu []" dalam konteks PHP normal? "[]" berarti: membuat elemen baru di dalam "sesuatu". Elemen baru bisa menjadi segalanya. Tetapi apa yang ingin Anda ungkapkan adalah: array objek dengan tipe yang sama dan tipe tepat. Seperti yang Anda lihat, produsen IDE memperkenalkan konteks baru. Konteks baru yang harus Anda pelajari. Konteks baru yang harus dipelajari oleh pengembang PHP lain (untuk memahami dokumen Anda). Gaya buruk (!).
Karena array Anda memiliki satu dimensi, Anda mungkin ingin memanggil "array objek" sebagai "daftar". Ketahuilah bahwa "daftar" memiliki arti yang sangat istimewa dalam bahasa pemrograman lain. Akan lebih baik jika menyebutnya "koleksi" misalnya.
Ingat: Anda menggunakan bahasa pemrograman yang memungkinkan Anda semua opsi OOP. Gunakan kelas sebagai ganti array dan buat kelas Anda dapat dilalui seperti array. Misalnya:
Atau jika Anda ingin menyimpan objek internal pada level yang berbeda dalam array multi dimensi / struktur objek:
Solusi ini menggantikan array Anda dengan objek tipe "orderCollection", tetapi sejauh ini tidak memungkinkan penyelesaian kode di dalam IDE Anda. Baik. Langkah berikutnya:
Menerapkan metode yang diperkenalkan oleh antarmuka dengan docblocks - khususnya:
Jangan lupa untuk menggunakan petunjuk tipe untuk:
Solusi ini berhenti memperkenalkan banyak:
seluruh file kode Anda (misalnya dalam loop), seperti yang dikonfirmasi Zahymaka dengan jawabannya. Pengguna API Anda tidak dipaksa untuk memperkenalkan docblock itu, untuk memiliki penyelesaian kode. Untuk memiliki @return hanya pada satu tempat mengurangi redundansi (@var) semut mungkin. Taburkan "docBlocks with @var" akan membuat kode Anda lebih mudah dibaca.
Akhirnya kamu sudah selesai. Terlihat sulit untuk dicapai? Sepertinya mengambil palu untuk memecahkan kacang? Tidak benar-benar, karena Anda terbiasa dengan antarmuka itu dan dengan kode bersih. Ingat: kode sumber Anda ditulis sekali / banyak dibaca.
Jika penyelesaian kode IDE Anda tidak berfungsi dengan pendekatan ini, beralihlah ke pendekatan yang lebih baik (mis. IntelliJ IDEA, PhpStorm, Netbeans) atau ajukan permintaan fitur pada pelacak masalah produsen IDE Anda.
Terima kasih kepada Christian Weiss (dari Jerman) karena menjadi pelatih saya dan karena mengajari saya hal-hal hebat. PS: Temui saya dan dia di XING.
sumber
SomeObj[]
Anda tahu itu adalah array dua dimensiSomeObj
contoh dan kemudian Anda tahu apa yang harus dilakukan dengannya. Saya tidak berpikir itu tidak mengikuti kredo "kode bersih".@return <className>
untukcurrent()
dan semua orang. PhpStorm mendukung sehingga sangat membantu saya. Terima kasih sobat!Gunakan
array[type]
di Zend Studio.Di Zend Studio,
array[MyClass]
atauarray[int]
atau bahkanarray[array[MyClass]]
bekerja dengan baik.sumber
Di NetBeans 7.0 (mungkin lebih rendah juga) Anda bisa mendeklarasikan tipe pengembalian "array with Text objects" sama seperti
@return Text
dan petunjuk kode akan berfungsi:Sunting: memperbarui contoh dengan saran @Bob Fanger
dan gunakan saja:
Itu tidak sempurna tetapi lebih baik daripada hanya membiarkannya hanya "dicampur", yang tidak membawa nilai.
CONS adalah Anda diizinkan untuk menginjak array sebagai Obyek Teks yang akan melempar kesalahan.
sumber
Seperti yang disebutkan DanielaWaranie dalam jawabannya - ada cara untuk menentukan jenis $ item ketika Anda mengulangi lebih dari $ item dalam $ collectionObject: Tambahkan
@return MyEntitiesClassName
kecurrent()
dan sisa dariIterator
danArrayAccess
-metode yang mengembalikan nilai.Ledakan! Tidak perlu di
/** @var SomeObj[] $collectionObj */
atasforeach
, dan berfungsi baik dengan objek koleksi, tidak perlu mengembalikan koleksi dengan metode khusus yang dijelaskan sebagai@return SomeObj[]
.Saya kira tidak semua IDE mendukungnya tetapi berfungsi dengan baik di PhpStorm, yang membuat saya lebih bahagia.
Contoh:
Apa yang berguna saya akan menambahkan memposting jawaban ini
Dalam kasus saya
current()
dan sisainterface
-metode yang diterapkan diAbstract
kelas -koleksi dan saya tidak tahu apa jenis entitas yang akhirnya akan disimpan dalam koleksi.Jadi di sini adalah triknya: Jangan tentukan tipe return di kelas abstrak, alih-alih gunakan instuksi PhpDoc
@method
dalam deskripsi kelas koleksi tertentu.Contoh:
Sekarang, penggunaan kelas:
Sekali lagi: Saya kira tidak semua IDE mendukungnya, tetapi PhpStorm mendukungnya. Coba milikmu, kirim komentar hasilnya!
sumber
Saya tahu saya terlambat ke pesta, tapi saya sudah mengerjakan masalah ini baru-baru ini. Saya harap seseorang melihat ini karena jawaban yang diterima, meskipun benar, bukan cara terbaik Anda bisa melakukan ini. Setidaknya tidak di PHPStorm, saya belum menguji NetBeans.
Cara terbaik melibatkan perluasan kelas ArrayIterator daripada menggunakan tipe array asli. Ini memungkinkan Anda untuk mengetikkan petunjuk di tingkat kelas daripada di tingkat contoh, yang berarti Anda hanya perlu PHPDoc sekali, tidak di seluruh kode Anda (yang tidak hanya berantakan dan melanggar KERING, tetapi juga bisa bermasalah ketika datang ke refactoring - PHPStorm memiliki kebiasaan melewatkan PHPDoc saat refactoring)
Lihat kode di bawah ini:
Kuncinya di sini adalah PHPDoc
@method MyObj current()
mengesampingkan jenis kembali yang diwarisi dari ArrayIterator (yaitumixed
). Dimasukkannya PHPDoc ini berarti bahwa ketika kita beralih menggunakan properti kelasforeach($this as $myObj)
, kita kemudian mendapatkan penyelesaian kode ketika merujuk ke variabel$myObj->...
Bagi saya, ini adalah cara paling rapi untuk mencapai ini (setidaknya sampai PHP memperkenalkan Typed Array, jika mereka melakukannya), seperti yang kita nyatakan tipe iterator di kelas iterable, bukan pada contoh kelas yang tersebar di seluruh kode.
Saya belum menunjukkan di sini solusi lengkap untuk memperluas ArrayIterator, jadi jika Anda menggunakan teknik ini, Anda mungkin juga ingin:
offsetGet($index)
dannext()
is_a($object, MyObj::class)
dari konstruktor ke metode pribadioffsetSet($index, $newval)
danappend($value)
sumber
Masalahnya adalah bahwa
@var
hanya dapat menunjukkan tipe tunggal - Tidak mengandung formula yang kompleks. Jika Anda memiliki sintaks untuk "array Foo", mengapa berhenti di situ dan tidak menambahkan sintaks untuk "array array, yang berisi 2 Foo dan tiga Bar"? Saya mengerti bahwa daftar elemen mungkin lebih umum dari itu, tetapi ini merupakan lereng yang licin.Secara pribadi, saya pernah beberapa kali
@var Foo[]
menandakan "array Foo", tetapi tidak didukung oleh IDE.sumber
/* @var $foo Foo[] */
. Tulis saja jawaban di bawah tentang itu. Ini juga dapat digunakan di dalamforeach(){}
loopsumber
Saya telah menemukan sesuatu yang berfungsi, itu bisa menyelamatkan nyawa!
sumber