6

I am still having trouble with PHP5 Namespaces.

I have a namespace called Project and I am trying to access a class called registry inside of this Project namespace that has a namespace of Library so at the top of the file that is a Project namespace I use this line use Library\Registry;

Registry class is inside the Library Namespace

This should work but it doesn't, instead the ONLY way to access my registry class inside this Project namespace is to use this

$this->registry = new \Library\Registry;

I want to be able to use this instead...

$this->registry = new Registry;

That was the whole reason of using

use Library\Registry;

at the top of the Project namespace file


Below I have 3 small example scripts in a folder structure like this.
Library/registry.class.php a class in my Library folder
Controller/controller.class.php and class in my Controller directory
Controller/testing.php a test file to run the script.

E:\Library\Registry.class.php file

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

E:\Controller\Controller.class.php file

<?php
use Library\Registry;

namespace Project
{
    class Controller
    {
        public $registry;

        function __construct()
        {
            include('E:\Library\Registry.class.php');

            // This is where my trouble is
            // to make it work currently I have to use
            //  $this->registry = new /Library/Registry;
            // But I want to be able to use it like below and that is why
            // I have the `use Library\Registry;` at the top
            $this->registry = new Registry;
        }

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

E:\Controller\testing.php file

<?php
use Project\Controller;

include('testcontroller.php');

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

?>

I get this error...

Fatal error: Class 'Project\Registry' not found in PATH to file

unless I use this below on the controller.class.php file

$this->registry = new \MyLibrary\Registry;

Because in that file at the top I have use Library\Registry; I should be able to access it like this...

$this->registry = new Registry;

Please help me get it where I can use it like that instead

JasonDavis
  • 48,204
  • 100
  • 318
  • 537

4 Answers4

6
use Library\Registry;

namespace Project
{

I believe that's the wrong way round: you're useing Library\Registry in the global namespace, and then opening the Project namespace.

Put the use statement inside the namespace you want to import it into.

namespace Project
{
    use Library\Registry;
lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Actually the docs say you cannot do that, it trows a fatal error if you use the `use` after the namespace is set. In my example it caused this `Parse error: syntax error, unexpected T_CLASS, expecting ',' or ';' in E:\Controller\controller.class.php on line 8` – JasonDavis Dec 23 '11 at 14:51
  • @jasondavis No, that was because I forgot to put the semicolon at the end of the statement. Try it with the version I edited. (Incidentally, that should have been fairly obvious from the error...) – lonesomeday Dec 23 '11 at 14:58
  • You're right I should of spotted that. It seems to be working, is this the way it should always be done? After the namespace declaration? Everytime I think I fully got it with these namespaces, something pops up that doesn't work, working with multiple namespaces is where my trouble starts I should say. Thanks for your help. When looking at C# projects they do it the other way around so I think that adds to the confusion – JasonDavis Dec 23 '11 at 15:10
  • Yes, you always need to import into a namespace or into the global scope. [You can see some more information about this in the manual.](http://www.php.net/manual/en/language.namespaces.importing.php) – lonesomeday Dec 23 '11 at 15:12
2

You need to import your Registry class inside Project namespace, because you need em there, not in global scope.

<?php   
namespace Project
{
    use Library\Registry;

    class Controller
    {
        public $registry;

        function __construct()
        {
            include('E:\Library\Registry.class.php');

            // This is where my trouble is
            // to make it work currently I have to use
            //  $this->registry = new /Library/Registry;
            // But I want to be able to use it like below and that is why
            // I have the `use Library\Registry;` at the top
            $this->registry = new Registry;
        }

        function show()
        {
            $this->registry;
            echo '<br>Registry was ran inside testcontroller.php<br>';
        }
    }
}
?>
Timur
  • 6,668
  • 1
  • 28
  • 37
1

Just add: use \Library\Registry;

at top of your script under the namespace declaration

Then you can just say:

$registry = new Registry;

inside your class

By the way your class declaration is all wrong. You should not wrap your namespace inside curly braces, namespace is not a function.

This is how it should be. Also make sure the class declaration of Library\Registry is already included by either using include('/path/to/registry.php'); or using autoloader

namespace Project;

include('E:\Library\Registry.class.php');

use \Library\Registry;

    class Controller
    {
        public $registry;

        function __construct()
        {


            // This is where my trouble is
            // to make it work currently I have to use
            //  $this->registry = new /Library/Registry;
            // But I want to be able to use it like below and that is why
            // I have the `use Library\Registry;` at the top
            $this->registry = new Registry;
        }

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

Enjoy

Dmitri Snytkine
  • 1,096
  • 1
  • 8
  • 14
  • Dont you see I already have that in controller.class.php file – JasonDavis Dec 23 '11 at 14:43
  • There's nothing wrong with enclosing your namespace in curly brackets. [See the manual](http://www.php.net/manual/en/language.namespaces.definitionmultiple.php) – lonesomeday Dec 23 '11 at 14:47
  • Sorry, I really did not know about wrapping namespace in braces, just never seen anyone doing it this way. – Dmitri Snytkine Dec 23 '11 at 14:56
  • @Dmitri Snytkine sorry as well I think I read your answer wrong the first time, and you do provide the correct answer now. On another note, I really like the project you have done, the Q&A one, perhaps I could send you an email about namespaces and the how you did them in your project if you don't mind? – JasonDavis Dec 23 '11 at 18:42
0
<?php namespace Project;
    require_once 'your registry class file';
    use \Library\Registry as Registry;

Now you will be able to use...

    $this->registry = new Registry;
Shakil Ahmed
  • 1,481
  • 2
  • 19
  • 26