After three years at the day job I’ve been granted access to a physical escape key. I prefer a “build everything back by hand” approach to setting up a new laptop, and this includes pulling over two locally run PHP applications I use to automate my job. One’s a WordPress P2 instance I use to log my daily work, the other is a bespoke Laravel application I built to automate common drudgery during our two week “answer the questions support engineers can’t” rotations.
This is the first new laptop I’ve setup where I decided to go “full
homebrew” for PHP. In the past I used the liip project and it’s predecessor for PHP, and I installed a MySQL server directly from the MySQL project. I have a bias towards sticking with the projects that got me here — but
homebrew finally won me over with its support for multiple versions of PHP and an easier experience deploying PHP-FPM via
Still — setting everything up turned into the dance of 1,000 paper cuts that modern PHP’s become.
PHP, MySQL, and Homebrew Paper Cuts
First, I forgot
homebrew‘s apache server is configured for port
8080 by default, and I had to do the “which PHP-FPM FastCGI
VirtualHost configuration will I use” dance (Servers for Hackers has the configuration I chose). I also had a brief fear and loathing moment where it seemed like apache’s proxy module was linked incorrectly but I’d enabled
mod_proxy_fcgi.so without enabling
mod_proxy.so and the result was missing symbols. I also did my usual 24 minutes of head scratching until I remembered “oh, right, all the directories above an apache root directory need to be executable”.
homebrew to install MySQL seems to have brought MySQL 8 to my system. When I moved my databases over I forgot that
--all-databases command includes systems tables, and importing them into a clean install on MySQL 8 wrecked things pretty good. Once I cleaned that up (by running
brew uninstall mysql, and then deleting data in
/usr/local/var/mysql) I got to play the MySQL legacy password game and update my accounts to use the old password system (PHP can’t seem to connect using anything else). Also, the venerable Sequel Pro is having all sorts of issues (timeouts, crashing) when it’s talking to this MySQL 8 instance. I’m living with the
mysql command line interface for now — but if I was doing PHP full time I’d be unsure whether to see if
homebrew can run MySQL 5.6 or some version of percona, chase down the SequelPro bugs, install MySQL workbench, or chase down a new MySQL GUI application.
WordPress P2 Paper Cuts
Leaving MySQL behind — when I installed my P2 instance, the PHP 7.4 I’d installed via
homebrew immediately started warning me about a bad regular expression. I’m apparently using the P2 classic theme which hasn’t had an update in few years. Some googling around showed me that there’s a new project named O2 and that Automattic’s commercial arm is selling hosted P2. I thought really hard about abandoning this for a text file — but in for a penny, in for a pound.
I started poking at the bad regular expression in P2
var $mentions_regex = '/\B@([\w-\.]+)\b/';
It looks like the intent of this regular expression is to match three distinct character classes
\w - \.
But in PHP 7.4 I was getting a warning about an invalid range
Warning: preg_match(): Compilation failed: invalid range in character class at offset 7
Which meant that something thought I wanted the range of characters between
\.. So was this a change in the regular expression engine? Better validation in the regular expression engine? Validation that PHP itself was doing before passing something into the regular expression engine? I didn’t have time to go on that particular snipe hunt so I changed the regular expression to be
\w\.- and hoped it was right — I wasn’t too worried since is a personal log for my eyes only.
But then PHP 7.4 seemed to be caching the warning. Was it the WordPress cache? Some sort of PHP object cache like APC? Or was it the new PHP 7.4 preloading? Smelling another snipe hunt, I installed PHP 7.3 via
$ brew install email@example.com
and used it instead. The same regular expression error was there, but this time the caching behavior I’d seen was gone and I could fix the regular expression.
Laravel Application Paper Cuts
Then I moved on to my Laravel application — I pulled it out of source control and was getting weird cipher related errors —
production.ERROR: RuntimeException: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths. in /path/to/app/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php:43
but I’d forgotten the
.env file (where the cipher key is configured) wasn’t stored in source control. Annoying, but that’s the system sort of working.
More confounding was every SQL query failing with
local.ERROR: PDOException: SQLSTATE: Syntax error or access violation: 1231 Variable ‘sql_mode’ can’t be set to the value of ‘NO_AUTO_CREATE_USER’ in /path/to/app/vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php:150
My first naive thought was more MySQL 8 paper cuts — but after some digging and research into what
sql_mode was, and remembering my WordPress install could query fine (although WordPress doesn’t use PDO and Laravel does, was that related? sigh) — I finally realized that Laravel itself is setting
sql_mode, and that
NO_AUTO_CREATE_USER isn’t a valid value in MySQL 8. Laravel’s fixed this more recently. Once again citing “I don’t have time for this” I patched my local application and moved on.