Project

General

Profile

Actions

Feature #21381

open

Feature #21380: Hosting migration

Upgrade to PHP 8.1.x as part of Reclaim migration

Added by Boone Gorges 20 days ago. Updated 10 days ago.

Status:
New
Priority name:
Normal
Assignee:
Category name:
Server
Target version:
Start date:
2024-11-01
Due date:
% Done:

0%

Estimated time:
Deployment actions:

Description

One takeaway from our initial meeting with Reclaim is that they cannot support our current version of PHP, which is 7.4.x. The minimum version their infrastructure can support is 8.1.x. This is not ideal; it would have been nice to move everything over without making this change at the same time. But it sounds like it won't be possible.

8.1.x is out of active support, but is in security support through 31 Dec 2025. https://www.php.net/supported-versions.php All things being equal, I'd like to upgrade to the lowest possible versions as part of this migration - fewer things to break. As such, my current thinking is that we aim for 8.1.x, and after the successful migration, immediately begin planning for an upgrade to the 8.3.x series. We can target this latter move for sometime during the first half of 2025.

I don't anticipate that a huge amount of work will be necessary for the upgrade. But we should do some brainstorming about what we can do in advance. Here are some rough initial thoughts:

1. Create a php-8.1 branch. Perhaps we will simply use Ray's branch from #18496
2. Update linting and PHPCS rules, along with GitHub Action config https://github.com/cuny-academic-commons/cac/blob/master/.github/workflows/lint-php.yml#L19, to run against PHP 8.1. Jeremy, I'll lean on you to do this, since you helped to set up the GitHub CI.
3. As soon as Reclaim is able, we get a test version of the Commons running in the production-environment-to-be. The team comes up with a list items to be tested manually in this new environment. This will include mission-critical parts of the Commons that are subject to breakage in new environments (email sending, media upload, object caching, etc). Then we delegate out the testing as needed to members of the team.
4. At some point - this could happen after the migration - we remove exceptions in our CI that are related to PHP 8-only code. See eg https://github.com/cuny-academic-commons/cac/blob/2.4.x/developer/lint-php/lint-php.sh. Similarly, we can upgrade plugins that are excluded from our upgrade scripts because of PHP compat. See eg https://github.com/cuny-academic-commons/wp-cli-cac/commit/8d76f4d426c0998d4707e02e3a1bf80c7453cc64

If anyone has ideas about other steps we can take to frontload or automate some of the testing, or to otherwise decrease the amount of stress and uncertainty related to this upgrade, I'd be happy to hear them :-D


Related issues

Related to CUNY Academic Commons - Bug #18496: PHP 8+ CompatibilityNew2023-07-21

Actions
Actions #1

Updated by Boone Gorges 20 days ago

  • Related to Bug #18496: PHP 8+ Compatibility added
Actions #2

Updated by Jeremy Felt 13 days ago

I've dug into this a bit and started making some big changes to our PHPCS configuration to try and highlight issues. I've added comments in the XML file to document the decision to exclude some rules from the ruleset.

My working branch at the moment is https://github.com/cuny-academic-commons/cac/tree/fix/php-compat-analysis

Some general conclusions:
  • There are a large number of constants and functions set to be removed in PHP 8.4. I added individual exclude rules for those so that we're aware. It's a large list that we can ignore for now, but is kind of eye-opening for the future.
  • create_function() is used enough that we should probably just add a polyfill.
  • get_magic_quotes_gpc() is also easy enough to add a return false polyfill.
  • There are a bunch of old INI directives that I don't think are consequential. No fatal error results in the ini_set() or ini_get() of these and nothing in code seemed to be critical.
  • Several things have had their behavior changed in PHP since 7.0, 7.1, or 7.2. I've excluded them because they would likely have reared their head already if they were impactful.

