Apa kegunaan kata kunci global ?
Apakah ada alasan untuk memilih satu metode ke metode lainnya?
- Keamanan?
- Performa?
- Ada yang lain?
Metode 1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
Metode 2:
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
Kapan masuk akal untuk digunakan global
?
Bagi saya, ini tampaknya berbahaya ... tetapi mungkin hanya karena kurangnya pengetahuan. Saya tertarik pada alasan teknis yang didokumentasikan (misalnya dengan contoh kode, tautan ke dokumentasi ...).
Terima kasih sebelumnya!
Karunia
Ini adalah pertanyaan umum yang bagus tentang topik ini, saya (@Gordon) menawarkan hadiah untuk mendapatkan jawaban tambahan. Apakah jawaban Anda sesuai dengan jawaban saya atau memberikan sudut pandang yang berbeda tidak masalah. Karena global
topik ini muncul sesekali, kita dapat menggunakan jawaban "kanonik" yang bagus untuk ditautkan.
php
language-design
Pascal Qyy
sumber
sumber
goto
? Mengapa orang menggunakannya? Mereka tidak menggunakannya (saya harap setidaknya): PJawaban:
Dunia itu jahat
Hal ini berlaku untuk
global
kata kunci serta segala sesuatu yang menjangkau dari lingkup lokal ke lingkup global (statika, lajang, register, konstanta). Anda tidak ingin menggunakannya. Panggilan fungsi tidak harus bergantung pada apapun di luar, misalnyaSemua ini akan membuat kode Anda bergantung di luar. Artinya, Anda harus mengetahui status global lengkap aplikasi Anda sebelum dapat memanggil semua ini dengan andal. Fungsi tidak dapat ada tanpa lingkungan tersebut.
Menggunakan superglobals mungkin bukan kelemahan yang jelas, tetapi jika Anda memanggil kode Anda dari Command Line, Anda tidak memiliki
$_GET
atau$_POST
. Jika kode Anda bergantung pada masukan dari ini, Anda membatasi diri Anda pada lingkungan web. Abstraksi permintaan menjadi objek dan gunakan itu sebagai gantinya.Dalam kasus penggandengan nama kelas yang di-hardcode (statis, konstanta), fungsi Anda juga tidak bisa ada tanpa kelas itu tersedia. Itu bukan masalah jika itu adalah kelas dari namespace yang sama, tetapi ketika Anda memulai campuran dari namespace yang berbeda, Anda membuat kekacauan yang kusut.
Penggunaan kembali sangat terhambat oleh semua hal di atas. Begitu juga dengan unit-testing .
Juga, tanda tangan fungsi Anda berbohong saat Anda berpasangan dengan ruang lingkup global
adalah pembohong, karena mengklaim saya dapat memanggil fungsi itu tanpa memberikan apapun padanya. Hanya ketika saya melihat pada fungsi tubuh yang saya pelajari, saya harus mengatur lingkungan ke dalam keadaan tertentu.
Jika fungsi Anda memerlukan argumen untuk dijalankan, buat argumen tersebut eksplisit dan teruskan di:
dengan jelas menyampaikan dari tanda tangan apa yang diperlukan untuk dipanggil. Tidak tergantung pada lingkungan untuk berada dalam keadaan tertentu. Anda tidak perlu melakukannya
Ini masalah menarik (kata kunci global) vs mendorong (argumen). Saat Anda mendorong / menyuntikkan dependensi, fungsinya tidak lagi bergantung pada bagian luar. Ketika Anda melakukannya,
fn(1)
Anda tidak harus memiliki variabel yang menahan 1 di suatu tempat di luar. Tetapi ketika Anda menarik global$one
di dalam fungsi, Anda berpasangan dengan cakupan global dan mengharapkannya memiliki variabel yang didefinisikan di suatu tempat. Fungsi itu tidak lagi independen.Lebih buruk lagi, ketika Anda mengubah global di dalam fungsi Anda, kode Anda akan segera benar-benar tidak dapat dipahami, karena fungsi Anda memiliki efek samping di semua tempat.
Karena kurangnya contoh yang lebih baik, pertimbangkan
Dan kemudian Anda melakukannya
Tidak ada cara untuk melihat bahwa
$foo
diubah dari ketiga baris ini. Mengapa memanggil fungsi yang sama dengan argumen yang sama tiba-tiba mengubah outputnya atau mengubah nilai dalam status global? Suatu fungsi harus melakukan X untuk input yang ditentukan Y. Selalu.Ini menjadi lebih parah saat menggunakan OOP, karena OOP adalah tentang enkapsulasi dan dengan menjangkau lingkup global, Anda melanggar enkapsulasi. Semua Singletons dan Registri yang Anda lihat dalam kerangka kerja ini adalah bau kode yang harus dihapus demi Injeksi Ketergantungan. Pisahkan kode Anda.
Sumber Daya Lainnya:
static
dianggap berbahayasumber
Satu alasan besar yang menentang
global
adalah bahwa itu berarti fungsinya bergantung pada ruang lingkup lain. Ini akan menjadi berantakan dengan sangat cepat.vs.
Membutuhkan
$str1
dan$str2
diatur dalam cakupan panggilan agar fungsi berfungsi berarti Anda memperkenalkan dependensi yang tidak perlu. Anda tidak dapat mengganti nama variabel-variabel ini lagi dalam lingkup ini tanpa mengganti nama mereka dalam fungsi juga, dan dengan demikian juga di semua lingkup lain yang Anda gunakan fungsi ini. Ini segera berubah menjadi kekacauan saat Anda mencoba melacak nama variabel Anda.global
adalah pola yang buruk bahkan untuk memasukkan hal-hal global seperti$db
sumber daya. Ada akan datang hari ketika Anda ingin mengubah nama$db
tetapi tidak bisa, karena seluruh aplikasi Anda tergantung pada nama.Membatasi dan memisahkan ruang lingkup variabel sangat penting untuk menulis aplikasi setengah jalan yang kompleks.
sumber
$db
? Itu PDO, diedarkan ke mana-mana. Mengapa diubah ketika saya dapat memperbarui informasi koneksi secara terpisah?$db
variabel global ? Karena suatu hari Anda akan menemukan pengujian unit dan perlu mengelola lebih dari satu koneksi database pada satu waktu untuk itu? Banyak, banyak alasan.Bola dunia tidak bisa dihindari.
Ini adalah diskusi lama, tetapi saya masih ingin menambahkan beberapa pemikiran karena saya merindukannya dalam jawaban yang disebutkan di atas. Jawaban-jawaban itu menyederhanakan apa yang terlalu global dan menyajikan solusi yang sama sekali bukan solusi untuk masalah. Masalahnya adalah: apa cara yang tepat untuk menangani variabel global dan penggunaan kata kunci global? Untuk itu pertama-tama kita harus mengkaji dan mendeskripsikan apa itu global.
Lihatlah kode Zend ini - dan harap dipahami bahwa saya tidak menyarankan Zend ditulis dengan buruk:
Ada banyak dependensi yang tidak terlihat di sini. Konstanta itu sebenarnya adalah kelas. Anda juga dapat melihat require_once di beberapa halaman framework ini. Require_once adalah ketergantungan global, sehingga menciptakan ketergantungan eksternal. Itu tidak bisa dihindari untuk kerangka kerja. Bagaimana Anda bisa membuat kelas seperti DecoratorPluginManager tanpa banyak kode eksternal yang bergantung padanya? Itu tidak dapat berfungsi tanpa banyak tambahan. Menggunakan Zend framework, pernahkah Anda mengubah implementasi antarmuka? Sebuah antarmuka sebenarnya bersifat global.
Aplikasi lain yang digunakan secara global adalah Drupal. Mereka sangat memperhatikan desain yang tepat, tetapi seperti kerangka kerja besar lainnya, mereka memiliki banyak ketergantungan eksternal. Lihat global di halaman ini:
Pernah menulis redirect ke halaman login? Itu mengubah nilai global. (Dan apakah Anda tidak mengatakan 'WTF', yang saya anggap sebagai reaksi yang baik terhadap dokumentasi aplikasi Anda yang buruk.) Masalah dengan global bukanlah bahwa mereka global, Anda membutuhkannya untuk memiliki aplikasi yang berarti. Masalahnya adalah kompleksitas dari keseluruhan aplikasi yang dapat membuatnya menjadi mimpi buruk untuk ditangani. Sesi bersifat global, $ _POST global, DRUPAL_ROOT global, include / install.core.inc 'adalah global yang tidak dapat dimodifikasi. Ada dunia besar di luar fungsi apa pun yang diperlukan agar fungsi tersebut dapat melakukan tugasnya.
Jawaban Gordon salah, karena dia melebih-lebihkan independensi suatu fungsi dan menyebut suatu fungsi sebagai pembohong terlalu menyederhanakan situasi. Fungsi tidak berbohong dan ketika Anda melihat contohnya, fungsi tersebut dirancang dengan tidak benar - contohnya adalah bug. (Ngomong-ngomong, saya setuju dengan kesimpulan ini bahwa seseorang harus memisahkan kode.) Jawaban dari penipuan sebenarnya bukanlah definisi yang tepat dari situasi tersebut. Fungsi selalu berfungsi dalam cakupan yang lebih luas dan contohnya terlalu sederhana. Kita semua akan setuju dengannya bahwa fungsi itu sama sekali tidak berguna, karena mengembalikan konstanta. Fungsi itu bagaimanapun juga merupakan desain yang buruk. Jika Anda ingin menunjukkan bahwa latihan itu buruk, harap berikan contoh yang relevan. Mengganti nama variabel di seluruh aplikasi bukanlah masalah besar jika memiliki IDE (atau alat) yang bagus. Pertanyaannya adalah tentang ruang lingkup variabel, bukan perbedaan ruang lingkup dengan fungsi. Ada waktu yang tepat bagi suatu fungsi untuk menjalankan perannya dalam proses (itulah sebabnya ia dibuat terlebih dahulu) dan pada waktu yang tepat itu dapat memengaruhi fungsi aplikasi secara keseluruhan, karenanya juga bekerja pada variabel global . Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama: karenanya juga bekerja pada variabel global. Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama: karenanya juga bekerja pada variabel global. Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama:
Dalam kedua contoh, nilai $ z diubah dalam fungsi tertentu. Dalam kedua cara pemrograman, Anda dapat membuat perubahan tersebut di banyak tempat lain dalam kode. Anda dapat mengatakan bahwa menggunakan global Anda dapat memanggil $ z di mana saja dan mengubahnya di sana. Ya kamu bisa. Tapi maukah kamu? Dan jika dilakukan di tempat-tempat yang tidak tepat, bukankah itu harus disebut bug?
Bob Fanger mengomentari xzyfer.
Haruskah ada yang menggunakan apa saja dan terutama kata kunci 'global'? Tidak, tetapi seperti semua jenis desain, cobalah untuk menganalisis apa itu tergantung dan bergantung padanya. Cobalah untuk mencari tahu kapan itu berubah dan bagaimana itu berubah. Mengubah nilai global seharusnya hanya terjadi dengan variabel yang dapat berubah dengan setiap permintaan / tanggapan. Artinya, hanya untuk variabel yang termasuk dalam aliran fungsional suatu proses, bukan implementasi teknisnya. Pengalihan URL ke halaman login termasuk dalam aliran fungsional suatu proses, kelas implementasi yang digunakan untuk antarmuka ke implementasi teknis. Anda dapat mengubah yang terakhir selama versi aplikasi yang berbeda, tetapi tidak boleh mengubahnya dengan setiap permintaan / tanggapan.
Untuk lebih memahami kapan masalah bekerja dengan global dan kata kunci global dan kapan tidak, saya akan memperkenalkan kalimat berikutnya, yang berasal dari Wim de Bie saat menulis tentang blog: 'Personal yes, private no'. Ketika suatu fungsi mengubah nilai variabel global demi fungsinya sendiri, maka saya akan menyebutnya penggunaan pribadi variabel global dan bug. Tetapi ketika perubahan variabel global dibuat untuk pemrosesan aplikasi yang tepat secara keseluruhan, seperti pengalihan pengguna ke halaman login, maka menurut saya mungkin desainnya bagus, bukan menurut definisi buruk dan tentu saja bukan anti pola.
Dalam retrospeksi terhadap jawaban Gordon, menipu dan xzyfer: mereka semua memiliki 'private yes' (dan bug) sebagai contoh. Itulah mengapa mereka menentang penggunaan global. Saya akan melakukannya juga. Namun, mereka tidak datang dengan contoh 'pribadi ya, tidak pribadi' seperti yang telah saya lakukan dalam jawaban ini beberapa kali.
sumber
xyz
dansetZ
. Yang pertama mengubah status global, yang kedua adalah metode kelas dan hanya mengubah status instance tempat ia dipanggil.global
di drupal 7.26 (yang merupakan versi terbaru), beberapa dari hit tersebut ada di komentar dan beberapa lainnya muncul dalam kode yang tidak tersentuh selama bertahun-tahun. Saya berharap mereka tidak akan menggunakanglobal
s di drupal 8.Sederhananya jarang ada alasan untuk
global
dan tidak pernah ada alasan yang baik dalam kode PHP modern IMHO. Terutama jika Anda menggunakan PHP 5. Dan lebih khusus lagi jika Anda mengembangkan kode Berorientasi Objek.Globals secara negatif mempengaruhi pemeliharaan, keterbacaan dan pengujian kode. Banyak penggunaan
global
can dan harus diganti dengan Dependency Injection atau hanya meneruskan objek global sebagai parameter.sumber
Jangan ragu untuk menggunakan kata kunci global di dalam fungsi di PHP. Terutama jangan mengambil orang-orang yang dengan anehnya berkhotbah / berteriak bagaimana global itu 'jahat' dan yang lainnya.
Pertama, karena apa yang Anda gunakan sangat bergantung pada situasi dan masalah, dan TIDAK ada satu solusi / cara untuk melakukan apapun dalam pengkodean. Benar-benar mengesampingkan kekeliruan kata sifat religius yang tidak dapat didefinisikan, subjektif, seperti 'jahat' ke dalam persamaan.
Inti masalah :
Wordpress dan ekosistemnya menggunakan kata kunci global dalam fungsinya. Bisa kode OOP atau bukan OOP.
Dan sampai sekarang Wordpress pada dasarnya adalah 18,9% dari internet, dan menjalankan aplikasi / aplikasi raksasa yang tak terhitung banyaknya mulai dari Reuters hingga Sony, hingga NYT, hingga CNN.
Dan itu melakukannya dengan baik.
Penggunaan kata kunci global di dalam fungsi membebaskan Wordpress dari pembengkakan MASSIVE yang akan terjadi mengingat ekosistemnya yang sangat besar. Bayangkan setiap fungsi menanyakan / meneruskan variabel apa pun yang diperlukan dari plugin lain, inti, dan pengembalian. Ditambahkan dengan interdependensi plugin, yang akan berakhir dengan mimpi buruk variabel, atau mimpi buruk array yang diteruskan sebagai variabel. NERAKA untuk dilacak, sangat sulit untuk di-debug, sangat sulit untuk dikembangkan. Jejak memori yang sangat besar karena pembengkakan kode dan pembengkakan variabel juga. Lebih sulit untuk menulis juga.
Mungkin ada orang yang datang dan mengkritik Wordpress, ekosistemnya, praktik mereka, dan apa yang terjadi di sekitar bagian tersebut.
Tidak ada gunanya, karena ekosistem ini hampir 20% dari keseluruhan internet. Rupanya, itu TIDAK berhasil, itu melakukan tugasnya dan banyak lagi. Yang artinya sama untuk kata kunci global.
Contoh bagus lainnya adalah fundamentalisme "iframe is evil". Satu dekade yang lalu menggunakan iframe adalah bidah. Dan ada ribuan orang yang menentang mereka melalui internet. Kemudian datang facebook, kemudian datang sosial, sekarang iframe ada di mana-mana dari kotak 'suka' ke otentikasi, dan voila - semua orang tutup mulut. Ada orang-orang yang masih tidak tutup mulut - benar atau salah. Tapi tahukah Anda, hidup terus berjalan meskipun ada pendapat seperti itu, dan bahkan orang-orang yang menentang iframe satu dekade lalu sekarang harus menggunakannya untuk mengintegrasikan berbagai aplikasi sosial ke aplikasi organisasi mereka sendiri tanpa mengucapkan sepatah kata pun.
......
Fundamentalisme Coder adalah sesuatu yang sangat, sangat buruk. Sebagian kecil di antara kita mungkin diberkahi dengan pekerjaan yang nyaman di perusahaan monolitik yang solid yang memiliki cukup pengaruh untuk menanggung perubahan konstan dalam teknologi informasi dan tekanan yang ditimbulkannya terkait persaingan, waktu, anggaran, dan pertimbangan lainnya, dan oleh karena itu dapat berlatih. fundamentalisme dan kepatuhan yang ketat terhadap 'kejahatan' atau 'barang' yang dianggap. Posisi nyaman yang mengingatkan kita pada usia tua ini, meskipun penjajahnya masih muda.
Namun bagi mayoritas, dunia IT adalah dunia yang terus berubah di mana mereka perlu berpikiran terbuka dan praktis. Tidak ada tempat bagi fundamentalisme, kesampingkan kata kunci yang keterlaluan seperti 'kejahatan' di parit garis depan teknologi informasi.
Gunakan saja apa pun yang paling masuk akal untuk masalah AT HAND, dengan pertimbangan yang sesuai untuk masa depan dekat, menengah, dan panjang. Jangan menghindar untuk menggunakan fitur atau pendekatan apa pun karena fitur atau pendekatan tersebut memiliki permusuhan ideologis yang merajalela, di antara subset pembuat kode yang diberikan.
Mereka tidak akan melakukan pekerjaanmu. Kamu akan. Bertindak sesuai dengan keadaan Anda.
sumber
Saya pikir setiap orang telah cukup banyak menjelaskan tentang aspek negatif global. Jadi saya akan menambahkan hal positif serta instruksi untuk penggunaan global yang tepat:
Tujuan utama global adalah untuk berbagi informasi antar fungsi. kembali ketika tidak ada yang seperti kelas, kode php terdiri dari banyak fungsi. Terkadang Anda perlu berbagi informasi antar fungsi. Biasanya global digunakan untuk melakukan ini dengan risiko data rusak dengan menjadikannya global.
Sekarang sebelum beberapa orang bodoh yang beruntung memulai komentar tentang injeksi ketergantungan saya ingin bertanya kepada Anda bagaimana pengguna fungsi seperti contoh
get_post(1)
akan mengetahui semua ketergantungan fungsi. Juga pertimbangkan bahwa ketergantungan mungkin berbeda dariversi ke versi dan server ke server. Masalah utama dari ketergantungan injeksi adalah ketergantungan harus diketahui terlebih dahulu. Dalam situasi di mana ini tidak mungkin atau variabel global yang tidak diinginkan adalah satu-satunya cara untuk mencapai tujuan ini.
Karena pembuatan kelas, sekarang fungsi umum dapat dengan mudah dikelompokkan dalam kelas dan berbagi data. Melalui implementasi seperti Mediator, bahkan objek yang tidak terkait dapat berbagi informasi. Ini tidak lagi diperlukan.
Penggunaan lain untuk global adalah untuk tujuan konfigurasi. Sebagian besar di awal skrip sebelum pemuat otomatis apa pun dimuat, koneksi database dibuat, dll.
Selama pemuatan sumber daya, global dapat digunakan untuk mengkonfigurasi data (yaitu database mana yang akan digunakan di mana file perpustakaan berada, url server, dll). Cara terbaik untuk melakukannya adalah dengan menggunakan
define()
fungsi tersebut karena nilai-nilai ini tidak akan sering berubah dan dapat dengan mudah ditempatkan dalam file konfigurasi.Penggunaan terakhir untuk global adalah untuk menyimpan data umum (yaitu CRLF, IMAGE_DIR, IMAGE_DIR_URL), tanda status yang dapat dibaca manusia (yaitu ITERATOR_IS_RECURSIVE). Di sini global digunakan untuk menyimpan informasi yang dimaksudkan untuk digunakan aplikasi secara luas sehingga memungkinkan mereka untuk diubah dan membuat perubahan tersebut muncul di seluruh aplikasi.
Pola tunggal menjadi populer di php selama php4 ketika setiap instance dari suatu objek menggunakan memori. Singleton membantu menghemat ram dengan hanya mengizinkan satu contoh objek yang akan dibuat. Sebelum referensi bahkan injeksi ketergantungan akan menjadi ide yang buruk.
Implementasi php baru dari objek dari PHP 5.4+ menangani sebagian besar masalah ini, Anda dapat dengan aman melewatkan objek dengan sedikit atau tanpa penalti lagi. Ini tidak lagi diperlukan.
Penggunaan lain untuk singletons adalah instance khusus di mana hanya satu instance dari objek yang harus ada pada satu waktu, instance itu mungkin ada sebelum / setelah eksekusi skrip dan objek itu dibagi di antara berbagai skrip / server / bahasa dll. Di sini pola singleton memecahkan solusi dengan cukup baik.
Jadi kesimpulannya jika Anda berada di posisi 1, 2 atau 3 maka menggunakan global akan menjadi wajar. Namun dalam situasi lain Metode 1 harus digunakan.
Jangan ragu untuk memperbarui contoh lain di mana global harus digunakan.
sumber
Tidak masuk akal untuk membuat fungsi concat menggunakan kata kunci global.
Ini digunakan untuk mengakses variabel global seperti objek database.
Contoh:
Ini dapat digunakan sebagai variasi pada pola Singleton
sumber