Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
280 views
in Technique[技术] by (71.8m points)

php - Why use class aliases?

Why would we use the class_alias function? For example:

Class Test {
 public function __construct(){
   echo "Class initialized"; 
 }
}

class_alias("Test", "AnotherName"); 

$instance = new AnotherName();   # equivalent to $instance = new Test();

According to the manual, "The aliased class is exactly the same as the original class."

What is this useful for?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Surprisingly, nobody has mentioned the obvious reason why one would do this: the use keyword can only be used in the outmost scope, and is processed at compile-time, so you can't use SomeClass based on some condition, nor can it be block-scoped:

namespace Foo;
if (!extension_loaded('gd'))
{
    use ImagesMagicImage as Image;
}
else
{
    use ImagesGdImage as Image;
}
class ImageRenderer
{
    public function __construct(Image $img)
    {}
}

This won't work: though the use statements are in the outmost scope, these imports are, as I said before, performed at compile-time, not run-time. As an upshot, this code behaves as though it was written like so:

namespace Foo;
use ImagesGdImage as Image;
use ImagesMagicImage as Image;

Which will produce an error (2 class with the same alias...)
class_alias however, being a function that is called at run-time, so it can be block scoped, and can be used for conditional imports:

namespace Foo;
if (!extension_loaded('gd'))
{
    class_alias('Images\MagicImage', 'Image');
}
else
{
    class_alias('Images\GdImage','Image');
}
class ImageRenderer
{
    public function __construct(Image $img)
    {}
}

Other than that, I suspect the main benefit of class_alias is that all code written, prior to PHP 5.3 (which introduced namespaces) allowed you to avoid having to write things like:

$foo = new My_Lib_With_Pseudo_Name_Spaces_Class();

Instead of having to refactor that entire code-base and create namespaces, It's just a lot easier to add a couple of:

class_alias('My_Lib_With_Pseudo_Name_Spaces_Class', 'MyClass');

To the top of the script, along with some //TODO: switch to Namespaces comments.

Another use case might be while actually transferring these classes to their namespaced counterparts: just change the class_alias calls once a class has been refactored, the other classes can remain intact.
When refactoring your code, chances are you're going to want to rethink a couple of things, so a use-case like aichingm suggested might not be too far fetched.

Last thing I can think of, but I haven't seen this yet, is when you want to test some code with a mock object, you might use class_alias to make everything run smoothly. However, if you have to do this, you might aswell consider the test a failure, because this is indicative of badly written code, IMO.

Incidently, just today I came across another use-case for class_alias. I was working on a way to implement a lib, distilled from a CLI tool for use in a MVC based web-app. Some of the classes depended on an instance of the invoked command to be passed, from which they got some other bits and bolts.
Instead of going through the trouble of refactoring, I decided to replace the:

use ApplicationCommandsSomeCommand as Invoker;

Statements with:

if (PHP_SAPI === 'cli')
{
    class_alias('\Application\Commands\SomeCommand', 'Invoker');
}
else
{
    class_alias('\Web\Models\Services\SomeService', 'Invoker');
}

and, after a quick :%s/SomeCommand/Invoker/g in vim, I was good to go (more or less)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...