ฉันจะเรียกวิธีการคงที่จากวิธีอื่นภายในชั้นเรียนเดียวกันได้อย่างไร
$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