Inoryy
Inoryy

Reputation: 8425

PHP Namespaces - go up a level?

Example1:

namespace Inori\Test;

class MainTest { }

Example2:

namespace Inori\Test\SubTest;

class SubTest extends ???? { }

Question: is there a way to quickly go up a level in namespace so SubTest could extend MainTest? something like "../MainTest"? Or am I stuck with \Inori\Test\MainTest?

Upvotes: 23

Views: 10605

Answers (2)

user1983507
user1983507

Reputation:

See that accepted answer is already provided. However, hereby a code you can use to take advantage of relative namespaces (note: feel free to use code below for free and reference to author in your code is not required, no guarantees are provided by author and use of code is on own risk).

update: code can be used inside your class to dynamically and quickly load other classes via relative namespaces. Starter of this topic is looking for a way to extend class to other class via relative namespace, that remains not possible also not with this code.

In your class just add the following code:

public function TestRelativeNamespace()
{
    // (e.g., param1 = site\lib\firm\package\foo, param2 = .\..\..\different)
    $namespace = $this->GetFullNamespace(__NAMESPACE__, '.\\..\\..\\different');

    // will print namespace: site\lib\firm\different
    print $namespace;

    // to create object
    $className = $namespace . '\\TestClass';
    $test = new $className();
}

public function GetFullNamespace($currentNamespace, $relativeNamespace)
{
    // correct relative namespace
    $relativeNamespace = preg_replace('#/#Di', '\\', $relativeNamespace);

    // create namespace parts
    $namespaceParts = explode('\\', $currentNamespace);

    // create parts for relative namespace
    $relativeParts = explode('\\', $relativeNamespace);

    $part;
    for($i=0; $i<count($relativeParts); $i++) {
        $part = $relativeParts[$i];

        // check if just a dot
        if($part == '.') {

            // just a dot - do nothing
            continue;
        }
        // check if two dots
        elseif($part == '..') {

            // two dots - remove namespace part at end of the list
            if(count($namespaceParts) > 0) {

                // remove part at end of list
                unset($namespaceParts[count($namespaceParts)-1]);

                // update array-indexes
                $namespaceParts = array_values($namespaceParts);
            }
        }
        else {

            // add namespace part
            $namespaceParts[] = $part;
        }
    }

    if(count($namespaceParts) > 0) {
        return implode('\\', $namespaceParts);
    }
    else {
        return '';
    }

}

Upvotes: 1

takteek
takteek

Reputation: 7110

Relative namespaces aren't supported. There's a request for it though: https://bugs.php.net/bug.php?id=52504

If you import your classes at the top of the file it shouldn't be that big of a deal.

namespace Inori\Test\SubTest;
use Inori\Test\MainTest;

class SubTest extends MainTest { }

Upvotes: 22

Related Questions