
“A couple of times” I had to take up the migration of projects from yii1 to yii2 and I want to share my experience with the community. There is nothing difficult in this process and there will be no revelations. The nature of the publication - your experience + tutorial for beginners.
Prerequisites
If the projects historically made on the first version of yii continue to evolve, then each developer who works with them sooner or later comes the thought: "
how good it would be if it were on yii2 ".
')
But things don't usually go further than that. the amount of work seems enormous. In general, the way it is, the volume is huge, but still not beyond - according to the saying “the eyes are afraid.” Plus, to move on to actions, a certain amount of willpower is needed (I internally prepared for the migration of the first project for almost a year).
My idea of migration is under the cut.
Before “showing the code” I will write many letters “why did I do it”, because reasons determine the nature of the work. I had 2 similar cases.
In the first project, everything was simple. I am a co-owner and the only developer. Therefore, the reason "I just got tired of writing on yii1" is quite compelling. Write should be "in a high", otherwise the output can get
crap poor quality.
In the second case, I am a contractor in a project that was written for a long time by different developers without a clear architecture. Therefore, the output is a huge pile of legacy code. To rewrite it is easier to
shoot yourself to quit, the customer does not recognize “refactoring for the sake of refactoring,” so each new developer increased the volumes of this heap even more.
Stalemate: Everyone understands that there is a problem code, but they cannot break out of this circle. I suggested a gradual modular migration to yii2. After 1.5 months, part of the site earned on yii2, which means there is a place where to migrate and an infrastructure in which you can work meaningfully. Of course, you can continue to write badly, but you can’t justify yourself by saying “look at the horror around”.
Think before you start
For myself, I defined a few rules. If you start a migration, then either they should be respected or not worth starting.
- We need to understand and accept "why do we need this hemorrhoids." There can be any motivation, but it should outweigh all the disadvantages with a large margin.
- You should not start the migration if the project does not have a clear future in the forecast for 2-3 years ahead. Or you do it for fun.
- All new functionality, all development, all new we write on yii2. Only support should remain in yii1. If this rule is not followed, then you will receive 2 active branches at once, which will require 2 times more resources. And, since there is always not enough resources, this may all end.
- Do not set the task "stupidly rewrite everything that is." “To rewrite everything” is so abstract and boring that if you voice it to your team in precisely this wording, then in their saddened faces you can read a lot of interesting things about yourself.
- Since even “everything you want” cannot be immediately rewritten, then you need a plan for gradual migration - by pages, by services, by modules.
- The most important! Consider the migration to yii2 best, as a deep refactoring of the entire project, aimed at development. Then it may turn out that a third of the project does not need to be rewritten at all (if it works well, it works “as is” and requires only minimal support), and part of the project can be beautifully buried. Those. not just killing the services / pages, but altering the project in such a way that they will simply not be needed.
Idea of migration
My idea of migration is the simultaneous collaboration of two branches of the same project on yii1 and yii2 in the same domain, on the same virtual host. Gradually, incrementally port services / pages / modules to yii2.
For example, there is a website running on yii1
site.ru/ # site.ru/news # site.ru/pages # site.ru/comments #
Rewrote the news on yii2, received:
site.ru/ # site.ru/news # (yii2) site.ru/pages # site.ru/comments #
Rewrote feedback received
site.ru/ # site.ru/news # (yii2) site.ru/pages # site.ru/comments # (yii2)
And so gradually, page by page, until we rewrite everything that we want to rewrite. It is clear that the more we rewrote, the easier the process is. The most difficult is always the first step: the first page, the first module, the first service.
Part one. Just to work at the same time.
I will add tautology, but everything is really simple. In the simplest version, keep both branches (yii1 and yii2) in the same work area, for example, like this:
/var/www/site/htdocs/ - DOCUMENT_ROOT /var/www/site/yii1/ - yii1 /var/www/site/yii2/ - yii2
Or so /var/www/site/public_html/ - DOCUMENT_ROOT /var/www/site/protected/ - yii1 /var/www/site/yii2/ - yii2
or so
/var/www/site/ - DOCUMENT_ROOT /var/www/site/protected/ - yii1 /var/www/site/yii2/ - yii2
It doesn’t matter how you name and place directories. It is necessary to make so that the code on yii1 and yii2 lay nearby and was available for work in one virtual host. And all the magic of simultaneous work will be in the input scripts index.php and .htaccess.
What are the advantages of this approach:
- In your development environment will be available immediately 2 branches of the project. This can be convenient, because for a long time will have to work with them at the same time, switching back and forth.
- Both projects will have direct access to DOCUMENT_ROOT, which is important for simple work with css / js statics.
Cons can be both aesthetic (by type: what for to interfere all together), and associated with multi-user work. Yes, you can share code storage locations and share projects in the development environment. Essentially this does not change, just add nuances.
Personally, I created a separate project in the IDE for the yii2 branch, even when the branch files were physically next to each other.
Basic example. Sources of the yii1 / yii2 project branches in one directory
DOCUMENT_ROOT uses 2 input scripts.
index.php - yii1 index_yii2.php - yii2.
In file structure htdocs/ htdocs/index.php htdocs/index_yii2.php yii1/ yii2/
index.phpIf you do not change the file structure for the project on yii1, then your index.php will remain unchanged.
for example <?php $app = Yii::createApplication('WebApplication', $config); $app->run(); ?>
index_yii2.php <?php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev');
.htaccessIn .htaccess we will do the routing between yii1 and yii2
Options +FollowSymlinks RewriteEngine On RewriteBase / # yii2 # # RewriteRule ^test index_yii2.php [L] RewriteRule ^news index_yii2.php [L] # action RewriteRule ^page/one index_yii2.php [L] # RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # yii1 RewriteRule . index.php
Those. The following URLs are processed by index_yii2.php and run on yii2.
https://site/test https://site/news https://site/page/one
For the rest of the site is responsible index.php (yii1).
This is the basic launch of simultaneous operation. Of course, each will have its own nuances: the team, users, access rights, servers, different repositories, etc. And everyone will have their own garden.
The sources of the yii1 / yii2 branches are separated by directories
For example, if you have your own server, you can spread the storage of project branches in different directories.
/var/www/site/htdocs - DOCUMENT_ROOT site.ru /var/www/site/protected - yii1 /srv/site_yii2 - yii2
Then you need to change the path to the directory with the project yii2 in index_yii2.php. Of course, it will work this way if disabled, or open_basedir is configured. Plus the corresponding rights on the server and disabled / configured, SELinux.
index_yii2.php <?php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); $pathYii2 = '/srv/site_yii2/'; require $pathYii2 . 'vendor/autoload.php'; require $pathYii2 . 'vendor/yiisoft/yii2/Yii.php'; require $pathYii2 . 'common/config/bootstrap.php'; require $pathYii2 . 'frontend/config/bootstrap.php'; $config = yii\helpers\ArrayHelper::merge( require $pathYii2 . 'common/config/main.php', require $pathYii2 . 'common/config/main-local.php', require $pathYii2 . 'frontend /config/main.php', require $pathYii2 . 'frontend /config/main-local.php' ); (new yii\web\Application($config))->run();?>
What's next
If there are users on the site, then unified authorization is a critical element without which the simultaneous work of 2 branches is, in fact, impossible. In the next article I plan to show how easy it is to organize a single authorization. For example, authorization itself remains in yii1, but authorized users are transparently visible in the yii2 branch or vice versa.