Don't even try to run a Symfony 1.4 project on PHP 8 on your server, if you do, you will find plenty of deprecations and for sure a Fatal error that will stop the project from working, even if the project is empty:
And it's quite important to mention, that this is only the code related to the framework itself! Your own code might be incompatible with PHP 8.2 as well. PHP has gone through a thorough optimization since that version, new features were included such as a significant performance boost, improvements in error handling, and other important features such as match expressions, named arguments, union types, etc.
Upgrading a project from a very old version of PHP is certainly not an easy task, it will take time, having a codebase with unit testing will definitely help you out with that, but in case you don't have such a tool to your disposition, don't be afraid and take just a step at a time. Just like the thing we are going to teach you today, which is basically the upgrade of the Symfony framework itself to be compatible with PHP 8.2. This will not guarantee that your project will work out of the box with just the upgrade of the framework because as I mentioned before, this is going to depend on your project codebase. But it's definitely an important step when trying to make your old Symfony 1.4-based application compatible with PHP 8.2.
Important note before upgrading to 8.2
It's recommended to upgrade sequentially from PHP 5.6 to PHP 7.2 and finally to PHP 8.2 as it will be easier for you to debug the project later and make your own code compatible with PHP 8.2 (but this is merely a personal recommendation, for the Symfony framework code is easily interchangeable, yet your apps/
code won't be, so please keep that in mind when doing the upgrade). We wrote a year ago about how to upgrade a Symfony 1.4-based project to work with PHP 7.2 here, so be sure to check it out before following this tutorial.
Having said that, let's get started with the upgrade.
1. Prepare original project files
As shown in the following Treeview, our original project of Symfony 1.4, which works in PHP 7.2 looks like this:
project/
├── Check.php
├── apps/
├── cache/
├── check_configuration.php
├── composer.json
├── composer.lock
├── config/
├── data/
├── lib/
├── log/
├── nbproject
├── package.xml
├── plugins/
├── readme.textile
├── sandbox.py
├── symfony-1.4.27
├── test/
├── trunk/
└── web/
The project works properly in PHP 5.6 with the original structure. To make it fully compatible with PHP 8.2, we need to tweak some stuff.
2. Create a composer.json file
The project should work with composer from now on, proceed to create a new composer file using the following command in the root directory of your project:
composer init
Or alternatively, create it manually with at least the following structure:
{
"name": "ourcodeworld/projectname",
"type": "project",
"authors": [
{
"name": "Your Name",
"email": "[email protected]"
}
],
"require": {
}
}
Note that till this point there is no autoloader file that you can include in your project or composer.lock
file. To create the autoloader, you will need to install the first library that you need (Symfony itself).
3. Install Symfony 1.4 with support for PHP 8.2
The new version of Symfony that supports PHP 8.2 will be Symfony 1.5 which is unofficially maintained by the guys at FriendsOfSymfony1, can be installed with the following command:
composer require friendsofsymfony1/symfony1 "1.5.*"
After installing Symfony 1.4 you will now have the following project structure:
project/
├── Check.php
├── apps/
├── cache/
├── check_configuration.php
├── composer.json
├── composer.lock
├── config/
├── data/
├── lib/
├── log/
├── nbproject
├── package.xml
├── plugins/
├── readme.textile
├── sandbox.py
├── symfony-1.4.27
├── test/
├── trunk/
├── vendor/
└── web/
4. Install the ORM
In Symfony 1.4 you were able to use Doctrine or Propel as ORM, so in case your project uses Doctrine 1, you can install it with the following command:
composer require friendsofsymfony1/doctrine1
It's compatible with PHP 8.2 so you shouldn't have any problem with this package.
5. Configuring your project to use the new Symfony
Now, in the old Symfony project, on the ProjectConfiguration.class.php
file, specifically located at the project/config
directory, you will find the line that imports the autoload of Symfony 1.4 (sfCoreAutoload.class.php
):
<?php
require_once dirname(__FILE__) . '/../symfony-1.4.27/lib/autoload/sfCoreAutoload.class.php';
You need to update it, so instead of loading the old Symfony autoload, it will load the autoload file of composer:
<?php
// File: myproject/config/ProjectConfiguration.class.php
// 1. Use the autoload file of Composer
require_once dirname(__FILE__) . '/../vendor/autoload.php';
sfCoreAutoload::register();
class ProjectConfiguration extends sfProjectConfiguration
{
// ....
// Your code
}
After saving the changes in the file, your application should be able to run on a PHP 8.2 environment:
6. Running commands
Finally, in case you want to know how to run commands in Symfony 1.4, stuff like cleaning the cache, doing reverse engineering, building the models from the schema, or generating the schema itself, you need to know that the binary path has changed. It is located now in the vendor directory, inside the data/bin directory of Symfony 1.4. For example, to clean the cache of your project you can simply run the following command:
php vendor/friendsofsymfony1/symfony1/data/bin/symfony cc
Which is going to generate an output similar to the following one:
>> cache Clearing cache type "all" for "frontend" app and "prod" env
>> file+ /var/www/html/data/frontend_prod-cli.lck
>> chmod 777 /var/www/html/data/frontend_prod-cli.lck
>> file- /var/www/html/cache/frontend/prod/config/config_factories.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_module.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_module.yml.php
>> file- /var/www/html/cache/frontend/prod/config/config_autoload.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_global_components_config_security.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_module.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_security.yml.php
>> file- /var/www/html/cache/frontend/prod/config/config_core_compile.yml.php
>> file- /var/www/html/cache/frontend/prod/config/config_services.yml.php
>> file- /var/www/html/cache/frontend/prod/config/config_databases.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_filters.yml.php
>> file- /var/www/html/cache/frontend/prod/config/config_settings.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_view.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_security.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_view.yml.php
>> file- /var/www/html/cache/frontend/prod/config/modules_myapp_config_security.yml.php
Common must-fixes
After implementing the basic upgrade, there will be some things that you need to fix as well.
1. Use Doctrine_Core instead of Doctrine
There are some cases where an old naming convention may lead to exceptions like the following one:
Fatal error: Uncaught Error: Class 'Doctrine' not found in \plugins\sfDoctrineGuardPlugin\lib\validator\sfGuardValidatorUser.class.php:67
Stack trace: #0 \plugins\sfDoctrineGuardPlugin\lib\validator\sfGuardValidatorUser.class.php(44): sfGuardValidatorUser->getTable()
#1 \vendor\friendsofsymfony\symfony1\lib\validator\sfValidatorBase.class.php(327): sfGuardValidatorUser->doClean(Array)
#2 \vendor\friendsofsymfony\symfony1\lib\validator\sfValidatorSchema.class.php(254): sfValidatorBase->clean(Array)
#3 \vendor\friendsofsymfony\symfony1\lib\validator\sfValidatorSchema.class.php(192): sfValidatorSchema->postClean(Array)
#4 \vendor\friendsofsymfony\symfony1\lib\validator\sfValidatorSchema.class.php(90): sfValidatorSchema->doClean(Array)
#5 \vendor\friendsofsymfony\symfony1\lib\form\sfForm.class.php(259): sfValidatorSchema->clean(Array)
#6 \vendor\friendsofsymfony\symfony1\lib\form\addon\sfFormSymfony.class.php in \plugins\sfDoctrineGuardPlugin\lib\validator\sfGuardValidatorUser.class.php on line 67
2. Increase session.gc_maxlifetime
There are other regular exceptions, for example when trying to increase the session timeout on the factories.yml
of your project:
# You can find more information about this file on the symfony website:
# https://symfony.com/legacy/doc/reference/1_4/en/05-Factories
# ...
all:
# ...
# ...
user:
class: myUser
param:
timeout: 21600
3. Your own code
Of course, you will need to upgrade your deprecated code, the one that doesn't belong to the Symfony 1.4 core but to your controllers, templates, and tasks.
Happy coding ❤️!