12

I am new with this namespace thing.

I have 2 classes(separate files) in my base directory, say class1.php and class2.php inside a directory src/.

class1.php

namespace \src\utility\Timer;

class Timer{
    public static function somefunction(){

    }
}

class2.php

namespace \src\utility\Verification;
use Timer;

class Verification{
     Timer::somefunction();
}

When I execute class2.php, i get the Fatal error that

PHP Fatal error: Class 'Timer' not found in path/to/class2.php at line ***

I read somewhere on SO, that I need to create Autoloaders for this. If so, how do I approach into creating one, and if not, then what else is the issue?

UPDATE

I created an Autoloader which will require all the required files on top of my php script. So, now the class2.php would end up like this.

namespace \src\utility\Verification;
require '/path/to/class1.php'
use Timer;
//or use src\utility\Timer ... both doesn't work.

class Verification{
     Timer::somefunction();
}

This also does not work, and it shows that class not found. But, if I remove all the namespaces, and use's. Everything works fine.

5
  • Try in ur class2.php with use \src\Timer\Timer as Timer; Commented Apr 22, 2016 at 7:26
  • @ManinderpreetSingh Tried. Same issue. Commented Apr 22, 2016 at 7:28
  • I think you should check out Composer. A namespace is merely a unique identifier for a class. PHP's autoload is overloaded when a class is instantiated whilst it does not exist but before the pre-processor throws a T_FATAL error. Common practice is to then replace \ with / and load it from a folder structure (why the namespace usually matches a directory structure. Commented Apr 22, 2016 at 10:06
  • @ash Can you tell me in brief how Composer will be helpful in my project? I need to use Namespaces. I hope you have read my Update in the question. Commented Apr 22, 2016 at 10:14
  • It doesn't fix your namespaces, it helps you load your classes when to instansiate them in your code. checkout PHP The Right Way Commented Apr 22, 2016 at 10:17

2 Answers 2

28

We can solve the namespace problem in two ways

1) We can just use namespace and require

2) We can use Composer and work with the autoloading!

The First Way (Namespace and require) way

Class1.php (Timer Class)

namespace Utility;

class Timer
   {
    public static function {}
   }

Class2.php (Verification Class)

namespace Utility;
require "Class1.php";

//Some interesting points to note down!
//We are not using the keyword "use" 
//We need to use the same namespace which is "Utility" 
//Therefore, both Class1.php and Class2.php has "namespace Utility"

//Require is usually the file path!
//We do not mention the class name in the require " ";
//What if the Class1.php file is in another folder?
//Ex:"src/utility/Stopwatch/Class1.php"  

//Then the require will be "Stopwatch/Class1.php"
//Your namespace would be still "namespace Utility;" for Class1.php

class Verification
   {
     Timer::somefunction();
   }

The Second Way (Using Composer and the autoloading way)

Make composer.json file. According to your example "src/Utility" We need to create a composer.json file before the src folder. Example: In a folder called myApp you will have composer.json file and a src folder.

   {
     "autoload": {
     "psr-4": {
        "Utility\\":"src/utility/"
        }
     }   
   }

Now go to that folder open your terminal in the folder location where there is composer.json file. Now type in the terminal!

   composer dump-autoload

This will create a vendor folder. Therefore if you have a folder named "MyApp" you will see vendor folder, src folder and a composer.json file

Timer.php(Timer Class)

namespace Utility;

class Timer
     {
      public static function somefunction(){}
     }

Verification.php (Verification Class)

namespace Utility; 
require "../../vendor/autoload.php"; 
use Utility\Timer; 

class Verification
  {
     Timer::somefunction(); 
  }

This method is more powerful when you have a complex folder structure!!

Sign up to request clarification or add additional context in comments.

Comments

1

You are going to need to implement an autoloader, as you have already read about it in SO.

You could check the autoloading standard PSR-4 at http://www.php-fig.org/psr/psr-4/ and you can see a sample implementation of PSR-4 autoloading and an example class implementation to handle multiple namespaces here https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md.

2 Comments

I see. I was in fact reading those right now. This means, that the keywords namespace and use are kinda useless without an Autoloader?
Namespaces are just a way of encapsulating items as the docs say

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.