Subversion-Projekte lars-tiefland.ci

Revision

Revision 2258 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
68 lars 1
<?php
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
2414 lars 9
 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
68 lars 10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
2414 lars 32
 * @copyright	Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
33
 * @license	https://opensource.org/licenses/MIT	MIT License
68 lars 34
 * @link	https://codeigniter.com
35
 * @since	Version 1.0.0
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
 
40
/**
41
 * System Initialization File
42
 *
43
 * Loads the base classes and executes the request.
44
 *
45
 * @package		CodeIgniter
46
 * @subpackage	CodeIgniter
47
 * @category	Front-controller
48
 * @author		EllisLab Dev Team
49
 * @link		https://codeigniter.com/user_guide/
50
 */
51
 
52
/**
53
 * CodeIgniter Version
54
 *
55
 * @var	string
56
 *
57
 */
2414 lars 58
	const CI_VERSION = '3.1.11';
68 lars 59
 
60
/*
61
 * ------------------------------------------------------
62
 *  Load the framework constants
63
 * ------------------------------------------------------
64
 */
65
	if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
66
	{
67
		require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
68
	}
69
 
2049 lars 70
	if (file_exists(APPPATH.'config/constants.php'))
71
	{
72
		require_once(APPPATH.'config/constants.php');
73
	}
68 lars 74
 
75
/*
76
 * ------------------------------------------------------
77
 *  Load the global functions
78
 * ------------------------------------------------------
79
 */
80
	require_once(BASEPATH.'core/Common.php');
81
 
82
 
83
/*
84
 * ------------------------------------------------------
85
 * Security procedures
86
 * ------------------------------------------------------
87
 */
88
 
89
if ( ! is_php('5.4'))
90
{
91
	ini_set('magic_quotes_runtime', 0);
92
 
93
	if ((bool) ini_get('register_globals'))
94
	{
95
		$_protected = array(
96
			'_SERVER',
97
			'_GET',
98
			'_POST',
99
			'_FILES',
100
			'_REQUEST',
101
			'_SESSION',
102
			'_ENV',
103
			'_COOKIE',
104
			'GLOBALS',
105
			'HTTP_RAW_POST_DATA',
106
			'system_path',
107
			'application_folder',
108
			'view_folder',
109
			'_protected',
110
			'_registered'
111
		);
112
 
113
		$_registered = ini_get('variables_order');
114
		foreach (array('E' => '_ENV', 'G' => '_GET', 'P' => '_POST', 'C' => '_COOKIE', 'S' => '_SERVER') as $key => $superglobal)
115
		{
116
			if (strpos($_registered, $key) === FALSE)
117
			{
118
				continue;
119
			}
120
 
121
			foreach (array_keys($$superglobal) as $var)
122
			{
123
				if (isset($GLOBALS[$var]) && ! in_array($var, $_protected, TRUE))
124
				{
125
					$GLOBALS[$var] = NULL;
126
				}
127
			}
128
		}
129
	}
130
}
131
 
132
 
133
/*
134
 * ------------------------------------------------------
135
 *  Define a custom error handler so we can log PHP errors
136
 * ------------------------------------------------------
137
 */
138
	set_error_handler('_error_handler');
139
	set_exception_handler('_exception_handler');
140
	register_shutdown_function('_shutdown_handler');
141
 
142
/*
143
 * ------------------------------------------------------
144
 *  Set the subclass_prefix
145
 * ------------------------------------------------------
146
 *
147
 * Normally the "subclass_prefix" is set in the config file.
148
 * The subclass prefix allows CI to know if a core class is
149
 * being extended via a library in the local application
150
 * "libraries" folder. Since CI allows config items to be
151
 * overridden via data set in the main index.php file,
152
 * before proceeding we need to know if a subclass_prefix
153
 * override exists. If so, we will set this value now,
154
 * before any classes are loaded
155
 * Note: Since the config file data is cached it doesn't
156
 * hurt to load it here.
157
 */
158
	if ( ! empty($assign_to_config['subclass_prefix']))
159
	{
160
		get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
161
	}
162
 
