Getting Error in PHP Autoload

517 views Asked by At

I am using PSR-0 for auto loading, I know that I need to use PSR-4 which I will do it latter part. Even if PSR-4, answers are welcome.

I am having the following directory structure for which the auto loading works fine.

+ www/entity
|__ /EntityGenerator
|       |__ /Database
|       |       |__ DatabaseConnection
|       |       |__ DatabaseConnectionInterface
|       |       |__ DatabaseRepositoryInterface
|       |       
|       |__ /Exception
|
|__ autoload.php
|__ index.php

For the following directory structure its giving error as follows

Warning: require(EntityGenerator\Database\DatabaseConnection.php): failed to open stream: No such file or directory in C:\wamp\www\entity\EntityGenerator\autoload.php on line 15

+ www/entity
| __ /EntityGenerator
        |__ /Database
        |       |__ DatabaseConnection
        |       |__ DatabaseConnectionInterface
        |       |__ DatabaseRepositoryInterface
        |       
        |__ /Exception
        |__ autoload.php
        |__ index.php

Can anyone explain why I am getting the error with second directory structure.

If anyone needs the whole code for testing, please find the below link

https://github.com/channaveer/EntityGenerator

2

There are 2 answers

5
apokryfos On BEST ANSWER

Your problem is you're using a relative path, which is not always set as the current script's directory. You need to use absolute paths to be sure you're loading what you need to load.

function autoload($className)
{
    $namespaceRoot = "EntityGenerator"; 
    $className = ltrim($className, '\\');
    if (strpos($className,$namespaceRoot) !== 0) { return; } //Not handling other namespaces
    $className = substr($className, strlen($namespaceRoot));
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
    require __DIR__.DIRECTORY_SEPARATOR.$fileName; //absolute path now
}
spl_autoload_register('autoload');

__DIR__ is guaranteed to return the directory which the current script is in.

2
Mehmet SÖĞÜNMEZ On

It's because directory structure. You're trying to load EntityGenerator\Database\DatabaseConnection. it's match with path in the first example but not for second one. Just look at the path from autoload.php. It's looking for paths in it's path. EntityGenerator is a valid path in www/entity which's path for autoload.php. But not for www/entity/EntityGenerator at second example.