DEV Community

yuki777
yuki777

Posted on

8

Install multiple PHP versions and automatically switch versions for each directory

Description

  • Translated from Qiita
  • I want to use multiple versions of PHP
  • I want to automatically switch between different versions of PHP for each directory
  • I don't want to do php builds because they are too difficult
  • I want to support Mac and Ubuntu

Install brew

  • Install Brew
  • I thought brew was for macs only, but it can be installed on ubuntu too!

Install php

  • Install php
  • Additional packages can be installed as needed, such as imagemagick
  • In this article, *PHP is installed with brew. *
brew update
brew tap shivammathur/php
brew install php@8.1
brew install php@8.0
brew install php@7.4
brew install pkg-config
brew install imagemagick
Enter fullscreen mode Exit fullscreen mode

Install phpenv

  • Install phpenv
  • phpenv is used to switch between PHP versions using phpenv global, phpenv local, etc.
  • In this article, phpenv does not install PHP.
# Install phpenv
curl -L https://raw.githubusercontent.com/phpenv/phpenv-installer/master/bin/phpenv-installer | bash

# Setup phpenv
$(cat << 'EOF' >> ~/.zshrc
# phpenv
export PHPENV_ROOT="$HOME/.phpenv"
if [ -d "${PHPENV_ROOT}" ]; then
  export PATH="${PHPENV_ROOT}/bin:${PATH}"
  eval "$(phpenv init -)"
fi
EOF
)

# restart shell
exec $SHELL -l
Enter fullscreen mode Exit fullscreen mode

Link each version of php installed by brew to ~/.phpenv/versions

  • You need to link the php installed by brew so that phpenv can manage them. Manual work is tedious, so I wrote a script.
curl -fsSL https://gist.githubusercontent.com/yuki777/6244823b8aa8cf4457e97e6407ada5ad/raw/e988f8a1c112e4063768664104ba14d799e63782/link-phps.bash | bash
Enter fullscreen mode Exit fullscreen mode

Source

#!/usr/bin/env bash

set -au

## Check cellar dir
cellarDir=$(brew --prefix)/Cellar
if [ ! -d "$cellarDir" ]; then
  echo "Not found. brew package path $cellarDir :("
  echo
  exit 1
fi

parentDirs=$(find $cellarDir/php* -type d -maxdepth 0)
echo "# Link the php installed by Brew to ~/.phpenv/versions"
for parentDir in $parentDirs
do
  childDirs=$(find "$parentDir"/* -type d -maxdepth 0)
  for childDir in $childDirs
  do
    phpPath=$childDir/bin/php
    if [ ! -f "$phpPath" ]; then
      continue
    fi
    major=$($phpPath -r 'echo PHP_MAJOR_VERSION;')
    minor=$($phpPath -r 'echo PHP_MINOR_VERSION;')
    patch=$($phpPath -r 'echo PHP_RELEASE_VERSION;')

    # unlink
    rm -f "$HOME"/.phpenv/versions/"$major"."$minor"
    rm -f "$HOME"/.phpenv/versions/"$major"."$minor"."$patch"

    # link
    linkCommand="ln -s $childDir $HOME/.phpenv/versions/$major.$minor"
    echo "$linkCommand"
    $linkCommand
    linkCommand="ln -s $childDir $HOME/.phpenv/versions/$major.$minor.$patch"
    echo "$linkCommand"
    $linkCommand
  done
done
Enter fullscreen mode Exit fullscreen mode

Tests

  • Test that running php -v in global will use php 8.1
  • Test that php 7.4 is automatically switched to php 7.4 when you move to the /tmp/php7.4
cd /tmp && mkdir php74 php80 php81

# set version
cd /tmp         && phpenv global 8.1 # set 8.1 as a global
cd /tmp/php74   && phpenv local  7.4 # pin 7.4 in this dir
cd /tmp/php80   && phpenv local  8.0 # pin 8.0 in this dir
cd /tmp/php81   && phpenv local  8.1 # pin 8.1 in this dir

# test version
cd /tmp         && php -v # => 8.1
cd /tmp/php74   && php -v # => 7.4
cd /tmp/php80   && php -v # => 8.0
cd /tmp/php81   && php -v # => 8.1
Enter fullscreen mode Exit fullscreen mode

Notes on brew upgrade

  • When php is upgraded by brew upgrade, symlink will be broken, so you need to re-run the link.
curl -fsSL https://gist.githubusercontent.com/yuki777/6244823b8aa8cf4457e97e6407ada5ad/raw/e988f8a1c112e4063768664104ba14d799e63782/link-phps.bash | bash
Enter fullscreen mode Exit fullscreen mode

Summary

  • Want to use multiple versions of PHP => with phpenv.
  • Want to automatically switch between different versions of php for each directory => with phpenv.
  • Don't want to waste time with php builds => install php with brew.
  • I want to support Mac and Ubuntu => with brew and my own scripts.
  • Special thanks, uzulla-san's slide

and others

  • About pecl installation
  • This article is written assuming a clean installation, but there are cases where php, direnv, brew-php-switcher, etc. have already been installed.
  • About specifying php version in vscode and phpstorm
  • I will write more if there is demand for it.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up