-
-
Save rhukster/f4c04f1bf59e0b74e335ee5d186a98e2 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# Creator: Phil Cook | |
# Modified: Andy Miller | |
# | |
# >>> IMPORTANT: Moved to: https://github.com/rhukster/sphp.sh | |
# >>> Kept here for legacy purposes | |
# | |
osx_major_version=$(sw_vers -productVersion | cut -d. -f1) | |
osx_minor_version=$(sw_vers -productVersion | cut -d. -f2) | |
osx_patch_version=$(sw_vers -productVersion | cut -d. -f3) | |
osx_patch_version=${osx_patch_version:-0} | |
osx_version=$((${osx_major_version} * 10000 + ${osx_minor_version} * 100 + ${osx_patch_version})) | |
homebrew_path=$(brew --prefix) | |
brew_prefix=$(brew --prefix | sed 's#/#\\\/#g') | |
brew_array=("5.6","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2") | |
php_array=("php@5.6" "php@7.0" "php@7.1" "php@7.2" "php@7.3" "php@7.4" "php@8.0" "php@8.1" "php@8.2") | |
php_installed_array=() | |
php_version="php@$1" | |
php_opt_path="$brew_prefix\/opt\/" | |
php5_module="php5_module" | |
apache_php5_lib_path="\/lib\/httpd\/modules\/libphp5.so" | |
php7_module="php7_module" | |
apache_php7_lib_path="\/lib\/httpd\/modules\/libphp7.so" | |
php8_module="php_module" | |
apache_php8_lib_path="\/lib\/httpd\/modules\/libphp.so" | |
native_osx_php_apache_module="LoadModule ${php5_module} libexec\/apache2\/libphp5.so" | |
if [ "${osx_version}" -ge "101300" ]; then | |
native_osx_php_apache_module="LoadModule ${php7_module} libexec\/apache2\/libphp7.so" | |
fi | |
# Has the user submitted a version required | |
if [[ -z "$1" ]]; then | |
echo "usage: sphp version [-s|-s=*] [-c=*]" | |
echo | |
echo " version one of:" ${brew_array[@]} | |
echo | |
exit | |
fi | |
php_module="$php5_module" | |
apache_php_lib_path="$apache_php5_lib_path" | |
simple_php_version=$(echo "$php_version" | sed 's/^php@//' | sed 's/\.//') | |
if [[ simple_php_version -ge 70 && simple_php_version -lt 80 ]]; then | |
php_module="$php7_module" | |
apache_php_lib_path="$apache_php7_lib_path" | |
elif [[ simple_php_version -ge 80 ]]; then | |
php_module="$php8_module" | |
apache_php_lib_path="$apache_php8_lib_path" | |
fi | |
apache_change=1 | |
apache_conf_path="$homebrew_path/etc/httpd/httpd.conf" | |
apache_php_mod_path="$php_opt_path$php_version$apache_php_lib_path" | |
# What versions of php are installed via brew | |
for i in ${php_array[*]}; do | |
version=$(echo "$i" | sed 's/^php@//') | |
if [[ -d "$homebrew_path/etc/php/$version" ]]; then | |
php_installed_array+=("$i") | |
fi | |
done | |
# Check that the requested version is supported | |
if [[ " ${php_array[*]} " == *"$php_version"* ]]; then | |
# Check that the requested version is installed | |
if [[ " ${php_installed_array[*]} " == *"$php_version"* ]]; then | |
# Switch Shell | |
echo "Switching to $php_version" | |
echo "Switching your shell" | |
for i in ${php_installed_array[@]}; do | |
brew unlink $i | |
done | |
brew link --force "$php_version" | |
# Switch apache | |
if [[ $apache_change -eq 1 ]]; then | |
echo "Switching your apache conf" | |
for j in ${php_installed_array[@]}; do | |
loop_php_module="$php5_module" | |
loop_apache_php_lib_path="$apache_php5_lib_path" | |
loop_php_version=$(echo "$j" | sed 's/^php@//' | sed 's/\.//') | |
if [[ loop_php_version -ge 70 && loop_php_version -lt 80 ]]; then | |
loop_php_module="$php7_module" | |
loop_apache_php_lib_path="$apache_php7_lib_path" | |
elif [[ loop_php_version -ge 80 ]]; then | |
loop_php_module="$php8_module" | |
loop_apache_php_lib_path="$apache_php8_lib_path" | |
fi | |
apache_module_string="LoadModule $loop_php_module $php_opt_path$j$loop_apache_php_lib_path" | |
comment_apache_module_string="#$apache_module_string" | |
# If apache module string within apache conf | |
if grep -q "$apache_module_string" "$apache_conf_path"; then | |
# If apache module string not commented out already | |
if ! grep -q "$comment_apache_module_string" "$apache_conf_path"; then | |
sed -i.bak "s/$apache_module_string/$comment_apache_module_string/g" $apache_conf_path | |
fi | |
# Else the string for the php module is not in the apache config then add it | |
else | |
sed -i.bak "/$native_osx_php_apache_module/a\\ | |
$comment_apache_module_string\\ | |
" $apache_conf_path | |
fi | |
done | |
sed -i.bak "s/\#LoadModule $php_module $apache_php_mod_path/LoadModule $php_module $apache_php_mod_path/g" $apache_conf_path | |
echo "Restarting apache" | |
brew services stop httpd | |
brew services start httpd | |
fi | |
echo "" | |
php -v | |
echo "" | |
echo "All done!" | |
else | |
echo "Sorry, but $php_version is not installed via brew. Install by running: brew install $php_version" | |
fi | |
else | |
echo "Unknown version of PHP. PHP Switcher can only handle arguments of:" ${brew_array[@]} | |
fi |
Work well, except when switching 7.x to 8.0: httpd.conf is well modified but php_info() stay at php 7.4. (it's ok for php cli).
Need to replace
#brew services stop httpd
#brew services start httpd
sudo apachectl stop
sleep 0.25
sudo apachectl start
Hi,
I don't use macOS, but I was tasked with setting up an environment for someone on one of the new Apple Silicon MacBooks. (don't know if relevant)
I found that PHP was installed in /opt/homebrew/etc/php
rather than /usr/local/etc/php
, causing the script to fail. Modifying the script at line 58 to edit the search path accordingly seems to be enough, however.
Hi,
I don't use macOS, but I was tasked with setting up an environment for someone on one of the new Apple Silicon MacBooks. (don't know if relevant)
I found that PHP was installed in
/opt/homebrew/etc/php
rather than/usr/local/etc/php
, causing the script to fail. Modifying the script at line 58 to edit the search path accordingly seems to be enough, however.
Super useful @Lombra ! I was just about to post this.
Also note that I had to update line 52, which is the Apache config path to /opt/homebrew/etc/httpd/httpd.conf
otherwise the switch doesn't update and reload Apache.
I really want to update this with automatic support for both intel + m1 paths. Not had a chance to look at this yet.
Awesome script! ❤️
I have created a lightweight version for those who use PHP-FPM as Brew service instead of mod_php
in Apache. 🧑💻
Besides the fact FPM is preferred according to Apache Wiki, the major advantage of such approach is you don't have to restart Apache, nor modify its config files. You simply setup your PHP-FPM instances with the same basic configuration (meaning on the same port) and only choose which one should be running to handle PHP for Apache.
It also, of course, links correct Brew binaries.
Feel free to use it from here. 🚀
Work well, except when switching 7.x to 8.0: httpd.conf is well modified but php_info() stay at php 7.4. (it's ok for php cli).
Need to replace#brew services stop httpd #brew services start httpd sudo apachectl stop sleep 0.25 sudo apachectl start
Yes same for me
It might be better not to restrict the PHP version, and instead use Homebrew error codes to detect when a version isn't available. With the shivammathur/php
tap, at the time of writing this comment, there's php@8.1
and php@8.2
. And PHP is on a relatively fast release cycle with 8.1 planned to be released later this year (2021), and 8.2 planned for 2022.
Aside, just to point out the competition, there's this package available in the homebrew/core tap: brew-php-switcher
(lol, which is by Phil Cook 😁).
Work well, except when switching 7.x to 8.0: httpd.conf is well modified but php_info() stay at php 7.4. (it's ok for php cli).
Need to replace#brew services stop httpd #brew services start httpd sudo apachectl stop sleep 0.25 sudo apachectl start
Yes same for me
Same here i get really random results and i have to restart apache few times.. Anyone have any insights why is this happening, never happened before i migrate to m1?
In my case, it was the use of sudo when restarting HTTPD in SPHP. The OS boots HTTPD without sudo but then when using SPHP, sudo triggers a second instance. You can verify by executing:
brew services list
sudo brew services list
is switching to php8.1 available?
@adrian-kumu replace lines 12+13 from:
brew_array=("5.6","7.0","7.1","7.2","7.3","7.4","8.0")
php_array=("php@5.6" "php@7.0" "php@7.1" "php@7.2" "php@7.3" "php@7.4" "php@8.0")
TO:
brew_array=("5.6","7.0","7.1","7.2","7.3","7.4","8.0","8.1")
php_array=("php@5.6" "php@7.0" "php@7.1" "php@7.2" "php@7.3" "php@7.4" "php@8.0" "php@8.1")
Now the switch script is properly switching to php8.1
Updated for 8.1.
Not working for me on a freshly new install macos monterey, using a intel proc.
I installed php with brew install shivammathur/php/php@7.4
and when i use sphp i have the following error message :
Sorry, but php@7.3 is not installed via brew. Install by running: brew install php@7.3
@lchabrand, do you have PHP 7.3 installed because that's what it's complaining about. Also, checkout brew install brew-php-switcher
, however I'm not sure how up-to-date it is. It works with PHP 8.1.
$ brew info brew-php-switcher
brew-php-switcher: stable 2.4 (bottled), HEAD
Switch Apache / Valet / CLI configs between PHP versions
https://github.com/philcook/php-switcher
I run nginx rather than apache, and always prefer FPM, so this approach doesn't work generically enough to support that kind of config. As a result, I much prefer @rozsival's approach, and so i just posted a fork of his script that supports PHP 8.1 and drops old versions that are no longer supported.
Note that it's also possible to set up a redirect on the macOS firewall so that you don't have to run nginx/apache on a privileged port, and you can then have it run on its default port 8080, and the firewall forwards traffic from port 80. This is much more robust that reconfiguring the web server every time.
@lchabrand wrote:
Not working for me on a freshly new install macos monterey, using a intel proc. I installed php with
brew install shivammathur/php/php@7.4
and when i use sphp i have the following error message :Sorry, but php@7.3 is not installed via brew. Install by running: brew install php@7.3
I had the same problem. I changed line 58 to:
if [[ -d "$homebrew_path/opt/php@$version" ]]; then
But then had other problems with the php path. Realized it was because I originally installed php using the built in apache, then used brew to install apache AFTER I installed php, so I uninstalled my php files, example:
brew uninstall shivammathur/php/php@7.4
and then reinstalled them:
brew install shivammathur/php/php@7.4
then switched line 58 back to:
if [[ -d "$homebrew_path/etc/php/$version" ]]; then
I only installed the versions of php that I needed, so I found it helpful to list the php brew versions installed if I try to switch to one that isn't:
after line 119, which currently reads:
echo "Sorry, but $php_version is not installed via brew. Install by running: brew install $php_version."
I added a list of brew installed versions by removing the quote at the end of line 119 and adding a line afterwards to get a list of installed versions, so line 119 & 120 now read:
echo "Sorry, but $php_version is not installed via brew. Install by running: brew install $php_version.
Brew installed versions: " ${php_installed_array[@]}
It's that time of year again. Now that Homebrew has php 8.2 available the script needs a slight update to include 8.2.
The arrays near the top of the script brew_array
and php_array
can be updated as seen below.
## TODO: Update 'brew_array' and 'php_array' when new version of php are released
brew_array=("5.6","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2")
php_array=("php@5.6" "php@7.0" "php@7.1" "php@7.2" "php@7.3" "php@7.4" "php@8.0" "php@8.1" "php@8.2")
Note: If you don't have 8.1 installed you'll see an error Error: No such keg: /usr/local/Cellar/php@8.1
. Not that it's a big deal, but if it bothers you, then you can run brew install php@8.1
or remove it from the above arrays.
For an Update for the PHP version to 8.2.. change those lines(12 and 13) to the ones below
brew_array=("5.6","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2")
php_array=("php@5.6" "php@7.0" "php@7.1" "php@7.2" "php@7.3" "php@7.4" "php@8.0" "php@8.1" "php@8.2")
I'm using GNU grep as default instead of MacOS's version of it, and since it was upgraded to 3.8, sphp started throwing warnings (8 per installed php version):
grep: warning: stray \ before /
I understand that the backslash is required as the regex is also used for sed, so I'm not quite sure how best to fix this. As a workaround I've modified sphp to call /usr/bin/grep
.
@dregad, in addition to that change, I would remove the unnecessary escapes in the variable values altogether, and then do localized replacements for the sed
calls by using something like ${apache_php_mod_path//\//\\\/}
(the general form is ${VAR//PATTERN/REPLACE}
).
Using the full path for every non-built-in command creates predictability in the script and reduces inconsistencies between user machines.
To help with consistency and to reduce maintenance, small wrapper functions can be written inside the script for each non-built-in. For example:
grep() {
/usr/bin/grep "$@"
}
Then grep
can be used without a path or backslash prefix in the rest of the script.
I would also run the script through ShellCheck and shfmt.
If anyone wants to rewrite the script and optimize it, I will gladly test it!
@rhukster thanks for considering this as a permanent change to sphp script.
Since Gists do not allow pull requests, how would you like to receive contributions ? Is a simple comment here with a patch OK, or would you prefer to get the changes from a fork of the Gist ?
I might just move this to a full repo. Overkill for one file generally but in these situations PRs and issues would be helpful.
Let me do that today.
@rhukster just wondering if you ever got around to creating a repo for this script to allow contributions via pull requests. If so, a link would be nice as I didn't find it.
Dang forgot all about it.. going to create that repo now.
@rhukster just wondering if you ever got around to creating a repo for this script to allow contributions via pull requests. If so, a link would be nice as I didn't find it.
Here it is: https://github.com/rhukster/sphp.sh
Thanks @rhukster. FYI you forgot to update a link in your blog article, PHP Switcher Script
in the paragraph after the subtitle still points to Gist.
cheers, will update that too.
For PHP8 its not working for me because instead of
php8_module
now its justphp_module
.