Làm thế nào để tôi gọi một phương thức tĩnh từ một phương thức khác trong cùng một lớp?
$this->staticMethod();
hoặc là
$this::staticMethod();
Làm thế nào để tôi gọi một phương thức tĩnh từ một phương thức khác trong cùng một lớp?
$this->staticMethod();
hoặc là
$this::staticMethod();
Câu trả lời:
self::staticMethod();
$this
chỉ tồn tại nếu một đối tượng đã được khởi tạo và bạn chỉ có thể sử dụng $this->method
từ bên trong một đối tượng hiện có. Nếu bạn không có đối tượng mà chỉ gọi một phương thức tĩnh và trong phương thức đó bạn muốn gọi một phương thức tĩnh khác trong cùng một lớp, bạn phải sử dụng self::
. Vì vậy, để tránh các lỗi tiềm ẩn (và cảnh báo nghiêm ngặt), tốt hơn là sử dụng self
.
$this
, nhưng vấn đề không xuất hiện cho đến khi mã được đẩy sang stage
. không có lỗi trở lại, giá trị chỉ là 0
. hãy cẩn thận với điều này, sử dụngself::
Giả sử đây là lớp học của bạn:
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"; }
}
Từ bên trong foo()
phương thức, chúng ta hãy xem xét các tùy chọn khác nhau:
$this->staticMethod();
Vì vậy, đó gọi staticMethod()
là một phương thức ví dụ, phải không? Nó không. Điều này là do phương thức được khai báo là public static
trình thông dịch sẽ gọi nó là phương thức tĩnh, vì vậy nó sẽ hoạt động như mong đợi. Có thể lập luận rằng làm như vậy làm cho nó ít rõ ràng hơn từ mã mà một cuộc gọi phương thức tĩnh đang diễn ra.
$this::staticMethod();
Vì PHP 5.3 bạn có thể sử dụng $var::method()
để có nghĩa <class-of-$var>::
; Điều này khá thuận tiện, mặc dù trường hợp sử dụng ở trên vẫn còn khá độc đáo. Vì vậy, điều đó đưa chúng ta đến cách gọi phổ biến nhất của một phương thức tĩnh:
self::staticMethod();
Bây giờ, trước khi bạn bắt đầu nghĩ rằng ::
là các nhà điều hành cuộc gọi tĩnh, hãy để tôi cung cấp cho bạn một ví dụ khác:
self::bar();
Điều này sẽ in baz = 1
, có nghĩa là $this->bar()
và self::bar()
làm chính xác điều tương tự; đó ::
chỉ là một toán tử phân giải phạm vi. Nó ở đó để thực hiện parent::
, self::
và static::
làm việc và cung cấp cho bạn quyền truy cập vào các biến tĩnh; làm thế nào một phương thức được gọi phụ thuộc vào chữ ký của nó và cách người gọi được gọi.
Để xem tất cả điều này trong thực tế, xem đầu ra 3v4l.org này .
self::bar()
có vẻ sai lệch - bây giờ có bị phản đối không? (sử dụng self::
để gọi một phương thức cá thể chứ không phải là một phương thức tĩnh).
self
khi gọi một phương thức tĩnh. Theo định nghĩa: phương thức tĩnh có thể gọi được từ mọi nơi và không nhận được tham số "tự". Tuy nhiên, tôi thấy sự tiện lợi của php
cú pháp đó , để bạn không phải viết MyClassName::
. Tôi đã quen với các ngôn ngữ gõ tĩnh, trong đó trình biên dịch phải được cung cấp tất cả các biến có sẵn trong phạm vi hiện tại, do đó (tương đương với) self::
có thể được bỏ qua. Vì vậy, người ta chỉ nói self instanceMethod
; không có lý do để nói self staticMethod
.
Đây là một phản hồi rất muộn, nhưng thêm một số chi tiết về các câu trả lời trước đó
Khi gọi các phương thức tĩnh trong PHP từ một phương thức tĩnh khác trên cùng một lớp, điều quan trọng là phải phân biệt giữa self
và tên lớp.
Lấy ví dụ mã này:
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);
Đầu ra của mã này là:
Lớp gốc
Lớp học mở rộng
Điều này là do self
tham chiếu đến lớp mà mã nằm trong, chứ không phải là lớp mã mà nó được gọi từ đó.
Nếu bạn muốn sử dụng một phương thức được định nghĩa trên một lớp kế thừa lớp gốc, bạn cần sử dụng một cái gì đó như:
$class = get_called_class();
$class::function_name();
self::
) về trường hợp nào (hiếm) trong đó phương thức tĩnh A gọi phương thức tĩnh B khác và B đã bị ghi đè trong lớp con. IMHO, sẽ ít gây nhầm lẫn hơn khi hạn chế phương thức ghi đè lên phương thức "cá thể"; sử dụng khả năng đó một cách tiết kiệm ở cấp độ tĩnh. Nói cách khác, người đọc mã của bạn mong đợi phương thức ghi đè các phương thức cá thể (đó là bản chất của mã hóa OO), nhưng không phải là phương thức tĩnh.
self
sẽ không được sử dụng trong trường hợp đó. Bạn đã khai báo một lớp riêng như một phần mở rộng cho lớp đầu tiên. Sử dụng self
trong lớp mở rộng sẽ đề cập đến lớp mở rộng. Điều này không mâu thuẫn với các câu trả lời khác, nhưng nó chắc chắn giúp chứng minh phạm vi self
.
Trong phiên bản PHP sau này self::staticMethod();
cũng sẽ không hoạt động. Nó sẽ ném lỗi tiêu chuẩn nghiêm ngặt.
Trong trường hợp này, chúng ta có thể tạo đối tượng cùng lớp và gọi theo đối tượng
đây là ví dụ
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
fun1
không sử dụng self
, nó không hợp lý để biến nó thành một phương thức cá thể. Cách thích hợp để làm điều này trong php là khai báo public static function fun1
, sau đó gọi bằng cách chỉ định lớp : Foo::fun1
. Tôi chắc chắn đó là cách dự định để sửa lỗi tiêu chuẩn nghiêm ngặt đó.
self
so với$this
): stackoverflow.com/questions/151969/php-elf-vs-this