ฉันจะเรียกวิธีการคงที่จากวิธีอื่นภายในชั้นเรียนเดียวกันได้อย่างไร
$this->staticMethod();
หรือ
$this::staticMethod();
ฉันจะเรียกวิธีการคงที่จากวิธีอื่นภายในชั้นเรียนเดียวกันได้อย่างไร
$this->staticMethod();
หรือ
$this::staticMethod();
คำตอบ:
self::staticMethod();
$thisมีอยู่ถ้าวัตถุได้รับการยกตัวอย่างและคุณสามารถใช้$this->methodจากภายในวัตถุที่มีอยู่เท่านั้น ถ้าคุณมีวัตถุ self::แต่เพียงโทรวิธีการแบบคงที่และในวิธีการที่คุณต้องการที่จะเรียกวิธีการแบบคงที่อื่นในระดับเดียวกันคุณต้องใช้ ดังนั้นเพื่อหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้น (และคำเตือนอย่างเคร่งครัด) selfมันจะดีกว่าที่จะใช้
$this ไม่มีข้อผิดพลาดกลับมาคุ้มค่าเป็นเพียงstage 0ระวังด้วยสิ่งนี้ใช้self::
สมมติว่านี่คือคลาสของคุณ:
class Test
{
private $baz = 1;
public function foo() { ... }
public function bar()
{
printf("baz = %d\n", $this->baz);
}
public static function staticMethod() { echo "static method\n"; }
}
จากภายในfoo()วิธีลองดูที่ตัวเลือกต่างๆ:
$this->staticMethod();
เพื่อที่จะเรียกstaticMethod()ว่าเป็นวิธีการอินสแตนซ์ใช่มั้ย มันไม่ใช่. นี่เป็นเพราะวิธีการได้รับการประกาศเป็นpublic staticล่ามจะเรียกมันว่าเป็นวิธีการแบบคงที่ดังนั้นมันจะทำงานตามที่คาดไว้ อาจเป็นที่ถกเถียงกันอยู่ว่าการทำเช่นนั้นทำให้เห็นได้ชัดน้อยลงจากรหัสที่มีการเรียกใช้เมธอดแบบคงที่
$this::staticMethod();
ตั้งแต่ PHP 5.3 คุณสามารถใช้$var::method()เพื่อหมายถึง<class-of-$var>::; นี่ค่อนข้างสะดวกแม้ว่ากรณีการใช้งานด้านบนยังค่อนข้างแปลก ดังนั้นสิ่งนี้จึงนำเราไปสู่วิธีการทั่วไปในการเรียกใช้เมธอดแบบสแตติก:
self::staticMethod();
ตอนนี้ก่อนที่คุณจะเริ่มคิดว่า::เป็นผู้ประกอบการคงเรียกร้องให้ฉันให้คุณอีกตัวอย่างหนึ่ง:
self::bar();
นี้จะพิมพ์baz = 1ซึ่งหมายความว่า$this->bar()และself::bar()ทำสิ่งเดียวกัน; นั่นเป็นเพราะ::เป็นเพียงผู้ดำเนินการแก้ไขปัญหาขอบเขต มันจะทำให้มีparent::, self::และstatic::การทำงานและให้คุณสามารถเข้าถึงตัวแปรคงที่; วิธีการเรียกใช้ขึ้นอยู่กับลายเซ็นและวิธีการโทรที่ถูกเรียก
หากต้องการดูทั้งหมดนี้ในการดำเนินการให้ดูที่การส่งออก 3v4l.org นี้
self::bar()ดูเหมือนจะทำให้เข้าใจผิด - ตอนนี้เลิกใช้แล้วหรือยัง? (ใช้self::เพื่อเรียกวิธีการอินสแตนซ์แทนที่จะเป็นวิธีแบบคงที่)
selfเมื่อเรียกวิธีการคงที่ ตามคำจำกัดความ: วิธีการคงที่สามารถเรียกได้จากทุกที่และไม่ได้รับพารามิเตอร์ "ตัวเอง" อย่างไรก็ตามผมเห็นความสะดวกสบายของว่าไวยากรณ์เพื่อที่คุณจะได้ไม่ต้องเขียนphp MyClassName::ฉันคุ้นเคยกับภาษาที่พิมพ์แบบคงที่ซึ่งคอมไพเลอร์จะต้องได้รับตัวแปรทั้งหมดที่มีอยู่ในขอบเขตปัจจุบันดังนั้น (สามารถเทียบเท่า) self::สามารถละเว้น ดังนั้นคนเดียวเท่านั้นพูดself instanceMethod; self staticMethodไม่มีเหตุผลที่จะบอกว่า
นี่เป็นการตอบกลับที่ช้ามาก แต่เพิ่มรายละเอียดเกี่ยวกับคำตอบก่อนหน้า
เมื่อพูดถึงการเรียกใช้เมธอดสแตติกใน PHP จากวิธีสแตติกอื่นในคลาสเดียวกันสิ่งสำคัญคือการแยกความแตกต่างระหว่างselfและชื่อคลาส
ยกตัวอย่างโค้ดนี้:
class static_test_class {
public static function test() {
echo "Original class\n";
}
public static function run($use_self) {
if($use_self) {
self::test();
} else {
$class = get_called_class();
$class::test();
}
}
}
class extended_static_test_class extends static_test_class {
public static function test() {
echo "Extended class\n";
}
}
extended_static_test_class::run(true);
extended_static_test_class::run(false);
ผลลัพธ์ของรหัสนี้คือ:
ชั้นเรียนดั้งเดิม
ชั้นเรียนขยาย
นี้เป็นเพราะ selfหมายถึงคลาสที่มีโค้ดอยู่แทนที่จะเป็นคลาสของโค้ดที่ถูกเรียกใช้
หากคุณต้องการใช้วิธีที่กำหนดไว้ในคลาสที่สืบทอดคลาสดั้งเดิมคุณต้องใช้สิ่งต่อไปนี้:
$class = get_called_class();
$class::function_name();
self::เกิดขึ้นในกรณี (หายาก) ซึ่งวิธีการแบบคงที่ A เรียกวิธีการแบบคงที่อีกแบบ B และ B ถูกแทนที่ในคลาสย่อย IMHO มันมีความสับสนน้อยกว่าในการ จำกัด วิธีการแทนที่ "วิธี" ตัวอย่าง ใช้ความสามารถนั้นเท่าที่จำเป็นในระดับคงที่ ใส่อีกวิธีหนึ่งผู้อ่านรหัสของคุณคาดหวังว่าวิธีการแทนที่วิธีการอินสแตนซ์ (นั่นคือสาระสำคัญของการเข้ารหัส OO) แต่ไม่ใช่ของแบบคงที่
selfจะไม่ใช้ในกรณีนั้น คุณได้ประกาศคลาสที่แยกต่างหากเป็นส่วนขยายของคลาสแรก การใช้selfภายในคลาสที่ขยายเพิ่มจะอ้างถึงคลาสที่ขยายเพิ่ม นี้ไม่ได้ขัดแย้งกับคำตอบอื่น ๆ selfแต่อย่างแน่นอนจะช่วยแสดงให้เห็นถึงขอบเขตของ
ในเวอร์ชัน PHP ต่อมา self::staticMethod();ก็จะไม่ทำงาน มันจะโยนข้อผิดพลาดมาตรฐานที่เข้มงวด
ในกรณีนี้เราสามารถสร้างวัตถุของคลาสเดียวกันและเรียกตามวัตถุ
นี่คือตัวอย่าง
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
fun1จะไม่ได้ใช้selfมันก็ไม่ได้เป็นเหตุผลที่จะทำให้มันเป็นวิธีการ วิธีการที่เหมาะสมที่จะทำเช่นนี้ใน PHP คือการประกาศนั้นเรียกโดยระบุคลาส:public static function fun1 Foo::fun1ฉันมั่นใจว่าเป็นวิธีที่ตั้งใจในการแก้ไขข้อผิดพลาดมาตรฐานที่เข้มงวด
selfกับ$this): stackoverflow.com/questions/151969/php-self-vs-this