I have one directory that is going to keep all "helper" classes and functions. Let's call the directory helpers.
I want to configure PSR-4 fallback directory to point to this helpers directory:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
From Composer documentation:
... fallback directory where any namespace will be looked for.
So my understanding is that if my files/classes in that directory have PSR-4 compliant names my application should be able to find them there.
Now I created a file helpers/Logger.php with class Logger
What namespace should be for this class in order to 1) comply with PSR-4 and 2) just work?
I have tried
namespace Logger;
And load class as
$logger = new Logger();
But I receive error Class Logger not found
Deeper dive into composer code (loadClass() method) showed me that it actually finds and includes the file helpers/Logger.php, but the class still cannot be found for some reason.
According to PSR-4 namespace should be something like this:
namespace Helpers;
And class should be called like this:
$logger = new Helpers\Logger();
I have Class Helpers\Logger not found, but in addition the file helpers/Logger.php is not even included.
The logic inside Composer's loadClass() method for fallback is following:
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
........
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
So it actually tries to match the file name against the fully qualified class name.
So it seems that I am missing something in my understanding of PSR-4.
But what exactly?
Edit
To check it all I run a simple file from project root, all other libraries that are configured via composer are loaded correctly (for example, Pimple is working fine):
<?php
require_once __DIR__ . '/vendor/autoload.php';
$app = new \Pimple\Container();
/** Register logger */
$app['logger'] = function ($c) {
return new Helpers\Logger();
};
$app['logger']->info('test');
This fallback works as a definition of directory for global namespace. So yes, it may be used for autoloading any class in any namespace, but you still need to follow PSR-4 rules for them. Directory structure should represent namespaces structure. If you have rules like:
"autoload": {
"psr-4": {
"": "helpers/"
}
}
your Helpers\Logger
class should be in helpers/Helpers/Logger.php
, because in this way Composer will resolve class file path from autoloading rules.
helpers/Helpers/Logger.php
^ ^ ^
| | |
| | Class name part
| |
| Namespace part
|
Static prefix for global namespace
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With