Mengapa banyak Pengembang PHP benci menggunakan isset () dan / atau fungsi defensif PHP lainnya yang sama seperti empty ()?

27

Selama di stackoverflow, saya melihat masalah ini muncul sepanjang waktu:

Bahkan Pekka (yang menawarkan banyak saran PHP yang solid) telah menabrak E_NOTICEmonster yang ditakuti dan berharap untuk solusi yang lebih baik daripada menggunakan isset(): isset () dan empty () membuat kode jelek

Secara pribadi, saya menggunakan isset()dan empty()di banyak tempat untuk mengelola aliran aplikasi saya. Sebagai contoh:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Bahkan cuplikan sederhana seperti ini:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

tampaknya sangat logis bagi saya. Itu tidak terlihat seperti mengasapi, sepertinya kode stabil. Tetapi banyak pengembang menjalankan aplikasi mereka dengan E_NOTICEdiaktifkan, menemukan banyak pemberitahuan "indeks array tidak diinisialisasi" yang membuat frustrasi, dan kemudian meringis pada prospek memeriksa variabel yang ditentukan dan "membuang sampah sembarangan" dengan kode mereka isset().

Saya menganggap bahasa lain menangani berbagai hal secara berbeda. Berbicara dari pengalaman, JavaScript tidak sesopan PHP. Variabel yang tidak terdefinisi biasanya akan menghentikan eksekusi skrip. Juga, (berbicara dari pengalaman ), saya yakin bahasa seperti C / C ++ hanya akan menolak untuk dikompilasi.

Jadi, apakah pengembang PHP hanya malas? (tidak berbicara tentang Anda, Pekka, saya tahu Anda refactoring aplikasi lama.) Atau apakah bahasa lain menangani variabel tidak terdefinisi lebih anggun daripada mengharuskan programmer untuk memeriksa terlebih dahulu apakah mereka didefinisikan?

(Saya tahu ada E_NOTICEpesan lain selain variabel yang tidak terdefinisi, tetapi yang tampaknya menjadi yang paling menyebabkan kesulitan)

Tambahan
Dari jawaban sejauh ini, saya bukan satu-satunya yang berpikir isset()bukan kode mengasapi. Jadi, saya bertanya-tanya sekarang, apakah ada masalah dengan programmer dalam bahasa lain yang menggemakan yang ini? Atau apakah ini semata-mata masalah budaya PHP?

Stephen
sumber
4
Sayangnya saya telah melihat php devs bekerja dengan "peringatan" dimatikan juga.
Viper_Sb
Aduh. Itu adalah menyedihkan.
Stephen
1
Bukan menjadi pengguna PHP saya bertanya-tanya: mengapa Anda perlu memeriksa variabel yang tidak terdefinisi?
Winston Ewert
2
@ Winston: Masalah dengan PHP (berbeda dengan banyak bahasa lain) adalah PHP memungkinkan banyak kombinasi konfigurasi. Misalnya, programmer dapat memutuskan untuk mengabaikan peringatan, pemberitahuan, dan pemberitahuan penghentian. Pengembang yang lebih berpengalaman akan bekerja dengan setel kesalahan_laporan untuk melaporkan semuanya. PHP juga memiliki banyak fungsi yang membuang kesalahan dan mengembalikan kode status daripada membuang pengecualian. Seseorang harus sangat akrab dengan bahasa untuk dapat kode pertahanan dan berhasil. Banyak bahasa lain tidak mengizinkan pilihan. Ketat biasanya merupakan opsi default dan satu-satunya.
Wil Moore III
1
Saya tidak suka isset () karena verbositas yang ditambahkannya. Bentuk @ yang lebih baik akan menjadi alternatif yang bagus.
Kzqai

Jawaban:

34

Saya kode ke E_STRICTdan tidak ada yang lain.

Menggunakan cek kosong dan mengeluarkan tidak membuat kode Anda jelek, itu membuat kode Anda lebih bertele-tele. Dalam benak saya apa hal terburuk mutlak yang dapat terjadi dari menggunakannya? Saya mengetik beberapa karakter lagi.

