PHP Conference Japan 2024

get_called_class

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

get_called_class「後期靜態綁定」的類別名稱

說明

get_called_class(): 字串

取得呼叫靜態方法所在的類別名稱。

參數

此函式沒有參數。

傳回值

傳回類別名稱。

錯誤/例外

如果 get_called_class() 從類別外部呼叫,則會拋出 錯誤。在 PHP 8.0.0 之前,會引發 E_WARNING 等級的錯誤。

更新日誌

版本 說明
8.0.0 從類別外部呼叫此函式現在會拋出 錯誤。先前會引發 E_WARNING 並且函式會返回 false

範例

範例 #1 使用 get_called_class()

<?php

class foo {
public static function
test() {
var_dump(get_called_class());
}
}

class
bar extends foo {
}

foo::test();
bar::test();

?>

以上範例會輸出:

string(3) "foo"
string(3) "bar"

另請參閱

新增註釋

使用者貢獻的註釋 9 則註釋

Safak Ozpinar
10 年前
從 PHP 5.5 開始,您也可以使用「static::class」來取得被呼叫的類別名稱。

<?php
class Bar {
public static function
test() {
var_dump(static::class);
}
}

class
Foo extends Bar {

}

Foo::test();
Bar::test();
?>

輸出

字串(3) "Foo"
字串(3) "Bar"
luc at s dot illi dot be
11 年前
在閉包範圍內的 get_called_class()

<?PHP
抽象類別 Base
{
protected static
$stub = ['baz'];

//final public function boot()
static public function boot()
{
echo
__METHOD__.'-> '.get_called_class().PHP_EOL;

array_walk(static::$stub, function()
{
echo
__METHOD__.'-> '.get_called_class().PHP_EOL;
});
}

public function
__construct()
{
self::boot();
echo
__METHOD__.'-> '.get_called_class().PHP_EOL;

array_walk(static::$stub, function()
{
echo
__METHOD__.'-> '.get_called_class().PHP_EOL;
});
}
}

類別
Sub 延伸 Base
{
}

// 靜態呼叫 boot
Base::boot(); echo PHP_EOL;
// Base::boot -> Base
// Base::{closure} -> Base

Sub::boot(); echo PHP_EOL;
// Base::boot -> Sub
// Base::{closure} -> Base

new Sub;
// Base::boot -> Sub
// Base::{closure} -> Base
// Base->__construct -> Sub
// Base->{closure} -> Sub

// 實例化後呼叫 boot
new Sub;
// Base::boot -> Sub
// Base::{closure} -> Base
// Base->__construct -> Sub
// Base->{closure} -> Sub
?>
amcolin at 126 dot com
4 年前
命名空間 root;
類別 Factor {
protected static $instance = null;

private function __construct() {

}

public static function getInstance() {
if (!self::$instance) {
$name = get_called_class();
self::$instance = new $name();
}

return self::$instance;
}
}

命名空間 admin\test;

use root\Factor;

類別 Single 延伸 Factor {
public function abc() {
return 'abc';
}
}

命名空間 index;

use admin\test\Single;

類別 Index {
public function get() {
return Single::getInstance();
}
}

$index = new Index();
var_dump($index->get());

結果是

object(admin\test\Single)#2 (0) {
}
uebele
13 年前
參考: https://php.dev.org.tw/manual/en/language.oop5.late-static-bindings.php

我認為值得在此頁面上提及的是,許多 get_called_function() 返回值的用法可以用舊關鍵字 static 的新用法來處理,例如
<?php
static::$foo;
?>

對比
<?php
$that
=get_called_class();
$that::$foo;
?>

我之前一直使用 $that:: 作為 self:: 的慣用替代方案,直到我在 Google 上搜尋到上述網址。我已成功將所有 $that 的用法都替換為 static,例如:
<?php
static::$foo; //以及...
new static();
?>

由於 static:: 有其限制:「另一個不同之處是 static:: 只能參考靜態屬性。」因此,可能仍然需要使用 $that:: 來呼叫靜態函式;雖然我目前還沒有用到這種語法。
fantomx1 at gmail dot com
7 年前
在 PHP 5.6(7 以下版本)中以靜態方式呼叫動態方法時,雖然允許這樣做,但卻無法正常運作,它會錯誤地評估呼叫我們目標類別的類別,因此包含的方法必須是靜態的。
danbettles at yahoo dot co dot uk
16 年前
在 PHP 5.3 中,可以使用 get_called_class 撰寫一個完全自包含的 Singleton 基礎類別。

<?php

abstract class Singleton {

protected function
__construct() {
}

final public static function
getInstance() {
static
$aoInstance = array();

$calledClassName = get_called_class();

if (! isset (
$aoInstance[$calledClassName])) {
$aoInstance[$calledClassName] = new $calledClassName();
}

return
$aoInstance[$calledClassName];
}

final private function
__clone() {
}
}

class
DatabaseConnection extends Singleton {

protected
$connection;

protected function
__construct() {
// @todo 連線到資料庫
}

public function
__destruct() {
// @todo 關閉資料庫連線
}
}

$oDbConn = new DatabaseConnection(); // 致命錯誤

$oDbConn = DatabaseConnection::getInstance(); // 回傳單一實例
?>
php at itronic dot at
15 年前
如果您呼叫一個靜態的 getInstance() 函式,從另一個類別建立一個類別的實例,則該函式必須是靜態的,如果不是靜態的,則會回傳呼叫者類別的原始名稱,而不是目前類別的名稱。

範例

<?php

class a {
function
getXName() {
return
x::getClassName();
}
function
getXStaticName() {
return
x::getStaticClassName();
}

}

class
b extends a {
}

class
x {
public function
getClassName() {
return
get_called_class();
}
public static function
getStaticClassName() {
return
get_called_class();
}
}

$a = new a();

$b = new b();

echo
$a->getXName(); // 將會回傳 "a"
echo $b->getXName(); // 將會回傳 "b"

echo $a->getXStaticName(); // 將會回傳 "x"
echo $b->getXStaticName(); // 將會回傳 "x"

?>
Abhi Beckert
15 年前
注意,如果你的方法沒有宣告為靜態 (static),這段程式碼的行為將不如預期!例如:

<?php

class foo {
static public function
test() {
var_dump(get_called_class());
}

public function
testTwo() {
var_dump(get_called_class());
}
}

class
bar extends foo {
}

class
abc {
function
test() {
foo::test();
bar::test();
}

function
testTwo() {
foo::testTwo();
bar::testTwo();
}
}

echo
"基本範例\n";
foo::test();
bar::test();

echo
"沒有 static 宣告的基本範例\n";
foo::testTwo();
bar::testTwo();

echo
"在類別中\n";
$abc = new abc();
$abc->test();

echo
"在沒有 static 宣告的類別中\n";
$abc->testTwo();

?>

結果是

基本範例
字串 'foo'
字串 'bar'

沒有 static 宣告的基本範例
字串 'foo'
字串 'bar'

在類別中
字串 'foo'
字串 'bar'

在沒有 static 宣告的類別中
字串 'abc'
字串 'abc'
a dot cudbard-bell at sussex dot ac dot uk
15 年前
這是一個取得類別繼承樹的簡單方法,無論函式實際定義在哪個類別中。也可以作為靜態函式方法使用。

<?php
class A {
public function
get_class_tree(){
$cur_class = get_called_class();
do {
echo
$cur_class;
}
while(
$cur_class = get_parent_class($cur_class));
}
}

class
B {

}

class
C {

}

$foo = new C();
$foo->get_class_tree();

?>

CBA
To Top