Reputation: 1045
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:
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
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?
Upvotes: 2
Views: 223
Reputation: 64536
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.
Upvotes: 2