Rujukan: Apakah skop pembolehubah, pembolehubah manakah boleh diakses dari mana dan apakah ralat "pembolehubah tidak ditentukan"?
P粉023650014
P粉023650014 2023-10-19 10:50:15
0
2
616


Nota: Ini ialah soalan rujukan yang berkaitan dengan skop pembolehubah dalam PHP. Sila tutup mana-mana daripada banyak soalan yang sesuai dengan pola ini sebagai pendua soalan ini.

Apakah "skop pembolehubah" dalam PHP? Bolehkah pembolehubah dalam satu fail .php boleh diakses dalam fail .php yang lain? Mengapa saya kadangkala mendapat ralat "undefined variable" ?

P粉023650014
P粉023650014

membalas semua(2)
P粉311563823

Walaupun pembolehubah yang ditakrifkan dalam skop fungsi tidak boleh diakses dari luar, ini tidak bermakna anda tidak boleh menggunakan nilainya selepas fungsi selesai. PHP mempunyai static 关键字,在面向对象的 PHP 中广泛用于定义静态方法和属性,但应该记住 static terkenal yang juga boleh digunakan untuk menentukan pembolehubah statik di dalam fungsi.

Apakah itu "pembolehubah statik"?

Pembolehubah statik adalah berbeza daripada pembolehubah biasa yang ditakrifkan dalam skop fungsi Pembolehubah statik tidak akan 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 kita mentakrifkan $counter 没有 static 那么每次回显的值将与传递给函数的 $num 参数相同。使用 static kita boleh membina kaunter mudah ini tanpa penyelesaian tambahan.

Kes penggunaan pembolehubah statik

  1. Simpan nilai antara panggilan seterusnya ke fungsi.
  2. Simpan nilai antara panggilan rekursif apabila tiada jalan (atau tiada jalan) Tujuan) menghantarnya sebagai parameter.
  3. Cache biasanya terbaik untuk mendapatkan semula nilai sekali. untuk Sebagai contoh, hasil membaca fail tidak boleh diubah pada pelayan.

Petua

Pembolehubah statik hanya wujud dalam skop fungsi tempatan. tak boleh jadi Diakses di luar fungsi di mana ia ditakrifkan. jadi anda boleh Pastikan ia akan mengekalkan nilainya sehingga panggilan seterusnya Fungsi ini.

Pembolehubah statik hanya boleh ditakrifkan sebagai skalar atau skalar Ungkapan (sejak PHP 5.6). tidak dapat tidak memberikan nilai lain kepadanya Yang mengakibatkan kegagalan, sekurang-kurangnya setakat penulisan ini. Walau bagaimanapun, anda boleh melakukan ini pada 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 agak "berkongsi" antara kaedah objek Rakan sekelas. Ia mudah difahami dengan melihat contoh di bawah:

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. Pembolehubah statik akan berkelakuan seperti yang diharapkan jika objek adalah dari kelas yang berbeza (atau memanjangkan satu sama lain).

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

Cara lain untuk mengekalkan nilai antara panggilan fungsi ialah menggunakan penutupan. Penutupan diperkenalkan dalam PHP 5.3. Ringkasnya, mereka membenarkan anda menyekat akses kepada set pembolehubah tertentu dalam skop fungsi kepada fungsi tanpa nama lain, yang akan menjadi satu-satunya cara untuk mengaksesnya. Berada di dalam pembolehubah penutupan mungkin meniru (lebih kurang berjaya) konsep OOP seperti "pemalar kelas" (jika ia diluluskan oleh nilai dalam penutupan) atau "sifat peribadi" (jika diluluskan melalui rujukan) dalam pengaturcaraan berstruktur .

Yang terakhir ini sebenarnya membenarkan penggunaan penutupan dan bukannya pembolehubah statik. Ia sentiasa terpulang kepada pembangun untuk memutuskan perkara yang hendak digunakan, tetapi perlu dinyatakan bahawa pembolehubah statik pastinya berguna apabila menggunakan rekursi dan patut mendapat perhatian pembangun.

P粉895187266

Apakah itu "skop pembolehubah"?

Pembolehubah adalah terhad dalam "skop" 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 dari $foo = 'bar'; 一次,并不意味着您可以从引用 $foo >应用程序内的其他地方。变量 $foo >Di tempat lain dalam apl

. Pembolehubah $foo mempunyai skop tertentu, di mana ia sah, dan hanya kod dalam skop yang sama boleh mengakses pembolehubah.

Bagaimana untuk menentukan skop dalam PHP?

Ia sangat mudah: PHP mempunyai skop fungsi. Ini adalah satu-satunya pembatas julat yang terdapat dalam PHP. Pembolehubah di dalam fungsi hanya tersedia di 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

. Sebarang pembolehubah yang diisytiharkan di luar mana-mana fungsi adalah dalam skop global ini.

