Php use namespace class not found

I posted some questions previously regarding the use of Namespaces in PHP and from what I got, this example code I have below should be working.

However I am getting errors when I try to use Namespace in PHP like this. Here is the first error when running the code below as is...

Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6

E:\Controller\testing.php File

<?php
use \Controller;

include('testcontroller.php');

$controller = new Controller;
$controller->show();
?>

E:\Controller\testcontroller.php File

<?php
use \Library\Registry;

namespace Controller
{
    class Controller
    {
        public $registry;

        function __construct()
        {
            include('E:\Library\Registry.class.php');
            $this->registry = new Registry;
        }

        function show()
        {
            echo $this->registry;
            echo '<br>Registry was ran inside testcontroller.php<br>';
        }
    }
}
?>

E:\Library\Registry.class.php File

<?php
namespace Library\Registry
{
    class Registry
    {
        function __construct()
        {
            return 'Registry.class.php Constructor was ran';
        }
    }
}
?>

As you can see I tried to make it as simple as possible just to get the Namespace part working. I have tried different variations and cannot seem to figure it out.

asked Dec 22, 2011 at 23:10

JasonDavisJasonDavis

47.2k97 gold badges305 silver badges526 bronze badges

Even when using use statement, you need to specify the namespace of the class you are trying to instantiate. There are a lot of examples here: http://www.php.net/manual/en/language.namespaces.importing.php

To understand it better, I will describe to you how it works. In your case, when you do use \Controller, the whole Controller namespace becomes available to you, but not the classes that are in this namespace. So, for example:

<?php
include('testcontroller.php');

use \Controller;

// Desired class is in namespace!
$controller = new Controller\Controller();

// Error, because in current scope there is no such class
$controller = new Controller();

$controller->show();
?>

Another example:

testcontoller.php:

<?php
namespace Some\Path\To\Controller;

class Controller
{
    function __construct()
    {

    }

    function show()
    {
        echo '<br>Was run inside testcontroller.php<br>';
    }
}
?>

testing.php:

<?php
include('testcontroller.php');

use \Some\Path\To\Controller;

// We now can access Controller using only Controller namespace,
// not Some\Path\To\Controller
$controller = new Controller\Controller();

// Error, because, again, in current scope there is no such class
$controller = new Controller();

$controller->show();
?>

If you wish to import exactly the Controller class, you need to do use Controller\Controller - then this class will be accessible in your current scope.

Andrew

17k11 gold badges95 silver badges107 bronze badges

answered Dec 23, 2011 at 9:33

6

Its not that good idea to name the namespace, like the class, because it is confusing (and I think this is what happens here). There moment you define the alias via use Controller this referenes to either a class \Controller, or the namespace \Controller, but your class, because it is within the namespace, is named \Controller\Controller 1

use Controller;
$class = new Controller\Controller;

or

$class = new \Controller\Controller;

or

use Controller\Controller;
$class = new Controller;

The idea is, that the moment you try to access a class with its relative name it tries to map the "first part" against any alias defined using use (remeber use MyClass is the same as use MyClass as MyClass. The thing after as is the alias).

namespace MyNamespace\MyPackage\SomeComponent\And\So\On {
  class MyClass {}
}
namespace Another {
  use MyNamespace\MyPackage\SomeComponent; // as SomeComponent
  $class =              new SomeComponent\An\So\On\MyClass;
}

As you can see PHP finds SomeComponent as the first part and maps it against the SomeComponent-alias the line above.

You can read more about it in the manual about namespaces.

1 Its called "Full-qualified classname", if you name a class with its complete name.

answered Dec 23, 2011 at 7:07

KingCrunchKingCrunch

126k20 gold badges147 silver badges171 bronze badges

When you put a class Controller in the namespace Controller, then you have to reference it that way:

$controller = new Controller\Controller();

\Controller would be a class in the global (default) namespace, i.e. as if you used no namespace at all.

answered Dec 22, 2011 at 23:16

Php use namespace class not found

Dan SoapDan Soap

9,9491 gold badge39 silver badges49 bronze badges

6

Strangely I have found that in my example code from the Question above, if I change all the Namespace's that are defined to something like MyLibrary so it would be like this code below...

E:\Library\Registry.class.php File

<?php
namespace MyLibrary
{
    class Registry
    {
        function __construct()
        {
            echo 'Registry.class.php Constructor was ran';
        }
    }
}
?>

Then when I use use MyLibrary\Registry; in another file, I am able to access it how I had planned...

$this->registry = new Registry;

The reason this is very strange to me is this now makes a class name appear to be a Namespace as well. So I would not need to set a Namespace to 'MyLibrary\Library' to access the Registry instead I would do it like I showed in this answer to be able to access it with just calling the name of the class.

I hope this makes sense and helps someone else. I will not accept this as the answer as I am hoping someone with more know-how will come in and post a better Answer with explanation

answered Dec 23, 2011 at 0:22

JasonDavisJasonDavis

47.2k97 gold badges305 silver badges526 bronze badges

try

<?php
use \Library\Registry;

namespace Controller;
class Controller
{
    public $registry;
    function __construct()
    {
        include('E:\Library\Registry.class.php');
        $this->registry = new Registry;
    }
    function show()
    {
        echo $this->registry;
        echo '<br>Registry was ran inside testcontroller.php<br>';
    }
}
?>

and

<?php
namespace Library\Registry;
class Registry
{
    function __construct()
    {
        return 'Registry.class.php Constructor was ran';
    }
}
?>

answered Dec 22, 2011 at 23:18

AschererAscherer

8,1023 gold badges41 silver badges60 bronze badges

0

First off, I believe you are using composer or composer is initialised in your project. If so, check composer.json file for your autoload, psr-4 definition. For example, if the root of your application is "App", then in your psr-4, you should be doing "autoload": { "psr-4": { "App\\": "./" } }, Furthermore, remember to clear composer cache and dump-autoload from the terminal as follows:

composer clear-cache
composer dump-autoload

answered Jul 30 at 16:06

Php use namespace class not found