Zack Webster
Zack Webster

Reputation: 137

Confusion understanding PHP namespaces

I am learning about and implementing PHP namespaces. Please refer to the following code:

<?php

namespace Xicor\core;

class App {

  public function __construct() {

    $registry = Registry::getInstance();

    //TODO: init router

    //TODO: call controller@action
    $controllerName = 'Xicor\app\controllers\\'.'Index';
    $action = 'show';

    $controller = new $controllerName();
    $controller->$action();

  }

}

The above code works perfectly.

If I add throw new Exception('Lorem Ipsum') within the constructor, I'll get an error as expected. To make it work, I must use throw new \Exception('Lorem Ipsum') so that we are referring to the global namespace.

But, why does $controllerName = 'Xicor\app\controllers\\'.'Index'; successfully import the right class.

Why do I not have to use $controllerName = '\Xicor\app\controllers\\'.'Index'; (with \ prefixed)?

If it affects anything, here's my autoloader:

<?php

spl_autoload_register(function($name) {
  //replace \ with DIRECTORY_SEPARATOR
  $path = str_replace('\\', DS, $name);
  //replace Xicor with root
  $path = str_replace('Xicor', __DIR__, $path); // __DIR__ doesn't return a trailing slash
  //add .php at end
  $path .= '.php';

  if(file_exists($path)) {
    require_once($path);
  }
});

Upvotes: 1

Views: 61

Answers (1)

MHewison
MHewison

Reputation: 856

As I understand it. PHP will work in the current namespace within a class unless specified otherwise (a preceding \).

Example

namespace Bar;

class Foo {
    function __construct()
    {
        // references current namespace, looks for Bar\Baz;
        $baz = new Baz();
    }
}

class Baz {
    function __construct()
    {
        try {
            // do stuff

            // references global namespace
        } catch(\Exception $e) {
            var_dump($e->getMessage());
        }


    }

    function foo() {

        // This will prepend the current namespace to the class, in actual fact it will first look for "Bar\Bar\Foo"
        // When it isnt found, it will move on and look at spl_autoload_register to try to resolve this class,
        // Failing that you will get a ClassNotFoundException
        $foo = new Bar\Foo();
    }
}

Please see. https://www.php.net/manual/en/language.namespaces.rules.php and https://www.php.net/manual/en/language.namespaces.faq.php#language.namespaces.faq.full for reference

Upvotes: 1

Related Questions