Search code examples
phpclassnamespacesincludeloader

required class inside namespace cannot instantiate


Ok, i made 3 files i have index.php where i include the namespace.php where i have 2 functions:

Namespace namespaceName{

class classLoader{
         public function __construct() {
            //not used
         }

         public function executeFunctionOutsideTheNamespace() {
            include("class.php");
             new classExtended("badass");
        }
}

class classBase{
    public function __construct(){

    }
}
}

Now from index.php i try dynamically to call a function from a third file class.php where is a class that extends one class from namespaces. Here is the class.php code

class classExtended extends namespaceName\classBase
{    
    public function __construct($action) {
        echo $action;
    }
}

And of course my index.php file

require("namespace.php");

$namespace= new namespaceName\classLoader(); 
$oController = $namespace->executeFunctionOutsideTheNamespace();

$oController is instance of classLoader() right? now i call the function executeFunctionOutsideTheNamespace from class classLoader() from namespace namespaceName and i tell to include("class.php"); and to instantiate extended class witch is a estension of classBase fromNamespace. I recide a Fatal error: Class 'namespaceName\classExtended' not found in C:\xampp\htdocs\exercices\namespace.php on line 10


Solution

  • The fact that class.php was include()ed inside of the classLoader class, which resides inside the namespaceName namespace does not cause it to inherit the namespace from the including file.

    So including class.php loads the class classExtended into the global namespace, meaning to access it as your code is, you would need to use

    new \classExtended("cool");
    

    In order to get classExtended into the namespace namespaceName, since it resides in its own file you will need to declare the namespace in that file. Doing this also means you need to remove namespaceName from the extends declaration, lest PHP start looking for the nested namespaceName\namespaceName\classBase. The file class.php must become

    namespace namespaceName;
    
    // Declare the class without the namespace in extends
    // since classExtended is now in the same namespace as classBase
    class classExtended extends classBase
    {    
        public function __construct($action) {
            echo $action;
        }
    }
    

    I would strongly recommend becoming familiar with the PSR-4 class autoloading standard defined by the PHP Framework Interoperability Group, and use Composer to handle your class autoloading. Namespacing then becomes mostly a matter of filesystem layouts, and file inclusion is handled automatically.