Ayat konsekuensi dari tidak menggunakannya, paling tidak peringatan.

Josh K.
sumber
7
Lingkungan pengembangan saya juga E_STRICT. Saya menekan semua kesalahan dalam produksi, tapi itu hanya untuk memastikan tidak ada yang melewati saya dalam pengembangan.
Stephen
2
+1 Josh, aku juga sama. Saat Anda memprogram di E_STRICT, Anda tahu bahwa Anda tidak akan pernah memiliki kejutan dalam kode Anda. Satu-satunya cara untuk terbang, imo.
EricBoersma
3
@Stephen: Selalu matikan kesalahan untuk produksi. Itu hanya jaring pengaman. Pembangunan harus (IMO) selalu E_STRICT. Tulis kode dan selesaikan semua peringatan dan kesalahan.
Josh K
apakah kamu nuri aku? :)
Stephen
@Stephen: Saya setuju. :)
Josh K
17

Saya pikir pemberitahuan tentang elemen yang tidak diketahui adalah kesalahan desain di PHP. Saya tidak yakin itu mungkin untuk memperbaiki kesalahan sekarang, tapi menghasilkan banyak kode boilerplate seperti if(isset($foo['abc']) && $foo['abc'] == '123')- kode ini tidak harus memiliki isset, karena maksud adalah untuk memeriksa apakah ada '123' di tempat tertentu $foodan jika tidak ada ada itu jelas bukan '123'. Satu-satunya alasan Anda harus menulis kode dua kali lebih banyak karena kesalahan desain yang tidak menguntungkan ini di PHP. Dan pemberitahuan sangat mahal di PHP, sayangnya, hanya menonaktifkannya bukan pilihan untuk kode di mana kinerja menjadi perhatian.

Jadi ya, itu membuat kode IMHO jelek dan itu mengganggu saya. Dan itu bukan karena kurangnya pengalaman - saya menggunakan PHP sejak tahun 1998 dan saya ingat ketika ada .php3ekstensi dan itu berarti "itu bukan PHP 2". Mungkin saya malas :) Tapi kemalasan - setidaknya jenis tertentu - adalah kebajikan bagi seorang programmer.

Di sisi lain, penggunaan valid issetdan empty- sama seperti yang ada di posting asli - baik-baik saja. Saya hanya berpikir PHP terlalu bersemangat tentang peringatan di tempat-tempat isset/emptyyang tidak terlalu dibutuhkan.

StasM
sumber
3
Kanan. Ini masalah verbositas. $eg = isset($_GET['eg'])? $_GET['eg'] : null;bertele-tele. Saya benar-benar berharap ada operator lain yang bukan "penindas kesalahan" semata-mata untuk mendukung makna singkat dari $eg = @$_GET['eg'];"accept-the-non-exist-of-this-array-key-as-a-null". Saya cenderung menggunakan fungsi pendek, hari ini.
Kzqai
7
Sepakat. 4 tahun kemudian, masukkan Null Coalesce Operator: wiki.php.net/rfc/isset_ternary memberi kami$eg = $_GET['eg'] ?? null;
Steve
Atau lakukan saja sekarang dengan operator penekan kesalahan, mis $eg = @$_GET['eg'] ?: null;. Saya biasanya tidak menggunakannya, tetapi dalam hal ini kami secara eksplisit mengharapkan kesalahan itu dan memutuskan untuk mengabaikannya. Ini satu karakter lebih lama dari nol menyatu dan itu tidak sebagus (itu menekan semua kesalahan, dan mungkin ada ArrayAccess melakukan hal-hal yang funky di sana, bukan hanya array), tetapi secara umum melakukan pekerjaan.
El Yobo
12

Saya percaya PHP, sebagai bahasa bebas, yang ditafsirkan dan digunakan di web, memiliki proporsi yang sangat tinggi dari pembuat kode yang tidak profesional dan tidak terlatih yang tidak sepenuhnya menyadari mengapa mereka harus membuat kode pertahanan dan hanya melihat peringatan sebagai kesalahan lain yang tidak perlu. .

