class_alias

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

class_alias创建类的别名

说明

class_alias(string $class, string $alias, bool $autoload = true): bool

基于用户定义的类 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 的新类别名。

参见

添加注释

用户贡献注释 16 notes

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
7 年前
它也适用于 Trait!

<?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
12 年前
如果你在命名空间中定义了类 '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!
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
?>
请注意最后一行中的别名与“真实”类名一样不区分大小写。
stanislav dot eckert at vizson dot de
8 年前
class_alias() 仅为用户定义的类创建别名,不为 PHP 提供的类创建别名(PHP 将显示警告“class_alias() 的第一个参数必须是用户定义类的名称”。要为所有类型的类创建别名,请使用命名空间

<?php

// 不起作用
class_alias("ZipArchive", "myZip");

// 创建类 "ZipArchive" 的别名 "myZip"
use \ZipArchive as myZip;

?>
sergey dot karavay at gmail dot com
11 年前
首先,您可能想知道
<?php class A {}; class_alias('A', 'B'); ?>

等效于
<?php class A {}; class B extends A {}; ?>

class_alias 与类扩展不相同!私有方法/属性在子类中不可见,但在别名类中则可见。
Anonymous
3 年前
检查是否为别名
<?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']
?>
info at ensostudio dot ru
3 年前
注意:此函数为用户类设置别名,您不能使用类似于此的代码
<?php
class_alias
('ArrayObject', 'ArrObj');
?>
adam at adamhahn dot com
12 年前
需要注意的是,

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

如果您尝试为其创建别名的类不存在,或者无法使用自动加载器加载,您将生成 PHP 警告。
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) 的声明必须与 Foo::fx(Bar $bar) 兼容,位于 ~/Bar2.php 的第 2 行
petar dot karan dot pk at gmail dot com
10 年前
如果您需要在 PHP 版本 < 5.3 中使用相同的函数,您可以使用以下代码

<?php
function class_alias($original,$alias) {
$newclass = create_function('','class '.$alias.' extends '.$original.' {}');
$newclass();
}
?>
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) 的声明必须与 Foo::fx(Bar $bar) 兼容,位于 ~/Bar2.php 的第 2 行
Anonymous
11 年前
类似 class_alias,但用于函数

<?php
function function_alias ($original, $alias) {

$args = func_get_args();
assert('count($args) == 2', 'function_alias() 要求正好两个参数');
assert('is_string($original) && is_string($alias)', 'function_alias() 要求字符串参数');

// 有效的函数名 - https://php.net/manual/en/functions.user-defined.php
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $original) > 0',
"'$original' 不是有效的函数名");
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $alias) > 0',
"'$alias' 不是有效的函数名");

$aliasNamespace = substr($alias, 0, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') : 0);
$aliasName = substr($alias, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') + 1 : 0);
$serializedOriginal = var_export($original, true);

eval(
"
namespace
$aliasNamespace {
function
$aliasName () {
return call_user_func_array(
$serializedOriginal, func_get_args());
}
}
"
);

}

?>

希望 function_alias 能尽快加入到 php 中...
To Top