Sondre
Sondre

Reputation: 1898

Using namespaces with classes created from a variable

So I created these two classes

//Quarter.php
namespace Resources;
class Quarter {
    ...
}


//Epoch.php
namespace Resources;
class Epoch {

    public static function initFromType($value, $type) {
        $class = "Quarter";
        return new $class($value, $type);
    }    
}

Now this is a a very simplified version of both, but is enough to illustrate my question. The classes as they are shown here will not work as it will not find the Quarter class. To make it work I could change the $class variable to

$class = "\Resources\Quarter";

So my question is: Why do I need to use the namespace here when both classes are already members of the same namespace. The namespace is only needed when I put the classname in a variable so doing:

    public static function initFromType($value, $type) {
        return new Quarter($value, $type);
    }    

will work without problems. Why is this and is there any potential traps here I need to avoid?

Upvotes: 4

Views: 1239

Answers (1)

deceze
deceze

Reputation: 522606

Because strings can be passed around from one namespace to another. That makes name resolution ambiguous at best and easily introduces weird problems.

namespace Foo;

$class = 'Baz';

namespace Bar;

new $class;  // what class will be instantiated?

A literal in a certain namespace does not have this problem:

namespace Foo;

new Baz;     // can't be moved, it's unequivocally \Foo\Baz

Therefore, all "string class names" are always absolute and need to be written as FQN:

$class = 'Foo\Baz';

(Note: no leading \.)

You can use this as shorthand, sort of equivalent to a self-referential self in classes:

$class = __NAMESPACE__ . '\Baz';

Upvotes: 5

Related Questions