mOrloff
mOrloff

Reputation: 2617

Autoloading a third party library via Composer's autoloader?

I've got a little Laravel4 project into which I need to incorporate a third party library. This library is not available via GIT or Packagist (only from the vendor), so I downloaded it into my vendor directory (had to add some custome vendor and package directories).

Rather than just include()-ing it as suggested by the vendor's documentation, I'm hoping to just use the existing Composer autoloader, and can use a hand figuring out what I'm doing wrong.

My dir tree is like this

path/to/project
 |__ app
 |__ vendor
 |   |__ merchantcompany
 |       |__ client
 |           |__ src
 |               |__ client.php
 |__ blah
 |__ blah

And I updated my compser.json to include:

"autoload": {
    "psr-4": {
         "MerchantCompany\\": "vendor/merchantcompany/client/src"
     },
     ...

I also tried "MerchantCompany\\": "src", but to no avail.

WHAT am I missing?

NOTE: The class from the vendor is not namespaced.
Am I under the correct assumption that this is fine, or should I be adding a namespace to the class script?

Upvotes: 0

Views: 1747

Answers (2)

Sven
Sven

Reputation: 70863

You are currently doing it wrong. You manually inject the package into a folder that is managed by Composer (which can wipe that directory if seen fit), and you incorporate the autoloading sort of into your own code.

Composer offers a way to add the needed metadata to projects which do not have them. This is the "package" type of repository described in https://getcomposer.org/doc/04-schema.md#repositories

If you look at the example given there for Smarty, you see that you basically need to add a key "type" with value "package" and a key "package" with the content of the composer.json file you'd like to see contained inside the project.

In this case there is a version tag added (in sync with the version of Smarty being used, just in case some later versions make use of Composer and Packagist, which Smarty does since some version 3.1.x) to allow Composer to reference this version, a name for that package (both values can be arbitrarily made up if you doubt you'll ever get that software with Composer support), and a URL to download the code from (you don't have to provide both a ZIP download AND a repository if you don't know them).

The thing that is missing is the definition of autoloading, which can be added just the same way as everywhere else. If nothing else works, use "classmap". Composer will then scan all files for occurrences of classes, interfaces and traits and will generate an array containing the accompanying filenames. You can however also use PSR-0 or PSR-4 if the code conforms to that standard.

Note that PSR-4 can only be used for classes using namespaces! Without namespaces, you must use either PSR-0, or classmap. From the short piece of directory listing I doubt the code is compatible with PSR-0, so just use classmap for quick results.

As a suggestion:

"repositories": [
    {
        "type": "package",
        "package": {
            "name": "merchantvendor/client",
            "version": "1.0.0",
            "dist": {
                "url": "http://example.com/zip-download-url.zip",
                "type": "zip"
            },
            "autoload": {
                "classmap": ""
            }
        }
    }
],
"require": {
    "otherstuff": "...",
    "merchantvendor/client": "1.0.0"
}

Upvotes: 2

Aken Roberts
Aken Roberts

Reputation: 13447

PSR-4 is a namespace-based autoload standard. You won't be able to use it if your vendor's PHP package does not utilize namespaces.

If the package's files are class based (not procedural functions like a helpers file), then you can use Composer's classmap autoloader instead. Otherwise you can use the files autoloader, which basically includes the file on every request, regardless if you use it or not.

Note that since you are defining the path to these files manually, they do not need to be in your vendor folder. I'd actually recommend that you put the library in a different, non-.gitignore folder, since it is an external dependency that you can not automatically include into your project via Composer.

Of course you can always nag your vendor into updating their package to be more compliant with things like PSR-4 and namespaces. :)

Upvotes: 0

Related Questions