Use different PHP version CLI executable for one command
Asked Answered
B

10

40

So I have Gentoo box with three PHP versions installed (nevermind the reasons):

  1. /usr/bin/php -> /usr/lib64/php5.4/bin/php
  2. /usr/bin/php5.5 -> /usr/lib64/php5.5/bin/php
  3. /usr/bin/php5.6 -> /usr/lib64/php5.4/bin/php

I want to install Laravel framework using composer:

$ composer create-project laravel/laravel --prefer-dist

This however throws an error because Laravel requires PHP > 5.5.9 and the default php interpreter is 5.4. So I issue another command:

$ /usr/bin/php5.6 /usr/bin/composer create-project laravel/laravel --prefer-dist

This takes me one step further, but then some post-install commands from Laravel's composer.json comes into play, and installation crashes.

This is due to the fact, that composer.json commands look like this:

"post-install-cmd": [
    "php artisan clear-compiled",
    "php artisan optimize"
],

As you can see, the "default" interpreter is used again!

Now, proper PHP files start with following shebang:

#!/usr/bin/env php

This is nice feature as PHP interpreter can be found under different locations on different systems. Unfortunatelly, in this case env command returns path to the first executable it finds in $PATH environmental variable.

How could I possibly alter current session environment or what kind of trick to perform so for the execution of whole Laravel installation process php command would invoke /usr/bin/php5.6 instead of /usr/bin/php?

I don't want to change $PATH variable or modify files like composer, composer.json or Laravel's CLI utility artisan.


Edit: also assume that I want to do this from regular user account (i.e. with no root permissions).

Bronez answered 3/7, 2015 at 12:27 Comment(4)
How about creating a temporary symlink and restoring it later? Also look at GNU stowRavenous
You'll have to craft a custom wrapper script, which honors an exported PHP_BIN environment variable for example, or defaults to /usr/bin/php else. (See also In Bash, when to alias, when to script, and when to write a function?) -- Also, once you have more than three versions installed, you're officially a hoarder.Decreasing
About alias: sadly this does not work. Perhaps because alias does not work when php is invoked by composer or by /usr/bin/env.Bronez
Perfect answer. Thanks.Outwear
C
46

Maybe you can try to fix the environnement!

$ php -v
PHP 5.4.x (cli) ...
$ set PATH="/usr/lib64/php5.6/bin:$PATH"
$ php -v
PHP 5.6.x (cli) ...

Or, if you don't want to modify the PATH for your shell session, you can scope the change for the current command only:

$ php -v
PHP 5.4.x (cli) ...
$ env PATH="/usr/lib64/php5.6/bin:$PATH" php -v
PHP 5.6.x (cli) ...
$ php -v
PHP 5.4.x (cli) ...
Craal answered 5/8, 2015 at 17:27 Comment(6)
That is it! I have entered: PATH="/usr/lib64/php5.6/bin:$PATH" php /usr/bin/composer create-project laravel/laravel --prefer-dist and installation completed successfully! Setting PATH in one line with command does not change global PATH variable. Thanks a lot Guillaume Crico!Bronez
Using Mac nothing changes with either method, where do you unset the path to the default php?Charbonneau
This is not working for me: env PATH="/opt/php71/bin/php:$PATH" php -v keeps telling php 5.xMai
Also tried this variant: PATH="/opt/php71/bin/php:$PATH" sh -c 'php -v' and it's the same. At least I can see the PATH is being modified if I run PATH="/opt/php71/bin/php:$PATH" sh -c 'echo $PATH | grep php' but even having php 7 in the PATH the following php -v command still executes php 5.Mai
The first one, using 'set PATH' does not work for me on Debian. It does not change to 5.6.x. It is permanently 5.4.x.Alberto
same for me,tooCondiment
I
46

Default PHP executable can be found using:

$ which php

In most cases it is link to particular PHP version:

lrwxrwxrwx 1 root root      21 aug 15  2016 /usr/bin/php -> /usr/bin/php7.1

To change it to different version just relink it to another

$ sudo rm /usr/bin/php

$ sudo ln -s /usr/bin/php5.6 /usr/bin/php

Before relink you have to make sure target PHP version is installed.

Inconsequent answered 24/4, 2017 at 10:52 Comment(4)
can't believe that this one really helped me! thanks!Minnaminnaminnie
@Inconsequent Bro,Thanks+++Roots
Thank you! Needed to search a lot to find this useful answer.Errecart
You could use sudo mv -n /usr/bin/php /usr/bin/php.old in order to preserve a copy of the old version.Nippers
M
14

Identify where the current generic php command is and to which binary it points to with which php.

It will give you a path to a symlink like you mention in your question

/usr/bin/php -> /usr/lib64/php5.4/bin/php

Edit the symlink to point to which ever php version you want for now, see here https://unix.stackexchange.com/questions/88824/how-can-i-edit-symlinks

When you are done just reverse the process.

UPDATE: you can also add an alias for the current user by editing ~/.bashrc and adding the following

alias php='/usr/bin/php5.6'

see if this works out

