Pertanyaan Apakah variabel global dalam PHP dianggap praktik yang buruk? Jika ya, mengapa?


function foo () {
    global $var;
    // rest of code
}

Dalam proyek-proyek PHP kecil saya biasanya pergi dengan cara prosedural. Saya biasanya memiliki variabel yang berisi konfigurasi sistem, dan ketika saya harus mengakses variabel ini dalam suatu fungsi, saya lakukan global $var;.

Apakah ini praktik yang buruk?


75
2017-10-13 01:19


asal


Jawaban:


Ketika orang berbicara tentang variabel global dalam bahasa lain itu berarti sesuatu yang berbeda dengan apa yang dilakukannya di PHP. Itu karena variabel tidak sangat global dalam PHP. Ruang lingkup program PHP khas adalah satu permintaan HTTP. Variabel sesi sebenarnya memiliki cakupan yang lebih luas daripada variabel "global" PHP karena biasanya mencakup banyak permintaan HTTP.

Sering (selalu?) Anda dapat memanggil fungsi anggota dalam metode seperti preg_replace_callback() seperti ini:

preg_replace_callback('!pattern!', array($obj, 'method'), $str);

Lihat panggilan balik untuk lebih.

Intinya adalah benda-benda telah dibaut ke PHP dan dalam beberapa hal menyebabkan beberapa kecanggungan.

Jangan terlalu khawatir dengan menerapkan standar atau konstruksi dari bahasa yang berbeda ke PHP. Perangkap umum lainnya adalah mencoba mengubah PHP menjadi bahasa OOP murni dengan menempelkan model objek di atas segalanya.

Seperti halnya yang lain, gunakan variabel "global", kode prosedural, kerangka kerja tertentu dan OOP karena masuk akal, menyelesaikan masalah, mengurangi jumlah kode yang perlu Anda tulis atau membuatnya lebih mudah dipelihara dan lebih mudah dipahami, bukan karena Anda berpikir kamu harus.


86
2017-10-13 01:22



Variabel global jika tidak digunakan dengan hati-hati dapat membuat masalah lebih sulit ditemukan. Katakanlah Anda meminta skrip php dan Anda mendapatkan peringatan yang mengatakan bahwa Anda mencoba mengakses indeks array yang tidak ada di beberapa fungsi.

Jika array yang Anda coba akses bersifat lokal ke fungsi, Anda memeriksa fungsi untuk melihat apakah Anda telah membuat kesalahan di sana. Mungkin ada masalah dengan input ke fungsi sehingga Anda memeriksa tempat di mana fungsi tersebut dipanggil.

Tetapi jika array itu bersifat global, Anda perlu memeriksa semua tempat di mana Anda menggunakan variabel global itu, dan bukan hanya itu, Anda harus mencari tahu dalam urutan apa referensi tersebut ke variabel global diakses.

Jika Anda memiliki variabel global dalam sebuah kode, itu menyulitkan untuk mengisolasi fungsionalitas dari kode itu. Mengapa Anda ingin mengisolasi fungsionalitas? Jadi Anda bisa mengujinya dan menggunakannya kembali di tempat lain. Jika Anda memiliki beberapa kode yang tidak perlu Anda uji dan tidak perlu digunakan kembali maka menggunakan variabel global baik-baik saja.


22
2017-10-13 03:34



saya setuju dengan cletus. saya akan menambahkan dua hal:

  1. gunakan awalan agar Anda dapat segera mengidentifikasinya sebagai global (mis. $ g_)
  2. menyatakan mereka di satu tempat, jangan menyebarkannya ke seluruh kode.

salam Hormat, mengenakan


15
2017-10-13 01:39



Siapa yang bisa membantah pengalaman, gelar sarjana, dan rekayasa perangkat lunak? Bukan saya. Saya hanya akan mengatakan bahwa dalam mengembangkan aplikasi PHP satu halaman berorientasi objek, saya memiliki lebih menyenangkan ketika saya tahu saya dapat membangun semuanya dari awal tanpa khawatir tentang tabrakan namespace. Membangun dari awal adalah sesuatu yang banyak orang tidak lakukan lagi. Mereka memiliki pekerjaan, tenggat waktu, bonus, atau reputasi yang harus diperhatikan. Tipe ini cenderung menggunakan begitu banyak kode pra-bangun dengan taruhan tinggi, sehingga mereka tidak dapat mengambil risiko menggunakan variabel global sama sekali.

Mungkin buruk untuk menggunakan variabel global, meskipun hanya digunakan di area global suatu program, tetapi jangan melupakan mereka yang hanya ingin bersenang-senang dan buat sesuatu bekerja.

Jika itu berarti menggunakan beberapa variabel (<10) dalam namespace global, yang hanya bisa digunakan di area global suatu program, jadi itu saja. Ya, ya, MVC, injeksi ketergantungan, kode eksternal, bla, bla, bla, bla. Tapi, jika Anda telah memasukkan 99,99% dari kode Anda ke ruang nama dan kelas, dan kode eksternal sandboxed, dunia tidak akan berakhir (saya ulangi, dunia tidak akan berakhir) jika Anda menggunakan variabel global.

