无聊,决定水一把。
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压缩类等等。或许你已经注意到这里返回的是引用而非值,就像它将加载的类作为静态变量一样,这些细节地方最终提高了整个系统的访问速度。
Der allgemeine Prozess: Definieren Sie zunächst ein statisches Array und geben Sie es direkt zurück, wenn die Klasse bereits im Array vorhanden ist. Scannen Sie das Verzeichnis $directory (Standardwert ist Bibliotheken) unter den Ordnern APPPATH und BASEPATH (diese beiden konstanten Werte sind zuvor bekannt), um festzustellen, ob die Datei $class.php vorhanden ist. Fügen Sie das Standardklassenpräfix CI_ ( hinzu. der dritte Der Standardwert jedes Parameters) erfordert bei der Prüfung, ob die Klasse vorhanden ist, die Datei, falls vorhanden (hier ist ersichtlich, dass class_exists() nicht zuerst die Klassendatei laden muss, wenn beurteilt wird, ob die Klasse vorhanden ist). , und sobald die Datei erscheint, laden Sie sie, und break springt heraus. Achten Sie auf die Scanreihenfolge, zuerst APPPATH und dann BASEPATH. Wenn nur der erste Parameterklassenname übergeben wird, suchen wir zuerst in den Bibliotheken des von uns selbst entwickelten Anwendungsverzeichnisses und gehen dann zu den Bibliotheken des Systemverzeichnisses.
Da wir die Kernklassen von CI erweitern (erben) können, müssen wir nach dem Scannen der Kernklassenverzeichnisse (Namen mit dem Präfix CI_) von APPPATH und BASEPATH auch scannen, ob es Anpassungen unter den Bibliotheken der APPPATH-Erweiterungsklassen gibt ( standardmäßig mit dem Präfix MY_ versehen), laden Sie sie, falls vorhanden, und instanziieren Sie dann ein entsprechendes Objekt (wenn es eine Erweiterungsklasse gibt, handelt es sich um eine Erweiterungsklasse), speichern Sie es im statischen Array $_classes und geben Sie das Objekt zurück.
Kehren Sie zum CodeIgniter.php-Skript zurück, nachdem Sie ein allgemeines Verständnis von Common.php haben.
Zeilen 54-66: Laden Sie das Skript APPPATH.'config/constants.php'. Constants.php enthält, wie der Name schon sagt, Framework-Konstanten, die einige Konstanten zentral definieren, sodass wir sie beim Hinzufügen von Konstanten hier einfügen können. zu definieren.
Zeilen 68-78: Zunächst wird eine benutzerdefinierte Fehlerbehandlungsmethode _Exception_handler definiert. Bestimmen Sie die PHP-Version. Wenn es nicht 5.3 ist, deaktivieren Sie die magic_quotes-Referenz. Diese Konfiguration wurde in Version 5.3 veraltet, um die Sicherheit zu verbessern.
Zeilen 80-99: Hier ist die vorübergehende Hinzufügung des zuvor erwähnten benutzerdefinierten Konfigurationsinformationsarrays $assign_to_config, implementiert durch die Methode get_config. Die if-Anweisung ist nicht standardmäßig definiert hier läuft es auch nicht.
Zeilen 101–109: Legen Sie die maximale Ausführungszeit des benutzerdefinierten Skripts auf 300 Sekunden fest (etwas länger, länger, wenn Protokolle ausgeführt werden)
Zeilen 111–118: Laden Sie den Kernklassen-Benchmark und setzen Sie zwei Markierungspunkte. Die Benchmark-Testklasse dient zum Testen der Speichergröße, der Ausführungszeit und anderer Informationen, die zwischen einer bestimmten Startmarke und der Endmarke belegt sind. Zum Testen muss sie natürlich in Verbindung mit einem sogenannten Analysator in CI verwendet werden.
Zeilen 120–132: Laden Sie die Kernklasse Hooks, Hook und setzen Sie einen Hook, den das System auszuführen beginnt (eigentlich nicht ausgeführt, da die Konfigurationsinformationen dazu in application/config/config.php standardmäßig auf false gesetzt sind). , d. h. der Hook ist nicht aktiviert) ). Es entspricht einem Trigger, der mit der Ausführung eines bestimmten Codes beginnt, bevor etwas ausgeführt werden soll, z. B. bevor der Controller geladen wird, nach dem Laden usw., und der den angegebenen Code ausführt, sobald der Controller geladen ist. Hier wird versucht, eine pre_system-Erweiterung (vor der Systemausführung) aufzurufen, die standardmäßig nicht ausgeführt wird.
Zeilen 134–145: Laden Sie die Kernklasse Config, die Konfigurationsklasse, die zum Laden anderer erforderlicher Konfigurationsinformationen verwendet wird, und lädt die Konfigurationsinformationen erneut in das Array $assign_to_config, wenn das Array definiert ist.
Zeilen 147–159: Kernklasse Utf8, Codierungsklasse laden.
Zeilen 161–166: Kernklassen-URI laden, Routing.
Zeilen 168–180: Laden Sie die Kernklasse Router, die Pfadverarbeitungsklasse und die Methode _set_routing, um den Zugriffspfad festzulegen. Wenn das Pfadkonfigurationsarray $routing (das standardmäßig auskommentiert sein soll) definiert ist, wird die Standardroutingkonfiguration überschrieben. Wenn Sie einen Skriptpfad eingeben, der nicht existiert, stoppt es bei diesem Schritt und beginnt mit der Meldung 404. Natürlich muss es von der Methode im Router verarbeitet werden.
In der Router-Klasse ist URI als Mitglied vorhanden. Die eigentliche Verarbeitungsmethode befindet sich in der URI-Klasse. Jeder, der damit vertraut ist, weiß, dass die Zugriffsmethode von CI standardmäßig die Form eines Segments hat soll für Suchmaschinen vorteilhafter sein. Eine einfache Zugriffsmethode ist localhost/ci/index.php/Controller/Function/Arguments. Sie analysieren das Zugriffsformular in den erforderlichen Controller, die aufzurufende Methode und die bereitgestellte Parameterliste . Abfragezeichenfolgenform. Die spezifische Methode ist etwas kompliziert.
Zeile 187: Laden Sie die Kernklassenausgabe.
Zeilen 189–200: Verwenden Sie die Hooks-Klasse und die Output-Klasse, um zu erkennen, ob ein Cache vorhanden ist. Wenn dies der Fall ist, wird die Cache-Seite direkt ausgegeben und das Skript springt heraus. Dies ist auch der Grund, warum im Anwendungsflussdiagrammteil der CI-Einführung nach der Pfadverarbeitung, wenn ein Cache vorhanden ist, dieser direkt ausgegeben wird.
Zeile 207: Laden Sie die Kernklasse Security.
Zeile 214: Laden Sie die Kernklasseneingabe.
Zeile 221: Kernklasse Lang, Sprachverarbeitung laden.
Zeilen 229–235: Laden Sie die Kernklasse Controller, die die Basisklasse aller Controller ist, und die globale Methode get_instance kann auch ihre Instanz abrufen. Das Coole an Controller ist, dass alle zuvor geladenen Instanzen geladen werden Load_calss Tool-Bibliotheken in den Bibliotheksverzeichnissen (Standard) (APPPATH und BASEPATH) werden alle als Objekte und als ihre Eigenschaftsmitglieder instanziiert. Daher wird die hier von der get_instance-Methode erhaltene Instanz von CI auch als Superobjekt bezeichnet (es scheint dieser Name zu sein), da über dieses Objekt alle zuvor geladenen Objektinstanzen abgerufen werden können.
Zeilen 238-242: Laden Sie im vorherigen Schritt eine benutzerdefinierte Erweiterungsklassendatei für die Kernklasse CI_Controller. Der Standardwert ist natürlich MY_Controller, wenn Sie ihn erweitert haben.
Zeilen 243-251: Extrahieren Sie das Verzeichnis und den Klassennamen des aktuell aufgerufenen Controllers über die Instanz des Kernklassen-Routers. Wenn er nicht vorhanden ist, wird er geladen Hier wird die Standard-Welcome-Controller-Datei geladen. Wenn Sie die Controller-Klassendatei selbst definieren und darauf zugreifen, wird sie natürlich auch hier eingebunden (extrahieren Sie das Unterverzeichnis $RTR->fetch_directory() über die Router-Klasse. Falls vorhanden, extrahieren Sie den Klassennamen $RTR-> ;fetch_class() (Suchen Sie danach), der if-Anweisungsblock in Zeile 246 dient dazu, zu prüfen, ob diese Klassendatei vorhanden ist.
Zeile 252: Setzen Sie eine Benchmark-Endmarkierung, um das Ende des Ladens grundlegender Kernklassen zu markieren (diese Tests werden standardmäßig nicht ausgeführt).
Zeilen 256-292: Sicherheitskontrolle. Rufen Sie zunächst den Klassennamen und den Methodennamen ab, die über die Router-Klasse ausgeführt werden sollen, und überprüfen Sie drei Elemente in der if-Bedingung. 1. Die Zeilen 243–251 oben suchen das dem Controller entsprechende Skript und laden es. Was aber, wenn es sich nur um ein leeres Skript mit einem passenden Namen handelt? Es funktioniert nicht, wenn nichts darin geschrieben ist. Sie müssen daher überprüfen, ob die Definition der Klasse vorhanden ist (class_exists). 2. Methodennamen, die mit dem Unterstrich _ beginnen, können nicht ausgeführt werden und es wird natürlich ein Fehler gemeldet ist die eigene Regel von CI, was bedeutet, dass die von der Klasse definierten Methoden, die mit _ beginnen, nicht funktionieren, selbst wenn es sich um öffentliche Zugriffsattribute handelt (mit Ausnahme eines _remap 3. Wenn die Methode in der Wenn die Klasse denselben Namen hat wie die Methode in der Kernklasse des Root-Controllers, funktioniert sie nicht. Machen Sie sich einfach einen Eindruck, wenn Sie den Methodennamen definieren. Die Eingabe des if führt wahrscheinlich zu einem 404.
Zeile 298: Die Hooks-Klasse versucht, eine pre_controller-Erweiterung (bevor der Controller ausgeführt wird) aufzurufen, die standardmäßig nicht verfügbar ist.
Zeilen 301–309: Die Benchmark-Klasse legt eine Startpunktmarkierung fest, um die Ausführungszeit des Controllers zu testen (Testinformationen werden standardmäßig nicht angezeigt) und instanziiert die zuvor geladene Controller-Klasse. Der Standardwert ist Willkommen.
Zeile 315: Hooks versucht, die Erweiterung von post_controller_constructor auszuführen (nachdem die aufgerufene Controller-Klasse erstellt wurde), die standardmäßig nicht verfügbar ist.
Zeilen 317-364: Beginnen Sie mit dem Aufruf der angegebenen Methode der angegebenen Controller-Klasse (natürlich ist dies der Standardmethodenindex des Standard-Controllers Willkommen). Schauen Sie sich diesen Prozess zunächst an. Wenn Ihre Controller-Klasse eine Methode enthält, rufen Sie sie einfach auf. Dies ist auch die Regel für Methoden von a CI-Klasse. Passen Sie diese Neuzuordnungsmethode einfach an. StandardWillkommen