function foo () {
global $var;
// rest of code
}
Dalam proyek PHP kecil saya, saya biasanya menggunakan cara prosedural. Saya biasanya memiliki variabel yang berisi konfigurasi sistem, dan ketika saya belum mengakses variabel ini dalam suatu fungsi, saya melakukannya global $var;
.
Apakah ini praktik yang buruk?
php
global-variables
global
KRTac
sumber
sumber
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 benar - benar global di PHP. Cakupan program PHP tipikal adalah satu permintaan HTTP. Variabel sesi sebenarnya memiliki cakupan yang lebih luas daripada variabel "global" PHP karena biasanya mencakup banyak permintaan HTTP.
Seringkali (selalu?) Anda dapat memanggil fungsi anggota dengan metode
preg_replace_callback()
seperti ini:preg_replace_callback('!pattern!', array($obj, 'method'), $str);
Lihat panggilan balik untuk lebih lanjut.
Intinya adalah bahwa objek telah dibaut ke PHP dan dalam beberapa hal menyebabkan beberapa kecanggungan.
Jangan terlalu menyibukkan diri dengan menerapkan standar atau konstruksi dari bahasa berbeda ke PHP. Perangkap umum lainnya adalah mencoba mengubah PHP menjadi bahasa OOP murni dengan menempelkan model objek di atas segalanya.
Seperti yang lainnya, gunakan variabel "global", kode prosedural, kerangka kerja tertentu, dan OOP karena masuk akal, memecahkan masalah, mengurangi jumlah kode yang perlu Anda tulis atau membuatnya lebih mudah dipelihara dan lebih mudah dipahami, bukan karena Anda berpikir kamu harus.
sumber
array ($obj, 'callbackMethod')
dalam panggilan kepreg_replace_callback()
? (Saya tahu, saya telah menjadi mangsa perangkap OOP ini ...)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 Anda mencoba mengakses indeks dari sebuah array yang tidak ada di beberapa fungsi.
Jika array yang Anda coba akses bersifat lokal untuk fungsi tersebut, Anda memeriksa fungsi tersebut untuk melihat apakah Anda telah membuat kesalahan di sana. Mungkin ada masalah dengan masukan ke fungsi sehingga Anda memeriksa tempat di mana fungsi tersebut dipanggil.
Tetapi jika array itu global, Anda perlu memeriksa semua tempat di mana Anda menggunakan variabel global itu, dan tidak hanya itu, Anda harus mencari tahu bagaimana urutan referensi ke variabel global itu diakses.
Jika Anda memiliki variabel global dalam sebuah kode, maka fungsionalitas kode tersebut akan sulit diisolasi. Mengapa Anda ingin memisahkan fungsionalitas? Jadi, Anda dapat mengujinya dan menggunakannya kembali di tempat lain. Jika Anda memiliki beberapa kode, Anda tidak perlu menguji dan tidak perlu menggunakan kembali maka menggunakan variabel global tidak masalah.
sumber
saya setuju dengan cletus. saya akan menambahkan dua hal:
salam, don
sumber
$DB = 'foo';
Siapa yang dapat membantah pengalaman, gelar sarjana, dan rekayasa perangkat lunak? Bukan saya. Saya hanya akan mengatakan bahwa dalam mengembangkan aplikasi PHP satu halaman berorientasi objek, saya lebih bersenang-senang ketika saya tahu saya dapat membangun semuanya dari awal tanpa khawatir tentang tabrakan namespace. Membangun dari awal adalah sesuatu yang tidak lagi dilakukan banyak orang. Mereka memiliki pekerjaan, tenggat waktu, bonus, atau reputasi yang harus diperhatikan. Jenis ini cenderung menggunakan begitu banyak kode yang dibuat sebelumnya dengan taruhan tinggi, sehingga mereka tidak dapat mengambil risiko menggunakan variabel global sama sekali.
Menggunakan variabel global mungkin buruk, meskipun hanya digunakan di area global suatu program, tapi jangan lupakan mereka yang hanya ingin bersenang-senang dan membuat sesuatu berfungsi .
Jika itu berarti menggunakan beberapa variabel (<10) di namespace global, yang hanya digunakan di area global program, biarlah. Ya, ya, MVC, injeksi ketergantungan, kode eksternal, bla, bla, bla, bla. Tetapi, jika Anda telah memasukkan 99,99% kode Anda ke dalam namespace dan kelas, dan kode eksternal di-sandbox, dunia tidak akan berakhir (saya ulangi, dunia tidak akan berakhir) jika Anda menggunakan variabel global.
Secara umum, saya tidak akan mengatakan penggunaan variabel global adalah praktik yang buruk . Saya akan mengatakan bahwa menggunakan variabel global (bendera dan semacamnya) di luar area global suatu program akan menimbulkan masalah dan (dalam jangka panjang) tidak disarankan karena Anda dapat kehilangan jejak statusnya dengan mudah. Juga, saya akan mengatakan bahwa semakin banyak Anda belajar, semakin tidak bergantung Anda pada variabel global karena Anda akan mengalami "kegembiraan" melacak bug yang terkait dengan penggunaannya. Ini saja akan mendorong Anda untuk menemukan cara lain untuk menyelesaikan masalah yang sama. Secara kebetulan, ini cenderung mendorong orang-orang PHP ke arah belajar bagaimana menggunakan namespace dan kelas (anggota statis, dll ...).
Bidang ilmu komputer sangat luas. Jika kita menakut-nakuti semua orang agar tidak melakukan sesuatu karena kita menyebutnya buruk , maka mereka kehilangan kesenangan untuk benar-benar memahami alasan di balik label tersebut.
Gunakan variabel global jika Anda harus, tetapi kemudian lihat apakah Anda dapat menyelesaikan masalah tanpa variabel tersebut. Tabrakan, pengujian, dan debugging akan lebih berarti jika Anda benar-benar memahami sifat sebenarnya dari masalah, bukan hanya deskripsi masalah.
sumber
Kami dapat menggambarkan masalah ini dengan pseudo-code berikut
function foo() { global $bob; $bob->doSomething(); }
Pertanyaan pertama Anda di sini sudah jelas
Apakah kamu bingung? Baik. Anda baru saja mempelajari mengapa global itu membingungkan dan dianggap sebagai praktik yang buruk. Jika ini adalah program nyata, kesenangan Anda berikutnya adalah melacak semua contoh
$bob
dan berharap Anda menemukan yang tepat (ini menjadi lebih 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 (dalam 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 sepertiinclude('file.php');
pekerjaan Anda memelihara kode seperti ini menjadi semakin sulit 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 meneruskan alat yang kita butuhkan ke dalam fungsi atau kelas.
function foo(\Bar $bob) { $bob->doSomething(); }
Ini jauh lebih mudah untuk dipahami dan dipertahankan. Tidak ada yang menebak di mana
$bob
itu diatur karena penelepon bertanggung jawab untuk mengetahui itu (itu menyampaikan apa yang perlu kita ketahui). Lebih baik lagi, kita bisa menggunakan deklarasi tipe untuk membatasi apa yang sedang diteruskan. Jadi kita tahu itu$bob
adalah salah satu contohBar
kelas, atau turunan dari anakBar
, artinya kita tahu kita bisa menggunakan metode kelas itu. Dikombinasikan dengan autoloader standar (tersedia sejak PHP 5.3), kita sekarang dapat melacak di manaBar
didefinisikan. PHP 7.0 atau yang lebih baru menyertakan deklarasi tipe yang diperluas, di mana Anda juga dapat menggunakan tipe skalar (sepertiint
ataustring
).sumber
$bob = Bar::instance();
kapan saja Anda membutuhkannya.Sebagai:
global $my_global; $my_global = 'Transport me between functions'; Equals $GLOBALS['my_global']
adalah praktik yang buruk (Seperti Wordpress
$pagenow
) ... hmmmPertimbangkan ini:
$my-global = 'Transport me between functions';
adalah kesalahan PHP Tapi:
$GLOBALS['my-global'] = 'Transport me between functions';
adalah TIDAK kesalahan, hypens tidak akan berbenturan dengan "umum" pengguna menyatakan variabel, seperti
$pagenow
. Dan Menggunakan UPPERCASE menunjukkan superglobal sedang digunakan, mudah dikenali dalam kode, atau dilacak dengan menemukan dalam fileSaya menggunakan tanda hubung, jika saya malas membuat kelas dari segalanya untuk satu solusi, seperti:
$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
Tetapi dalam kasus penggunaan yang lebih luas, saya menggunakan SATU global sebagai array:
$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... '; $GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
Yang terakhir bagi saya, praktik yang baik tentang tujuan atau penggunaan "cola light", daripada mengacaukan kelas tunggal setiap kali "menyimpan" beberapa data. Tolong beri komentar jika saya salah atau melewatkan sesuatu yang bodoh di sini ...
sumber