Secara umum, saya tidak akan mengatakan menggunakan variabel global kebiasaan buruk. Saya akan mengatakan bahwa menggunakan variabel global (bendera dan semacamnya) di luar area global suatu program meminta masalah dan (dalam jangka panjang) keliru karena Anda dapat kehilangan jejak negara mereka dengan mudah. Juga, saya akan mengatakan itu semakin banyak Anda belajar, semakin tidak bergantung Anda akan pada variabel global karena Anda akan mengalami "kegembiraan" melacak bug yang terkait dengan penggunaannya. Ini saja akan memberi insentif kepada Anda untuk menemukan cara lain untuk memecahkan masalah yang sama. Kebetulan, ini cenderung mendorong orang PHP ke arah belajar bagaimana menggunakan ruang nama dan kelas (anggota statis, dll ...).

Bidang ilmu komputer sangat luas. Jika kita menakut-nakuti orang lain untuk melakukan sesuatu karena kita memberinya label buruk, maka mereka kehilangan kesenangan untuk benar-benar memahami alasan di balik label.

Gunakan variabel global jika Anda harus, tetapi kemudian lihat apakah Anda dapat menyelesaikan masalah tanpa mereka. Tabrakan, pengujian, dan debugging lebih berarti ketika Anda memahami dengan baik sifat sebenarnya dari masalah, bukan hanya deskripsi masalah.


4
2018-01-10 16:47



Sebagai:

global $my_global; 
$my_global = 'Transport me between functions';
Equals $GLOBALS['my_global']

adalah praktik buruk (Seperti Wordpress $pagenow)... hmmm

Pertimbangkan ini:

$my-global = 'Transport me between functions';

adalah kesalahan PHP Tapi:

$GLOBALS['my-global'] = 'Transport me between functions';

aku s TIDAK kesalahan, hypens tidak akan berbenturan dengan "menyatakan" variabel yang menyatakan pengguna, seperti $pagenow. Dan Menggunakan UPPERCASE menunjukkan superglobal yang digunakan, mudah dikenali dalam kode, atau dilacak temukan di file

Saya menggunakan tanda hubung, jika saya malas membangun kelas segalanya untuk satu solusi, seperti:

$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';

Tetapi Dalam kasus penggunaan yang lebih luas, saya gunakan SATU globals sebagai array:

$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... ';
$GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';

Yang terakhir ini untuk saya, praktik yang baik pada "cola light" tujuan atau penggunaan, alih-alih kekacauan dengan kelas tunggal setiap kali untuk "cache" beberapa data. Tolong beri komentar jika aku salah atau kehilangan sesuatu yang bodoh di sini ...


0
2017-10-17 05:03



Diposting ulang dari SO Betaasi yang berakhir

Kita dapat mengilustrasikan masalah ini dengan pseudo-code berikut

function foo() {
     global $bob;
     $bob->doSomething();
}

Pertanyaan pertama Anda di sini adalah pertanyaan yang jelas

Dimana $bob berasal dari?

Apakah kamu bingung? Baik. Anda baru saja belajar mengapa global membingungkan dan dianggap sebagai praktik yang buruk. Jika ini adalah program nyata, sedikit kesenangan Anda selanjutnya adalah melacak semua contoh $bobdan berharap Anda menemukan yang tepat (ini semakin buruk jika $bob digunakan di mana-mana). Lebih buruk lagi, jika orang lain pergi dan mendefinisikan $bob (atau Anda lupa dan menggunakan kembali variabel itu) kode Anda dapat rusak (pada contoh kode di atas, memiliki objek yang salah, atau tidak ada objek sama sekali, akan menyebabkan kesalahan fatal). Karena hampir semua program PHP menggunakan kode seperti include('file.php'); pekerjaan Anda mempertahankan kode seperti ini menjadi lebih keras secara eksponensial semakin banyak file yang Anda tambahkan.

Bagaimana kita menghindari Globals?

Cara terbaik untuk menghindari global adalah filosofi yang disebut Injeksi Ketergantungan. Di sinilah kita melewati alat yang kita butuhkan ke dalam fungsi atau kelas.

function foo(\Bar $bob) {
    $bob->doSomething();
}

Ini adalah banyak lebih mudah dimengerti dan dipelihara. Tidak ada dugaan di mana $bob didirikan karena penelepon bertanggung jawab untuk mengetahui bahwa (itu melewati kita apa yang perlu kita ketahui). Lebih baik lagi, kita bisa menggunakannya ketik deklarasi untuk membatasi apa yang sedang dilewati. Jadi kami tahu itu $bob adalah salah satu contoh dari Bar kelas, atau turunan dari seorang anak dari Bar, artinya kita tahu kita bisa menggunakan metode kelas itu. Dikombinasikan dengan autoloader standar (tersedia sejak PHP 5.3), kita sekarang dapat melacak ke mana Bar didefinisikan. PHP 7.0 atau yang lebih baru menyertakan deklarasi tipe diperluas, di mana Anda juga dapat menggunakan jenis skalar (seperti int atau string).


-2
2017-08-24 00:21