PHP Conference Japan 2024

class_alias

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

class_alias创建类的别名

描述

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

基于用户定义的类class创建名为alias的别名。别名类与原始类完全相同。

注意: 从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() 创建的别名以小写字母声明。这意味着对于类MyClassclass_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!
[email protected]
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
?>
请注意最后一行,别名与“真正的”类名一样不区分大小写。
[email protected]
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 ' . $class . ' not exists');
}
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 . ' is alias for 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']
?>
[email protected]
13 年前
需要注意的是:

如果尚未定义或加载原始 $original 类,则将调用自动加载器以尝试加载它。

如果您尝试为其创建别名的类不存在,或者无法使用自动加载器加载,则会生成 PHP 警告。
[email protected]
4 年前
注意:此函数为用户类设置别名,您不能使用类似这样的代码:
<?php
class_alias
('ArrayObject', 'ArrObj');
?>
[email protected]
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!
?>
[email protected]
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