Welcome Guest, Not a member yet? Register   Sign In
Upgrade from CI3 to CI4 - By Running them together
#1

(This post was last modified: 02-09-2024, 09:13 PM by mkganesh. Edit Reason: Additional info about vendor folder )

Below is the approach I took to start upgrading from CI3 to CI4.

Step 1:
First make these below changes to your current(CI3) project.

Create a folder public and move index.php into it.
Open the public/index.php file and change

$system_path = 'system'; to $system_path = 'system_ci3';
Rename your system folder to system_ci3

Step 2: Rename Constants
This step is required as these CONSTANTS are used in both CI3 and CI4 and need to point to different locations.

Change the below lines in the public/index.php file
define('BASEPATH', $system_path); to
define('BASEPATH_CI3', $system_path);

define('FCPATH', dirname(__FILE__).DIRECTORY_SEPARATOR); to
define('FCPATH_CI3', dirname(__FILE__).DIRECTORY_SEPARATOR);

define('SYSDIR', basename(BASEPATH)); to
define('SYSDIR_CI3', basename(BASEPATH_CI3));

define('APPPATH', $application_folder.DIRECTORY_SEPARATOR); to
define('APPPATH_CI3', $application_folder.DIRECTORY_SEPARATOR);

define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR); to
define('VIEWPATH_CI3', $view_folder.DIRECTORY_SEPARATOR);

Search for these 5 constants through out your project and replace them with new value.
Once the values are replaced, test your project at this point. If all the values are replaced correctly there should be no errors.

Step 3: Rename Functions in Common.php
This step is required as these functions are named same in CI4.

Rename the below function name in system_ci3/core/Common.php
• log_message
• function_usable
• is_cli
• is_really_writable
• remove_invisible_characters
find and replace for above functions through out system_ci3 and application folder.

Step 4: Rename Functions in system_ci3/helpers
This step is required as some of these functions are named same in CI4. Not all functions are available in CI4. This step is done for maintaining consistency and easier debugging if there are errors at later stages.

Rename all the functions inside all the files in this folder.
For Step 3 and Step 4, I just added _ci3 at end of each function.
Eg: log_message was renamed to log_message_ci3
form_open was renamed to form_open_ci3
Please make sure you are replacing the correct functions as there can be same name functions inside a class, which need not be replaced.
Eg: set_value in form_helper.php needs to be replaced. There is set_value function inside system_ci3/libraries/Form_validation.php, this need not be replaced.
Test your project at this point, there should be no errors if everything was replaced correctly.

Step 5: Download CI4 and place code in your project.
Now download the latest CI4 code and copy the app, system, writable folders to your project’s base folder. Once copied you should have the following folder structure.
• app - CI4
• application - CI3
• system - CI4
• system_ci3 - CI3
• public
• writable

If you are using modules from vendor folder, that can be moved to the base directory along side the above directories and path of it can be changed in application/config.php
$config['composer_autoload'] = '/path/to/vendor/autoload.php';

Step 6: Running CI4 from CI3

In system_ci3/core/Controller.php file copy the below code. This is the code from codeigniter 4 public/index.php file. This loads CI4 application.


