略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: class_alias

2024-11-14

class_alias

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

class_alias为一个类创建别名

说明

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

基于用户定义的类 original 创建别名 alias。 这个别名类和原有的类完全相同。

参数

original

原有的类。

alias

类的别名。

autoload

如果原始类没有加载,是否使用自动加载(autoload)。

返回值

成功时返回 true, 或者在失败时返回 false

范例

示例 #1 class_alias() 例子

<?php

class foo { }

class_alias('foo''bar');

$a = new foo;
$b = new bar;

// the objects are the same
var_dump($a == $b$a === $b);
var_dump($a instanceof $b);

// the classes are the same
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)

参见

add a noteadd a note

User Contributed Notes 16 notes

up
30
mweierophinney at gmail dot com
9 years ago
class_alias() gives you the ability to do conditional imports.

Whereas the following will not work:

<?php
namespace Component;

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

class
Container extends ArrayObject
{
}
?>

the following, using class_alias, will:

<?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
{
}
?>

The semantics are slightly different (I'm now indicating that Container extends from an ArrayObject implementation in the same namespace), but the overall idea is the same: conditional imports.
up
14
nicolas dot grekas+php at gmail dot com
11 years ago
class_alias also works for interfaces!

<?php
interface foo {}
class_alias('foo', 'bar');
echo
interface_exists('bar') ? 'yes!' : 'no'; // prints yes!
?>
up
15
programmer-comfreek at hotmail dot com
10 years ago
If you defined the class 'original' in a namespace, you will have to specify the namespace(s), too:
<?php
namespace ns1\ns2\ns3;

class
A {}

class_alias('ns1\ns2\ns3\A', 'B');
/* or if you want B to exist in ns1\ns2\ns3 */
class_alias('ns1\ns2\ns3\A', 'ns1\ns2\ns3\B');
?>
up
5
robsonvnasc at gmail dot com
5 years ago
It also works with Traits!

<?php
trait Foo {}
class_alias("Foo","Bar");
echo
trait_exists("Bar") ? 'yes' : 'no';
?>
//yes
up
8
stanislav dot eckert at vizson dot de
6 years ago
class_alias() creates aliases only for user defined classes, not for classes supplied by PHP (PHP will show the warning "First argument of class_alias() must be a name of user defined class"). To create aliases for every kind of classes, use namespaces:

<?php

// Does not work
class_alias("ZipArchive", "myZip");

// Creates class alias "myZip" of class "ZipArchive"
use \ZipArchive as myZip;

?>
up
1
sergey dot karavay at gmail dot com
9 years ago
At first, you might wonder that:
<?php class A {}; class_alias('A', 'B'); ?>

is equivalent to:
<?php class A {}; class B extends A {}; ?>

class_alias is NOT equivalent to class extending! Private methods/properties are unseen in child classes, but in alias classes they are.
up
1
info at ensostudio dot ru
1 year ago
Note: this function set alias for user classes, you can't use something like this
<?php
class_alias
('ArrayObject', 'ArrObj');
?>
up
1
elliseproduction at gmail dot com
2 years ago
You can add a alias inside a class :

<?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!
up
1
Hayley Watson
4 years ago
The alias really is an alias for the existing class. It's not a new class of any kind - whether by inheritance or otherwise; it doesn't just look and behave exactly like the existing class; it really is the same class.

<?php

class foo
{
    public static
$count = 0;
}

class_alias('foo', 'bar');

bar::$count++;

echo
foo::$count; // Output: 1

echo get_class(new Bar); // Output: foo
?>
Note in the last line there that aliases are just as case-insensitive as "genuine" class names.
up
0
Anonymous
1 year ago
Check is alias:
<?php
/**
* @param string $class Class name
* @return bool
*/
function is_alias(string $class): bool
{
    return
$class !== (new ReflectionClass($class))->name;
}
?>
Get class aliases:
<?php
/**
* @param string $class Class name
* @param bool $throw Throw exception at error?
* @return string[]|null Aliases or null at error in silent mode
* @throws InvalidArgumentException Class not exists or it's alias
*/
function get_class_aliases(string $class, bool $throw = false): ?array
{
   
/**
     * @var array An array of defined classes: keys - classes, values - aliases
     */
   
static $classes = [];
   
// check: class exists
   
if (! class_exists($class, true)) {
        if (
$throw) {
            throw new
InvalidArgumentException('Class ' . $class . ' not exists');
        }
        return
null;
    }
   
// refresh list
   
$newClasses = array_diff(get_declared_classes(), array_keys($classes));
    if (
$newClasses) {
       
$abc = range('a', 'z');
        foreach (
$newClasses as $newClass) {
           
// fast check first char: class_alias() convert alias to lower case
           
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);
    }
   
// check: is alias?
   
if (! empty($classes[$class])) {
        if (
$throw) {
            throw new
InvalidArgumentException($class . ' is alias for class ' . $classes[$class]);
        }
        return
null;
    }
   
// find aliases
   
return array_keys($classes, $class, true);
}
?>
Usage:
<?php
class Foo {}
class_alias('Foo', 'Bar');
class_alias('Bar', 'Baz');
$aliases = get_class_aliases('Foo', true); // ['bar', 'baz']
?>
up
0
nicolas dot grekas+php at gmail dot com
11 years ago
At first, you might wonder that:
<?php class A {}; class_alias('A', 'B'); ?>

is equivalent to:
<?php class A {}; class B extends A {}; ?>

BUT when derivation creates a new class name - that means, you can then instantiate a new kind of objects - aliasing is just what it says: a synonym, so objects instantiated with the aliased name are of the exact same kind of objects instantiated with the non-aliased name.

See this code for example:
<?php
class A {};
class
B1 extends A {};
class_alias('A', 'B2');

$b1 = new B1; echo get_class($b1); // prints B1
$b2 = new B2; echo get_class($b2); // prints A !
?>
up
-2
adam at adamhahn dot com
10 years ago
Something to note,

If the $original class has not yet been defined or loaded, the auto loader will be invoked in order to try and load it.

If the class for which you are trying to create an alias does not exist, or can not be loaded with the auto loader, you will generate a PHP Warning.
up
-3
sofe2038 at gmail dot com
5 years ago
Doesn't work with coupled classes when used along with autoloading.

For example, in these classes where each class is autoloaded in a separate class file:

Foo.php:

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

Bar2.php:

<?php
class Bar2 implements Foo{
  public function
fx(Bar2 $bar){
   
// some implementation code here
 
}
}
?>

Bar.php:

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

When used with an autoloader like this:

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

Results in fatal error:

    Declaration of Bar2::fx(Bar2 $bar) must be compatible with Foo::fx(Bar $bar) in ~/Bar2.php on line 2
up
-15
petar dot karan dot pk at gmail dot com
8 years ago
If you need the same function in PHP version < 5.3 you can use this

<?php
function class_alias($original,$alias) {
   
$newclass = create_function('','class '.$alias.' extends '.$original.' {}');
   
$newclass();
}
?>
up
-4
sofe2038 at gmail dot com
5 years ago
Doesn't work with coupled classes when used along with autoloading.

For example, in these classes where each class is autoloaded in a separate class file:

Foo.php:

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

Bar2.php:

<?php
class Bar2 implements Foo{
  public function
fx(Bar2 $bar){
   
// some implementation code here
 
}
}
?>

Bar.php:

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

When used with an autoloader like this:

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

Results in fatal error:

    Declaration of Bar2::fx(Bar2 $bar) must be compatible with Foo::fx(Bar $bar) in ~/Bar2.php on line 2
up
-20
Anonymous
9 years ago
Like class_alias but for functions:

<?php
function function_alias ($original, $alias) {
 
 
$args = func_get_args();
 
assert('count($args) == 2', 'function_alias() require exactly two arguments');
 
assert('is_string($original) && is_string($alias)', 'function_alias() require string arguments');
 
 
// valid function name - http://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' is not a valid function name");
 
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $alias) > 0',
   
"'$alias' is not a valid function name");
 
 
$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());
      }
    }
  "
);
 
}

?>

Until hopefully function_alias is added to php...

官方地址:https://www.php.net/manual/en/function.class-alias.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3