Can I create an alias for an entire namespace in PHP?
P粉252423906
P粉252423906 2024-01-16 12:23:30
0
1
405

Can I create namespace aliases using PHP 8.1 functions (such as category names)?

We named the default namespace module in Company "Subcompany" and would like it to become "Company" now since its use has expanded.

A perfect answer is to have as little overhead as possible and allow transparent autoloading. One problem is that tools like Intelephense will understand this alias.

This project also uses Composer, so the answer to rewriting the namespace using it will also work.

P粉252423906
P粉252423906

reply all(1)
P粉613735289

Yes, and think: class_alias was introduced with PHP 5.3 with its new namespace language features. It was created to make it easier to migrate from a global namespace to a namespace - in fact is between namespaces.

However, you need to first register a category name for each old class/interface/trait/enumeration to the new counterpart.

My\Old\Lib\Name\Module\Submodule\Interface
My\Tiger\Lib\Name\Module\Submodule\Interface

The old library has disappeared and now there is a brand new Tiger library. All their classes etc. can be mapped by swapping namespace prefixes ('My\Old\Lib\Name\' -> 'My\Tiger\Lib\Name').

This can be done at runtime as PHP does most of the work for you.

Register an autoloader that loads the new namespace prefix based on the old namespace prefix, prefixing the category name with the old name.

Example:

spl_autoload_register(
    static function (string $class_name) {
        static $old = 'My\Old\Lib\Name\';
        static $new = 'My\Tiger\Lib\Name\';

        // only operate on the old namespace
        if (0 !== strpos($class_name, $old)) {
            return;
        }
        $new_name = substr_replace($class_name, $new, 0, strlen($old));
        class_alias($new_name, $class_name);
        $exists = class_exists($new_name);
    },
    $throw = true,   /* throw when registering fails */
    $prepend = false /* only alias at fall-through */
);

This code is very simple, just two explanations on the registration parameters:

  1. $throw = true: You want to stop your application immediately when the alias autoloader fails to register, otherwise you'll get weird "class not found" errors much later.
  2. $prepend = false: The callback should only be called if there is still code using the old class name. Therefore, standard code now comes first using the new namespace and standard autoloading.

Perhaps worth noting is the class_exists() part:

        $exists = class_exists($new_name);

If the new class has not been loaded yet, it triggers autoloading.

After registering the autoloader, the old code will automatically load the new class under the old alias.

use My\Old\Lib\Name\Module\Boring;

$boring = new Boring();
assert($boring instanceof My\Old\Lib\Name\Module\Boring);
var_dump(get_class($boring)); # string(31) "My\Tiger\Lib\Name\Module\Boring"
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template