Using conditional OR in requirements in a composer.json? - php

We have a problem with composer. Our library requires a either ... or ... library.
So basically it requires it like this:
"php-64bit": ">=5.4.0"
OR
"php": ">=5.4.0" AND "ext-example": "^1.0.2"
So basically it requires a specific PHP version.
Additionally it requires a 64bit version of PHP OR a specific library to work.
Is this possible to do with composer? If so how? If not can we solve it in another way?

I'd think you should not go overboard with your dependency definition.
Both platform situations require PHP 5.4 or later. I'd add that as the only hard dependency.
Composer has a "suggest" feature. Your extension could be suggested with a descriptive text to indicate that only the 32bit platform would need it.
Your code would already have to deal with the situation, so you probably have checks implemented to see whether you are using 64bits (and omit using the extension) or not. That code might emit an error when being used on 32bit without the extension.
"require": {
"php": ">=5.4"
},
"suggest": {
"ext-example":"Required to use this package on 32bit PHP"
}
This avoids having the user add a script to his composer.json that does nothing more than helping him understand why it fails when first trying to install your package. He'd have to read the documentation anyway.

I assume, you intend to make your library available through Packagist.
Composer can run scripts triggered by events, but only those defined in the root composer.json.
Include a script to detect the PHP environment OS agnostically (64 or 32bit) in your library. Since you require ">=5.4.0" in both cases, your script can conditionally require your additional library "ext-example": "^1.0.2" when in a 32bit environment.
Example Cmd.php in your library:
namespace Some\Name\Space;
class Cmd
{
public static function check32() {
// detect environment here... then:
if ($is32) {
$cmd = 'php composer.phar require vendor/32bit-library:dev-master';
exec($cmd, $output, $return_var);
}
}
}
This will run composer.phar in the app's root directory.
Referring entry in root composer.json:
"scripts": {
"post-install-cmd": [
"Some\\Name\\Space\\Cmd::check32"
]
}
The caveat here is that exec() must be available on your user's machine and that the user has to include your library as well as your post-install-cmd in their composer.json.

Related

Run composer using different version of PHP without changing the environment variables

I have multiples projects, some of them work with PHP 5.6 and other with PHP 7.1. To work with both projects simultaneously I have to change environment variables each time when I have to run Composer.
Is there a way to run composer command and tell to use the version of PHP I want? Like:
composer install -php=5.6
You can use platform setting in your composer.json config to fake PHP version used for dependency resolving and checks:
"config": {
"platform": {
"php": "7.1.18"
}
},
In this way you can set different PHP version for each project locally without modifying any global variable.
Composer is a PHP script so you can run it's PHAR as argument for php binary, for e.g. if you have php 5.6 in ~/bin/php56 you have to run ~/bin/php56 /path/to/composer.phar install

Composer can check MariaDB installation?

It is possibile to create a composer configuration that aims to check that mariadb is present/installed in the current machine?
i would do this by using composer scripts
A script, in Composer's terms, can either be a PHP callback (defined as a static method) or any command-line executable command. Scripts are useful for executing a package's custom code or package-specific commands during the Composer execution process.
Source: https://getcomposer.org/doc/articles/scripts.md#what-is-a-script-
according to the docs :
lib-<name> allows constraints to be made on versions of libraries used
by PHP. The following are available: curl, iconv, icu, libxml,
openssl, pcre, uuid, xsl.
so you can check against maraiDB using :
"require": {
....
"libmariadb2": "*",
....
}
this should throw an error like :
Problem 1
- The requested package libmariadb2 could not be found in any version, there may be a typo in the package name.
Note: the above requirement will only check against mariaDB lib , not the php extension, to add or only check against php extension use :
"require": {
....
"ext-pdo": "*"
OR
"ext-mysqli": "*"
....
}

Namespacing issue? or something else?