163
/*
164
 * ------------------------------------------------------
165
 *  Should we use a Composer autoloader?
166
 * ------------------------------------------------------
167
 */
168
	if ($composer_autoload = config_item('composer_autoload'))
169
	{
170
		if ($composer_autoload === TRUE)
171
		{
172
			file_exists(APPPATH.'vendor/autoload.php')
173
				? require_once(APPPATH.'vendor/autoload.php')
174
				: log_message('error', '$config[\'composer_autoload\'] is set to TRUE but '.APPPATH.'vendor/autoload.php was not found.');
175
		}
176
		elseif (file_exists($composer_autoload))
177
		{
178
			require_once($composer_autoload);
179
		}
180
		else
181
		{
182
			log_message('error', 'Could not find the specified $config[\'composer_autoload\'] path: '.$composer_autoload);
183
		}
184
	}
185
 
186
/*
187
 * ------------------------------------------------------
188
 *  Start the timer... tick tock tick tock...
189
 * ------------------------------------------------------
190
 */
191
	$BM =& load_class('Benchmark', 'core');
192
	$BM->mark('total_execution_time_start');
193
	$BM->mark('loading_time:_base_classes_start');
194
 
195
/*
196
 * ------------------------------------------------------
197
 *  Instantiate the hooks class
198
 * ------------------------------------------------------
199
 */
200
	$EXT =& load_class('Hooks', 'core');
201
 
202
/*
203
 * ------------------------------------------------------
204
 *  Is there a "pre_system" hook?
205
 * ------------------------------------------------------
206
 */
207
	$EXT->call_hook('pre_system');
208
 
209
/*
210
 * ------------------------------------------------------
211
 *  Instantiate the config class
212
 * ------------------------------------------------------
213
 *
214
 * Note: It is important that Config is loaded first as
215
 * most other classes depend on it either directly or by
216
 * depending on another class that uses it.
217
 *
218
 */
219
	$CFG =& load_class('Config', 'core');
220
 
221
	// Do we have any manually set config items in the index.php file?
222
	if (isset($assign_to_config) && is_array($assign_to_config))
223
	{
224
		foreach ($assign_to_config as $key => $value)
225
		{
226
			$CFG->set_item($key, $value);
227
		}
228
	}
229
 
230
/*
231
 * ------------------------------------------------------
232
 * Important charset-related stuff
233
 * ------------------------------------------------------
234
 *
235
 * Configure mbstring and/or iconv if they are enabled
236
 * and set MB_ENABLED and ICONV_ENABLED constants, so
237
 * that we don't repeatedly do extension_loaded() or
238
 * function_exists() calls.
239
 *
240
 * Note: UTF-8 class depends on this. It used to be done
241
 * in it's constructor, but it's _not_ class-specific.
242
 *
243
 */
244
	$charset = strtoupper(config_item('charset'));
245
	ini_set('default_charset', $charset);
246
 
247
	if (extension_loaded('mbstring'))
248
	{
249
		define('MB_ENABLED', TRUE);
250
		// mbstring.internal_encoding is deprecated starting with PHP 5.6
251
		// and it's usage triggers E_DEPRECATED messages.
252
		@ini_set('mbstring.internal_encoding', $charset);
253
		// This is required for mb_convert_encoding() to strip invalid characters.
254
		// That's utilized by CI_Utf8, but it's also done for consistency with iconv.
255
		mb_substitute_character('none');
256
	}
257
	else
258
	{
259
		define('MB_ENABLED', FALSE);
260
	}
261
 
262
	// There's an ICONV_IMPL constant, but the PHP manual says that using
263
	// iconv's predefined constants is "strongly discouraged".
264
	if (extension_loaded('iconv'))
265
	{
266
		define('ICONV_ENABLED', TRUE);
267
		// iconv.internal_encoding is deprecated starting with PHP 5.6
268
		// and it's usage triggers E_DEPRECATED messages.
269
		@ini_set('iconv.internal_encoding', $charset);
270
	}
271
	else
272
	{
273
		define('ICONV_ENABLED', FALSE);
274
	}
275
 
276
	if (is_php('5.6'))
277
	{
278
		ini_set('php.internal_encoding', $charset);
279
	}
