I want to use a library that defines some extensive dependencies in its composer.json file, even though it only uses one or two small classes of those dependencies.
Is it possible to set up my require in a way that composer thinks I already have those dependencies and lets me use some self-defined minimal mock classes instead?
Example: I want package lib/a which in turn requires lib/b.
Normally I would have something like this in my composer.json:
"require": {
"lib/a": "^2.2"
}
I thought that maybe 'provide' would fool composer:
"require": {
"lib/a": "^2.2"
},
"provide": {
"lib/b": "2.2.0"
}
But it seems to do nothing. Composer still downloads lib/b.
Is there any way to tell composer to ignore a certain dependency?
Turns out replace does what I want:
"require": {
"lib/a": "^2.2"
},
"replace": {
"lib/b": "*"
}
This tells composer that the package at hand replaces any version of lib/b
Related
I am trying to create a PHP library which includes other libraries, and I bet I'm missing something fundamental.
Using the AWS PHP SDK as a guide, I'd like to create a library which, after installing with Composer, requires other libraries, yet the entire scope of classes (both from the current library, and required libraries) all become available simply by using require 'vendor/autoload.php;'.
What are the basic requirements to set this up? Is it a matter of configuring composer.json, namespacing in a particular way, or both?
What you're describing is exactly Composer's main purpose - the definition of a package of code that may require and implement other packages.
Using the AWS SDK as a guide, if you look at the composer.json file, which provides all of the Composer configuration information, you'll see two require blocks, one labeled require and one labeled require-dev:
"require": {
"php": ">=5.5",
"guzzlehttp/guzzle": "^5.3.1|^6.2.1",
"guzzlehttp/psr7": "^1.4.1",
"guzzlehttp/promises": "~1.0",
"mtdowling/jmespath.php": "~2.2"
},
"require-dev": {
"ext-openssl": "*",
"ext-pcre": "*",
"ext-spl": "*",
"ext-json": "*",
"ext-dom": "*",
"ext-simplexml": "*",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"behat/behat": "~3.0",
"doctrine/cache": "~1.4",
"aws/aws-php-sns-message-validator": "~1.0",
"nette/neon": "^2.3",
"andrewsville/php-token-reflection": "^1.4",
"psr/cache": "^1.0"
},
This is how you define what other packages/libraries your library depends upon. The require section lists all other libraries that must be installed when your library is installed. The require-dev section lists libraries that may only be necessary when you are working in a development environment, and are not needed in your production environment.
When you specify other libraries that are required, Composer will install your library, and then go out and also require the libraries your library requires (and then the libraries those libraries require, and so on and so on).
Also included with the libraries to include, you'll notice that the version numbers are also included, to ensure compatibility.
The easiest way to add new dependencies I find is on the command line, with the composer require command, documented here: https://getcomposer.org/doc/03-cli.md#require. The command helps you search for the package you want if you don't know it exactly, and can resolve the latest version for you automatically (which you can override if you need/want to).
If you wish to require a development-only dependency, add the --dev flag when running the command.
Using this command, Composer will automatically update your composer.json file, pull down the dependency onto the local machine, and update your autoloader.
You should never need to do anything more than require_once vendor/autoload.php to ensure dependencies can be autoloaded - Composer will do all the legwork of setting up the autoloader so you don't have to, and keep everything up to date as new dependencies are added.
Here's the complete documentation on the composer.json schema: https://getcomposer.org/doc/04-schema.md. You will want to have a composer.json config file in the root of project, so you can configure composer for your project (and any others that require your library later). If you don't have one, you can use the composer init command to interactively create one. Documentation on that command is available here: https://getcomposer.org/doc/03-cli.md#init
And here's their basic usage guide, in case you haven't gone through it already: https://getcomposer.org/doc/01-basic-usage.md
I was working on a project and ended up having to make a small change to one of the packages I'm using.
That package is: shopifyextras/shopify-php-api-wrapper
Which you can find here: https://github.com/ShopifyExtras/PHP-Shopify-API-Wrapper
My previous composer.json file looked like this:
{
"require": {
"monolog/monolog": "1.*",
"shopifyextras/shopify-php-api-wrapper": "^1.1"
},
"autoload": {
"psr-0": { "MyApp\\": "src/" }
}
}
After forking the repo and making my changes (I forgot to create a new branch first, but created the branch after committing to master, and pushed it to github - I don't think this should cause any issues given that the branch exists and it does point to the correct head), I then updated my composer.json to use my fork.
After reading the composer docs (https://getcomposer.org/doc/05-repositories.md#vcs) I updated my composer.json to the following:
{
"minimum-stability": "dev",
"prefer-stable" : true,
"repositories": [
{
"type": "git",
"url": "https://github.com/JonLaliberte/PHP-Shopify-API-Wrapper.git"
}
],
"require": {
"monolog/monolog": "1.*",
"shopifyextras/shopify-php-api-wrapper": "dev-risksbugfix"
},
"autoload": {
"psr-0": { "MyApp\\": "src/" }
}
}
When I run composer update I receive the following error:
$ composer update --verbose
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package shopifyextras/shopify-php-api-wrapper could not be found in any version, there may be a typo in the package name.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
I have tried:
Using "risksbugfix" instead of "dev-risksbugfix"
Using type "vcs" instead of git"
Removing ".git" from the repo URL
Using "jonlaliberte/shopify-php-api-wrapper" instead of "shopifyextras/shopify-php-api-wrapper"
Any help would be greatly appreciated. Thanks!
Branch Alias
If you alias a non-comparable version (such as dev-develop) dev- must
prefix the branch name.
You branch is a non-comparable version dev-riskbugfix.
You might need to prefix it with dev-: dev-dev-riskbugfix.
Or rename the branch to riskbugfix and get rid of the dev-, then the alias would be dev-riskbugfix.
I'm trying to integrate processout but they only seem to support composer integration.
https://github.com/ProcessOut/processout-php
How would I integrate this just by uploading the /src/ folder into my project?
<?php
// Load dependencies
require 'vendor/autoload.php';
// Instantiate ProcessOut
$processout = new \ProcessOut\ProcessOut();
$processout->setProjectId('<project-id>');
$processout->setProjectSecret('<project-key>');
// Set this project as the default one for the current request
\ProcessOut\ProcessOut::setDefault($processout);
?>
You are ignoring that Composer is not an autoloader generator, but first and foremost a dependency manager. If you look at the composer.json file of the ProcessOut package you see:
"require": {
"php": ">=5.4",
"ext-curl": "*",
"ext-mbstring": "*",
"anlutro/curl": "1.4"
},
The last line is a package it depends on itself, and that you'll be missing out when not using Composer. You could theoretically load and include all dependencies recursively yourself, but in the end - just get composer and let it do its work.
They have a php release where you only have to load autoload.php:
https://github.com/ProcessOut/processout-php/releases
My project is based on the Zend Skeleton App, and I'm using Composer to add vendor packages. However, when I add the zendservice-amazon package, it is not getting autoloaded.
Here is part of my composer.json file:
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "2.3.*",
"zendframework/zendservice-amazon": "2.0.*",
"doctrine/doctrine-orm-module": "0.7.*",
"zf-commons/zfc-user-doctrine-orm": "dev-master"
}
I have looked at the autoload files in the vendor directory, and they include the ZendService\Amazon namespace. I've tried several different things, but it's not working.
I've double checked that composer's autoloader is being used, so this is really puzzling. Any ideas? Thanks in advance.
The documentation and examples are wrong in the Zend Framework documentation. Instead of:
$s3 = new \ZendService\Amazon\S3();
You need to add an extra "S3":
$s3 = new \ZendService\Amazon\S3\S3();
I've set up two projects, an 'init' and a library, which is required by the init. They both have PSR-0 autoloads set, but the autoload values from the library are not added to the vendor/composer/autoload_namespaces.php in the init project.
Sample composer.json from the Library:
{
"name": "lxp/library",
"description": "A test library",
"autoload": {
"psr-0": {
"LXP\\Library": "src/"
}
}
}
Sample composer.json from the project that requires that library:
{
"name": "lxp/init",
"name": "A test init",
"autoload": {
"psr-0": {
"LXP\\Init": "src/"
}
},
"repositories": [
{
"type": "composer",
"url": "http://satis.repo.redacted/"
}
],
"require": {
"lxp/library": "dev-master"
}
}
The library contains the class LXP\Library\Something in the file src/LXP/Library/Something.php.
The project that requires the library contains the class LXP\Init\Now in the file src/LXP/Init/Now.php.
When running composer install in the 'init' project, it downloads the library project and puts it in vendor correctly, but vendor/composer/autoload_namespaces.php doesn't contain the library's autoload information, only that of the current project.
What am I doing wrong? If I run dump-autoload in the library project then the autoload_namespaces.php file is correct, and a quick bootstrap script confirms that it does indeed pick up the class.
EDIT - This is a problem with the satis-generated packages.json. To fix it, I had to add the autoload information from the library's composer.json into the json file I supply to satis, which seems like an unnecessary duplication and so I'm probably doing it wrong. Is there a single place that autoload information can be stored for satis libraries? For example, can satis read the composer.json files that exist in the libraries it scans?
EDIT #2 - Satis does not read the composer.jsons from repositories specified as 'package' type. This is obvious in hindsight, because 'package' is used for libraries that do not have a composer.json, and is a way to wrap composer-like dependency management around them.
Changing the satis.json's repository to 'vcs' type meant that the composer.json was read, and the information (including the autoload specification) was parsed and stored in the packages.json.
#Seldaek - thank you for suggesting that my satis config was the problem, and I hope that this clarifies satis / composer behaviour for anyone else in my position.
I see two possible mistakes you may have done that would cause this:
You forgot to update your satis repo so the autoload config for lxp/init is not up to date in there
You are running composer install from a lock file, and that means composer just reads the info from the composer.lock file and does not update package metadata to the latest version available in satis. To solve this you should run composer update instead.
Try composer dump-autoload command.
It depends how you installing your library via Composer. For example, when downloading it as package type (same I believe with composer type), Composer never reads the composer.json file, so instead you should use vcs or git type. See: GH-6846.
Here is composer.json which should work:
{
"require": {
"lxp/library": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "http://satis.repo.redacted/"
}
]
}
Then run: composer install.
For troubleshooting, try running:
composer dump-autoload -o -vvv.
composer diagnose -vvv