4

I can write this in a file:

use Carbon\Carbon as Carbon;

I have tried to create a file 'aliases.php':

use Carbon\Carbon as Carbon;

which I then reference like so:

require __DIR__.'/../bootstrap/aliases.php';

printf("Right now is %s", Carbon::now()->toDateTimeString());

but that gives me the error: "Fatal error: Class 'Carbon' not found"

So how can I 'include' one file with all the pre-defined aliases?

S..
  • 5,511
  • 2
  • 36
  • 43

2 Answers2

6

First of all, the reason why your aliases.php file doesn't work is because use statements are visible only within the file they're declared in. In other words they work in your aliases.php file, but not in files that include/require aliases.php.

From the PHP documentation Using namespaces: Aliasing/Importing:

Note:

Importing rules are per file basis, meaning included files will NOT inherit the parent file's importing rules.

Secondly, due to how namespacing works in PHP, it's not possible to do what you are trying to do. When PHP sees a class name, it always tries to find the class in the current namespace and there is no way to change that. Therefore, if you call Carbon in any namespaced code, it will be interpreted as Current\Namespace\Carbon, and if you call it from global namespace, it will be interpreted as \Carbon.

The only thing that comes to my mind that could do something similar is to declare a class in the global namespace that would extend the class you're trying to use and then use those classes instead. For carbon it would be:

<?php
use Carbon\Carbon as BaseCarbon;

class Carbon extends BaseCarbon {}

Then in your code you could access it by:

\Carbon::now();

Keep in mind that you'll need to prefix the classname with \ so that it's always taken from the global namespace, unless the code you're executing is in global namespace already.

icc97
  • 11,395
  • 8
  • 76
  • 90
jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
  • Thanks for such a concise explanation and the alternative method. Some of my namespace paths are very long, so basically just wanted to tidy them up elsewhere, maybe I'll just stick to them as extending each class could get messy. – S.. Aug 02 '15 at 09:57
  • I would do the same as it's the proper way of using namespaces. And most, if not all, IDEs add use statements automatically so it shouldn't add any overhead. – jedrzej.kurylo Aug 02 '15 at 10:03
  • Is there any documentation for the "use statements are visible only within the file they're declared in" quote? It's exactly what I was looking for but couldn't find it in the PHP namespace docs – icc97 Aug 16 '15 at 03:07
  • Now that I knew what to look for I found it :) – icc97 Aug 16 '15 at 03:15
1

Extending does not work with final classes.

class_alias is a better option.


function assert_true(bool $actual) {
    if ($actual !== true) {
        echo "ERROR: Expected true", PHP_EOL;
        echo (new \AssertionError("Expected true"))->getTraceAsString(), PHP_EOL;
        return;
    }
    
    echo "Validated\n";
}

function assert_false(bool $actual) {
    if ($actual !== false) {
        echo "ERROR: Expected true", PHP_EOL;
        echo (new \AssertionError("Expected false"))->getTraceAsString(), PHP_EOL;
        return;
    }
    
    echo "Validated\n";
}

function validate($a, $b) {
    // the objects are the same
    assert_true($a == $b);
    assert_false($a === $b, false);
    assert_true($a instanceof $b);
    
    // the classes are the same
    assert_true($a instanceof foo);
    assert_true($a instanceof bar);
    
    assert_true($b instanceof foo);
    assert_true($b instanceof bar);
}


class foo { }

class baz extends foo {
    
}

class_alias('foo', 'bar');



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

echo "Aliasing \n=========\n\n";
validate($a, $b);

echo PHP_EOL, PHP_EOL;

echo "Inheritance \n=========\n\n";
validate($a, $c);

Joyce Babu
  • 19,602
  • 13
  • 62
  • 97