3
declare(strict_types=1);
6
* This file is part of CodeIgniter 4 framework.
8
* (c) CodeIgniter Foundation <admin@codeigniter.com>
10
* For the full copyright and license information, please view
11
* the LICENSE file that was distributed with this source code.
16
use CodeIgniter\Cache\FactoriesCache;
17
use CodeIgniter\CLI\Console;
18
use CodeIgniter\Config\DotEnv;
26
* Bootstrap for the application
33
* Used by `public/index.php`
36
* web: Invoked by HTTP request
37
* php-cli: Invoked by CLI via `php public/index.php`
39
* @return int Exit code.
41
public static function bootWeb(Paths $paths): int
43
static::definePathConstants($paths);
44
if (! defined('APP_NAMESPACE')) {
45
static::loadConstants();
47
static::checkMissingExtensions();
49
static::loadDotEnv($paths);
50
static::defineEnvironment();
51
static::loadEnvironmentBootstrap($paths);
53
static::loadCommonFunctions();
54
static::loadAutoloader();
55
static::setExceptionHandler();
56
static::initializeKint();
58
$configCacheEnabled = class_exists(Optimize::class)
59
&& (new Optimize())->configCacheEnabled;
60
if ($configCacheEnabled) {
61
$factoriesCache = static::loadConfigCache();
64
static::autoloadHelpers();
66
$app = static::initializeCodeIgniter();
67
static::runCodeIgniter($app);
69
if ($configCacheEnabled) {
70
static::saveConfigCache($factoriesCache);
73
// Exits the application, setting the exit code for CLI-based
74
// applications that might be watching.
81
* @return int Exit code.
83
public static function bootSpark(Paths $paths): int
85
static::definePathConstants($paths);
86
if (! defined('APP_NAMESPACE')) {
87
static::loadConstants();
89
static::checkMissingExtensions();
91
static::loadDotEnv($paths);
92
static::defineEnvironment();
93
static::loadEnvironmentBootstrap($paths);
95
static::loadCommonFunctions();
96
static::loadAutoloader();
97
static::setExceptionHandler();
98
static::initializeKint();
99
static::autoloadHelpers();
101
static::initializeCodeIgniter();
102
$console = static::initializeConsole();
104
return static::runCommand($console);
108
* Used by `system/Test/bootstrap.php`
110
public static function bootTest(Paths $paths): void
112
static::loadConstants();
113
static::checkMissingExtensions();
115
static::loadDotEnv($paths);
116
static::loadEnvironmentBootstrap($paths, false);
118
static::loadCommonFunctions();
119
static::loadAutoloader();
120
static::setExceptionHandler();
121
static::initializeKint();
122
static::autoloadHelpers();
126
* Used by `preload.php`
128
public static function preload(Paths $paths): void
130
static::definePathConstants($paths);
131
static::loadConstants();
132
static::defineEnvironment();
133
static::loadEnvironmentBootstrap($paths, false);
135
static::loadAutoloader();
139
* Load environment settings from .env files into $_SERVER and $_ENV
141
protected static function loadDotEnv(Paths $paths): void
143
require_once $paths->systemDirectory . '/Config/DotEnv.php';
144
(new DotEnv($paths->appDirectory . '/../'))->load();
147
protected static function defineEnvironment(): void
149
if (! defined('ENVIRONMENT')) {
150
// @phpstan-ignore-next-line
151
$env = $_ENV['CI_ENVIRONMENT'] ?? $_SERVER['CI_ENVIRONMENT']
152
?? getenv('CI_ENVIRONMENT')
155
define('ENVIRONMENT', $env);
159
protected static function loadEnvironmentBootstrap(Paths $paths, bool $exit = true): void
161
if (is_file($paths->appDirectory . '/Config/Boot/' . ENVIRONMENT . '.php')) {
162
require_once $paths->appDirectory . '/Config/Boot/' . ENVIRONMENT . '.php';
168
header('HTTP/1.1 503 Service Unavailable.', true, 503);
169
echo 'The application environment is not set correctly.';
176
* The path constants provide convenient access to the folders throughout
177
* the application. We have to set them up here, so they are available in
178
* the config files that are loaded.
180
protected static function definePathConstants(Paths $paths): void
182
// The path to the application directory.
183
if (! defined('APPPATH')) {
184
define('APPPATH', realpath(rtrim($paths->appDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
187
// The path to the project root directory. Just above APPPATH.
188
if (! defined('ROOTPATH')) {
189
define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR);
192
// The path to the system directory.
193
if (! defined('SYSTEMPATH')) {
194
define('SYSTEMPATH', realpath(rtrim($paths->systemDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
197
// The path to the writable directory.
198
if (! defined('WRITEPATH')) {
199
define('WRITEPATH', realpath(rtrim($paths->writableDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
202
// The path to the tests directory
203
if (! defined('TESTPATH')) {
204
define('TESTPATH', realpath(rtrim($paths->testsDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
208
protected static function loadConstants(): void
210
require_once APPPATH . 'Config/Constants.php';
213
protected static function loadCommonFunctions(): void
215
// Require app/Common.php file if exists.
216
if (is_file(APPPATH . 'Common.php')) {
217
require_once APPPATH . 'Common.php';
220
// Require system/Common.php
221
require_once SYSTEMPATH . 'Common.php';
225
* The autoloader allows all the pieces to work together in the framework.
226
* We have to load it here, though, so that the config files can use the
229
protected static function loadAutoloader(): void
231
if (! class_exists(Autoload::class, false)) {
232
require_once SYSTEMPATH . 'Config/AutoloadConfig.php';
233
require_once APPPATH . 'Config/Autoload.php';
234
require_once SYSTEMPATH . 'Modules/Modules.php';
235
require_once APPPATH . 'Config/Modules.php';
238
require_once SYSTEMPATH . 'Autoloader/Autoloader.php';
239
require_once SYSTEMPATH . 'Config/BaseService.php';
240
require_once SYSTEMPATH . 'Config/Services.php';
241
require_once APPPATH . 'Config/Services.php';
243
// Initialize and register the loader with the SPL autoloader stack.
244
Services::autoloader()->initialize(new Autoload(), new Modules())->register();
247
protected static function autoloadHelpers(): void
249
Services::autoloader()->loadHelpers();
252
protected static function setExceptionHandler(): void
254
Services::exceptions()->initialize();
257
protected static function checkMissingExtensions(): void
259
if (is_file(COMPOSER_PATH)) {
263
// Run this check for manual installations
264
$missingExtensions = [];
271
if (! extension_loaded($extension)) {
272
$missingExtensions[] = $extension;
276
if ($missingExtensions === []) {
281
'The framework needs the following extension(s) installed and loaded: %s.',
282
implode(', ', $missingExtensions)
285
header('HTTP/1.1 503 Service Unavailable.', true, 503);
291
protected static function initializeKint(): void
293
Services::autoloader()->initializeKint(CI_DEBUG);
296
protected static function loadConfigCache(): FactoriesCache
298
$factoriesCache = new FactoriesCache();
299
$factoriesCache->load('config');
301
return $factoriesCache;
305
* The CodeIgniter class contains the core functionality to make
306
* the application run, and does all the dirty work to get
307
* the pieces all working together.
309
protected static function initializeCodeIgniter(): CodeIgniter
311
$app = Config\Services::codeigniter();
313
$context = is_cli() ? 'php-cli' : 'web';
314
$app->setContext($context);
320
* Now that everything is set up, it's time to actually fire
321
* up the engines and make this app do its thang.
323
protected static function runCodeIgniter(CodeIgniter $app): void
328
protected static function saveConfigCache(FactoriesCache $factoriesCache): void
330
$factoriesCache->save('config');
333
protected static function initializeConsole(): Console
335
$console = new Console();
337
// Show basic information before we do anything else.
338
// @phpstan-ignore-next-line
339
if (is_int($suppress = array_search('--no-header', $_SERVER['argv'], true))) {
340
unset($_SERVER['argv'][$suppress]); // @phpstan-ignore-line
344
$console->showHeader($suppress);
349
protected static function runCommand(Console $console): int
351
$exit = $console->run();
353
return is_int($exit) ? $exit : EXIT_SUCCESS;