What, a technical post? It happens. Rarely. Usually, I’m focused on the tech that goes into a book, but sometimes the real world intervenes.
Like PHP. PHP is very much the real world. My site has been running PHP 7.4 for a while, which goes end of life on 28 November. I put this off as long as possible, but it’s time to update.
I run my e-bookstore on Woocommerce, which is built on WordPress, which is built on PHP. What started as a silly experiment has become the center of my business. I need to minimize downtime, which means I must check everything before upgrading. It’s PHP, which means it’s a maze of twisty little modules that all look alike. PHP has this annoying habit of adding, removing, splitting, and changing modules. Running PHP applications on FreeBSD is all about finding the module your application needs, so I want to identify all possible problems before changing.
First, let’s see what packages need upgrading.
# pkg info -x php
mod_php74-7.4.32_1
php74-7.4.32
php74-ctype-7.4.32
php74-curl-7.4.32
php74-dom-7.4.32
php74-exif-7.4.32
php74-fileinfo-7.4.32
php74-filter-7.4.32
php74-gd-7.4.32
php74-iconv-7.4.32
php74-intl-7.4.32
php74-json-7.4.32
php74-mbstring-7.4.32
php74-mysqli-7.4.32
php74-openssl-7.4.32
php74-pcntl-7.4.32
php74-pdo-7.4.32
php74-pdo_mysql-7.4.32
php74-pecl-imagick-im7-3.5.1_1
php74-phar-7.4.32
php74-posix-7.4.32
php74-session-7.4.32
php74-simplexml-7.4.32
php74-soap-7.4.32
php74-tokenizer-7.4.32
php74-xml-7.4.32
php74-xmlreader-7.4.32
php74-xmlrpc-7.4.32
php74-xmlwriter-7.4.32
php74-zip-7.4.32_1
php74-zlib-7.4.32
31 packages. Software like Tiny Tiny RSS and WordPress depend on PHP, but if the underlying PHP software has all the necessary libraries then they should just work. Should. But PHP modules sometimes disappear, get replaced, or get renamed. I want a list of all the modules I need before running any commands. So, what would the PHP 8.0 version of these packages be named? I have to iterate through sed a couple times to trim out excess version information and wind up with this.
# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g
mod_php80
php80
php80-ctype
php80-curl
php80-dom
php80-exif
php80-fileinfo
php80-filter
...
Those look sensible. Now check to see if the packages exist.
I could automate this by checking the exit code of each command, but the list is short enough that I can process it by hand. I run one package search at a time, letting xargs prompt me for each one so I can eyeball the results.
# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g | xargs -L1 -p pkg search
pkg search mod_php80?…y
mod_php80-8.0.25 PHP Scripting Language
pkg search php80?…y
This particular search will spew a couple hundred lines of output, but I’m confident the base PHP 8.0 package is in there.
...
php80-intl-8.0.25 The intl shared extension for php
pkg search php80-json?...y
pkg search php80-mbstring?...
Ooops! Pay attention here. There is no package for PHP 8.0’s JSON module! Make a note of that.
At the end, I have problems with three packages: php80-json, php80-openssl, and php80-xmlrpc. Freshports tells me that the JSON and OpenSSL modules were added into the default PHP 8.0 package, so I can cross those off my list.
The XML-RPC module is another tale. PHP 8.0 no longer has an XML module. Fortunately, that same bug lists a replacement pecl-xmlrpc. There’s a related php80-pecl-xmlrpc module.
I have a list of modules to install. For a last check, I’ll look for anything that depends on PHP 7.4.
# pkg info -dx php74
The list looks different, but contains the same modules. I’m as prepared as I can be.
One last check. Make a list of the packages to install. Eyeball it to make sure it looks right.
# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g > php8.pkg
Create a boot environment, and do a dry run. If I remove all packages with PHP in their name, what will get pulled? Using -n tells me what the command would do, but doesn’t actually change anything.
# bectl create 12.3-p7-lastbeforePHP
# pkg remove -nx php74
That list looks sensible. Now remove the packages, and install everything on our list.
# pkg remove -x php74
# cat php8.pkg | xargs -L1 -p pkg install -y
The -p argument to xargs prompts me for confirmation, so I can use -y on the pkg command. The install fails on the nonexistent JSON, OpenSSL, and XMLRPC modules, but that’s expected.
At the end, I manually install php80-pecl-xmlrpc.
Reboot.
Test, test, test. Run a test purchase. It works.
Everything looks okay? I guess I can turn it over to the Crowdsourced Monitoring System, aka “y’all,” and go make some paying words.