Analizing the problem
The problem in installing the dependencies without Composer is the autoloading system.
Composer use a homemade autoloader based on an array map, this is a de-facto standard.
But this autoloading system, "fortunally" in this case, is not PSR-4 compliant.
PSR-4 is the de-iure standard for autoload a class in PHP, so you can't escape from autoloading. You must use one of them.
Solution Proposal
Require the custom autoload.php file early in your source code. Manually configure this brilliant PSR-4 autoloader to autoload a VendorClass in a VendorNamespace anywhere in your code.
Real life example
Look at this example:
I have a legacy project who can't and won't use Composer. This project can be speed up in development with this fantastic package for command line scripts.
This is my project directory structure:
- src
- tests
- vendor (not the Composer's one)
This package has this directory structure:
- examples
- src
- Commando
- tests
The only thing I need is the src folder. Placing this folder in my vendor folder would be fine. So my custom autoloader would be like this:
// Constants
$base_path = "path\to\my\project";
$autoloader_class = '\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
define("BASE_PATH", str_replace("\\", DIRECTORY_SEPARATOR, $base_path));
// Autoloader
require_once BASE_PATH.'\vendor\MarcoConsiglio-Wichee\PSR-4-Autoloading\Psr4AutoloaderClass.php';
// Init the autoloader.
$package = [
"nategood\commando" => [
"namespace" => "Commando",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\nategood\commando\src\Commando')
],
"kevinlebrun\colors.php" => [
"namespace" => "Colors",
"path" => str_replace("\\", DIRECTORY_SEPARATOR, '\vendor\kevinlebrun\colors.php\src\Colors')
]
];
// Register namespaces.
$loader = new \PSR4\Psr4AutoloaderClass;
$loader->register();
// Namespace // Path to source
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]);
$loader->addNamespace($package["nategood\commando"]["namespace"], BASE_PATH.$package["nategood\commando"]["path"]."\Util");
$loader->addNamespace($package["kevinlebrun\colors.php"]["namespace"], BASE_PATH.$package["kevinlebrun\colors.php"]["path"]);
Now I can use the command package anywhere in my project!
Pros & Cons
This solution allow you to:
- Easely and manually build your own custom autoloader (you only need to specify the
VendorNamespace and the folder(s) where search for VendorClasses in the VendorNamespace.
- Freely organize your composer dependency anywhere in your project folder (and why not, outside it)
- Import a composer package as is in your project (either downloading locally with Composer or cloning the package repository) or a relevant part of it (i.e removing composer.json file or files that require the composer autoloader).
Cons:
- Manually build your custom autoloader means to work on every required dependency of your project (i hope not a lot).
- Mistakes in package source paths can be tedious and frustrating.
- Works only with PSR-4 compliant file names (i.e. can't use a
A.class.php file name)
includethe files.