Rumah > Soal Jawab > teks badan
P粉7864325792023-07-24 11:19:34
Walaupun pembolehubah yang ditakrifkan dalam skop fungsi tidak boleh diakses dari luar, ini tidak bermakna nilainya tidak boleh digunakan selepas fungsi selesai. PHP mempunyai kata kunci statik yang terkenal, yang digunakan secara meluas untuk menentukan kaedah dan sifat statik dalam PHP berorientasikan objek, tetapi anda perlu ingat bahawa kata kunci statik juga boleh digunakan untuk menentukan pembolehubah statik di dalam fungsi.
Pembolehubah statik adalah berbeza daripada pembolehubah biasa yang ditakrifkan dalam skop fungsi kerana ia tidak kehilangan nilainya apabila pelaksanaan program meninggalkan skop. Mari kita pertimbangkan contoh berikut menggunakan pembolehubah statik:
function countSheep($num) { static $counter = 0; $counter += $num; echo "$counter sheep jumped over fence"; } countSheep(1); countSheep(2); countSheep(3);
Hasil:
1 sheep jumped over fence 3 sheep jumped over fence 6 sheep jumped over fence
Jika kami tidak menggunakan kata kunci statik untuk mentakrifkan pembolehubah $counter, output nilai setiap kali akan sama dengan parameter $num yang dihantar ke fungsi. Menggunakan kata kunci statik membolehkan anda membina kaunter mudah ini tanpa memerlukan penyelesaian tambahan.
Pembolehubah statik hanya wujud dalam skop fungsi tempatan. Ia tidak boleh diakses di luar fungsi di mana ia ditakrifkan. Oleh itu, anda boleh memastikan bahawa nilainya kekal tidak berubah sehingga masa berikutnya fungsi dipanggil.
Pembolehubah statik hanya boleh ditakrifkan sebagai skalar atau ungkapan skalar (sejak PHP 5.6). Menetapkan nilai lain kepadanya pasti akan mengakibatkan ralat, sekurang-kurangnya pada masa penulisan ini. Walau bagaimanapun, anda boleh melakukan ini dalam baris kod seterusnya:
function countSheep($num) { static $counter = 0; $counter += sqrt($num);//imagine we need to take root of our sheep each time echo "$counter sheep jumped over fence"; }
Hasil:
2 sheep jumped over fence 5 sheep jumped over fence 9 sheep jumped over fence
Fungsi statik ialah mekanisme "perkongsian" antara kaedah objek kelas yang sama. Ia boleh difahami dengan mudah dengan melihat contoh berikut:
class SomeClass { public function foo() { static $x = 0; echo ++$x; } } $object1 = new SomeClass; $object2 = new SomeClass; $object1->foo(); // 1 $object2->foo(); // 2 oops, $object2 uses the same static $x as $object1 $object1->foo(); // 3 now $object1 increments $x $object2->foo(); // 4 and now his twin brother
Ini hanya berfungsi untuk objek kelas yang sama. Jika objek adalah daripada kelas yang berbeza (walaupun ia memanjangkan satu sama lain), pembolehubah statik akan berkelakuan seperti yang diharapkan.
Satu lagi cara untuk mengekalkan nilai antara panggilan fungsi adalah dengan menggunakan penutupan. Penutupan diperkenalkan dalam PHP 5.3. Ringkasnya, mereka membenarkan anda menyekat akses kepada set pembolehubah tertentu kepada fungsi tanpa nama lain dalam skop fungsi, yang akan menjadi satu-satunya cara untuk mengakses pembolehubah tersebut. Dalam penutupan, pembolehubah boleh meniru (lebih kurang berjaya) konsep "pemalar kelas" (jika ia dihantar ke penutupan mengikut nilai) atau "sifat peribadi" (jika diluluskan melalui rujukan) dalam pengaturcaraan berorientasikan objek.
Malah, yang terakhir membenarkan penggunaan penutupan dan bukannya pembolehubah statik. Kaedah mana yang hendak digunakan bergantung sepenuhnya kepada keputusan pembangun, tetapi perlu dinyatakan bahawa pembolehubah statik sangat berguna apabila menangani rekursi dan patut mendapat perhatian pembangun.
P粉5746952152023-07-24 09:30:10
Pembolehubah mempunyai "skop" terhad atau "di mana ia boleh diakses". Hanya kerana anda menulis $foo = 'bar' sekali di suatu tempat dalam aplikasi anda tidak bermakna anda boleh merujuk $foo di tempat lain dalam aplikasi anda. Pembolehubah $foo adalah sah dalam skop tertentu dan hanya boleh diakses melalui kod dalam skop yang sama.
Sangat mudah: PHP mempunyai skop fungsi. Ini adalah satu-satunya pembatas skop yang wujud dalam PHP. Pembolehubah di dalam fungsi hanya boleh digunakan dalam fungsi tersebut. Pembolehubah di luar fungsi boleh digunakan di mana-mana di luar fungsi, tetapi tidak boleh digunakan di dalam mana-mana fungsi. Ini bermakna terdapat skop khas dalam PHP: skop global. Pembolehubah yang diisytiharkan di luar sebarang fungsi adalah dalam skop global.
<?php $foo = 'bar'; function myFunc() { $baz = 42; }
$foo
is in the global scope, $baz
is in a local scope inside myFunc
. Only code inside myFunc
has access to $baz
. Only code outside myFunc
has access to $foo
Kedua-duanya tidak mempunyai akses kepada yang lain:
<?php $foo = 'bar'; function myFunc() { $baz = 42; echo $foo; // doesn't work echo $baz; // works } echo $foo; // works echo $baz; // doesn't work
Sempadan fail tidak memisahkan skop.
a.php
<?php $foo = 'bar';
b.php
<?php include 'a.php'; echo $foo; // works!
Peraturan yang digunakan pada kod yang disertakan adalah sama seperti yang digunakan pada mana-mana kod lain: hanya fungsi boleh memisahkan skop. Dari segi skop, anda boleh memikirkan memasukkan fail sebagai kod salin dan tampal.
c.php
<?php function myFunc() { include 'a.php'; echo $foo; // works } myFunc(); echo $foo; // doesn't work!
Dalam contoh di atas, a.php terkandung di dalam myFunc, dan mana-mana pembolehubah dalam a.php hanya mempunyai skop fungsi setempat. Hanya kerana mereka kelihatan berskop global dalam a.php tidak bermakna mereka sebenarnya, ia benar-benar bergantung pada konteks di mana kod itu disertakan/dilaksanakan.
Setiap pengisytiharan fungsi baharu memperkenalkan skop baharu, semudah itu.
function foo() { $foo = 'bar'; $bar = function () { // no access to $foo $baz = 'baz'; }; // no access to $baz }
$foo = 'foo'; class Bar { public function baz() { // no access to $foo $baz = 'baz'; } } // 无法访问 $baz。
Berurusan dengan isu skop mungkin kelihatan menjengkelkan, tetapi skop pembolehubah terhad adalah penting untuk menulis aplikasi yang kompleks! Jika setiap pembolehubah yang anda isytiharkan dalam aplikasi anda boleh diakses dari mana-mana sahaja, anda tidak akan dapat menjejaki perubahan pada pembolehubah tersebut. Anda hanya boleh memberikan pembolehubah bilangan yang terhad bagi nama wajar dan anda mungkin mahu menggunakan pembolehubah "$name" di lebih daripada satu tempat. Jika anda hanya boleh mempunyai satu nama pembolehubah unik dalam aplikasi anda, anda perlu menggunakan skema penamaan yang sangat kompleks untuk memastikan keunikan pembolehubah dan untuk memastikan anda tidak menukar pembolehubah yang salah daripada sekeping kod yang salah.
Seperti berikut:
function foo() { echo $bar; }
Apakah fungsi di atas jika tiada skop? Dari mana datangnya $bar? Apakah statusnya? Adakah ia dimulakan? Adakah anda perlu menyemak setiap masa? Ini tidak boleh dikekalkan. Yang membawa kita ke...
function foo($bar) { echo $bar; return 42; }
Pembolehubah $bar dihantar secara eksplisit ke dalam skop sebagai parameter fungsi. Hanya dengan melihat fungsi ini, jelas dari mana nilai yang digunakannya berasal. Kemudian, ia secara eksplisit mengembalikan nilai. Pemanggil boleh memastikan pembolehubah mana yang akan digunakan oleh fungsi dan dari mana nilai pulangan datang:
$baz = 'baz'; $blarg = foo($baz);
$foo = 'bar'; $baz = function () use ($foo) { echo $foo; }; $baz();
Fungsi tanpa nama secara eksplisit termasuk pembolehubah $foo daripada skop sekelilingnya. Ambil perhatian bahawa ini tidak sama dengan skop global.
global
Seperti yang dinyatakan sebelum ini, skop global adalah istimewa dan fungsi boleh mengimport pembolehubah secara eksplisit daripada skop global:
$foo = 'bar'; function baz() { global $foo; echo $foo; $foo = 'baz'; }
Fungsi ini menggunakan dan mengubah suai pembolehubah global $foo. Jangan buat begini! (Melainkan anda benar-benar benar-benar tahu apa yang anda lakukan, dan walaupun begitu: jangan lakukannya!)
Pemanggil fungsi ini hanya akan melihat ini:
baz(); // outputs "bar" unset($foo); baz(); // no output, WTF?! baz(); // outputs "baz", WTF?!?!!
Tiada tanda bahawa fungsi ini mempunyai sebarang kesan sampingan, tetapi ia sebenarnya berlaku. Ini dengan mudah boleh bertukar menjadi keadaan yang tidak kemas apabila beberapa fungsi sentiasa diubah suai dan bergantung pada beberapa keadaan global. Anda mahu fungsi itu tidak mempunyai kewarganegaraan, hanya beroperasi pada inputnya dan mengembalikan output yang ditentukan, tidak kira berapa kali anda memanggilnya.
Elakkan menggunakan skop global dalam apa jua keadaan jika boleh, khususnya, pembolehubah tidak boleh "diekstrak" daripada skop global ke dalam skop tempatan.