Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PSR4 auto load without composer

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 ?

like image 292
Happy Coder Avatar asked Sep 19 '16 10:09

Happy Coder


People also ask

How do you autoload in php?

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.

How do I use autoload composer?

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.

What does composer dump-autoload do?

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.

What is the use of vendor autoload PHP?

In addition, the vendor/autoload. php file is automatically created. This file is used for autoloading libraries for the PHP project.

What does PSR mean in composer dump-autoload?

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.

How to load classes in composer using PSR-4?

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:

What is PSR 4 autoloader example?

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:

How to autoload all classes from another folder in composer?

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" ] } }


3 Answers

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.

like image 159
Thibault Avatar answered Oct 09 '22 07:10

Thibault


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.

like image 9
LSA Avatar answered Oct 09 '22 07:10

LSA


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

like image 3
jerryurenaa Avatar answered Oct 09 '22 07:10

jerryurenaa