Search code examples
phpcomposer-phpautoload

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 ?


Solution

  • 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.