280
 
281
/*
282
 * ------------------------------------------------------
283
 *  Load compatibility features
284
 * ------------------------------------------------------
285
 */
286
 
287
	require_once(BASEPATH.'core/compat/mbstring.php');
288
	require_once(BASEPATH.'core/compat/hash.php');
289
	require_once(BASEPATH.'core/compat/password.php');
290
	require_once(BASEPATH.'core/compat/standard.php');
291
 
292
/*
293
 * ------------------------------------------------------
294
 *  Instantiate the UTF-8 class
295
 * ------------------------------------------------------
296
 */
297
	$UNI =& load_class('Utf8', 'core');
298
 
299
/*
300
 * ------------------------------------------------------
301
 *  Instantiate the URI class
302
 * ------------------------------------------------------
303
 */
304
	$URI =& load_class('URI', 'core');
305
 
306
/*
307
 * ------------------------------------------------------
308
 *  Instantiate the routing class and set the routing
309
 * ------------------------------------------------------
310
 */
311
	$RTR =& load_class('Router', 'core', isset($routing) ? $routing : NULL);
312
 
313
/*
314
 * ------------------------------------------------------
315
 *  Instantiate the output class
316
 * ------------------------------------------------------
317
 */
318
	$OUT =& load_class('Output', 'core');
319
 
320
/*
321
 * ------------------------------------------------------
322
 *	Is there a valid cache file? If so, we're done...
323
 * ------------------------------------------------------
324
 */
325
	if ($EXT->call_hook('cache_override') === FALSE && $OUT->_display_cache($CFG, $URI) === TRUE)
326
	{
327
		exit;
328
	}
329
 
330
/*
331
 * -----------------------------------------------------
332
 * Load the security class for xss and csrf support
333
 * -----------------------------------------------------
334
 */
335
	$SEC =& load_class('Security', 'core');
336
 
337
/*
338
 * ------------------------------------------------------
339
 *  Load the Input class and sanitize globals
340
 * ------------------------------------------------------
341
 */
342
	$IN	=& load_class('Input', 'core');
343
 
344
/*
345
 * ------------------------------------------------------
346
 *  Load the Language class
347
 * ------------------------------------------------------
348
 */
349
	$LANG =& load_class('Lang', 'core');
350
 
351
/*
352
 * ------------------------------------------------------
353
 *  Load the app controller and local controller
354
 * ------------------------------------------------------
355
 *
356
 */
357
	// Load the base controller class
358
	require_once BASEPATH.'core/Controller.php';
359
 
360
	/**
361
	 * Reference to the CI_Controller method.
362
	 *
363
	 * Returns current CI instance object
364
	 *
365
	 * @return CI_Controller
366
	 */
367
	function &get_instance()
368
	{
369
		return CI_Controller::get_instance();
370
	}
371
 
372
	if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
373
	{
374
		require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
375
	}
376
 
377
	// Set a mark point for benchmarking
378
	$BM->mark('loading_time:_base_classes_end');
379
 
380
/*
381
 * ------------------------------------------------------
382
 *  Sanity checks
383
 * ------------------------------------------------------
384
 *
385
 *  The Router class has already validated the request,
386
 *  leaving us with 3 options here:
387
 *
388
 *	1) an empty class name, if we reached the default
389
 *	   controller, but it didn't exist;
390
 *	2) a query string which doesn't go through a
391
 *	   file_exists() check
392
 *	3) a regular request for a non-existing page
393
 *
394
 *  We handle all of these as a 404 error.
395
 *
396
 *  Furthermore, none of the methods in the app controller
397
 *  or the loader class can be called via the URI, nor can
398
 *  controller methods that begin with an underscore.
399
 */
400
 
401
	$e404 = FALSE;
402
	$class = ucfirst($RTR->class);
403
	$method = $RTR->method;
404
 
405
	if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
406
	{
407
		$e404 = TRUE;
408
	}
409
	else