I am trying to implement the Graphaware\neo4j client in php
neo4j-php-client
I ran composer to download the files to the working directory .www
and tried initiating the client using
require_once(BASEPATH.'vendor/autoload.php');
use GraphAware\Neo4j\Client\ClientBuilder;
$client = ClientBuilder::create()->addConnection('default', 'http://neo4j:myPassword#localhost:7474')->build();
I get this error.
<b>Fatal error</b>: Class 'GraphAware\Neo4j\Client\ClientBuilder' not found in <b>*path_to_my_www_dir\index.php*</b> on line <b>36</b><br />
Why am i seeing this?
I'm the maintainer of GraphAware Neo4j Client.
My bet is that you have been disturbed when reading the README of the repository.
The current master branch contains the code for 4.0#alpha, so if you ran in the command line composer require graphaware/neo4j-php-client chances are high that composer installed the last stable version in the 3.X series and thus the required class doesn't exist there.
I would suggest you try to install the alpha7 version of the client by running :
composer require graphaware/neo4j-php-client:^4.0#alpha
Let me know if you have other issues
We ran into the issue with neo4j-php-client not supporting PHP 5.5 as well. While the "correct" solution is to upgrade to a newer version of PHP, it isn't exactly the most convenient--especially if you just want to start evaluating this library. The only reason that PHP >= 5.6 is required is for Neo4j's bolt protocol, so as long as you stick to using the http protocol instead everything will work fine. In order to get composer to play nice though, you have to make a few changes to neo4j-php-client's composer.json:
Change "php": ">= 5.6" to "php": ">= 5.5"
Replace "graphaware/neo4j-bolt": "^1.5" with "graphaware/neo4j-common": "^3.0"
We ended up forking the library on Github and then updated our composer.json to use our modified version of neo4j-php-client. The relevant parts are:
{
...
"require": {
...
"graphaware/neo4j-php-client": "dev-OptionalBoltSupport"
},
...
"repositories": [
...
{
"type": "vcs",
"url": "https://github.com/wnielson/neo4j-php-client"
}
]
}
After doing this you can run composer update and neo4j-php-client should install fine.
You simply need to require vendor/autoload.php as said in documentation.
So require_once 'vendor/autoload.php'; will solve your problem.
The problem is that, even if you are using use ..., your php file didn't know anything about the php class file you're trying to create.
You need to include that file using include or require function.

Why do CodeIgniter projects sometimes include composer.phar package?

I'm new to Composer and in my current project I would like to install a bunch of PHP libraries like:
Doctrine
Security Library (Which i have no idea but looking for in CodeIgniter)
Bootstrap layout libraries and other when necessary
For that matter , I would like to use Composer based library management in my application,
and i get confused that if i have to include composer.phar on my project directory or not.
since i have it on my environment path and I can run Composer form command line .
How can integrate the above libraries into my codeigniter application then..
Appreciate your toughs!
The composer.phar file is an executable and it should not be committed. What it actually does is that it looks in your composer.json file and there you can declare some more dependencies (libraries for example) and their version:
{
"require": {
"doctrine/orm": "*"
}
}
The version in this case is declared with "*" so Composer will get the latest version. This is very useful if there are more people on the project, to make sure all of them have the same version of dependencies installed (so the composer.json file must be committed).
If you run "composer.phar update" on the other hand, this will get the latest version of all dependencies, no matter the version placed in composer.json and updates the lock file with the new versions.

Force composer to require PHP Version between Version X and Version Y