With all that said, a preliminary-ish report of seemingly major error frequency looks like this:

   1 PHPCompatibility.Classes.RemovedClasses.sqlitedatabaseRemoved
   1 PHPCompatibility.ControlStructures.ForbiddenBreakContinueOutsideLoop.FatalError
   1 PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundInStatic
   1 PHPCompatibility.FunctionUse.OptionalToRequiredFunctionParameters.mktime_hourHardRequired
   1 PHPCompatibility.FunctionUse.RemovedFunctions.eregDeprecatedRemoved
   1 PHPCompatibility.ParameterValues.RemovedMbStrrposEncodingThirdParam.Removed
   2 PHPCompatibility.FunctionUse.RemovedFunctions.eregiDeprecatedRemoved
   2 PHPCompatibility.Interfaces.InternalInterfaces.datetimeinterfaceFound
   2 PHPCompatibility.Operators.ChangedConcatOperatorPrecedence.Found
   2 PHPCompatibility.ParameterValues.RemovedPCREModifiers.Removed
   3 PHPCompatibility.Extensions.RemovedExtensions.eregDeprecatedRemoved
   3 PHPCompatibility.Variables.ForbiddenThisUseContexts.OutsideObjectContext
   4 PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
   4 PHPCompatibility.FunctionUse.OptionalToRequiredFunctionParameters.parse_str_resultHardRequired
   4 PHPCompatibility.FunctionUse.RemovedFunctions.mysql_get_server_infoDeprecatedRemoved
   4 PHPCompatibility.Operators.RemovedTernaryAssociativity.Removed
   9 PHPCompatibility.FunctionUse.RemovedFunctionParameters.define_case_insensitiveDeprecatedRemoved
  11 PHPCompatibility.Variables.ForbiddenThisUseContexts.Global
  14 PHPCompatibility.FunctionUse.RemovedFunctions.eachDeprecatedRemoved
  41 PHPCompatibility.ParameterValues.RemovedImplodeFlexibleParamOrder.Removed
A few highlights:
  • implode() and join() previously accepted the delimiter as the second argument.(!) There are 41 cases we need to remove or hotfix because they will fatal in PHP 8.x.
  • each() used to be a thing to iterate on an array? (TIL) I've already excluded a couple in which there was a fallback. We'll need to look at the remaining 14.
  • There are 14 places where $this is now used incorrectly that need to be fixed.
  • There are 9 define() statements with a 3rd parameter that needs to be removed.
  • And then a handful of other bits and bobs that I think get decreasingly worrisome, mostly because the number of instances drops quite a bit and a lot of code seems to be hidden in weird vendor libraries and things that may not be used or is hard to actually trigger in a real world scenario.

My guess from here is that we spin off a couple tickets for the above highlights. Fixing things like join() is a bit eye-numbing, but not necessarily difficult, so it seems like a good chunk of these can disappear pretty quickly.

I do think I'm on board with just updating to PHP 8.1 to start to avoid even more edge cases. The update to PHP 8.3 next year may not be so bad. There seems to have been a much bigger shift from 8.0 to 8.1 than from 8.1. to 8.3.

Okay, one more list! Here are the plugins/themes that have files that generated the current errors. If any of these stand out as those that could just be removed, that's obviously helpful. :)

plugins/LayerSlider
plugins/_fix-simplepie-errors
plugins/acf-views
plugins/amazon-link
plugins/better-search
plugins/chatbot
plugins/constant-contact-api
plugins/custom-database-applications-by-caspio
plugins/easy-appointments
plugins/elementor-pro
plugins/event-organiser
plugins/events-calendar-pro
plugins/events-manager
plugins/export-wp-page-to-static-html
plugins/extended-categories-widget
plugins/geo-mashup
plugins/google-calendar-events
plugins/jetpack-boost
plugins/js_composer
plugins/newsletters-lite
plugins/otter-blocks
plugins/peters-custom-anti-spam-image
plugins/q-and-a
plugins/simple-tags
plugins/simply-static
plugins/threewp-broadcast
plugins/tubepress
plugins/widget-entries
plugins/wp-live-preview-links
plugins/wp-o-matic
plugins/wp-rss-multi-importer
plugins/wptouch
plugins/wysija-newsletters
themes/Avada
themes/bp-nelo
themes/elemental
themes/nelo-for-tags
themes/onetone
themes/oxygen
themes/platform
themes/project-ar2
themes/teleplaza-cbox-theme

I'll update the linting script as well to see if it highlights anything different.

Actions #3

Updated by Boone Gorges 10 days ago

Jeremy, thanks so much for these initial findings.

Where it's easy to polyfill, let's do so. We're looking for easy wins here.

Here's where we keep track of plugins that are no longer available to be activated by Commons members: https://github.com/cuny-academic-commons/cac/blob/0dae44ae21267be15269350c8a76f057183cc809/wp-content/mu-plugins/cac-functions.php#L866 We also have tools on the production site like wp cac-network-info query that let us see who's using these plugins. In most cases we need to go ahead and fix the plugins in question no matter what, but in cases where the fixes are non-trivial, it will be helpful to see usage details based on the tools I've mentioned.

When handling hotfixes, it would be nice to take note of whether the plugin is actively maintained. Many of the plugins on your list probably are not actively maintained; see #20829 and related tickets. When a plugin has been abandoned, we can patch our version without much concern. In the (probably rare) case where an actively-updated plugin needs to be patched, it would be nice to send upstream patches, if it's not a huge amount of extra work.

Splitting off new tickets from this one, to fix families of related errors, seems like a good step.

Actions

Also available in: Atom PDF