I have one package in a project which is autoloaded using composer and composer.json entry is as follows :
"autoload": {
"psr-4": {
"CompanyName\\PackageName\\": "packages/package-folder/src/"
}
}
Now I am copying this over to another project which is not using composer. How can I autoload this same package there ?
The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.
After you create the composer. json file in your project root with the above contents, you just need to run the composer dump-autoload command to create the necessary autoloader files. These will be created under the vendor directory. Finally, you need to include the require 'vendor/autoload.
Composer dump-autoload: The composer dump-autoload will not download any new thing, all it does is looking for all the classes and files it needs to include again.
In addition, the vendor/autoload. php file is automatically created. This file is used for autoloading libraries for the PHP project.
However, if you run the composer dump-autoload command again, the index.php file will work properly. PSR stands for PHP Standard Recommendation. PSR is a PHP specification published by the PHP Framework Interop Group or PHP-FIG.
Composer package manager supports PSR-4 which means, if you follow the standard, you can load your classes in your project automatically using Composer's vendor autoloader. Now in your code you can do the following:
PHP PSR-4: Autoloader. Example. PSR-4 is an accepted recommendation that outlines the standard for autoloading classes via filenames. This recommendation is recommended as the alternative to the earlier (and now deprecated) PSR-0. The fully qualified class name should match the following requirement:
In the composer.json, you add the following code: This code means that Composer will autoload all class files defined the app/models folder. If you have classes from other folders that you want to load, you can specify them in classmap array: { "autoload": { "classmap": [ "app/models", "app/services" ] } }
You have to read the composer and load the classes yourself for each namespaces defined into the composer.json
.
Here is how :
function loadPackage($dir)
{
$composer = json_decode(file_get_contents("$dir/composer.json"), 1);
$namespaces = $composer['autoload']['psr-4'];
// Foreach namespace specified in the composer, load the given classes
foreach ($namespaces as $namespace => $classpaths) {
if (!is_array($classpaths)) {
$classpaths = array($classpaths);
}
spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir) {
// Check if the namespace matches the class we are looking for
if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
// Remove the namespace from the file path since it's psr4
$classname = str_replace($namespace, "", $classname);
$filename = preg_replace("#\\\\#", "/", $classname).".php";
foreach ($classpaths as $classpath) {
$fullpath = $dir."/".$classpath."/$filename";
if (file_exists($fullpath)) {
include_once $fullpath;
}
}
}
});
}
}
loadPackage(__DIR__."/vendor/project");
new CompanyName\PackageName\Test();
Of course, I don't know the classes you have in the PackageName.
The /vendor/project
is where your external library was cloned or downloaded. This is where you have the composer.json
file.
Note: this works only for psr4 autoload.
EDIT : Adding support for multiple classpaths for one namespace
EDIT2 : I created a Github repo to handle this code, if anyone wants to improve it.
Yes, this question is 6months old, however I just used the following.
I just found the following solution to the problem. I just locally ran the command composer dump-autoload -o
in my project folder. After that I simply had to upload the contents of ./vendor/composer folder and the /vendor/autoload.php to the server and it worked again.
This is helpful in case you cannot run composer on the server.
I am not a fan of Composer for many reasons. 1st reason shared hosting services do not offer composer as a package therefor it makes it harder to deliver low budget applications or simple MVC custom frameworks. Here is a work around that is compliant with PSR4 standards.
Assuming you add this auto-load method in a file in the root directory and that we are auto-loading classes for everything inside a folder called "src" here is how to archive this.
define('ROOT', dirname(__DIR__));
define('SLASH', DIRECTORY_SEPARATOR);
spl_autoload_register(function ($className)
{
$fileName = sprintf("%s%ssrc%s%s.php", ROOT, SLASH, SLASH, str_replace("\\", "/", $className));
if (file_exists($fileName))
{
require ($fileName);
}
else
{
echo "file not found {$fileName}";
}
});
now in every file you should add a namespace and if you have a dependency the use. here is a basic example in
namespace myapp;
use Core\Example;
Also, all your folders inside src should start with a capital letter in my example.
and done. Cheers @jerryurenaa
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