Question

I am fiddling around with autoloading, and trying to make a file structure that abides to the PSR-0 Standard. However I am getting this error:

Warning: require(GetMatchHistory\api.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Test\Test.php on line 15

Fatal error: require(): Failed opening required 'GetMatchHistory\api.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\Test\Test.php on line 15

And here is my file structure:

File structure

I am using Test PHP with this autoloader function:

function autoload($className)
{
    $className = ltrim($className, '\\');
    $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 $fileName;
}

spl_autoload_register('autoload');

$Query = new GetMatchHistory_api();

This function is copy-pasted from the suggested PSR-0 function here

Am I misunderstanding with regards to how the structure should be? The class within "api.php" is GetMatchHistory_api

Edit: Another problem

I have used the suggested answer by MrCode, however now I am having an issue where the autoloader wont load a class that is in another directory.

use Classes\Queries\History\GetMatchHistoryAPI;
use Classes\Queries\History\GetMatchHistoryBASE;
use Classes\Utilities\send;

When I am calling the send class, from within a function inside GetMatchHistoryAPI, I am receiving the error:

Warning: require(Classes\Queries\History\send.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Test\Test.php on line 15

However, as you can tell from the above image, the send class is not in that file path. Why is this error occurring?

Was it helpful?

Solution

Based on that structure, you would need to rename the class to Classes_Queries_GetMatchHistory_api and change the code that instantiates it to:

$Query = new Classes_Queries_GetMatchHistory_api();

The reason for this is your Test.php resides at the root and the api class is in the directory Classes/Queries/GetMatchHistory.


Example using namespaces instead of the underscore method:

api.php:

namespace Classes\Queries\GetMatchHistory;

class api
{

}

Test.php:

spl_autoload_register('autoload');
$Query = new Classes\Queries\GetMatchHistory\api();

Or using use:

use Classes\Queries\GetMatchHistory\api;

spl_autoload_register('autoload');
$Query = new api();

To address your comment:

I was going to have the same class names, but under a different folder (so GetMatchHistory - api.php and GetMatchDetails - api.php). I guess this would make it too ambiguous when calling the classes however

Namespaces are designed to solve this very problem. Namespaces allow you to have classes with the same name (but in different namespaces) and avoid any conflicts.

As an example, you have an api class under both GetMatchHistory and GetMatchDetails.

File: Classes/Queries/GetMatchHistory/api.php

namespace Classes\Queries\GetMatchHistory;

class api
{
    public function __construct(){
        echo 'this is the GetMatchHistory api';
    }
}

File: Classes/Queries/GetMatchDetails/api.php

namespace Classes\Queries\GetMatchDetails;

class api
{
    public function __construct(){
        echo 'this is the GetMatchDetails api, I am separate to the other!';
    }
}

File: Test.php (usage example)

spl_autoload_register('autoload');

$historyApi = new Classes\Queries\GetMatchHistory\api();
$detailsApi = new Classes\Queries\GetMatchDetails\api();

If you like, you can give an alias instead of typing out the whole fully qualified namespace:

use Classes\Queries\GetMatchHistory\api as HistoryApi;
use Classes\Queries\GetMatchDetails\api as DetailsApi;

$historyApi = new HistoryApi();
$detailsApi = new DetailsApi();

As you can see, namespaces make it possible to have multiple different classes with the same name, without having conflicts or making it ambiguous.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top