410
	{
411
		require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
412
 
413
		if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
414
		{
415
			$e404 = TRUE;
416
		}
417
		elseif (method_exists($class, '_remap'))
418
		{
419
			$params = array($method, array_slice($URI->rsegments, 2));
420
			$method = '_remap';
421
		}
1257 lars 422
		elseif ( ! method_exists($class, $method))
68 lars 423
		{
424
			$e404 = TRUE;
425
		}
1257 lars 426
		/**
427
		 * DO NOT CHANGE THIS, NOTHING ELSE WORKS!
428
		 *
429
		 * - method_exists() returns true for non-public methods, which passes the previous elseif
430
		 * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct()
431
		 * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited
432
		 * - People will only complain if this doesn't work, even though it is documented that it shouldn't.
433
		 *
434
		 * ReflectionMethod::isConstructor() is the ONLY reliable check,
435
		 * knowing which method will be executed as a constructor.
436
		 */
2107 lars 437
		elseif ( ! is_callable(array($class, $method)))
1257 lars 438
		{
439
			$reflection = new ReflectionMethod($class, $method);
440
			if ( ! $reflection->isPublic() OR $reflection->isConstructor())
441
			{
442
				$e404 = TRUE;
443
			}
444
		}
68 lars 445
	}
446
 
447
	if ($e404)
448
	{
449
		if ( ! empty($RTR->routes['404_override']))
450
		{
451
			if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2)
452
			{
453
				$error_method = 'index';
454
			}
455
 
456
			$error_class = ucfirst($error_class);
457
 
458
			if ( ! class_exists($error_class, FALSE))
459
			{
460
				if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
461
				{
462
					require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
463
					$e404 = ! class_exists($error_class, FALSE);
464
				}
465
				// Were we in a directory? If so, check for a global override
466
				elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
467
				{
468
					require_once(APPPATH.'controllers/'.$error_class.'.php');
469
					if (($e404 = ! class_exists($error_class, FALSE)) === FALSE)
470
					{
471
						$RTR->directory = '';
472
					}
473
				}
474
			}
475
			else
476
			{
477
				$e404 = FALSE;
478
			}
479
		}
480
 
481
		// Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
482
		if ( ! $e404)
483
		{
484
			$class = $error_class;
485
			$method = $error_method;
486
 
487
			$URI->rsegments = array(
488
				1 => $class,
489
				2 => $method
490
			);
491
		}
492
		else
493
		{
494
			show_404($RTR->directory.$class.'/'.$method);
495
		}
496
	}
497
 
498
	if ($method !== '_remap')
499
	{
500
		$params = array_slice($URI->rsegments, 2);
501
	}
502
 
503
/*
504
 * ------------------------------------------------------
505
 *  Is there a "pre_controller" hook?
506
 * ------------------------------------------------------
507
 */
508
	$EXT->call_hook('pre_controller');
509
 
510
/*
511
 * ------------------------------------------------------
512
 *  Instantiate the requested controller
513
 * ------------------------------------------------------
514
 */
515
	// Mark a start point so we can benchmark the controller
516
	$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
517
 
518
	$CI = new $class();
519
 
520
/*
521
 * ------------------------------------------------------
522
 *  Is there a "post_controller_constructor" hook?
523
 * ------------------------------------------------------
524
 */
525
	$EXT->call_hook('post_controller_constructor');
526
 
527
/*
528
 * ------------------------------------------------------
529
 *  Call the requested method
530
 * ------------------------------------------------------
531
 */
532
	call_user_func_array(array(&$CI, $method), $params);
533
 
534
	// Mark a benchmark end point
535
	$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
536
 
537
/*
538
 * ------------------------------------------------------
539
 *  Is there a "post_controller" hook?
540
 * ------------------------------------------------------
541
 */
542
	$EXT->call_hook('post_controller');
543
 
544
/*
545
 * ------------------------------------------------------
546
 *  Send the final rendered output to the browser
547
 * ------------------------------------------------------
548
 */
549
	if ($EXT->call_hook('display_override') === FALSE)
550
	{
551
		$OUT->_display();
552
	}
553
 
554
/*
555
 * ------------------------------------------------------
556
 *  Is there a "post_system" hook?
557
 * ------------------------------------------------------
558
 */
559
	$EXT->call_hook('post_system');