Saya mendengar poin-poin ini dari pengembang junior dan script-coders otodidak sepanjang waktu:

  • Mengapa menginisialisasi variabel jika akan tetap ada?
  • Mengapa memeriksa apakah ada sesuatu sebelum kita menggunakannya, sama dengan tidak terdefinisi dengan false?
  • Jika saya awalan dengan @ itu memperbaiki kode saya, mengapa rumit?

Jika mereka tidak pernah mengalami bahasa yang sangat diketik, atau mengalami jebakan variabel yang tidak dideklarasikan / tidak terinstalasi, maka mereka mengambil beberapa meyakinkan. Saya menemukan mereka biasanya menyerah begitu mereka telah mengalami kenikmatan kode debug selama satu jam atau lebih untuk menemukan itu kesalahan ketik pada nama variabel yang menyebabkan masalah.

Faktor kuat lainnya adalah penggunaan PHP dalam industri web, yang cenderung lebih mementingkan throughput daripada keamanan dan kualitas kode.

Orbling
sumber
10
"Saya percaya PHP [...] memiliki proporsi yang sangat tinggi untuk pembuat kode yang tidak profesional, tidak terlatih" Sebagai pengembang PHP yang berdedikasi, saya sangat setuju dengan Anda. +1
Stephen
@Stephen Ya saya kode terutama dalam PHP dan jQuery akhir-akhir ini, meskipun saya memiliki pendidikan formal, tetapi kode yang Anda lihat sebagai seorang profesional yang Anda bertanggung jawab sebelum ... kadang-kadang bertentangan dengan kepercayaan. ;-)
Orbling
1
Saya pikir itu masalah nyata dengan PHP. Selain beberapa keanehan dalam bahasa (yang mereka selesaikan dengan lambat di setiap versi baru) ada suasana amatiran di sekitarnya. Saya bisa membayangkan menjadi seorang pengembang PHP profesional kadang-kadang bisa membuat frustrasi, karena Anda dibandingkan dengan 'keponakan bos dari sekitar sudut'.
Erik van Brakel
1
@Erik PHP adalah kerabat Perl yang cukup buruk sepuluh tahun yang lalu, sekarang merupakan bahasa yang diartikan cukup masuk akal, terutama untuk penggunaan web. Ada alasan perusahaan seperti Facebook menggunakannya. Tetapi karena tersedia di mana-mana, set amatir menggunakannya secara luas dan ini merusak reputasi.
Orbling
5

Ya, mereka malas. Banyak dari mereka ...

Sayangnya mentalitas banyak pembuat kode PHP adalah "Tidak ada titik pengkodean defensif jika Anda bisa mendapatkan hasil akhir yang sama lebih cepat dengan mengandalkan bahasa untuk menangani kesalahan yang disebabkan oleh variabel yang hilang dll." Saya tahu, saya telah bekerja dengan beberapa dari mereka.

Mereka cenderung juga menjadi orang-orang yang secara misterius menuju makan siang lebih awal ketika kurangnya penanganan dan pelaporan kesalahan yang benar membuat server langsung selama beberapa jam ...

Gruffputs
sumber
5
-1 untuk pendapat subjektif tentang coders PHP.
Josh K
4
@Josh, setelah menjadi programmer PHP Senior selama 4 1/2 tahun dan kode PHP on dan off sejak 1999, aku takut aku agak subyektif. Saya seharusnya memenuhi syarat dengan "Di sisi lain, coders PHP yang lebih berpengalaman tidak malas dan melakukan hal-hal dengan benar" ...
Gruffputs
1
Yang seharusnya Anda miliki.
Josh K
5

Saya mencoba untuk menghindari penggunaan isset () dan empty () dengan menghindari penggunaan array sebagai objek transfer data. Buat kelas yang dapat dikonfigurasi untuk menerima set properti terbatas dengan default waras dan validasi input ke properti itu. Ia bahkan dapat mengimplementasikan antarmuka ArrayAccess sehingga Anda dapat menggunakannya seperti array. Ini juga memungkinkan Anda untuk menggunakan petunjuk tipe dalam tanda tangan metode Anda untuk menangkap kesalahan ketika seseorang mencoba untuk melewati jenis entitas yang salah ke metode Anda.

