PHP Conference Japan 2024

class_alias

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

class_alias建立類別的別名

描述

class_alias(字串 $class, 字串 $alias, 布林值 $autoload = true): 布林值

建立一個名為 alias 的別名,基於使用者定義的類別 class。別名類別與原始類別完全相同。

注意自 PHP 8.3.0 起,class_alias() 也支援建立 PHP 內建類別的別名。

參數

class

原始類別。

alias

類別的別名。

autoload

如果找不到原始類別,是否要自動載入

回傳值

成功時回傳 true,失敗時回傳 false

更新日誌

版本 描述
8.3.0 class_alias() 現在支援建立內建類別的別名。

範例

範例 #1 class_alias() 範例

<?php

class Foo { }

class_alias('Foo', 'Bar');

$a = new Foo;
$b = new Bar;

// 兩個物件相同
var_dump($a == $b, $a === $b);
var_dump($a instanceof $b);

// 兩個類別相同
var_dump($a instanceof Foo);
var_dump($a instanceof Bar);

var_dump($b instanceof Foo);
var_dump($b instanceof Bar);

?>

以上範例會輸出:

bool(true)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

注意事項

注意:

PHP 中的類別名稱不區分大小寫,這一點也反映在此函式中。 由 class_alias() 建立的別名會以小寫宣告。 這表示對於類別 MyClass,呼叫 class_alias('MyClass', 'MyClassAlias') 將會宣告一個名為 myclassalias 的新類別別名。

參見

新增筆記

使用者貢獻的筆記 14 則筆記

mweierophinney at gmail dot com
11 年前
class_alias() 讓您可以執行條件式引入。

然而以下程式碼無法運作

<?php
namespace Component;

if (
version_compare(PHP_VERSION, '5.4.0', 'gte')) {
use
My\ArrayObject;
} else {
use
ArrayObject;
}

class
Container extends ArrayObject
{
}
?>

以下程式碼,使用 class_alias,則可以運作

<?php
namespace Component;

if (
version_compare(PHP_VERSION, '5.4.0', 'lt')) {
class_alias('My\ArrayObject', 'Component\ArrayObject');
} else {
class_alias('ArrayObject', 'Component\ArrayObject');
}

class
Container extends ArrayObject
{
}
?>

語義略有不同(我現在表示 Container 繼承自相同命名空間中的 ArrayObject 實作),但整體概念相同:條件式引入。
robsonvnasc at gmail dot com
8 年前
它也適用於 Traits!

<?php
trait Foo {}
class_alias("Foo","Bar");
echo
trait_exists("Bar") ? 'yes' : 'no';
?>
//yes
nicolas dot grekas+php at gmail dot com
13 年前
class_alias 也適用於介面!

<?php
interface foo {}
class_alias('foo', 'bar');
echo
interface_exists('bar') ? 'yes!' : 'no'; // 顯示 yes!
?>
programmer-comfreek at hotmail dot com
13 年前
如果您在命名空間中定義了類別 'original',則也必須指定命名空間。
<?php
namespace ns1\ns2\ns3;

class
A {}

class_alias('ns1\ns2\ns3\A', 'B');
// 或如果您希望 B 存在於 ns1\ns2\ns3 中
class_alias('ns1\ns2\ns3\A', 'ns1\ns2\ns3\B');
?>
elliseproduction at gmail dot com
4 年前
您可以在類別內新增別名。

<?php

class foo{

function
__construct(){

echo(
'yes!');

}
}

class
bar {

function
__construct(){

class_alias('foo', 'fooAlias');

}

function
test(){

new
fooAlias;

}

}

$bar=new bar;

$bar->test(); // yes!
stanislav dot eckert at vizson dot de
9 年前
class_alias() 僅能為使用者自訂的類別建立別名,而不能為 PHP 提供的類別建立別名(PHP 會顯示警告「class_alias() 的第一個參數必須是使用者自訂類別的名稱」)。要為所有類型的類別建立別名,請使用命名空間。

<?php

// 無法運作
class_alias("ZipArchive", "myZip");

// 建立類別 "ZipArchive" 的別名 "myZip"
use \ZipArchive as myZip;

?>
Hayley Watson
6 年前
別名實際上是現有類別的別名。它並不是任何種類的新類別——無論是透過繼承或其他方式;它不僅看起來和行為與現有類別完全相同;它實際上就是同一個類別。

<?php

class foo
{
public static
$count = 0;
}

class_alias('foo', 'bar');

bar::$count++;

echo
foo::$count; // 輸出:1

echo get_class(new Bar); // 輸出:foo
?>
注意最後一行,別名與「真正的」類別名稱一樣不區分大小寫。
sergey dot karavay at gmail dot com
11 年前
一開始,您可能會認為
<?php class A {}; class_alias('A', 'B'); ?>

等同於
<?php class A {}; class B extends A {}; ?>