Contoh:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}
$foo 位于 global 范围内,$baz 位于 内的local 范围内myFunc。只有 myFunc 中的代码才能访问 $baz。只有myFunc外部的代码可以访问$foo$foo berada dalam skop global

dan $baz berada dalam skop

local

myFunc dalam . Hanya kod dalam myFunc boleh mengakses $baz. Hanya kod di luar myFunc boleh mengakses $foo. Mana-mana pihak tidak boleh mengakses 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

jangan pisahkan

Julat:

a.php

include代码的规则与适用于任何其他代码的规则相同:仅函数

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!
Berlaku untuk skop berasingan untuk

. Untuk tujuan skop, anda mungkin mempertimbangkan untuk memasukkan fail seperti salin dan tampal kod: a.php 包含在 myFunc 中,a.php 中的任何变量仅具有本地函数作用域。仅仅因为它们似乎位于a.php

c.php

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!
functionDalam contoh di atas, a.php terkandung dalam myFunc dan mana-mana pembolehubah dalam a.php hanya mempunyai skop fungsi setempat. Hanya kerana mereka kelihatan

berada dalam skop global dalam a.php tidak semestinya bermakna mereka ada, ia benar-benar bergantung pada konteks di mana kod itu terkandung/dilaksanakan.

Bagaimana pula dengan fungsi dan fungsi dalam kelas?

Setiap pengisytiharan

baharu memperkenalkan skop baharu, semudah itu.

Fungsi dalam fungsi (tanpa nama)

function foo() {
    $foo = 'bar';

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

    // no access to $baz
}
$nameKursus
$foo = 'foo';

class Bar {

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

}

// no access to $baz

Apakah kegunaan skop?

🎜Menguruskan isu skop mungkin kelihatan menjengkelkan, tetapi 🎜skop pembolehubah terhad adalah penting untuk menulis aplikasi yang kompleks! 🎜Jika setiap pembolehubah yang anda isytiharkan tersedia dari mana-mana tempat lain dalam aplikasi anda, anda akan melangkah melalui semua operasi anda pada pembolehubah anda tanpa cara sebenar untuk menjejaki perkara yang mengubah perkara tersebut. Anda terhad dalam nama masuk akal yang boleh anda berikan kepada pembolehubah anda dan anda mungkin mahu menggunakan pembolehubah "🎜" di lebih daripada satu tempat. Jika anda hanya boleh menggunakan nama pembolehubah unik ini sekali dalam aplikasi anda, maka anda perlu menggunakan skema penamaan yang sangat kompleks untuk memastikan pembolehubah anda unik dan anda tidak menukar pembolehubah yang salah daripada sekeping kod yang salah. 🎜 🎜Pemerhatian: 🎜
function foo() {
    echo $bar;
}

Apakah fungsi di atas jika tiada skop? $barDari mana asalnya? Apakah statusnya? Adakah ia dimulakan? Adakah saya perlu menyemaknya setiap kali? Ini tidak boleh dikekalkan. Yang membawa kita kepada...

Merentasi sempadan julat

Cara yang betul: menghantar masuk dan keluar pembolehubah

function foo($bar) {
    echo $bar;
    return 42;
}

Pembolehubah$barmasukkan skop ini secara eksplisit sebagai parameter fungsi. Melihat kepada fungsi ini, jelas dari mana nilai yang digunakannya. Kemudian ia secara eksplisit mengembalikan nilai. Pemanggil mempunyai keyakinan untuk mengetahui pembolehubah mana yang akan digunakan oleh fungsi dan dari mana nilai pulangannya akan 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 menyertakan $foo dalam skop sekelilingnya. Ambil perhatian bahawa ini tidak sama dengan skop global.

Salah cara:全局

Seperti yang dinyatakan sebelum ini, skop global agak istimewa dan fungsi boleh mengimport pembolehubah secara eksplisit daripadanya:

$foo = 'bar';

function baz() {
    global $foo;
    echo $foo;
    $foo = 'baz';
}

Fungsi ini menggunakan dan mengubah suai pembolehubah global$foo. Jangan lakukan ini! (Melainkan anda benar-benar benar-benar tahu apa yang anda lakukan, dan walaupun begitu: jangan lakukannya!)

Apa yang dilihat oleh pemanggil fungsi ini ialah:

baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!

Tiada tanda bahawa fungsi ini mempunyai sebarang kesan sampingan, tetapi ia berlaku. Ini boleh mengelirukan dengan mudah kerana sesetengah fungsi sentiasa diubah suai dan memerlukan beberapa keadaan global. Anda mahu fungsi menjadi tanpa negara, bertindak hanya pada inputnya dan mengembalikan output yang ditentukan, tidak kira berapa kali anda memanggilnya.

Anda harus mengelak daripada menggunakan skop global dalam apa jua cara jika boleh, yang pasti, anda tidak seharusnya "menarik" pembolehubah dari skop global ke skop tempatan.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan