"ขอบเขตตัวแปร" คืออะไร?
ตัวแปรมี "ขอบเขต" ที่ จำกัด หรือ "สถานที่ที่สามารถเข้าถึงได้" เพียงเพราะคุณ$foo = 'bar';
เคยเขียนที่ไหนสักแห่งในใบสมัครของคุณไม่ได้หมายความว่าคุณสามารถอ้างอิงได้$foo
จากทุกที่ในแอปพลิเคชัน ตัวแปร$foo
มีขอบเขตที่แน่นอนซึ่งถูกต้องและรหัสเฉพาะในขอบเขตเดียวกันเท่านั้นที่สามารถเข้าถึงตัวแปรได้
ขอบเขตที่กำหนดไว้ใน PHP เป็นอย่างไร
ง่ายมาก: PHP มีขอบเขตการทำงาน นั่นเป็นตัวคั่นขอบเขตชนิดเดียวที่มีอยู่ใน PHP ตัวแปรภายในฟังก์ชั่นนั้นใช้ได้เฉพาะในฟังก์ชั่นนั้นเท่านั้น ตัวแปรนอกฟังก์ชั่นสามารถใช้ได้ทุกที่นอกฟังก์ชั่น แต่ไม่มีในฟังก์ชั่นใด ๆ ซึ่งหมายความว่ามีขอบเขตพิเศษหนึ่งใน PHP: ขอบเขตทั่วโลก ตัวแปรใด ๆ ที่ประกาศภายนอกฟังก์ชั่นใด ๆ อยู่ภายในขอบเขตส่วนกลางนี้
ตัวอย่าง:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
}
$foo
อยู่ในโลกขอบเขต$baz
อยู่ในท้องถิ่นmyFunc
ที่อยู่ภายในขอบเขต รหัสภายในเท่านั้นที่myFunc
สามารถเข้าถึง$baz
ได้ รหัสภายนอก เท่านั้นที่myFunc
สามารถเข้าถึง$foo
ได้ ไม่มีสิทธิ์เข้าถึงอีก:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
echo $foo; // doesn't work
echo $baz; // works
}
echo $foo; // works
echo $baz; // doesn't work
ขอบเขตและไฟล์รวม
ขอบเขตไฟล์ไม่ได้แยกขอบเขต:
a.php
<?php
$foo = 'bar';
b.php
<?php
include 'a.php';
echo $foo; // works!
กฎเดียวกันนี้นำไปใช้กับinclude
รหัส d เช่นเดียวกับรหัสอื่น ๆ : function
ขอบเขตที่แยกต่างหากเท่านั้น สำหรับวัตถุประสงค์ของขอบเขตคุณอาจนึกถึงการรวมไฟล์เช่นการคัดลอกและการวางโค้ด:
c.php
<?php
function myFunc() {
include 'a.php';
echo $foo; // works
}
myFunc();
echo $foo; // doesn't work!
ในตัวอย่างข้างต้นa.php
รวมอยู่ภายในmyFunc
ตัวแปรใด ๆ ภายในa.php
เท่านั้นที่มีขอบเขตฟังก์ชั่นในท้องถิ่น เพียงเพราะพวกเขาดูเหมือนจะอยู่ในขอบเขตทั่วโลกในa.php
ไม่จำเป็นต้องหมายความว่าพวกเขาเป็นจริงขึ้นอยู่กับบริบทที่รหัสรวม / ดำเนินการมา
ฟังก์ชั่นเกี่ยวกับฟังก์ชั่นภายในฟังก์ชั่นและชั้นเรียน?
function
การประกาศใหม่ทุกครั้งจะแนะนำขอบเขตใหม่นั่นง่ายมาก
ฟังก์ชั่น (ไม่ระบุชื่อ) ภายในฟังก์ชั่น
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';
}
}
// no access to $baz
อะไรคือขอบเขตที่ดีสำหรับ?
การจัดการกับปัญหาการกำหนดขอบเขตอาจดูเหมือนน่ารำคาญ แต่ขอบเขตตัวแปร จำกัด มีความจำเป็นต่อการเขียนแอปพลิเคชันที่ซับซ้อน! หากตัวแปรทุกตัวที่คุณประกาศจะสามารถใช้งานได้จากที่อื่นภายในแอปพลิเคชันของคุณคุณจะต้องก้าวข้ามตัวแปรของคุณโดยไม่มีวิธีการที่แท้จริงในการติดตามสิ่งที่เปลี่ยนแปลงอะไร มีชื่อที่สมเหตุสมผลจำนวนมากที่คุณสามารถให้กับตัวแปรของคุณได้คุณอาจต้องการใช้ตัวแปร$name
มากกว่าหนึ่งแห่ง หากคุณสามารถมีชื่อตัวแปรที่ไม่ซ้ำกันนี้ได้เพียงครั้งเดียวในแอปของคุณคุณจะต้องใช้รูปแบบการตั้งชื่อที่ซับซ้อนมาก ๆ เพื่อให้แน่ใจว่าตัวแปรของคุณไม่เหมือนใครและคุณไม่ได้เปลี่ยนตัวแปรผิดจากโค้ดผิด
สังเกต:
function foo() {
echo $bar;
}
หากไม่มีขอบเขตฟังก์ชันข้างต้นจะทำอะไร ในกรณีที่ไม่$bar
มาจากไหน? รัฐนี้มีอะไร? มันจะเริ่มต้นได้ยัง? คุณต้องตรวจสอบทุกครั้งหรือไม่ สิ่งนี้ไม่สามารถบำรุงรักษาได้ ซึ่งนำเราไปที่ ...
ข้ามขอบเขตของขอบเขต
วิธีที่ถูกต้อง: ผ่านตัวแปรเข้าและออก
function foo($bar) {
echo $bar;
return 42;
}
ตัวแปร$bar
กำลังเข้ามาในขอบเขตนี้อย่างชัดเจนว่าเป็นอาร์กิวเมนต์ของฟังก์ชัน เพียงแค่ดูที่ฟังก์ชั่นนี้มันชัดเจนว่าค่าที่มันทำงานกับกำเนิด จากนั้นก็ชัดเจนส่งกลับค่า ผู้เรียกมีความมั่นใจในการรู้ว่าตัวแปรใดที่ฟังก์ชั่นนี้จะใช้งานและค่าที่ส่งคืนมาจาก:
$baz = 'baz';
$blarg = foo($baz);
การขยายขอบเขตของตัวแปรไปสู่ฟังก์ชั่นนิรนาม
$foo = 'bar';
$baz = function () use ($foo) {
echo $foo;
};
$baz();
ฟังก์ชั่นที่ไม่ระบุชื่อรวมไว้อย่างชัดเจน$foo
จากขอบเขตโดยรอบ โปรดทราบว่านี่ไม่ใช่ขอบเขตทั่วโลก
ทางที่ผิด: global
ดังที่กล่าวไว้ก่อนหน้านี้ขอบเขตทั่วโลกค่อนข้างพิเศษและฟังก์ชั่นสามารถนำเข้าตัวแปรจากมันได้อย่างชัดเจน:
$foo = 'bar';
function baz() {
global $foo;
echo $foo;
$foo = 'baz';
}
ฟังก์ชั่นนี้ใช้และแก้ไขตัวแปร$foo
กลาง อย่าทำอย่างนี้! (เว้นเสียแต่ว่าคุณจะรู้ว่ากำลังทำอะไรอยู่และจริงๆแล้ว: อย่า!)
ผู้เรียกฟังก์ชั่นนี้ทั้งหมดเห็นคือ:
baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!
ไม่มีข้อบ่งชี้ว่าฟังก์ชั่นนี้มีผลข้างเคียงแต่อย่างใด สิ่งนี้จะกลายเป็นเรื่องยุ่งเหยิงอย่างง่ายดายเพราะฟังก์ชั่นบางอย่างยังคงแก้ไขและต้องการสถานะโกลบอลบางอย่าง คุณต้องการให้ฟังก์ชั่นไร้สัญชาติทำหน้าที่เฉพาะอินพุตและส่งคืนเอาต์พุตที่กำหนดไว้อย่างไรก็ตามหลายครั้งที่คุณเรียกใช้
คุณควรหลีกเลี่ยงการใช้ขอบเขตทั่วโลกในทุกวิถีทางเท่าที่จะทำได้ แน่นอนที่สุดคุณไม่ควร "ดึง" ตัวแปรออกจากขอบเขตส่วนกลางไปยังขอบเขตภายใน