Upgrading your site to PHP 8
As many of you have heard, PHP 7 became End of Life last month, on November 28th. You probably also heard that this is terrible news for the security of your site and / or that upgrading your site to PHP 8 is a dreary task. While neither affirmation is the absolute truth, there are always a few kernels of truth in every plausible lie. Let's see what the end of PHP 7's service life means for your site and what you can do about it in pragmatic, practical terms.
Table of contents
- What does End of Life mean for PHP?
- What are the caveats of upgrading PHP?
- But, I don't want to upgrade!
- Make a continuous PHP upgrade plan
- Upgrading your site
- It still looks hard to me
What does End of Life mean for PHP?
PHP uses a timed version release strategy, much like Joomla itself. A new version is released every year and gets two years of Active Support (bug fixes and security fixes), and one year of Security Support (security fixes only). Supported versions are listed on PHP's site along with a handy timeline which tells you when PHP enters each support phase — and when they become End of Life (EOL).
Using an EOL version of PHP doesn't make your site insecure right away. There is usually some time between a PHP version becoming EOL and a security issue being discovered for this PHP version. There is no way to tell how long that will be. Moreover, the Linux distribution your hosting company uses to power their servers will backport some of the security fixes to older, EOL versions of PHP. However, there is no way to tell which and when.
Essentially, using an EOL PHP version gives you security uncertainty. You cannot possibly know if your site is secure or not, or when and if it will receive a security fix for the EOL PHP version. As a result, the best approach for your decision-making is to consider any PHP EOL version as insecure, therefore in need of an upgrade as soon as possible.
Key take-away: Always plan to upgrade PHP on your site when your currently used version enters its Security Support phase. This gives you a year to do it. If you find yourself on an EOL version of PHP, act immediately.
What are the caveats of upgrading PHP?
PHP is a living language. It evolves over time. This is necessary, as the way we build software, and the context in which it is used, also change over time. As a result some features we were using in the past get deprecated and ultimately removed, breaking software still using it. New features get implemented which might break code not expecting them. This is why people may tell you that upgrading your site is hard — they are using outdated software which typically predates the PHP version they are trying to upgrade to.
Ultimately, the difficulty of upgrading PHP is a question of whether your software provider is willing to commit the time and effort to keep up with the times. As a provider of software commonly used to facilitate the PHP upgrade process I always support the latest and greatest PHP version before it's released. This is not normal and I cannot possibly hold other developers to the same standard. It's doable, for sure, but it's really hard and very time consuming. After all those years I can't claim I always get it right, especially with some PHP changes which are either very hard to locate in the code, or clash with Joomla's core code not being ready for them yet.
It is more reasonable and more likely for third party extension developers to start working on supporting a new PHP version once Joomla itself supports it fully, usually 1–2 months since the new PHP version's first release. Doing that work will take anywhere between one to four months, depending on the resources of the extension developer. This means that the latest and greatest PHP version only becomes practically usable for Joomla sites between 6 to 9 months after its original release. Since new versions of PHP are released around December every year, that would be between May and August of the next calendar year.
Key take-away: You should not try to upgrade to the latest and greatest PHP version; just the immediately previous version. Around August or September, depending on your vacation schedule, you should start planning and testing your migration to the next PHP version.
But, I don't want to upgrade!
That's certainly your choice, but consider the following points.
An EOL version of PHP eventually becomes insecure, regardless of whether some of the security fixes from newer versions may or may not be applied to it by the Linux distribution's maintainers at some uncertain point in time. Your PHP version works fine and is secure until it's not. If you want to play this game of Russian Roulette nobody can stop you.
Newer versions of PHP are faster, leading to smaller page load times, which have a positive impact on your search engine scores. Sticking with an old version of PHP has an adverse impact to your site's search engine optimisation.
Newer versions of Joomla and its extensions drop support for older versions of PHP. This may leave you without an upgrade path for your site. Do remember that just because your Joomla version itself supports a wide range of PHP versions the same will not be true for third party extensions. For example, my company drops support for older PHP versions when we notice that not enough of our users are using our software on them, when the cost of supporting them far outweighs any commercial gains (or it becomes outright impossible in any meaningful way), or when we have to do that to ensure compatibility with newer PHP versions.
In the end of the day, your site is an Operational Expense, not a Capital Expense. The cost of maintaining it is a key component of the TCO (Total Cost of Ownership) of a site. If you are not willing to face that cost, there are static sites with a lower cost to operate (and less features), as well as site building platforms which are more restrictive and more expensive (but save you the time needed to maintain your site). In short, you can't have your pie and eat it too. Such is life.
Make a continuous PHP upgrade plan
Based on the two key take-aways above, a PHP migration plan has formulated itself:
- Every January take stock of the PHP versions you use on each of your sites and compare them to the active PHP versions.
- If a site is using a version older than the one listed as Security Support, upgrade as soon as possible.
- If a site is using a version listed as Security Support, make a plan to upgrade it by September to the middle of the two PHP versions listed on the aforementioned table.
- If a site is using that middle version, come back to it on August or September and see if it's possible to upgrade it to the latest version of PHP. If it's not possible, you'll come back to it in January.
If you have more sites you might want to stagger your plan. But you must always have a plan.
If you are a site integrator be sure to explain your plan to your client, as well as any caveats (e.g. you'll have to quote them for a partial rebuild if some extension you use won't support newer Joomla and PHP versions) when selling them a support contract. You do sell your client a support contract, right…?
Upgrading your site
While the following might look like a lot, it's really not. Most of what you will be reading is about why you're doing what you're doing and troubleshooting.
Your Joomla upgrade plan is as follows:
- Upgrade Joomla and all its extensions, including your template.
- Make sure that your extensions support the new PHP version.
- Make sure that the PHP settings between the current and the new PHP versions are the same.
- Upgrade PHP.
- If the site breaks, set Error Reporting to Maximum to figure out what broke and why.
Before you upgrade
Before you start thinking about upgrading your PHP version, you need to make sure that all of your software is compatible with it: Joomla itself, all your extensions, and your template (especially if it's based on a third party template framework).
Remember that software released before a certain PHP version itself was released will most definitely not support that PHP version! Developers are not psychics. We cannot support a future release of PHP or Joomla, before we know what and how will change. For newer versions, check with the developer of your extension or your template to find out which versions of Joomla and PHP each version of their software supports. Well over a decade ago I copied the idea of a version compatibility matrix for my software from desktop software publishers. Many developers have copied that idea too, or provide compatibility information in their documentation or downloads area. Do please check a developer's site before submitting a request with them.
Unfortunately, Joomla itself does not list the exact versions of PHP each of its versions is compatible with. Always go for the latest released version. At the time of this writing it's Joomla 4.2.6, which works great with PHP 8.1 and has preliminary support for PHP 8.2 (some deprecated notices are issues but they are being actively worked on).
That said, do keep in mind that Joomla 3.10 is currently in Security Maintenance. As such, it will NOT work correctly on anything newer than PHP 8.1. If you have a Joomla 3.10 site it's already past the time you should have made a plan to upgrade. By December 2024 you will have a site which runs an End of Life Joomla version on an End of Life PHP version — and there will not be an upgrade path for you, necessitating a rebuild from scratch.
Configure the PHP version before you upgrade to it
Each PHP version on your server has its own configuration which is independently managed. I have not once in my life seen a host which has a consistent configuration across different PHP versions, let alone one which copies over the configuration from a previous PHP version to a new one.
There a few configuration settings you will need to copy over from your current PHP version's configuration to your new PHP version's configuration (and while we're at it, let's see what they do as well):
- The enabled extensions. Many PHP features used by Joomla and its extensions — such as database (MySQL or PostgreSQL) support, JSON support, XML support, ZIP/compression support, image handling support, mb_string (Unicode) support etc — are not part of the PHP language proper. They are extensions to the PHP language. Extensions are optional and have to be explicitly enabled. By default, PHP cannot be used to run a site; someone needs to tell it to enable the required extensions. Shocking, I know!
- The maximum execution time. This determines the maximum amount of time a PHP application, like Joomla, can consume before returning anything to the browser. Some servers have a very low default, 5 to 10 seconds, which is not enough for longer operations such as sending newsletters, resizing images, or taking backups. A value between 30 and 60 seconds is usually what you need.
- The maximum allowed memory. Every time someone visits your site Joomla needs to load itself, the relevant Joomla extensions, and the relevant database data in memory, construct the HTML page in memory, and return it to the web server which sends it to the browser. By default, most servers use a low value around 32 MiB which is barely enough for a very lightweight site. More realistic memory sizes are around 128 MiB.
- The maximum uploaded file size. The default value in new PHP versions is 2 MiB which is not enough when you need to upload larger files such as photos taken with a modern smartphone or DSLR camera, or even most non-trivial Joomla extensions when using the Upload and Install method. You need something around 10 MiB to be safe. If you want to use the Upload and Update method in Joomla Update you need to set this to 32 MiB — it has to be big enough for the biggest Joomla upgrade package to be uploaded.
- The maximum POST size. This is also related to uploads, as well as editing long articles. It should be at least as big as the maximum uploaded file size. If you want to allow multiple file uploads, e.g. in a forum or helpdesk component, you should set this to as many times as the maximum number of files you want uploaded at once, times the maximum uploaded file size. For example, if you have a max upload size of 10 MiB and want to upload up to 5 files at once you need to set this to 10 ⨉ 5 = 50 MiB.
- The PHP temporary path. This is NOT the same as Joomla's temporary folder. This is used internally by PHP to be able to handle uploaded files, as well as some other tertiary functions. This should be a path your site can write to.
- The PHP session path. This must be a path your site can write to if you are going to use the ‘PHP’ method for session handling in Joomla's Global Configuration.
Most hosts offer an interface in their hosting control panel to manage these settings yourself. Check the setting in your current PHP version and write them down. Then go to the settings of the new PHP version you will be upgrading to and copy these settings over.
If you do not know how to do that, or your host does not provide such an interface, do ask your host to do it. It's literally part of what you're paying them to do for you.
Now, it's time to upgrade PHP! On most hosts this can be done from the hosting control panel interface. If unsure how to do it, ask your host. They definitely have documentation for it and they can point you to it if you cannot find it yourself.
Oops! It's broken!
As the Hitchhikers Guide to The Galaxy famously reads on its front cover:
You can always switch back to the previous PHP version. If your site must be online, do that. Then create a copy of your site — for example, using your host's “development site” feature or, if they don't have such a feature, using a third party tool such as Akeeba Backup — so you can follow the next steps on the non-critical copy of your site.
The first thing you need to figure out is, what do you mean “it's broken”?
If you see a lot of scary looking text with words like “deprecated”, “notice”, and “warning” it's very likely that you have set your Error Reporting setting in Global Configuration to anything other than None. If you can log into your site's backend do so, go to System, Global Configuration, Server tab, set Error Reporting to None, click on Save & Close. Visit the site's frontend again. Does it work? If yes, you're done.
If you do not have access to your site's backend, edit the
configuration.php file of your site. Find the line which has
$error_reporting in it and change it to read
public $error_reporting = 'none';
Visit the site's frontend again. Does it work? If yes, you're done.
If you see a message that Joomla cannot start the session or that the database connection cannot be established, double check the PHP configuration of the new PHP version. We discussed that a couple of sections earlier. The former message means that the PHP session path is not writeable by your site, or PHP hasn't enabled the extension for database support (typically called
mysqlnd for MySQL) in its configuration. The latter error definitely means that the PHP extension for database support is not enabled.
Do you see a scary red page with a ghost and reams of text? That's actually a good thing. It means that you are seeing a detailed error report. We'll come back to that. If you only see a white page, or a server page proclaiming 500 Internal Server Error you need to enable Site Debug. If you can log into your site's backend go to System, Global Configuration, System tab and set Debug System to Yes. Click on the Server tab and set Error Reporting to Maximum. If you do not have access to the backend of your site, edit the
configuration.php file of your site. Find the lines with
$debug in them and change them to read, respectively:
public $error_reporting = 'maximum'; public $debug = true;
Watch out! Doing that will expose potentially privileged information about your site's configuration to anyone who can see these pages. It's recommended that you only do that on a copy of your site.
Reloading the page you will see a scary red page with a ghost and reams of text. This is the detailed Joomla error report page which is used for troubleshooting. It tells developers what broken.
If you see a message towards the top that a function was not found / is undefined the problem is that a PHP extension used by Joomla itself or one of the third party extensions has not been enabled in the PHP configuration. Take a look at the earlier section about copying over the PHP configuration from the old to the new PHP version; you might have to ask your host for help if you can't spot the problem yourself.
If there is a parse error, or a message about declarations being incompatible, it means that either Joomla or one of its extensions is incompatible with the new PHP version you are trying to use. The latest file to be loaded, where the error occurred, is towards the top of the page. This will tell you whether it's Joomla itself or an extension. Either way you'll have to go back to your previous PHP version and upgrade Joomla or the third party extension. If you had already upgraded all extensions including your template, and any template framework it uses, you will need to contact the developer of the extension. Send them the full error report you received and ask them what is their plan to support the new PHP version. The error report will help them understand if their extension is really the problem, if so what the problem is, and fix it. Please keep in mind that an error not reported is an error not fixed.
Side note: if you tried to upgrade to the very latest PHP version it's very likely that your life will suck during the first 6 to 9 months of its release as neither Joomla nor third party extensions will be offering any realistic support for it. In this case, try using the immediately previous PHP version. Remember what we said earlier? Always go for the middle version in PHP's actively supported versions page.
If your site is using CRON jobs using CLI scripts (e.g. through the
cli/joomla.php Joomla CLI Application) you will also need to edit your CRON jobs. Remember that the first part of your CRON job command line is the path to the PHP CLI executable of the PHP version you want to use with your CRON job. Now that you've upgraded your site's PHP version you also need to upgrade your CRON jobs' PHP version by changing that path. What to change it to? Typically these paths follow a pattern, e.g.
/usr/bin/ea-php80 for PHP 8.0,
/usr/bin/ea-php81 for PHP 8.1 etc. If unsure, ask your host.
If you are using something like Admin Tools' .htaccess Maker keep in mind that as soon as you regenerate the .htaccess file your site will revert to the previous or the server's default PHP version. You see, on most servers, the PHP version change does nothing more than change a few lines at the end of your .htaccess file. Here's what I see on my blog site after upgrading to PHP 8.1:
# php -- BEGIN cPanel-generated handler, do not edit # Set the <E2><80><9C>ea-php81<E2><80><9D> package as the default <E2><80><9C>PHP<E2><80><9D> programming language. <IfModule mime_module> AddHandler application/x-httpd-ea-php81 .php .php8 .phtml </IfModule> # php -- END cPanel-generated handler, do not edit
You will need to copy the
AddHandler application/x-httpd-ea-php81 .php .php8 .phtml line to Admin Tools' .htaccess Maker page per its documentation. If you use a different extension, or some other tooling, to manage your .htaccess file you will have to do something similar. Please check the documentation of your tool.
It still looks hard to me
Unfamiliar is hard. Not having a plan is hard. Trying to remember everything under the sun is hard.
You know what makes it easy?
Checklists, documentation, and practice.
Despite rumours to the contrary, I am neither a robot, nor superhuman. Not only I am just as human as the next person, I have ADHD on top of it which makes it all the more difficult to remember things and focus. That's why I write documentation and make checklists.
Document what runs on each one of your sites and which versions of Joomla and PHP it supports. Therefore, you will know what to upgrade before you start upgrading PHP.
Use a non-critical site on each different host to get familiar with the PHP upgrade process. Keep notes, then turn them into a checklist. When you want to upgrade PHP you can follow your checklist, like a pilot. Make sure to include checklist steps for even the most obvious steps. Thank me later.
When you inevitably run into a problem use the troubleshooting information in this article to find a solution. Document the problem and its solution so next time you won't have to try and remember what you did a year or two ago. If the problem was, in retrospect, possible to prevent go ahead and adjust your checklist.
Here's the broad strokes of a checklist, to get you started:
- Information check
- Find the versions of your extensions
- Check which extensions support which Joomla and PHP versions
- Prepare PHP
- Copy the PHP settings from the current to the new PHP version
- Upgrade Joomla
- Upgrade extensions (including the template)
- Use Joomla's extensions update
- How to upgrade extensions not using Joomla's extensions update
- Upgrade PHP.
- Step-by-step process for upgrading PHP in your hosting environment
- Updating CRON jobs
- Copying over .htaccess settings to Admin Tools, or other 3rd party tools
The top level items are headings, or sub-checklists if you like. The second level items need to be expanded with step-by-step instructions. Use as much detail as you need
Stay safe, upgrade your sites, and be kind to one another.
© Copyright 2022 Nikolaos K. Dionysopoulos. All legal rights reserved. Distributed under the Creative Commons BY-NC 4.0 license.
Fantastic 🙌🏽 Thank you so much for this thorough walkthrough 🙏🏽 I wish I"d read it before I upgraded to PHP 8.1 a couple of days ago 😁 I did sceenshot the PHP settings and it looked like they were automatically transferred to the new version in cPanel. But I’ll go back and double check that things are according to your recommendations here. Also, I had no idea that updating the .htaccess in AT affects the PHP version (reverts it). I really have to check up on this. Thank you heaps 🙏🏽
After posting my first comment I've now checked my .htaccess. Since I upgraded to PHP 8.1 via cPanel a couple of days ago I now wanted to check the section that might have been added to my .htaccess. But there was nothing with either AddHandler or SetHandler in my .htaccess. Also, the modification date of the file was back in the end of October when I last generated it with Admin Tools.
So is this a good thing or a bad thing then I wonder 😊 This must mean my host is not using that method of editing the .htaccess when I change PHP version in cPanel then, right?
While the most common way to set the PHP version is modifying the site's .htaccess file, you are right that not all hosts use this method. Some hosts may use a .htaccess file at the parent folder of your web root. Others will modify the virtual host configuration and restart the service — especially hosts using virtualisation for site hosting. Some may simply swap out the symlinks of the “default” PHP version and reload the service.
Since the majority of hosts I have seen rely on modifying the .htaccess file in the site's web root I decided to add it as a truthism in the article to help people catch potential problems without overloading them with technicalities and conditionals which would ultimately confuse them.
I have tried to upgrade to 8.1 but PHPMailer no longer functions., Seems to be a well known problem https://github.com/php/php-src/issues/8086. Our hosting company is no help in fixing this - seems to be an MTA issue. Any clues?
PHPMailer, used by Joomla's Joomla\CMS\Mail\Mail API, works perfectly fine in PHP 8.1.
You seem to link to an issue report with PHP's mail() function. If you read the discussion carefully you will see that the problem is ultimately a bug in the sendmail implementation your host is using. It has nothing to do with Joomla, PHPMail, or PHP itself. The problem is that the host's sendmail implementation does not abide by the Internet standards. This has been reported in the past, since 2002 (nineteen years before PHP 8.1), and the answer remains the same: any mail transport agent which does not abide by the Internet standard is at fault. This is accurate and fair.
A simple and trivial workaround is to configure Joomla to use SMTP. This would no longer use sendmail, therefore you'd bypass the issue with your host's broken sendmail.
Better yet, ditch your host for a different one which actually cares about standards. If you're looking for a new host, check the very bottom of the joomla.org pages 😉