Aneurisma9
sumber
Pendekatan yang sangat menarik.
Toby
2

Salah satu pertanyaan yang dipertanyakan adalah pertanyaan saya, jadi saya ulangi.

Banyak pengembang salah mengira kehadiran banyak isset()sebagai tanda kualitas. Ini memberikan tampilan keandalan dan beberapa orang menganggapnya bahkan sebagai fitur keamanan.

Tetapi Anda harus mempertimbangkan bahwa PHP bukan bahasa yang dikompilasi. Ini adalah bahasa scripting dengan sistem tipe dinamis. Kesalahan E_NOTICE hanya kesalahan berdasarkan nama. Dan jika banyak issetdigunakan dengan tujuan menekan pemberitahuan, maka Anda sebenarnya hanya coding terhadap bahasa .

Jadi, apakah pengembang PHP hanya malas?

Memang demikian halnya jika Anda melihat banyak pemberitahuan dan peringatan dilemparkan. Banyak pemula tidak peduli tentang pemberitahuan, dan itu biasanya hasil dari orang yang benar-benar cacat error_reporting(0).

Namun Anda salah bahwa pengembang lain tidak mengenali E_NOTICE hanya karena mereka tidak @ atau tertekan oleh penerbit. Setidaknya itu adalah niat saya di balik pertanyaan pemberitahuan yang dipertahankan . Mereka bukan sesuatu untuk disingkirkan, tetapi terkadang informasi debug penting.

Seperti semua generalisasi, penggunaan isset yang tidak dipedulikan tidak mengarah pada kode yang optimal. Sangat penting untuk membedakan mana issetdan mana emptyyang perlu dan mana yang merupakan garam sintaksis .

Atau apakah ini semata-mata masalah budaya PHP?

Tidak, variabel "kesalahan" yang tidak ditentukan bukan masalah PHP saja. Bash, TCL dan Perl atau JavaScript memungkinkan penggunaan variabel yang tidak ditentukan. Fitur bahasa imanen ini tidak terlihat cacat di sana. Ada konstruksi bahasa yang serupa untuk memeriksa nilai yang tidak ditentukan. Namun mereka tidak selalu digunakan seperti dalam PHP, karena nilai undef tidak disalahartikan sebagai "kesalahan".

mario
sumber
1

Menarik. Saya jarang menggunakan isset (). Kode PHP saya jarang dalam keadaan di mana saya tidak tahu apakah suatu variabel telah ditetapkan di tempat pertama. Setiap variabel GET atau POST yang digunakan diakses melalui fungsi yang akan memberikannya default jika tidak ada. Nilai default dalam panggilan fungsi biasanya secara eksplisit diatur ke 0 atau string kosong.

GrandmasterB
sumber
+1. Melewati ke fungsi atau metode kelas adalah solusi yang bagus. Saya benar-benar MELAKUKANNYA , tetapi dalam keadaan darurat contoh saya di atas masih terlihat bersih dan tidak kembung.
Stephen
0

Saya menggunakan isset dan mengosongkan banyak. Tapi sebagian besar tempat yang Anda sebutkan, seperti pemrosesan $ _REQUEST, kalau-kalau ada yang mengacaukan parameter. Dalam kasus di mana saya memiliki kendali atas semua variabel yang berkeliaran, saya menemukan bahwa saya biasanya tidak membutuhkannya.

Tesserex
sumber
0

Saya tidak suka menggunakan isset, tetapi jika ada banyak kode yang dilakukan oleh orang lain, maka itu bisa menjadi anugrah keselamatan. Saya menulis kode wee di bawah ini untuk membantu masalah ini, alih-alih menggunakan isset () isseter ($ a, $ b) akan mengembalikan $ b jika $ a tidak didefinisikan atau kosong, atau fungsi mengembalikan nol. Setiap perbaikan, selamat datang:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
bigal
sumber