class_alias 並不等同於類別繼承! 子類別看不到私有方法/屬性,但在別名類別中可以看到。
匿名
4 年前
檢查是否為別名
<?php
/**
* @param string $class 類別名稱
* @return bool
*/
function is_alias(string $class): bool
{
return
$class !== (new ReflectionClass($class))->name;
}
?>
取得類別別名
<?php
/**
* @param string $class 類別名稱
* @param bool $throw 發生錯誤時是否拋出例外?
* @return string[]|null 別名或是在靜默模式下發生錯誤時返回 null
* @throws InvalidArgumentException 類別不存在或是它本身就是別名
*/
function get_class_aliases(string $class, bool $throw = false): ?array
{
/**
* @var array 已定義類別的陣列:鍵 - 類別,值 - 別名
*/
static $classes = [];
// 檢查:類別是否存在
if (! class_exists($class, true)) {
if (
$throw) {
throw new
InvalidArgumentException('類別 ' . $class . ' 不存在');
}
return
null;
}
// 更新列表
$newClasses = array_diff(get_declared_classes(), array_keys($classes));
if (
$newClasses) {
$abc = range('a', 'z');
foreach (
$newClasses as $newClass) {
// 快速檢查第一個字元:class_alias() 會將別名轉換為小寫
if (in_array($newClass[0], $abc, true)) {
$realClass = (new ReflectionClass($newClass))->getName();
$classes[$newClass] = $newClass !== $realClass ? $realClass : null;
} else {
$classes[$newClass] = null;
}
}
unset(
$abc, $newClasses);
}
// 檢查:是否為別名?
if (! empty($classes[$class])) {
if (
$throw) {
throw new
InvalidArgumentException($class . ' 是類別 ' . $classes[$class] . ' 的別名');
}
return
null;
}
// 尋找別名
return array_keys($classes, $class, true);
}
?>
用法
<?php
class Foo {}
class_alias('Foo', 'Bar');
class_alias('Bar', 'Baz');
$aliases = get_class_aliases('Foo', true); // ['bar', 'baz']
?>
adam at adamhahn dot com
13 年前
注意事項:

如果 `$original` 類別尚未定義或載入,則會呼叫自動載入器嘗試載入它。

如果您嘗試建立別名的類別不存在,或者無法使用自動載入器載入,則會產生 PHP 警告。
info at ensostudio dot ru
4 年前
注意:此函式會為使用者類別設定別名,您不能像這樣使用:
<?php
class_alias
('ArrayObject', 'ArrObj');
?>
nicolas dot grekas+php at gmail dot com
13 年前
一開始,您可能會認為
<?php class A {}; class_alias('A', 'B'); ?>

等同於
<?php class A {}; class B extends A {}; ?>

但是,當繼承建立新的類別名稱時(也就是說,您可以實例化一種新的物件),別名只是它字面上的意思:同義詞,因此使用別名實例化的物件與使用非別名實例化的物件類型完全相同。

例如,請參考以下程式碼:
<?php
class A {};
class
B1 extends A {};
class_alias('A', 'B2');

$b1 = new B1; echo get_class($b1); // 輸出 B1
$b2 = new B2; echo get_class($b2); // 輸出 A !
?>
sofe2038 at gmail dot com
7 年前
與自動載入一起使用時,不適用於耦合類別。

例如,在這些類別中,每個類別都在單獨的類別檔案中自動載入:

Foo.php

<?php
interface Foo{
public function
fx(Bar $bar);
}
?>

Bar2.php

<?php
class Bar2 implements Foo{
public function
fx(Bar2 $bar){
// 一些實作程式碼
}
}
?>

Bar.php

<?php
class_alias
("Bar2", "Bar");
?>

當與像這樣的自動載入器一起使用時

<?php
spl_autoload_register
(function($class){
require(
$class . ".php");
});
new
Bar;
?>

會導致致命錯誤

Bar2::fx(Bar2 $bar) 的宣告必須與 ~/Bar2.php 第 2 行的 Foo::fx(Bar $bar) 相容
sofe2038 at gmail dot com
7 年前
與自動載入一起使用時,不適用於耦合類別。

例如,在這些類別中,每個類別都在單獨的類別檔案中自動載入:

Foo.php

<?php
interface Foo{
public function
fx(Bar $bar);
}
?>

Bar2.php

<?php
class Bar2 implements Foo{
public function
fx(Bar2 $bar){
// 一些實作程式碼
}
}
?>

Bar.php

<?php
class_alias
("Bar2", "Bar");
?>

當與像這樣的自動載入器一起使用時

<?php
spl_autoload_register
(function($class){
require(
$class . ".php");
});
new
Bar;
?>

會導致致命錯誤

Bar2::fx(Bar2 $bar) 的宣告必須與 ~/Bar2.php 第 2 行的 Foo::fx(Bar $bar) 相容
To Top