无聊,决定水一把。
CI(CodeIgniter)是我最早接触的一个框架,到现在也只是用了其中一点零碎的方法。一直想对其流程做个小结,却总是因各种各样的“理由”挨着。看见别人图表齐上阵,没那耐心,就从代码说起吧,权当做个笔记,纪念一下。
看在线的用户手册,也知道,将CI下载下来(最新版本2.2.1),解压到机子上,比如www目录,可改个根目录名(原名CodeIgniter-2.2-stable太长),初步目录文件如下,当然这在是windows下面。
访问下,如localhost/ci/index.php,就进入CI默认的Welcome页面
如何一步步加载这个页面的?首先访问的是index.php脚本
<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span> <span> 4</span> <span> *--------------------------------------------------------------- </span><span> 5</span> <span> * APPLICATION ENVIRONMENT </span><span> 6</span> <span> *--------------------------------------------------------------- </span><span> 7</span> <span> * </span><span> 8</span> <span> * You can load different configurations depending on your </span><span> 9</span> <span> * current environment. Setting the environment also influences </span><span> 10</span> <span> * things like logging and error reporting. </span><span> 11</span> <span> * </span><span> 12</span> <span> * This can be set to anything, but default usage is: </span><span> 13</span> <span> * </span><span> 14</span> <span> * development </span><span> 15</span> <span> * testing </span><span> 16</span> <span> * production </span><span> 17</span> <span> * </span><span> 18</span> <span> * NOTE: If you change these, also change the error_reporting() code below </span><span> 19</span> <span> * </span><span> 20</span> <span>*/</span> <span> 21</span> <span>define</span>('ENVIRONMENT', 'development'<span>); </span><span> 22</span> <span>/*</span> <span> 23</span> <span> *--------------------------------------------------------------- </span><span> 24</span> <span> * ERROR REPORTING </span><span> 25</span> <span> *--------------------------------------------------------------- </span><span> 26</span> <span> * </span><span> 27</span> <span> * Different environments will require different levels of error reporting. </span><span> 28</span> <span> * By default development will show errors but testing and live will hide them. </span><span> 29</span> <span>*/</span> <span> 30</span> <span> 31</span> <span>if</span> (<span>defined</span>('ENVIRONMENT'<span>)) </span><span> 32</span> <span>{ </span><span> 33</span> <span>switch</span><span> (ENVIRONMENT) </span><span> 34</span> <span> { </span><span> 35</span> <span>case</span> 'development': <span> 36</span> <span>error_reporting</span>(<span>E_ALL</span><span>); </span><span> 37</span> <span>break</span><span>; </span><span> 38</span> <span> 39</span> <span>case</span> 'testing': <span> 40</span> <span>case</span> 'production': <span> 41</span> <span>error_reporting</span>(0<span>); </span><span> 42</span> <span>break</span><span>; </span><span> 43</span> <span> 44</span> <span>default</span>: <span> 45</span> <span>exit</span>('The application environment is not set correctly.'<span>); </span><span> 46</span> <span> } </span><span> 47</span> <span>} </span><span> 48</span> <span> 49</span> <span>/*</span> <span> 50</span> <span> *--------------------------------------------------------------- </span><span> 51</span> <span> * SYSTEM FOLDER NAME </span><span> 52</span> <span> *--------------------------------------------------------------- </span><span> 53</span> <span> * </span><span> 54</span> <span> * This variable must contain the name of your "system" folder. </span><span> 55</span> <span> * Include the path if the folder is not in the same directory </span><span> 56</span> <span> * as this file. </span><span> 57</span> <span> * </span><span> 58</span> <span>*/</span> <span> 59</span> <span>$system_path</span> = 'system'<span>; </span><span> 60</span> <span> 61</span> <span>/*</span> <span> 62</span> <span> *--------------------------------------------------------------- </span><span> 63</span> <span> * APPLICATION FOLDER NAME </span><span> 64</span> <span> *--------------------------------------------------------------- </span><span> 65</span> <span> * </span><span> 66</span> <span> * If you want this front controller to use a different "application" </span><span> 67</span> <span> * folder then the default one you can set its name here. The folder </span><span> 68</span> <span> * can also be renamed or relocated anywhere on your server. If </span><span> 69</span> <span> * you do, use a full server path. For more info please see the user guide: </span><span> 70</span> <span> * http://codeigniter.com/user_guide/general/managing_apps.html </span><span> 71</span> <span> * </span><span> 72</span> <span> * NO TRAILING SLASH! </span><span> 73</span> <span> * </span><span> 74</span> <span>*/</span> <span> 75</span> <span>$application_folder</span> = 'application'<span>; </span><span> 76</span> <span> 77</span> <span>/*</span> <span> 78</span> <span> * -------------------------------------------------------------------- </span><span> 79</span> <span> * DEFAULT CONTROLLER </span><span> 80</span> <span> * -------------------------------------------------------------------- </span><span> 81</span> <span> * </span><span> 82</span> <span> * Normally you will set your default controller in the routes.php file. </span><span> 83</span> <span> * You can, however, force a custom routing by hard-coding a </span><span> 84</span> <span> * specific controller class/function here. For most applications, you </span><span> 85</span> <span> * WILL NOT set your routing here, but it's an option for those </span><span> 86</span> <span> * special instances where you might want to override the standard </span><span> 87</span> <span> * routing in a specific front controller that shares a common CI installation. </span><span> 88</span> <span> * </span><span> 89</span> <span> * IMPORTANT: If you set the routing here, NO OTHER controller will be </span><span> 90</span> <span> * callable. In essence, this preference limits your application to ONE </span><span> 91</span> <span> * specific controller. Leave the function name blank if you need </span><span> 92</span> <span> * to call functions dynamically via the URI. </span><span> 93</span> <span> * </span><span> 94</span> <span> * Un-comment the $routing array below to use this feature </span><span> 95</span> <span> * </span><span> 96</span> <span>*/</span> <span> 97</span> <span>//</span><span> The directory name, relative to the "controllers" folder. Leave blank </span><span> 98</span> <span> // if your controller is not in a sub-folder within the "controllers" folder </span><span> 99</span> <span> // $routing['directory'] = ''; </span><span>100</span> <span>101</span> <span> // The controller class file name. Example: Mycontroller </span><span>102</span> <span> // $routing['controller'] = ''; </span><span>103</span> <span>104</span> <span> // The controller function you wish to be called. </span><span>105</span> <span> // $routing['function'] = '';</span> <span>106</span> <span>107</span> <span>108</span> <span>/*</span> <span>109</span> <span> * ------------------------------------------------------------------- </span><span>110</span> <span> * CUSTOM CONFIG VALUES </span><span>111</span> <span> * ------------------------------------------------------------------- </span><span>112</span> <span> * </span><span>113</span> <span> * The $assign_to_config array below will be passed dynamically to the </span><span>114</span> <span> * config class when initialized. This allows you to set custom config </span><span>115</span> <span> * items or override any default config values found in the config.php file. </span><span>116</span> <span> * This can be handy as it permits you to share one application between </span><span>117</span> <span> * multiple front controller files, with each file containing different </span><span>118</span> <span> * config values. </span><span>119</span> <span> * </span><span>120</span> <span> * Un-comment the $assign_to_config array below to use this feature </span><span>121</span> <span> * </span><span>122</span> <span>*/</span> <span>123</span> <span>//</span><span> $assign_to_config['name_of_config_item'] = 'value of config item'; </span><span>124</span> <span>125</span> <span>126</span> <span>127</span> <span>// -------------------------------------------------------------------- </span><span>128</span> <span>// END OF USER CONFIGURABLE SETTINGS. DO NOT EDIT BELOW THIS LINE </span><span>129</span> <span>// --------------------------------------------------------------------</span> <span>130</span> <span>131</span> <span>/*</span> <span>132</span> <span> * --------------------------------------------------------------- </span><span>133</span> <span> * Resolve the system path for increased reliability </span><span>134</span> <span> * --------------------------------------------------------------- </span><span>135</span> <span>*/</span> <span>136</span> <span>137</span> <span>//</span><span> Set the current directory correctly for CLI requests</span> <span>138</span> <span>if</span> (<span>defined</span>('STDIN'<span>)) </span><span>139</span> <span> { </span><span>140</span> <span>chdir</span>(<span>dirname</span>(<span>__FILE__</span><span>)); </span><span>141</span> <span> } </span><span>142</span> <span>143</span> <span>if</span> (<span>realpath</span>(<span>$system_path</span>) !== <span>FALSE</span><span>) </span><span>144</span> <span> { </span><span>145</span> <span>$system_path</span> = <span>realpath</span>(<span>$system_path</span>).'/'<span>; </span><span>146</span> <span> } </span><span>147</span> <span>148</span> <span>//</span><span> ensure there's a trailing slash</span> <span>149</span> <span>$system_path</span> = <span>rtrim</span>(<span>$system_path</span>, '/').'/'<span>; </span><span>150</span> <span>151</span> <span>//</span><span> Is the system path correct?</span> <span>152</span> <span>if</span> ( ! <span>is_dir</span>(<span>$system_path</span><span>)) </span><span>153</span> <span> { </span><span>154</span> <span>exit</span>("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".<span>pathinfo</span>(<span>__FILE__</span>,<span> PATHINFO_BASENAME)); </span><span>155</span> <span> } </span><span>156</span> <span>157</span> <span>/*</span> <span>158</span> <span> * ------------------------------------------------------------------- </span><span>159</span> <span> * Now that we know the path, set the main path constants </span><span>160</span> <span> * ------------------------------------------------------------------- </span><span>161</span> <span>*/</span> <span>162</span> <span>//</span><span> The name of THIS file</span> <span>163</span> <span>define</span>('SELF', <span>pathinfo</span>(<span>__FILE__</span>,<span> PATHINFO_BASENAME)); </span><span>164</span> <span>165</span> <span>//</span><span> The PHP file extension </span><span>166</span> <span> // this global constant is deprecated.</span> <span>167</span> <span>define</span>('EXT', '.php'<span>); </span><span>168</span> <span>169</span> <span>//</span><span> Path to the system folder</span> <span>170</span> <span>define</span>('BASEPATH', <span>str_replace</span>("\\", "/", <span>$system_path</span><span>)); </span><span>171</span> <span>172</span> <span>//</span><span> Path to the front controller (this file)</span> <span>173</span> <span>define</span>('FCPATH', <span>str_replace</span>(SELF, '', <span>__FILE__</span><span>)); </span><span>174</span> <span>175</span> <span>//</span><span> Name of the "system folder"</span> <span>176</span> <span>define</span>('SYSDIR', <span>trim</span>(<span>strrchr</span>(<span>trim</span>(BASEPATH, '/'), '/'), '/'<span>)); </span><span>177</span> <span>178</span> <span>179</span> <span>//</span><span> The path to the "application" folder</span> <span>180</span> <span>if</span> (<span>is_dir</span>(<span>$application_folder</span><span>)) </span><span>181</span> <span> { </span><span>182</span> <span>define</span>('APPPATH', <span>$application_folder</span>.'/'<span>); </span><span>183</span> <span> } </span><span>184</span> <span>else</span> <span>185</span> <span> { </span><span>186</span> <span>if</span> ( ! <span>is_dir</span>(BASEPATH.<span>$application_folder</span>.'/'<span>)) </span><span>187</span> <span> { </span><span>188</span> <span>exit</span>("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".<span>SELF); </span><span>189</span> <span> } </span><span>190</span> <span>191</span> <span>define</span>('APPPATH', BASEPATH.<span>$application_folder</span>.'/'<span>); </span><span>192</span> <span> } </span><span>193</span> <span>194</span> <span>/*</span> <span>195</span> <span> * -------------------------------------------------------------------- </span><span>196</span> <span> * LOAD THE BOOTSTRAP FILE </span><span>197</span> <span> * -------------------------------------------------------------------- </span><span>198</span> <span> * </span><span>199</span> <span> * And away we go... </span><span>200</span> <span> * </span><span>201</span> <span>*/</span> <span>202</span> <span>require_once</span> BASEPATH.'core/CodeIgniter.php'<span>; </span><span>203</span> <span>204</span> <span>/*</span><span> End of file index.php </span><span>*/</span> <span>205</span> <span>/*</span><span> Location: ./index.php </span><span>*/</span>
21行:首先定义一个ENVIRONMENT常量为development,即开发环境。
31-47行:switch语句,由于当前环境是development,所以是设置报告所有级别的错误。
49-59行:$system_path变量定义CI的默认的系统脚本目录是 system,61-75行定义当前默认的供我们主要开发用的目录为 application。
77-105行:全部注释掉了,这里是我们可以强制设置系统加载时默认的目录名($routing['directory'])、控制器名($routing['directory'])和方法名($routing['directory']),虽然一般这些是设置在application\config\routes.php中(下图),访问的Welcome页面也是通过这个默认控制器Welcome类进行的,这里只是作为一个选择性的方式,其实没必要弄
108-129行:全部注释掉,用于自定义配置变量(CUSTOM CONFIG VALUES),前一篇说过,任何后端project中,总有些配置信息,只是各个项目或框架加载方式不同,这个$assign_to_config数组就存放我们的自定义配置信息,如$assign_to_config['home'] = 'localhost'; ,之所以注释掉,又是因为这只是一个可选的操作,CI的用户自定义配置信息,一般放在application\config目录下边,以自动加载信息(autoload.php),普通配置信息(config.php)、常量(constants.php)、数据库(database.php)等分开文件存储,所以一般不会在这里的去配置一个要用到的变量,$assign_to_config默认是没有定义的。
从131行到index.php文件末尾主要是对一些路径变量的定义。
137-141行:是为CLI(Command-Interface Line)的调用方式准备的,是直接在Mac/Linux系统上通过终端命令运行脚本,这个在CI中文官网(http://codeigniter.org.cn/user_guide/general/cli.html)也有介绍,如果定义了名为STDIN的常量,则将执行目录改为当前文件所在目录,当然前面没有出现过STDIN这个常量的定义,这里就不会执行了。
143-155行:确定框架存放系统脚本的目录变量$system_path,也就是前面图中的system目录,这里会检测它的有效性,无效的话程序就挂在这里了。
157-192行:定义若干主要目录常量,分别是SELF:当前脚本的文件名、EXT:脚本扩展名、BASEPATH:system目录的路径、FCPATH:当前脚本所在的目录、SYSDIR:system目录的目录名,不改动的话就是system。
179-194行:定义APPPATH常量,确定application所在的目录,就是以后我们主要开发的地方,使用is_dir检测,稍微注意的是is_dir可以检测相对目录,所以实际运行的是if里边的代码,APPPATH得到的是相对路径。
最后打印看看这些变(常)量的值都是啥,有的与存放目录相关:
202行:加载BASEPATH.'core/CodeIgniter.php'脚本,就是system目录下的核心类文件目录下的文件,进入到CI的核心类目录下的文件了。
=====================================================================================================
<span> 1</span> <?php <span>if</span> ( ! <span>defined</span>('BASEPATH')) <span>exit</span>('No direct script access allowed'<span>); </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span> * CodeIgniter </span><span> 4</span> <span> * </span><span> 5</span> <span> * An open source application development framework for PHP 5.1.6 or newer </span><span> 6</span> <span> * </span><span> 7</span> <span> * @package CodeIgniter </span><span> 8</span> <span> * @author EllisLab Dev Team </span><span> 9</span> <span> * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. </span><span> 10</span> <span> * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) </span><span> 11</span> <span> * @license http://codeigniter.com/user_guide/license.html </span><span> 12</span> <span> * @link http://codeigniter.com </span><span> 13</span> <span> * @since Version 1.0 </span><span> 14</span> <span> * @filesource </span><span> 15</span> <span>*/</span> <span> 16</span> <span> 17</span> <span>//</span><span> ------------------------------------------------------------------------</span> <span> 18</span> <span> 19</span> <span>/*</span><span>* </span><span> 20</span> <span> * System Initialization File </span><span> 21</span> <span> * </span><span> 22</span> <span> * Loads the base classes and executes the request. </span><span> 23</span> <span> * </span><span> 24</span> <span> * @package CodeIgniter </span><span> 25</span> <span> * @subpackage codeigniter </span><span> 26</span> <span> * @category Front-controller </span><span> 27</span> <span> * @author EllisLab Dev Team </span><span> 28</span> <span> * @link http://codeigniter.com/user_guide/ </span><span> 29</span> <span>*/</span> <span> 30</span> <span> 31</span> <span>/*</span><span>* </span><span> 32</span> <span> * CodeIgniter Version </span><span> 33</span> <span> * </span><span> 34</span> <span> * @var string </span><span> 35</span> <span> * </span><span> 36</span> <span>*/</span> <span> 37</span> <span>define</span>('CI_VERSION', '2.2.1'<span>); </span><span> 38</span> <span> 39</span> <span>/*</span><span>* </span><span> 40</span> <span> * CodeIgniter Branch (Core = TRUE, Reactor = FALSE) </span><span> 41</span> <span> * </span><span> 42</span> <span> * @var boolean </span><span> 43</span> <span> * </span><span> 44</span> <span>*/</span> <span> 45</span> <span>define</span>('CI_CORE', <span>FALSE</span><span>); </span><span> 46</span> <span> 47</span> <span>/*</span> <span> 48</span> <span> * ------------------------------------------------------ </span><span> 49</span> <span> * Load the global functions </span><span> 50</span> <span> * ------------------------------------------------------ </span><span> 51</span> <span>*/</span> <span> 52</span> <span>require</span>(BASEPATH.'core/Common.php'<span>); </span><span> 53</span> <span> 54</span> <span>/*</span> <span> 55</span> <span> * ------------------------------------------------------ </span><span> 56</span> <span> * Load the framework constants </span><span> 57</span> <span> * ------------------------------------------------------ </span><span> 58</span> <span>*/</span> <span> 59</span> <span>if</span> (<span>defined</span>('ENVIRONMENT') AND <span>file_exists</span>(APPPATH.'config/'.ENVIRONMENT.'/constants.php'<span>)) </span><span> 60</span> <span> { </span><span> 61</span> <span>require</span>(APPPATH.'config/'.ENVIRONMENT.'/constants.php'<span>); </span><span> 62</span> <span> } </span><span> 63</span> <span>else</span> <span> 64</span> <span> { </span><span> 65</span> <span>require</span>(APPPATH.'config/constants.php'<span>); </span><span> 66</span> <span> } </span><span> 67</span> <span> 68</span> <span>/*</span> <span> 69</span> <span> * ------------------------------------------------------ </span><span> 70</span> <span> * Define a custom error handler so we can log PHP errors </span><span> 71</span> <span> * ------------------------------------------------------ </span><span> 72</span> <span>*/</span> <span> 73</span> <span>set_error_handler</span>('_exception_handler'<span>); </span><span> 74</span> <span> 75</span> <span>if</span> ( ! is_php('5.3'<span>)) </span><span> 76</span> <span> { </span><span> 77</span> @<span>set_magic_quotes_runtime</span>(0); <span>//</span><span> Kill magic quotes</span> <span> 78</span> <span> } </span><span> 79</span> <span> 80</span> <span>/*</span> <span> 81</span> <span> * ------------------------------------------------------ </span><span> 82</span> <span> * Set the subclass_prefix </span><span> 83</span> <span> * ------------------------------------------------------ </span><span> 84</span> <span> * </span><span> 85</span> <span> * Normally the "subclass_prefix" is set in the config file. </span><span> 86</span> <span> * The subclass prefix allows CI to know if a core class is </span><span> 87</span> <span> * being extended via a library in the local application </span><span> 88</span> <span> * "libraries" folder. Since CI allows config items to be </span><span> 89</span> <span> * overriden via data set in the main index. php file, </span><span> 90</span> <span> * before proceeding we need to know if a subclass_prefix </span><span> 91</span> <span> * override exists. If so, we will set this value now, </span><span> 92</span> <span> * before any classes are loaded </span><span> 93</span> <span> * Note: Since the config file data is cached it doesn't </span><span> 94</span> <span> * hurt to load it here. </span><span> 95</span> <span>*/</span> <span> 96</span> <span>if</span> (<span>isset</span>(<span>$assign_to_config</span>['subclass_prefix']) AND <span>$assign_to_config</span>['subclass_prefix'] != ''<span>) </span><span> 97</span> <span> { </span><span> 98</span> get_config(<span>array</span>('subclass_prefix' => <span>$assign_to_config</span>['subclass_prefix'<span>])); </span><span> 99</span> <span> } </span><span>100</span> <span>101</span> <span>/*</span> <span>102</span> <span> * ------------------------------------------------------ </span><span>103</span> <span> * Set a liberal script execution time limit </span><span>104</span> <span> * ------------------------------------------------------ </span><span>105</span> <span>*/</span> <span>106</span> <span>if</span> (<span>function_exists</span>("set_time_limit") == <span>TRUE</span> AND @<span>ini_get</span>("safe_mode") == 0<span>) </span><span>107</span> <span> { </span><span>108</span> @<span>set_time_limit</span>(300<span>); </span><span>109</span> <span> } </span><span>110</span> <span>111</span> <span>/*</span> <span>112</span> <span> * ------------------------------------------------------ </span><span>113</span> <span> * Start the timer... tick tock tick tock... </span><span>114</span> <span> * ------------------------------------------------------ </span><span>115</span> <span>*/</span> <span>116</span> <span>$BM</span> =& load_class('Benchmark', 'core'<span>); </span><span>117</span> <span>$BM</span>->mark('total_execution_time_start'<span>); </span><span>118</span> <span>$BM</span>->mark('loading_time:_base_classes_start'<span>); </span><span>119</span> <span>120</span> <span>/*</span> <span>121</span> <span> * ------------------------------------------------------ </span><span>122</span> <span> * Instantiate the hooks class </span><span>123</span> <span> * ------------------------------------------------------ </span><span>124</span> <span>*/</span> <span>125</span> <span>$EXT</span> =& load_class('Hooks', 'core'<span>); </span><span>126</span> <span>127</span> <span>/*</span> <span>128</span> <span> * ------------------------------------------------------ </span><span>129</span> <span> * Is there a "pre_system" hook? </span><span>130</span> <span> * ------------------------------------------------------ </span><span>131</span> <span>*/</span> <span>132</span> <span>$EXT</span>->_call_hook('pre_system'<span>); </span><span>133</span> <span>134</span> <span>/*</span> <span>135</span> <span> * ------------------------------------------------------ </span><span>136</span> <span> * Instantiate the config class </span><span>137</span> <span> * ------------------------------------------------------ </span><span>138</span> <span>*/</span> <span>139</span> <span>$CFG</span> =& load_class('Config', 'core'<span>); </span><span>140</span> <span>141</span> <span>//</span><span> Do we have any manually set config items in the index.php file?</span> <span>142</span> <span>if</span> (<span>isset</span>(<span>$assign_to_config</span><span>)) </span><span>143</span> <span> { </span><span>144</span> <span>$CFG</span>->_assign_to_config(<span>$assign_to_config</span><span>); </span><span>145</span> <span> } </span><span>146</span> <span>147</span> <span>/*</span> <span>148</span> <span> * ------------------------------------------------------ </span><span>149</span> <span> * Instantiate the UTF-8 class </span><span>150</span> <span> * ------------------------------------------------------ </span><span>151</span> <span> * </span><span>152</span> <span> * Note: Order here is rather important as the UTF-8 </span><span>153</span> <span> * class needs to be used very early on, but it cannot </span><span>154</span> <span> * properly determine if UTf-8 can be supported until </span><span>155</span> <span> * after the Config class is instantiated. </span><span>156</span> <span> * </span><span>157</span> <span>*/</span> <span>158</span> <span>159</span> <span>$UNI</span> =& load_class('Utf8', 'core'<span>); </span><span>160</span> <span>161</span> <span>/*</span> <span>162</span> <span> * ------------------------------------------------------ </span><span>163</span> <span> * Instantiate the URI class </span><span>164</span> <span> * ------------------------------------------------------ </span><span>165</span> <span>*/</span> <span>166</span> <span>$URI</span> =& load_class('URI', 'core'<span>); </span><span>167</span> <span>168</span> <span>/*</span> <span>169</span> <span> * ------------------------------------------------------ </span><span>170</span> <span> * Instantiate the routing class and set the routing </span><span>171</span> <span> * ------------------------------------------------------ </span><span>172</span> <span>*/</span> <span>173</span> <span>$RTR</span> =& load_class('Router', 'core'<span>); </span><span>174</span> <span>$RTR</span>-><span>_set_routing(); </span><span>175</span> <span>176</span> <span>//</span><span> Set any routing overrides that may exist in the main index file</span> <span>177</span> <span>if</span> (<span>isset</span>(<span>$routing</span><span>)) </span><span>178</span> <span> { </span><span>179</span> <span>$RTR</span>->_set_overrides(<span>$routing</span><span>); </span><span>180</span> <span> } </span><span>181</span> <span>182</span> <span>/*</span> <span>183</span> <span> * ------------------------------------------------------ </span><span>184</span> <span> * Instantiate the output class </span><span>185</span> <span> * ------------------------------------------------------ </span><span>186</span> <span>*/</span> <span>187</span> <span>$OUT</span> =& load_class('Output', 'core'<span>); </span><span>188</span> <span>189</span> <span>/*</span> <span>190</span> <span> * ------------------------------------------------------ </span><span>191</span> <span> * Is there a valid cache file? If so, we're done... </span><span>192</span> <span> * ------------------------------------------------------ </span><span>193</span> <span>*/</span> <span>194</span> <span>if</span> (<span>$EXT</span>->_call_hook('cache_override') === <span>FALSE</span><span>) </span><span>195</span> <span> { </span><span>196</span> <span>if</span> (<span>$OUT</span>->_display_cache(<span>$CFG</span>, <span>$URI</span>) == <span>TRUE</span><span>) </span><span>197</span> <span> { </span><span>198</span> <span>exit</span><span>; </span><span>199</span> <span> } </span><span>200</span> <span> } </span><span>201</span> <span>202</span> <span>/*</span> <span>203</span> <span> * ----------------------------------------------------- </span><span>204</span> <span> * Load the security class for xss and csrf support </span><span>205</span> <span> * ----------------------------------------------------- </span><span>206</span> <span>*/</span> <span>207</span> <span>$SEC</span> =& load_class('Security', 'core'<span>); </span><span>208</span> <span>209</span> <span>/*</span> <span>210</span> <span> * ------------------------------------------------------ </span><span>211</span> <span> * Load the Input class and sanitize globals </span><span>212</span> <span> * ------------------------------------------------------ </span><span>213</span> <span>*/</span> <span>214</span> <span>$IN</span> =& load_class('Input', 'core'<span>); </span><span>215</span> <span>216</span> <span>/*</span> <span>217</span> <span> * ------------------------------------------------------ </span><span>218</span> <span> * Load the Language class </span><span>219</span> <span> * ------------------------------------------------------ </span><span>220</span> <span>*/</span> <span>221</span> <span>$LANG</span> =& load_class('Lang', 'core'<span>); </span><span>222</span> <span>223</span> <span>/*</span> <span>224</span> <span> * ------------------------------------------------------ </span><span>225</span> <span> * Load the app controller and local controller </span><span>226</span> <span> * ------------------------------------------------------ </span><span>227</span> <span> * </span><span>228</span> <span>*/</span> <span>229</span> <span>//</span><span> Load the base controller class</span> <span>230</span> <span>require</span> BASEPATH.'core/Controller.php'<span>; </span><span>231</span> <span>232</span> <span>function</span> &<span>get_instance() </span><span>233</span> <span> { </span><span>234</span> <span>return</span> CI_Controller::<span>get_instance(); </span><span>235</span> <span> } </span><span>236</span> <span>237</span> <span>238</span> <span>if</span> (<span>file_exists</span>(APPPATH.'core/'.<span>$CFG</span>->config['subclass_prefix'].'Controller.php'<span>)) </span><span>239</span> <span> { </span><span>240</span> <span>require</span> APPPATH.'core/'.<span>$CFG</span>->config['subclass_prefix'].'Controller.php'<span>; </span><span>241</span> <span> } </span><span>242</span> <span>243</span> <span>//</span><span> Load the local application controller </span><span>244</span> <span> // Note: The Router class automatically validates the controller path using the router->_validate_request(). </span><span>245</span> <span> // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.</span> <span>246</span> <span>if</span> ( ! <span>file_exists</span>(APPPATH.'controllers/'.<span>$RTR</span>->fetch_directory().<span>$RTR</span>->fetch_class().'.php'<span>)) </span><span>247</span> <span> { </span><span>248</span> show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'<span>); </span><span>249</span> <span> } </span><span>250</span> <span>251</span> <span>include</span>(APPPATH.'controllers/'.<span>$RTR</span>->fetch_directory().<span>$RTR</span>->fetch_class().'.php'<span>); </span><span>252</span> <span>253</span> <span>//</span><span> Set a mark point for benchmarking</span> <span>254</span> <span>$BM</span>->mark('loading_time:_base_classes_end'<span>); </span><span>255</span> <span>256</span> <span>/*</span> <span>257</span> <span> * ------------------------------------------------------ </span><span>258</span> <span> * Security check </span><span>259</span> <span> * ------------------------------------------------------ </span><span>260</span> <span> * </span><span>261</span> <span> * None of the functions in the app controller or the </span><span>262</span> <span> * loader class can be called via the URI, nor can </span><span>263</span> <span> * controller functions that begin with an underscore </span><span>264</span> <span>*/</span> <span>265</span> <span>$class</span> = <span>$RTR</span>-><span>fetch_class(); </span><span>266</span> <span>$method</span> = <span>$RTR</span>-><span>fetch_method(); </span><span>267</span> <span>268</span> <span>if</span> ( ! <span>class_exists</span>(<span>$class</span><span>) </span><span>269</span> OR <span>strncmp</span>(<span>$method</span>, '_', 1) == 0 <span>270</span> OR <span>in_array</span>(<span>strtolower</span>(<span>$method</span>), <span>array_map</span>('strtolower', <span>get_class_methods</span>('CI_Controller'<span>))) </span><span>271</span> <span> ) </span><span>272</span> <span> { </span><span>273</span> <span>if</span> ( ! <span>empty</span>(<span>$RTR</span>->routes['404_override'<span>])) </span><span>274</span> <span> { </span><span>275</span> <span>$x</span> = <span>explode</span>('/', <span>$RTR</span>->routes['404_override'<span>]); </span><span>276</span> <span>$class</span> = <span>$x</span>[0<span>]; </span><span>277</span> <span>$method</span> = (<span>isset</span>(<span>$x</span>[1]) ? <span>$x</span>[1] : 'index'<span>); </span><span>278</span> <span>if</span> ( ! <span>class_exists</span>(<span>$class</span><span>)) </span><span>279</span> <span> { </span><span>280</span> <span>if</span> ( ! <span>file_exists</span>(APPPATH.'controllers/'.<span>$class</span>.'.php'<span>)) </span><span>281</span> <span> { </span><span>282</span> show_404("{<span>$class</span>}/{<span>$method</span>}"<span>); </span><span>283</span> <span> } </span><span>284</span> <span>285</span> <span>include_once</span>(APPPATH.'controllers/'.<span>$class</span>.'.php'<span>); </span><span>286</span> <span> } </span><span>287</span> <span> } </span><span>288</span> <span>else</span> <span>289</span> <span> { </span><span>290</span> show_404("{<span>$class</span>}/{<span>$method</span>}"<span>); </span><span>291</span> <span> } </span><span>292</span> <span> } </span><span>293</span> <span>294</span> <span>/*</span> <span>295</span> <span> * ------------------------------------------------------ </span><span>296</span> <span> * Is there a "pre_controller" hook? </span><span>297</span> <span> * ------------------------------------------------------ </span><span>298</span> <span>*/</span> <span>299</span> <span>$EXT</span>->_call_hook('pre_controller'<span>); </span><span>300</span> <span>301</span> <span>/*</span> <span>302</span> <span> * ------------------------------------------------------ </span><span>303</span> <span> * Instantiate the requested controller </span><span>304</span> <span> * ------------------------------------------------------ </span><span>305</span> <span>*/</span> <span>306</span> <span>//</span><span> Mark a start point so we can benchmark the controller</span> <span>307</span> <span>$BM</span>->mark('controller_execution_time_( '.<span>$class</span>.' / '.<span>$method</span>.' )_start'<span>); </span><span>308</span> <span>309</span> <span>$CI</span> = <span>new</span> <span>$class</span><span>(); </span><span>310</span> <span>311</span> <span>/*</span> <span>312</span> <span> * ------------------------------------------------------ </span><span>313</span> <span> * Is there a "post_controller_constructor" hook? </span><span>314</span> <span> * ------------------------------------------------------ </span><span>315</span> <span>*/</span> <span>316</span> <span>$EXT</span>->_call_hook('post_controller_constructor'<span>); </span><span>317</span> <span>318</span> <span>/*</span> <span>319</span> <span> * ------------------------------------------------------ </span><span>320</span> <span> * Call the requested method </span><span>321</span> <span> * ------------------------------------------------------ </span><span>322</span> <span>*/</span> <span>323</span> <span>//</span><span> Is there a "remap" function? If so, we call it instead</span> <span>324</span> <span>if</span> (<span>method_exists</span>(<span>$CI</span>, '_remap'<span>)) </span><span>325</span> <span> { </span><span>326</span> <span>$CI</span>->_remap(<span>$method</span>, <span>array_slice</span>(<span>$URI</span>->rsegments, 2<span>)); </span><span>327</span> <span> } </span><span>328</span> <span>else</span> <span>329</span> <span> { </span><span>330</span> <span>//</span><span> is_callable() returns TRUE on some versions of PHP 5 for private and protected </span><span>331</span> <span> // methods, so we'll use this workaround for consistent behavior</span> <span>332</span> <span>if</span> ( ! <span>in_array</span>(<span>strtolower</span>(<span>$method</span>), <span>array_map</span>('strtolower', <span>get_class_methods</span>(<span>$CI</span><span>)))) </span><span>333</span> <span> { </span><span>334</span> <span>//</span><span> Check and see if we are using a 404 override and use it.</span> <span>335</span> <span>if</span> ( ! <span>empty</span>(<span>$RTR</span>->routes['404_override'<span>])) </span><span>336</span> <span> { </span><span>337</span> <span>$x</span> = <span>explode</span>('/', <span>$RTR</span>->routes['404_override'<span>]); </span><span>338</span> <span>$class</span> = <span>$x</span>[0<span>]; </span><span>339</span> <span>$method</span> = (<span>isset</span>(<span>$x</span>[1]) ? <span>$x</span>[1] : 'index'<span>); </span><span>340</span> <span>if</span> ( ! <span>class_exists</span>(<span>$class</span><span>)) </span><span>341</span> <span> { </span><span>342</span> <span>if</span> ( ! <span>file_exists</span>(APPPATH.'controllers/'.<span>$class</span>.'.php'<span>)) </span><span>343</span> <span> { </span><span>344</span> show_404("{<span>$class</span>}/{<span>$method</span>}"<span>); </span><span>345</span> <span> } </span><span>346</span> <span>347</span> <span>include_once</span>(APPPATH.'controllers/'.<span>$class</span>.'.php'<span>); </span><span>348</span> <span>unset</span>(<span>$CI</span><span>); </span><span>349</span> <span>$CI</span> = <span>new</span> <span>$class</span><span>(); </span><span>350</span> <span> } </span><span>351</span> <span> } </span><span>352</span> <span>else</span> <span>353</span> <span> { </span><span>354</span> show_404("{<span>$class</span>}/{<span>$method</span>}"<span>); </span><span>355</span> <span> } </span><span>356</span> <span> } </span><span>357</span> <span>358</span> <span>//</span><span> Call the requested method. </span><span>359</span> <span> // Any URI segments present (besides the class/function) will be passed to the method for convenience</span> <span>360</span> <span>call_user_func_array</span>(<span>array</span>(&<span>$CI</span>, <span>$method</span>), <span>array_slice</span>(<span>$URI</span>->rsegments, 2<span>)); </span><span>361</span> <span> } </span><span>362</span> <span>363</span> <span>364</span> <span>//</span><span> Mark a benchmark end point</span> <span>365</span> <span>$BM</span>->mark('controller_execution_time_( '.<span>$class</span>.' / '.<span>$method</span>.' )_end'<span>); </span><span>366</span> <span>367</span> <span>/*</span> <span>368</span> <span> * ------------------------------------------------------ </span><span>369</span> <span> * Is there a "post_controller" hook? </span><span>370</span> <span> * ------------------------------------------------------ </span><span>371</span> <span>*/</span> <span>372</span> <span>$EXT</span>->_call_hook('post_controller'<span>); </span><span>373</span> <span>374</span> <span>/*</span> <span>375</span> <span> * ------------------------------------------------------ </span><span>376</span> <span> * Send the final rendered output to the browser </span><span>377</span> <span> * ------------------------------------------------------ </span><span>378</span> <span>*/</span> <span>379</span> <span>if</span> (<span>$EXT</span>->_call_hook('display_override') === <span>FALSE</span><span>) </span><span>380</span> <span> { </span><span>381</span> <span>$OUT</span>-><span>_display(); </span><span>382</span> <span> } </span><span>383</span> <span>384</span> <span>/*</span> <span>385</span> <span> * ------------------------------------------------------ </span><span>386</span> <span> * Is there a "post_system" hook? </span><span>387</span> <span> * ------------------------------------------------------ </span><span>388</span> <span>*/</span> <span>389</span> <span>$EXT</span>->_call_hook('post_system'<span>); </span><span>390</span> <span>391</span> <span>/*</span> <span>392</span> <span> * ------------------------------------------------------ </span><span>393</span> <span> * Close the DB connection if one exists </span><span>394</span> <span> * ------------------------------------------------------ </span><span>395</span> <span>*/</span> <span>396</span> <span>if</span> (<span>class_exists</span>('CI_DB') AND <span>isset</span>(<span>$CI</span>-><span>db)) </span><span>397</span> <span> { </span><span>398</span> <span>$CI</span>->db-><span>close(); </span><span>399</span> <span> } </span><span>400</span> <span>401</span> <span>402</span> <span>/*</span><span> End of file CodeIgniter.php </span><span>*/</span> <span>403</span> <span>/*</span><span> Location: ./system/core/CodeIgniter.php </span><span>*/</span>
在CodeIgniter中,可以看到开头的英文描述,该脚本时系统初始化文件,主要作用是装载基类和执行请求。
31-45行:定义了CI_VERSION常量,描述当前框架版本,CI_CORE常量,目前我也不清楚没探究过,注释是CI的分支,啥意思?
52行:加载系统核心目录下的Common.php文件,Load the global functions,记得前一篇中说到,一般一个项目会将很多公共方法放在一个脚本中加载进来,通常取名Utilities.php,也可是Common.php,这里的Common.php也是这个意思,如它的解释是“加载全局函数”,即这里的函数都是后边直接拿来用的。在这个脚本中有两个重要的方法(目前来说)一个是get_config,单独拿出来如下
<span> 1</span> <?<span>php </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span>* Loads the main config.php file </span><span> 4</span> <span>* </span><span> 5</span> <span>* This function lets us grab the config file even if the Config class </span><span> 6</span> <span>* hasn't been instantiated yet </span><span> 7</span> <span>* </span><span> 8</span> <span>* @access private </span><span> 9</span> <span>* @return array </span><span>10</span> <span>*/</span> <span>11</span> <span>if</span> ( ! <span>function_exists</span>('get_config'<span>)) </span><span>12</span> <span>{ </span><span>13</span> <span>function</span> &get_config(<span>$replace</span> = <span>array</span><span>()) </span><span>14</span> <span> { </span><span>15</span> <span>static</span> <span>$_config</span><span>; </span><span>16</span> <span>17</span> <span>if</span> (<span>isset</span>(<span>$_config</span><span>)) </span><span>18</span> <span> { </span><span>19</span> <span>return</span> <span>$_config</span>[0<span>]; </span><span>20</span> <span> } </span><span>21</span> <span>22</span> <span>//</span><span> Is the config file in the environment folder?</span> <span>23</span> <span>if</span> ( ! <span>defined</span>('ENVIRONMENT') OR ! <span>file_exists</span>(<span>$file_path</span> = APPPATH.'config/'.ENVIRONMENT.'/config.php'<span>)) </span><span>24</span> <span> { </span><span>25</span> <span>$file_path</span> = APPPATH.'config/config.php'<span>; </span><span>26</span> <span> } </span><span>27</span> <span>28</span> <span>//</span><span> Fetch the config file</span> <span>29</span> <span>if</span> ( ! <span>file_exists</span>(<span>$file_path</span><span>)) </span><span>30</span> <span> { </span><span>31</span> <span>exit</span>('The configuration file does not exist.'<span>); </span><span>32</span> <span> } </span><span>33</span> <span>34</span> <span>require</span>(<span>$file_path</span><span>); </span><span>35</span> <span>36</span> <span>//</span><span> Does the $config array exist in the file?</span> <span>37</span> <span>if</span> ( ! <span>isset</span>(<span>$config</span>) OR ! <span>is_array</span>(<span>$config</span><span>)) </span><span>38</span> <span> { </span><span>39</span> <span>exit</span>('Your config file does not appear to be formatted correctly.'<span>); </span><span>40</span> <span> } </span><span>41</span> <span>42</span> <span>//</span><span> Are any values being dynamically replaced?</span> <span>43</span> <span>if</span> (<span>count</span>(<span>$replace</span>) > 0<span>) </span><span>44</span> <span> { </span><span>45</span> <span>foreach</span> (<span>$replace</span> <span>as</span> <span>$key</span> => <span>$val</span><span>) </span><span>46</span> <span> { </span><span>47</span> <span>if</span> (<span>isset</span>(<span>$config</span>[<span>$key</span><span>])) </span><span>48</span> <span> { </span><span>49</span> <span>$config</span>[<span>$key</span>] = <span>$val</span><span>; </span><span>50</span> <span> } </span><span>51</span> <span> } </span><span>52</span> <span> } </span><span>53</span> <span>54</span> <span>$_config</span>[0] =& <span>$config</span><span>; </span><span>55</span> <span>return</span> <span>$_config</span>[0<span>]; </span><span>56</span> <span> } </span><span>57</span> }
注释说它加载主要的config.php文件,它使得我们能抓取到配置文件,即便配置类还未被实例化。在CI中,有专门的核心配置类CI_Config来加载配置信息,而这里的get_config方法也能获得主要配置信息,注意是主要配置信息,在application/config目录下有很多其他的配置信息文件(前面在自定义配置变量时也说过CI将配置信息分为了很多文件),其中有一个config.php文件就是get_config能获取到的,这个文件存放的就是基本信息,如果你还想获取其他的配置信息,貌似就要用配置类了。所以如果想添加节本配置信息就在这个里边。
如果是第一次调用get_config方法,先声明静态变量$_config,如果已定义则直接返回它的索引为0的子数组。然后查看APPPATH/config/ENVIRONMENT/config.php文件是否存在(前面打印已知ENVIRONMENT常量值,未改动就是development,原始的框架中没有这个目录,所以这里加载的是application/config/config.php(只加载了这一个,其他的配置文件没有),可以打开看看config.php中定义了一个$config数组,一些基本定义如基础链接、链接后缀、编码、语言、缓存、日志、钩子等等。如果传入一个关联数组,它会将键-值(临时)加入$_config中。总之,get_config方法主要得到的是config.php中定义的数组变量。
与get_config相关的config_item方法则是得到这个数组变量中的某一项。
另一个比较重要的方法是load_class:
<span> 1</span> <?<span>php </span><span> 2</span> <span>/*</span><span>* </span><span> 3</span> <span>* Class registry </span><span> 4</span> <span>* </span><span> 5</span> <span>* This function acts as a singleton. If the requested class does not </span><span> 6</span> <span>* exist it is instantiated and set to a static variable. If it has </span><span> 7</span> <span>* previously been instantiated the variable is returned. </span><span> 8</span> <span>* </span><span> 9</span> <span>* @access public </span><span>10</span> <span>* @param string the class name being requested </span><span>11</span> <span>* @param string the directory where the class should be found </span><span>12</span> <span>* @param string the class name prefix </span><span>13</span> <span>* @return object </span><span>14</span> <span>*/</span> <span>15</span> <span>if</span> ( ! <span>function_exists</span>('load_class'<span>)) </span><span>16</span> <span>{ </span><span>17</span> <span>function</span> &load_class(<span>$class</span>, <span>$directory</span> = 'libraries', <span>$prefix</span> = 'CI_'<span>) </span><span>18</span> <span> { </span><span>19</span> <span>static</span> <span>$_classes</span> = <span>array</span><span>(); </span><span>20</span> <span>21</span> <span>//</span><span> Does the class exist? If so, we're done...</span> <span>22</span> <span>if</span> (<span>isset</span>(<span>$_classes</span>[<span>$class</span><span>])) </span><span>23</span> <span> { </span><span>24</span> <span>return</span> <span>$_classes</span>[<span>$class</span><span>]; </span><span>25</span> <span> } </span><span>26</span> <span>27</span> <span>$name</span> = <span>FALSE</span><span>; </span><span>28</span> <span>29</span> <span>//</span><span> Look for the class first in the local application/libraries folder </span><span>30</span> <span> // then in the native system/libraries folder</span> <span>31</span> <span>foreach</span> (<span>array</span>(APPPATH, BASEPATH) <span>as</span> <span>$path</span><span>) </span><span>32</span> <span> { </span><span>33</span> <span>if</span> (<span>file_exists</span>(<span>$path</span>.<span>$directory</span>.'/'.<span>$class</span>.'.php'<span>)) </span><span>34</span> <span> { </span><span>35</span> <span>$name</span> = <span>$prefix</span>.<span>$class</span><span>; </span><span>36</span> <span>37</span> <span>if</span> (<span>class_exists</span>(<span>$name</span>) === <span>FALSE</span><span>) </span><span>38</span> <span> { </span><span>39</span> <span>require</span>(<span>$path</span>.<span>$directory</span>.'/'.<span>$class</span>.'.php'<span>); </span><span>40</span> <span> } </span><span>41</span> <span>42</span> <span>break</span><span>; </span><span>43</span> <span> } </span><span>44</span> <span> } </span><span>45</span> <span>46</span> <span>//</span><span> Is the request a class extension? If so we load it too</span> <span>47</span> <span>if</span> (<span>file_exists</span>(APPPATH.<span>$directory</span>.'/'.config_item('subclass_prefix').<span>$class</span>.'.php'<span>)) </span><span>48</span> <span> { </span><span>49</span> <span>$name</span> = config_item('subclass_prefix').<span>$class</span><span>; </span><span>50</span> <span>51</span> <span>if</span> (<span>class_exists</span>(<span>$name</span>) === <span>FALSE</span><span>) </span><span>52</span> <span> { </span><span>53</span> <span>require</span>(APPPATH.<span>$directory</span>.'/'.config_item('subclass_prefix').<span>$class</span>.'.php'<span>); </span><span>54</span> <span> } </span><span>55</span> <span> } </span><span>56</span> <span>57</span> <span>//</span><span> Did we find the class?</span> <span>58</span> <span>if</span> (<span>$name</span> === <span>FALSE</span><span>) </span><span>59</span> <span> { </span><span>60</span> <span>//</span><span> Note: We use exit() rather then show_error() in order to avoid a </span><span>61</span> <span> // self-referencing loop with the Excptions class</span> <span>62</span> <span>exit</span>('Unable to locate the specified class: '.<span>$class</span>.'.php'<span>); </span><span>63</span> <span> } </span><span>64</span> <span>65</span> <span>//</span><span> Keep track of what we just loaded</span> <span>66</span> is_loaded(<span>$class</span><span>); </span><span>67</span> <span>68</span> <span>$_classes</span>[<span>$class</span>] = <span>new</span> <span>$name</span><span>(); </span><span>69</span> <span>return</span> <span>$_classes</span>[<span>$class</span><span>]; </span><span>70</span> <span> } </span><span>71</span> }
先看它的注释:这个方法作为一个单例,如果被请求的类没有出现过,则该类会被实例化为一个static variable,如果先前被实例化过则直接返回它。它的三个参数分别是请求的类名、所在目录,类名前缀。可以看到,目录默认是libraries,在application和system中均有它,它就是存放我们自定义的类库或者CI自带的类库的地方,就是自定义工具和CI提供的工具,如日历类、加密类、Ftp类、日志类、Session会话类、Email邮件收发类、JavaScript类、ZIP压缩类等等。或许你已经注意到这里返回的是引用而非值,就像它将加载的类作为静态变量一样,这些细节地方最终提高了整个系统的访问速度。
일반 프로세스: 먼저 정적 배열을 정의하고 클래스가 배열에 이미 존재하는 경우 직접 반환합니다. APPPATH 및 BASEPATH(이 두 상수 값은 이전에 알려져 있음) 폴더 아래의 $directory(기본값은 라이브러리) 디렉터리를 스캔하여 $class.php 파일이 있는지 확인합니다. 존재하는 경우 표준 클래스 접두사 CI_를 추가합니다. (세번째) 각 매개변수의 기본값), 클래스 존재 여부를 확인할 때 파일이 존재하면 require로 합니다. (여기서 보면 class_exists()가 클래스 파일을 먼저 로드할 필요가 없음을 알 수 있습니다. 클래스가 존재함), 파일이 나타나면 로드하고 break가 튀어나옵니다. 스캔 순서에 주의하세요. 먼저 APPPATH, 그 다음 BASEPATH입니다. 첫 번째 매개변수 클래스 이름만 전달되면 먼저 자체 개발한 애플리케이션 디렉터리의 라이브러리에서 검색한 다음 시스템 디렉터리의 라이브러리로 이동합니다.
CI의 핵심 클래스를 확장(상속)할 수 있으므로 APPPATH 및 BASEPATH의 핵심 클래스(CI_ 접두사가 붙은 이름) 디렉터리를 스캔한 후 APPPATH 확장 클래스 라이브러리 아래에 사용자 정의가 있는지도 스캔해야 합니다( 기본적으로 MY_ 접두사가 붙음), 해당 객체가 있으면 로드한 다음 해당 객체를 인스턴스화하고(확장 클래스가 있으면 확장 클래스입니다) $_classes 정적 배열에 저장하고 객체를 반환합니다.
Common.php에 대한 전반적인 이해를 마친 후 CodeIgniter.php 스크립트로 돌아갑니다.
54-66행: APPPATH.'config/constants.php' 스크립트를 로드합니다. 이름에서 알 수 있듯이 Constants.php에는 일부 상수를 중앙에서 정의하는 프레임워크 상수가 포함되어 있으므로 상수를 추가할 때 여기에 넣을 수 있습니다. 정의하다.
68-78행: 먼저 사용자 정의 오류 처리 방법인 _Exception_handler가 정의됩니다. PHP 버전을 확인하십시오. 5.3이 아닌 경우에는 Magic_quotes 참조를 끄십시오. 이 구성은 보안 향상을 위해 버전 5.3에서 더 이상 사용되지 않습니다.
80-99행: 앞서 언급한 $_config 배열에 앞서 언급한 $sign_to_config 사용자 정의 구성 정보 배열을 임시로 추가한 내용입니다. 앞서 언급한 것처럼 $sign_to_config는 기본적으로 정의되지 않습니다. 여기서도 실행되지 않습니다.
101-109행: 사용자 정의 스크립트의 최대 실행 시간을 300초로 설정합니다(약간 더 길며 로그를 실행하는 경우 더 길어짐)
111-118행: 핵심 클래스 Benchmark를 로드하고 두 개의 표시 지점을 설정합니다. 벤치마크 테스트 클래스는 특정 시작 표시와 끝 표시 사이에 차지하는 메모리 크기, 실행 시간 및 기타 정보를 테스트하는 것입니다. 테스트를 위해서는 물론 CI에서 분석기라는 것과 함께 사용해야 합니다.
120-132행: 핵심 클래스 Hooks를 로드하고, 후크하고, 시스템이 실행을 시작하는 후크를 설정합니다. (application/config/config.php의 구성 정보가 기본적으로 false로 설정되어 있기 때문에 실제로는 실행되지 않습니다.) , 즉 후크가 활성화되지 않습니다)). 이는 컨트롤러가 로드되기 전, 로드된 후 등 무언가가 실행되기 전에 특정 코드 실행을 시작하고 컨트롤러가 로드되면 지정된 코드를 실행하는 트리거와 동일합니다. 여기서는 기본적으로 실행되지 않는 pre_system(시스템 실행 전) 확장을 호출하려고 시도합니다.
134-145행: 기타 필수 구성 정보를 로드하는 데 사용되는 구성 클래스인 핵심 클래스 Config를 로드하고, 배열이 정의된 경우 $sign_to_config 배열의 구성 정보를 다시 로드합니다.
147-159행: 코어 클래스 Utf8, 인코딩 클래스를 로드합니다.
161-166행: 핵심 클래스 URI 로드, 라우팅.
168-180행: 액세스 경로를 설정하기 위한 핵심 클래스인 Router, 경로 처리 클래스 및 _set_routing 메소드를 로드합니다. 경로 구성 배열 $routing(기본적으로 주석 처리되어 언급됨)이 정의된 경우 기본 라우팅 구성이 재정의됩니다. 존재하지 않는 스크립트 경로를 입력하면 이 단계에서 멈추고 404 보고가 시작됩니다. 물론 라우터에서 메소드로 처리해야 합니다.
Router 클래스에는 URI가 그 멤버로 존재합니다. 실제 처리 방법은 URI 클래스에 있습니다. CI의 액세스 방법이 기본적으로 세그먼트 형식이라는 것을 잘 아시는 분은 아실 것입니다. 검색 엔진에 더 도움이 된다고 합니다. 간단한 액세스 방법은 localhost/ci/index.php/Controller/Function/Arguments입니다. 액세스 형식을 필수 컨트롤러, 호출할 메서드 및 제공된 매개변수 목록으로 구문 분석합니다. 물론 기존 메서드도 활성화할 수 있습니다. . 쿼리 문자열 형식. 구체적인 방법은 약간 복잡합니다.
187행: 핵심 클래스 출력을 로드합니다.
189-200행: Hooks 클래스와 Output 클래스를 사용하여 캐시가 있는지 감지합니다. 캐시가 있는 경우 캐시 페이지가 직접 출력되고 스크립트가 튀어나옵니다. CI 소개 중 애플리케이션 흐름도 부분에서 해당 경로를 처리한 후 캐시가 있으면 바로 출력하는 이유이기도 합니다.
207행: 핵심 클래스 Security를 로드합니다.
214행: 핵심 클래스 입력을 로드합니다.
221행: 언어 처리 핵심 클래스인 Lang을 로드합니다.
229-235행: 모든 컨트롤러의 기본 클래스인 Controller 핵심 클래스를 로드하고, get_instance 전역 메소드도 해당 인스턴스를 가져올 수 있습니다. Controller의 멋진 점은 이전에 로드된 클래스를 모두 로드한다는 것입니다. load_calss 라이브러리(기본) 디렉터리(APPPATH 및 BASEPATH)의 도구 라이브러리는 모두 개체 및 해당 속성 멤버로 인스턴스화됩니다. 따라서 여기서 get_instance 메소드로 얻은 인스턴스를 CI에서는 슈퍼객체(이 이름인 듯)라고도 부르는데, 이 객체를 통해서는 이전에 로드된 모든 객체 인스턴스를 얻을 수 있기 때문이다.
238-242행: 이전 단계에서 핵심 클래스 CI_Controller에 대한 사용자 정의 확장 클래스 파일을 로드합니다. 물론 확장한 경우 기본값은 MY_Controller입니다.
243-251행: 코어 클래스 Router의 인스턴스를 통해 현재 액세스된 컨트롤러의 디렉터리 및 클래스 이름을 추출합니다. 존재하지 않으면 오류가 보고됩니다. 기본 환영 컨트롤러 파일이 여기에 로드됩니다. 물론, 컨트롤러 클래스 파일을 직접 정의하고 접근하면 여기에도 포함되게 됩니다(Router 클래스를 통해 서브디렉토리 $RTR->fetch_directory()를 추출하고, 존재한다면 클래스명 $RTR->를 추출합니다) ;fetch_class() (찾아보세요), 246행의 if 문 블록은 이 클래스 파일이 존재하는지 확인하는 것입니다.
252행: 기본 핵심 클래스 로드의 끝을 표시하기 위해 벤치마크 종료 표시를 설정합니다(이러한 테스트는 기본적으로 실행되지 않습니다).
256-292행: 보안 검사. 먼저 Router 클래스를 통해 실행할 클래스명과 메소드명을 구하고, if 조건에서 3가지 항목을 확인합니다. 1. 위의 243~251번째 줄은 컨트롤러에 해당하는 스크립트를 찾아서 로드하는데, 이것이 이름이 일치하는 빈 스크립트일 뿐이라면 어떻게 될까요? 내부에 아무것도 쓰지 않으면 동작하지 않으므로 해당 클래스의 정의(class_exists)가 있는지 확인해야 합니다. 2. 밑줄 _로 시작하는 메소드 이름은 실행할 수 없으며, 당연히 오류가 직접 보고됩니다. 이는 CI 자체 규칙입니다. 즉, 클래스에서 정의한 _로 시작하는 메서드는 공개 액세스 속성인 경우에도 작동하지 않습니다(_remap 중 하나 제외). 클래스가 루트 컨트롤러의 핵심 클래스에 있는 메서드와 이름이 같으면 작동하지 않습니다. 메소드 이름을 정의할 때 인상을 남겨보세요. if를 입력하면 404가 발생할 가능성이 높습니다.
298행: Hooks 클래스는 기본적으로 사용할 수 없는 pre_controller(컨트롤러가 실행되기 전) 확장을 호출하려고 시도합니다.
301-309행: 벤치마크 클래스는 컨트롤러의 실행 시간을 테스트하기 위해 시작점 표시를 설정하고(테스트 정보는 기본적으로 표시되지 않음) 이전에 로드된 컨트롤러 클래스를 인스턴스화합니다. 기본값은 Welcome입니다.
315행: Hooks는 기본적으로 사용할 수 없는 post_controller_constructor의 확장(호출된 컨트롤러 클래스가 생성된 후)을 실행하려고 시도합니다.
317-364행: 지정된 컨트롤러 클래스의 지정된 메서드 호출을 시작합니다(물론 이는 기본 컨트롤러 Welcome의 기본 메서드 인덱스입니다). 먼저 이 프로세스를 살펴보세요. 컨트롤러 클래스에 _remap 메서드가 있으면 이를 호출하면 됩니다. 따라서 밑줄로 시작하는 메서드는 _remap을 제외합니다. 이 재매핑 방법을 사용하면 조정하기만 하면 됩니다. 기본환영