Let's imagine you have a huge application in CakePHP 2.x (or 1.x) and you're planning to upgrade to the latest CakePHP 4.x.
After doing some estimations, you realize the upgrade process is out of your scope, because you don't have the budget or developer availability to do it in 1 shot. At this point, some companies would abort the upgrade and keep working on 2.x for "some more time" until "this last release is delivered" or until "budget is available next fall", digging deeper and deeper into the rabbit hole…
There's an alternative you could follow if this is your case: proceed with the upgrade of a smaller portion of your application and let the 2 versions coexist for some time.
Warning: This is NOT for every project or company. Please carefully think about this decision as it has overhead you'll need to handle.
So, if your application has a portion that could be extracted, with a small set of dependencies from other areas of your application, or if you are creating a new feature with a limited set of dependencies with the rest of your application, this approach would be good for you.
In order to allow both applications to coexist, we are going to keep the CakePHP 1.x application as the main one, and use CakePHP 4.x as a subfolder inside of the first one. It's important to note that in order to share sessions between both applications you'll need to use a storage you can actually share, like database or cache based sessions (redis, etc). Then, you can use a configuration like this one (see below) to add a new upstream to handle your new application. Note: the upstream could be located in another server of your network, using a different PHP version etc.
We've used nginx as an example, but you can use the same approach in other web servers like Apache.
In our example we're going to use all paths starting with /api
to be managed by our new CakePHP 4.x application.
upstream cake4 {
# Note this could be any server/port in your network where the cake4 application is installed
server 127.0.0.1:9090;
}
# This is our CakePHP 2.x server
server {
server_name example.com;
root /var/virtual/example.com/app/webroot;
index index.php;
# All requests /api are forwarded to our CakePHP 4.x application
location /api {
proxy_pass http://cake4;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_intercept_errors on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
# This is our CakePHP 4.x server
server {
listen 9090;
server_name example.com;
root /var/virtual/cake4-example.com/webroot;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_intercept_errors on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
As you can see, we have 3 blocks defined in our configuration file:
-
upstream cake4 {...} to forward requests to the CakePHP 4.x application
-
server {... 2.x ...} using a location /api to forward all these calls to the CakePHP 4.x server
-
server {... 4.x ...} using a specific port (9090) to handle requests in CakePHP 4.x
Using this approach, you can break your application into 2 parts, and start moving features by path to CakePHP 4. You'll need to handle the changes in 2 projects for a while, and pay this overhead, but this could be better to maintain than a CakePHP 2.x application sitting on an old PHP version.
Happy baking!