Yeah i know, why the hell would i work with such an old framework like Symfony 1.4 when we are right now in the Symfony 5 version. The reason is simple, money. However only someone that works in a company with a very important and complex project understand how deep this conjecture is, not every company would be able to pay for a new port of an old project to a new one that uses the latest technologies.
However, as a programmer that loves to work with the latest stuff, i keep looking for a better way to do things. In some old post, we wrote how to provide support for PHP 5.5+ in your Symfony 1.4 project (considering that symfony 1.4 was meant to run on PHP 5.3, it was a huge advance till then btw). However, the mentioned support broke with the introduction of PHP 7, if you decided to run a Symfony 1.4 project in the mentioned version of PHP, you would only see a big disaster.
Fortunately, there's still a bunch of people like you and me that needs to support this kind of project. The guys at FriendsOfSymfony1 decided to expand the Symfony 1 lifespan through some enhancements (all of them are listed in the WHATS_NEW file) that are:
- DIC (Dependency Injection Container)
- Composer support
- PHP 7.2 support
- performance boost
- new widgets & validators
- some tickets fixed from the symfony trac
The project is quite understandable and according to the way you work, the installation may be different, however in this article we will explain you what we did to get one of our old Symfony 1.4 projects working with PHP 7.
1. Prepare original project files
As shown in the following treeview, our original project of Symfony 1.4, that works in PHP 5.6 looks like this:
original_project/
âââ apps/
âââ cache/
âââ Check.php
âââ check_configuration.php
âââ config/
âââ data/
âââ lib/
âââ log/
âââ nbproject/
âââ package.xml
âââ plugins/
âââ symfony
âââ symfony-1.4.27/
âââ test/
âââ trunk/
âââ web/
The project works quite well, if we serve the project through a web server for PHP 5.6 pointing to the web directory, it will run without any issues:
Now that we know that the project works, create a security copy of everything and remove the symfony-1.4.27 directory from your project as we won't use this version anymore.
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 project directory:
composer init
Or alternatively, creating 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 nor 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 7.2
The new version of symfony that supports PHP 7.2 will be Symfony 1.5 that is unofficially maintained by the guys at FriendsOfSymfony1, can be installed with the following command:
composer require lexpress/symfony1 "1.5.*"
After installing Symfony 1.4 you will now have the following project structure:
new_project/
âââ apps/
âââ cache/
âââ Check.php
âââ check_configuration.php
âââ config/
âââ data/
âââ lib/
âââ log/
âââ nbproject/
âââ package.xml
âââ plugins/
âââ symfony
âââ test/
âââ trunk/
âââ vendor/
âââ web/
As you can see, we have something special now which is the vendor
directory that exists because we provided manually composer support for Symfony 1.4 (we wrote about how to provide support for composer in Symfony 1.4 in this article) and that's what we did on the first steps.
4. Install the ORM
In Symfony 1.4 you were able to use Doctrine or Propel as ORM, so in case that your project uses Doctrine 1, you can install it with the following command:
composer require lexpress/doctrine1
If you used Propel instead, then you can install propel with the following one:
composer require propel/sf-propel-o-r-m-plugin
After installing the ORM, most of the stuff in your project may work now, however we still need to configure your old project to use the new version of Symfony.
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
):
require_once dirname(__FILE__) . '/../symfony-1.4.27/lib/autoload/sfCoreAutoload.class.php';
You need to change that, instead you will only need to use the composer autoload from the vendor directory like this:
<?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 of the file, your application should be able to run on a PHP 7.2 environment:
6. Running commands
Finally, in case that you want to know how to run commands in Symfony 1.4, we used to run the commands like this (which should work btw):
php symfony cc
As the symfony binary was usually in the root directory of the project, however if that binary isn't working, you can use the symfony binary from the vendor directory like this:
php vendor/lexpress/symfony1/data/bin/symfony cc
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 and 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\lexpress\symfony1\lib\validator\sfValidatorBase.class.php(327): sfGuardValidatorUser->doClean(Array)
#2 \vendor\lexpress\symfony1\lib\validator\sfValidatorSchema.class.php(254): sfValidatorBase->clean(Array)
#3 \vendor\lexpress\symfony1\lib\validator\sfValidatorSchema.class.php(192): sfValidatorSchema->postClean(Array)
#4 \vendor\lexpress\symfony1\lib\validator\sfValidatorSchema.class.php(90): sfValidatorSchema->doClean(Array)
#5 \vendor\lexpress\symfony1\lib\form\sfForm.class.php(259): sfValidatorSchema->clean(Array)
#6 \vendor\lexpress\symfony1\lib\form\addon\sfFormSymfony.class.php in \plugins\sfDoctrineGuardPlugin\lib\validator\sfGuardValidatorUser.class.php on line 67
The solution is quite simple, as the exception shows, the Doctrine class doesn't exists even though the doctrine package has been installed using composer, this happens because the class should be Doctrine_Core
, so replacing all the Doctrine
instances should fix the issue.
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
The following warning will appear globally on your project:
Warning: ini_set(): A session is active. You cannot change the session module's ini settings at this time in project\vendor\lexpress\symfony1\lib\user\sfBasicSecurityUser.class.php on line 257
This can be solved by simply increasing the session.gc_maxlifetime
property in your php.ini
file to at least 3600, you may increase it according to your needs:
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime=3600
3. Your own code
Of course you will need as well 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 ❤️!