I have a mix of different PHP versions running on my servers (max 5.3.5) and development machines (max 5.5.9).
Now I ran into the problem that I did a "composer update" to get the latest Version of some external Bundles.
My composer.json looks like
"require": {
"php": ">=5.3.3",
.....
},
I get some Bundles that required PHP 5.5. There is no problem on my dev machines; the problem occurs on the server.
Is it possibile to tell Composer to require a PHP version between 5.3.3 and 5.3.5? Or a max available Version?
I tried
"require": {
"php": ">=5.3.3, <=5.3.5",
.....
},
and
"require": {
"php": "<=5.3.5",
.....
},
but both didn't work out. I get a "The requested package php could not be found in any version, there may be a typo in the package name." Error.
Any Ideas?
Since the config parameter in composer.json is available. You could something like this:
{
"name": ".../...",
"config": {
"platform": {
"php": "5.3.5"
}
},
"require": {
...
}
}
https://getcomposer.org/doc/06-config.md#platform
I find it questionable to say the least that you are developing with the newest PHP available and are running production with a very outdated version. There will be plenty of possible problems arising from this, not only because of security patches that you would be missing, but more importantly because of PHP bug fixes that got introduced mostly in versions 5.3.9 and 5.3.23 that changes PHP behavior in some details pretty fundamentally. Not talking about the risk of accidentally using features of 5.4 or 5.5.
And there really is no way to make Composer deal with this situation. The PHP version that is used when running composer update determines the resolution of dependencies, being influenced by PHP version and installed PHP extensions.
You cannot define that a package should only be used for PHP versions between 5.3.3 and 5.3.5 if the PHP you are using for the update is not matching this version requirement. Because the used PHP version exceeds the upper version constraint, such a package is not eligible for fulfilling the version requirement, and Composer reports that no package has been found (not telling that it has seen the packages, but they had to be ignored because of the version constraint).
There are probably three obvious ways out:
Downgrade your development environment to the production version you are really using. If more than one is used: The oldest one. That way any requirements for PHP versions will be matched. Run composer update then, and you are done.
Upgrade your production environment. Needs no further explanation, but I have to mention that not only are you missing a lot of very nice PHP features, you are also missing a substantial performance increase, because PHP 5.5 is really that much faster than 5.3.
Add a "platform.php" configuration to either the global or project's composer.json. This will tell Composer to override the PHP version running Composer itself, and instead calculate the dependencies with that different PHP version. composer config -g platform.php 5.3.5 for global setting (will affect all further Composer runs), without -g for local setting (will only affect Composer operations in that project, in case you develop on more than one project with different production versions of PHP).
Remove your composer.lock and vendor directory.
Now place platform option to composer.json
"config": {
"platform": {
"php": "7.0"
}
},
and finally, run command composer install
Try this (remove comma):
"require": {
"php": ">=5.3.3 <=5.3.5",
.....
},
What about trying the tilde operator
Tilde Operator ~1.2 Very useful for projects that follow semantic versioning. ~1.2 is
equivalent to >=1.2,<2.0. For more details, read the next section
below.
Next Significant Release (Tilde Operator)#
The ~ operator is best explained by example:
~1.2 is equivalent to
=1.2,<2.0, while
~1.2.3 is equivalent
to >=1.2.3,<1.3. As you can see it is mostly useful for projects respecting semantic versioning. A common
usage would be to mark the minimum minor version you depend on, like ~1.2 (which allows anything up to, but not
including, 2.0). Since in theory there should be no backwards compatibility breaks until 2.0, that works well. Another way of looking at it is that using ~ specifies a minimum version, but allows the last digit specified to go up.
Note: Though 2.0-beta.1 is strictly before
2.0, a version constraint like
~1.2 would not install it. As
said above ~1.2 only means the
.2 can change but the
1. part is fixed.
Note: The ~ operator has an exception on its behavior for the major release number. This means for
example that ~1 is the same as
~1.0 as it will not allow the major number to increase trying to keep
backwards compatibility.
Is there any possibility to tell composer to require a PHP version
between 5.3.3 and 5.3.5?
Yes, there it is one:
Hyphenated Version Range ( - )
Inclusive set of versions. Partial
versions on the right include are completed with a wildcard. For
example 1.0 - 2.0 is equivalent to >=1.0.0 <2.1 as the 2.0 becomes
2.0.*. On the other hand 1.0.0 - 2.1.0 is equivalent to >=1.0.0 <=2.1.0.
Example: 1.0 - 2.0
https://getcomposer.org/doc/articles/versions.md#hyphenated-version-range-
or you may use composer.json like this:
{
"require": {
"guzzlehttp/guzzle": ">=5.3.4 <6"
}
}
- I personally prefer this way because it's much easier to read and remember IMHO.

Categories