PHP Code:
public function load_from_ci4() {
// Path to the front controller (this file)
define('FCPATH'FCPATH_CI3);
// Ensure the current directory is pointing to the front controller's directory
if (getcwd() . DIRECTORY_SEPARATOR !== FCPATH) {
    chdir(FCPATH);
}
/*
*---------------------------------------------------------------
* BOOTSTRAP THE APPLICATION
*---------------------------------------------------------------
* This process sets up the path constants, loads and registers
* our autoloader, along with Composer's, loads our constants
* and fires up an environment-specific bootstrapping.
*/
// Load our paths config file
// This is the line that might need to be changed, depending on your folder structure.
require FCPATH '../app/Config/Paths.php';
// ^^^ Change this line if you move your application folder
$paths = new Config\Paths();
// Location of the framework bootstrap file.
require rtrim($paths->systemDirectory'\\/ ') . DIRECTORY_SEPARATOR 'bootstrap.php';
// Load environment settings from .env files into $_SERVER and $_ENV
require_once SYSTEMPATH 'Config/DotEnv.php';
(new 
CodeIgniter\Config\DotEnv(ROOTPATH))->load();
// Load Config Cache
// $factoriesCache = new \CodeIgniter\Cache\FactoriesCache();
// $factoriesCache->load('config');
// ^^^ Uncomment these lines if you want to use Config Caching.

/*
* ---------------------------------------------------------------
* GRAB OUR CODEIGNITER INSTANCE
* ---------------------------------------------------------------
*
* The CodeIgniter class contains the core functionality to make
* the application run, and does all the dirty work to get
* the pieces all working together.
*/

$app Config\Services::codeigniter();
$app->initialize();
$context is_cli() ? 'php-cli' 'web';
$app->setContext($context);

/*
*---------------------------------------------------------------
* LAUNCH THE APPLICATION
*---------------------------------------------------------------
* Now that everything is set up, it's time to actually fire
* up the engines and make this app do its thang.
*/
$app->run();



Now you should be able to start writing code in CI4.
If you want to load the welcome controller, index function from CI4, just comment out all the existing code in index function and call load_from_ci4().


PHP Code:
public function index()
{
$this->load_from_ci4();
//$this->load->view('welcome_message');



In the App/Config/Routes.php
If you have

PHP Code:
$routes->get('welcome/index''Home::index'); 
then CI4 home page should load.
Reply
#2

Interesting method! Thank you for sharing.
Reply
#3

Another way: https://forum.codeigniter.com/showthread...#pid414435
Reply
#4

After running CI3 and CI4 by changing constants and renaming functions for almost 3 weeks on productions below are the issues I faced so far.
1. In CI3, CSRF token is cookie based only where as in CI4 it has option of session / cookie. If CSRF token is turned on in both CI3 and CI4, it will fail as tokens are verified and changed before the request is passed on the controller from where I was calling CI4, so CI4 will invalidate the request.
The solution I came up with was to validate the CSRF token in CI3 and set a session variable, if the session variable is set the CI4 will skip validating CSRF token.
2. CI4 is setting _ci_previous_url in session, this is not available is CI3, so if some pages are loaded from CI3 and some from CI4, this value will be wrong.
The solution is to set _ci_previous_url in CI3 also
3. Session path and cache path different in CI3 and CI4.
If you need to access to same session then make the path same (both are configurable so should not be hard)
Reply
#5

what about router ? how run router CI3 and CI4 in the same project
Reply
#6

(04-14-2024, 08:29 PM)win123139 Wrote: what about router ? how run router CI3 and CI4 in the same project

No Changes in CI3 Routing.

CI4 add the route like

$routes->get('welcome/index', 'Home::index');

And in CI3 welcome controller, index function comment all the lines of code and add $this->load_from_ci4();

This should load the CI4 Home controller, index function
Reply
#7

(04-14-2024, 11:54 PM)mkganesh Wrote:
(04-14-2024, 08:29 PM)win123139 Wrote: what about router ? how run router CI3 and CI4 in the same project

No Changes in CI3 Routing.

CI4 add the route like

$routes->get('welcome/index', 'Home::index');

And in CI3 welcome controller, index function comment all the lines of code and add $this->load_from_ci4();

This should load the CI4 Home controller, index function
thank you for quick reply but i'm confusing about step 6
where should this code be placed and why load_from_ci4 fuction define'FCPATH' FCPATH_CI3
public function load_from_ci4() {
// Path to the front controller (this file)
define FCPATH_CI3
Reply
#8

(04-15-2024, 01:26 AM)win123139 Wrote:
(04-14-2024, 11:54 PM)mkganesh Wrote:
(04-14-2024, 08:29 PM)win123139 Wrote: what about router ? how run router CI3 and CI4 in the same project

No Changes in CI3 Routing.

CI4 add the route like

$routes->get('welcome/index', 'Home::index');

And in CI3 welcome controller, index function comment all the lines of code and add $this->load_from_ci4();

This should load the CI4 Home controller, index function
thank you for quick reply but i'm confusing about step 6
where should this code be placed and why load_from_ci4 fuction define'FCPATH' FCPATH_CI3
public function load_from_ci4() {
// Path to the front controller (this file)
define FCPATH_CI3

Which Code?

The load_from_ci4 function mostly has the content of CI4's public/index.php file, except for few lines which are already set in CI3's index.php file.
FCPATH needs to point to the location of index file, which is already set in FCPATH_CI3.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB