Rumah  >  Soal Jawab  >  teks badan

Rujukan: Apakah skop pembolehubah, pembolehubah manakah boleh diakses dari mana, dan apakah ralat "pembolehubah tidak ditentukan"?

<p><br /></p><blockquote> <p>Nota: Ini ialah soalan rujukan untuk menangani skop pembolehubah dalam PHP Sila tutup mana-mana soalan yang sesuai dengan corak ini sebagai pendua soalan ini.</p> </blockquote> <p>Apakah maksud skop pembolehubah dalam PHP? Bolehkah pembolehubah dalam satu fail .php diakses dalam fail lain Mengapakah saya kadangkala mendapat mesej ralat "pembolehubah tidak ditentukan"?</p>
P粉018653751P粉018653751476 hari yang lalu550

membalas semua(2)saya akan balas

  • P粉786432579

    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.

    Tujuan pembolehubah statik

    1. Digunakan untuk menyimpan nilai antara panggilan fungsi berturut-turut.
    2. Simpan nilai antara panggilan rekursif apabila tiada cara (atau tujuan) untuk menyampaikannya sebagai hujah.
    3. Digunakan untuk menyimpan nilai yang biasanya paling baik diambil sekali sahaja. Sebagai contoh, hasil membaca fail tidak berubah pada pelayan.

    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.

    Adakah pembolehubah statik satu-satunya cara untuk mengekalkan nilai antara panggilan fungsi?

    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.

    balas
    0
  • P粉574695215

    P粉5746952152023-07-24 09:30:10

    Apakah skop berubah

    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.

    Bagaimana untuk menentukan skop dalam PHP?

    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.

    Contohnya:

    <?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

    Skop dan fail yang disertakan

    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.

    Mengenai fungsi dan kelas di dalam fungsi, bagaimana situasi lain dikendalikan?

    Setiap pengisytiharan fungsi baharu memperkenalkan skop baharu, semudah itu.

    (Tanpa Nama) berfungsi dalam fungsi.

    function foo() {
        $foo = 'bar';
    
        $bar = function () {
            // no access to $foo
            $baz = 'baz';
        };
    
        // no access to $baz
    }

    Kategori

    $foo = 'foo';
    
    class Bar {
    
        public function baz() {
            // no access to $foo
            $baz = 'baz';
        }
    
    }
    
    // 无法访问 $baz。

    Apakah kegunaan skop?

    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...

    Melintasi sempadan skop

    Cara yang betul: menghantar masuk dan keluar pembolehubah

    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);

    Meluaskan skop pembolehubah kepada fungsi tanpa nama

    $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.

    Salah cara: 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.

    balas
    0
  • Batalbalas