Mitchelmitchell answered 3/7, 2015 at 12:52 Comment(4)
This answer and a comment from Arkadiusz Drabczyk would be valid, but I forgot to mention, that I can't modify system symlinks (/usr/bin/*) as whole operation is to be done from common user account (no root).Bronez
updated answer, although i see @Decreasing already hinted towards aliasMitchelmitchell
Thanks, I have answered about alias in the comment to my question.Bronez
I came from Google so I think it worth to say this has been the best solution for me. I tried the @Guillaume 's solution which is really usefull, but at least in my case, after the composer update the system was trying to do a php artisan optimize (using the wrong php version again). So I created an alias just for the current user and it worked like a charm. Please note you have to log out and log in, otherwise the alias does not take effect. Thanks Alex!Glissade
S
10

Since PHP7 came around Debian Linux creates different executables for PHP versions 5 and 7 in /usr/bin by default (if you install both versions that is).

Calling those different versions from the command line is as simple as ever now:

kkarski@debian:~ $ php5 -v
PHP 5.6.26-0+deb8u1 (cli) (built: Sep 21 2016 12:37:50) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies


kkarski@debian:~ $ php -v
PHP 7.0.9-1~dotdeb+8.1 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.9-1~dotdeb+8.1, Copyright (c) 1999-2016, by Zend Technologies

This is obviously only good for simple scripts. For anything larger (composer, artisan etc.) you'll have to change the PATH variable.

To change the version your Apache server is using all you have to do is:

root@debian:~# a2dismod php5 && a2enmod php7.0
Module php5 disabled.
To activate the new configuration, you need to run:
  service apache2 restart
Considering conflict php5 for php7.0:
Enabling module php7.0.
To activate the new configuration, you need to run:
  service apache2 restart

and vice versa if you want to use the lower PHP version.

Mentioning it in case someone has similar problems on Debian.

Splint answered 17/10, 2016 at 12:15 Comment(1)
I was struggling with changing the version entirely... But your solution saved my day... +1 from me.. Thanks a tonne...Cinda
I
3

I find the easiest to achieve the same like just create a softlink like for example

ln -s /opt/php-7.0.32/bin/php /usr/bin/php7

ln -s /opt/php-7.1/bin/php /usr/bin/php71

ln -s /opt/php-5.6/bin/php /usr/bin/php56

then as you use your default version say it is php7.2 as just php for alternative version you can you php7 or php71 or php56

here ln -s /opt/php-7.1/bin/php /usr/bin/php71 is the source/orginal file and /usr/bin/php7 is the destination / link

Ironsmith answered 22/2, 2019 at 17:47 Comment(0)
K
2

On Ubuntu, you don't have to make any changes to the filesystem, you can just execute:

$ php{version} {script}

and substitute the version for what you have installed. For example:

php7.4 script.php
php8.2 script.php

To see which PHP versions are installed, just do ls /usr/bin/php*.

Kurland answered 3/5, 2023 at 22:38 Comment(0)
M
1

For anyone else who found no solution in the above, because they use composer update and somehow the wrong PHP version gets used. By using composer self-update I got some more info and eventually found out that in the composer.json you can specify a platform in the config section, which overrides what php version is used by composer. Simply changing this value or removing this config solved my issue.

composer.json "config": { "platform": { "php": "7.1" },

Melissa answered 11/6, 2018 at 8:53 Comment(2)
There's a bracket missing. Only you can edit it, as it's less than 6 chars change. "config": { "platform": { "php": "7.1" } },Tinishatinker
ok, after doing this, entering /usr/bin/env php -v still gives me php 5.4.16Tinishatinker
A
1

It's possible to do using alias, but keep in mind that aliases are not expanded by default.

You must also enable expanding of those.

$ shopt -s expand_aliases
$ alias php="/usr/local/bin/php-5.6"
$ ./some-script.sh
$ unalias php # back to previous version
Arrio answered 3/12, 2018 at 19:47 Comment(0)
T
0

I worked on a "script + docker image" to make multiple php versions available whenever I want during development: https://github.com/jclaveau/docker-php-multiversion

You can use it this way:

$ php 5.6 -v
PHP 5.6.40-15+ubuntu18.04.1+deb.sury.org+1 (cli) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans

$ php 7.3 -v
PHP 7.3.13-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Dec 18 2019 14:48:49) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.13, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.13-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.9.0, Copyright (c) 2002-2019, by Derick Rethans

As it uses Docker.io, you do not need to alter any part of your system configuration.

Hoping it would help you

Toxicology answered 6/1, 2020 at 1:5 Comment(2)
If its using Docker then you DO need to alter system configuration. First you need to install Docker, then you need to ensure security is correctly setup since Docker is known to have tons of security vulnerabilities. And last but not least, script will run in docker instead of on the machine itself which might cause some things to not work correctly depending on what you are trying to execute (eg. it will see a random string instead of hostname, you won't be able to connect to any services on the host machine, etc.).Steinman
I did this project as an experiment and I now dropped it for a while for multiple reasons including the use of tools like Renovate or Dependabot. Btw, you not wrong at all but some of your points could be expected like not being able to connect to hosts servicesToxicology
R
0

I had this requirement for composer which required PHP to be a specific version on a multi-tenant system which would end up affecting other web applications. I could not update the symbolic link to PHP for the whole system, I needed to switch the PHP version for this specific execution only, so I ended up with the following.

php80 `which composer` install

Note: As long as you have different versions of PHP installed it would just work.

`which composer` - expands to the path of the composer binary, so you do not have to type the full path.
Reduce answered 1/3, 2023 at 13:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.