Home  >  Article  >  Backend Development  >  Summary of CI loading process

Summary of CI loading process

WBOY
WBOYOriginal
2016-08-08 09:28:291043browse

  无聊,决定水一把。

  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>

View Code

  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>
View Code

  在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> }
View Code

  注释说它加载主要的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> }

View Code

  先看它的注释:这个方法作为一个单例,如果被请求的类没有出现过,则该类会被实例化为一个static variable,如果先前被实例化过则直接返回它。它的三个参数分别是请求的类名、所在目录,类名前缀。可以看到,目录默认是libraries,在application和system中均有它,它就是存放我们自定义的类库或者CI自带的类库的地方,就是自定义工具和CI提供的工具,如日历类、加密类、Ftp类、日志类、Session会话类、Email邮件收发类、JavaScript类、ZIP压缩类等等。或许你已经注意到这里返回的是引用而非值,就像它将加载的类作为静态变量一样,这些细节地方最终提高了整个系统的访问速度。

About the process: first define a static array, and return it directly if the class already exists in the array. Scan the $directory (default value is libraries) directory under the APPPATH and BASEPATH (these two constant values ​​are known before) folders to see if the $class.php file exists. If it exists, add CI's standard class prefix CI_ (the third The default value of each parameter), when checking whether the class exists, require the file if it exists (it can be seen from here that class_exists() does not need to load the class file first when judging whether the class exists), and once the file appears, load it, And break jumps out. Pay attention to the scanning order, first APPPATH and then BASEPATH. If only the first parameter class name is passed, we will first search in the libraries of the application directory we developed ourselves, and then go to the libraries of the system directory.

Since we can extend the core classes of CI (inherit them), after scanning the core class (names prefixed with CI_) directories of APPPATH and BASEPATH, we must also scan whether there are custom extensions under the libraries of APPPATH Classes (prefixed with MY_ by default), load them if any, and then instantiate a corresponding object (if there is an extension class, it is an extension class), store it in the $_classes static array and return the object.

 After you have a general understanding of Common.php, return to the CodeIgniter.php script.

  Lines 54-66: Load the APPPATH.'config/constants.php' script. Constants.php, as the name suggests, contains framework constants, which centrally defines some constants, so when we add constants, we can put them here to define them. .

 

  Lines 68-78: First, a custom error handling method _exception_handler is defined. Determine the PHP version. If it is not 5.3, turn off the magic_quotes reference. This configuration has been deprecated in version 5.3 to improve security.

  Lines 80-99: Here is the temporary addition of the $assign_to_config custom configuration information array mentioned earlier to the $_config array, implemented through the get_config method. As mentioned earlier, $assign_to_config is not defined by default, and the if statement here is not will run.

Lines 101-109: Set the maximum execution time of the custom script to 300 seconds (slightly longer, longer if running logs)

Lines 111-118: Load the core class Benchmark and set two mark points. The Benchmark benchmark test class is to test the memory size, execution time and other information occupied between a certain start mark and the end mark. For testing, of course it must be used in conjunction with something called an analyzer in CI.

Lines 120-132: Load the core class Hooks, hook, and set a hook for the system to start executing (actually not executed because the configuration information about it in application/config/config.php is set to false by default, that is, the hook is not enabled). It is equivalent to a trigger that starts executing certain code before something is to be executed, such as before the controller is loaded, after loading, etc., and the specified code is run once the controller is loaded. Here, it attempts to call a pre_system (before system execution) extension, which is not executed by default.

  Lines 134-145: Load the core class Config, the configuration class, which is used to load other required configuration information, and it loads the configuration information in the $assign_to_config array again if the array is defined.

Lines 147-159: Load core class Utf8, encoding class.

Lines 161-166: Load core class URI, routing.

Lines 168-180: Load the core class Router, the path processing class, and the _set_routing method to set the access path. If the path configuration array $routing (mentioned to be commented out by default) is defined, the default routing configuration will be overridden. If you enter a script path that does not exist, it will stop at this step and start reporting 404. Of course, it must be handled by the method in the Router.

 In the Router class, URI exists as a member of it. The actual processing method is in the URI class. Anyone who is familiar with it knows that the access method of CI is in the form of segment by default, which is said to be more conducive to search engines. A simple access method is localhost/ci/index.php/Controller/Function/Arguments. They parse the access form into the required controller, the method to be called, and the provided parameter list. Of course, traditional methods can also be enabled. Query string form. The specific method is slightly complicated.

Line 187: Load the core class Output.

Lines 189-200: Use the Hooks class and the Output class to detect whether there is cache. If there is, the cache page will be output directly and the script will jump out. This is also the reason why in the application flow chart part of the CI introduction, after the path is processed, if there is a cache, it will be output directly.

 

Line 207: Load the core class Security.

Line 214: Load the core class Input.

Line 221: Loading the core class Lang, language processing.

Lines 229-235: Load the core class Controller, which is the base class of all controllers, and the get_instance global method can also get its instance. The cool thing about Controller is that it will load all the libraries previously loaded through load_calss ( The tool libraries in the default) directories (APPPATH and BASEPATH) are all instantiated as objects and as its property members. Therefore, the instance obtained by the get_instance method here is also called a super object by CI (it seems to be this name), because through this object, all previously loaded object instances can be obtained.

Lines 238-242: Load the customized extension class file of the core class CI_Controller in the previous step. The default is MY_Controller, of course, if you have extended it.

Lines 243-251: Extract the directory and class name of the currently accessed controller through the instance of the core class Router. If it does not exist, an error will be reported. If it exists, it will be loaded. The default welcome controller file is loaded here. Of course, if you define the controller class file yourself and access it, it will also be included here (extract the subdirectory $RTR->fetch_directory() through the Router class, if it exists, extract the class name $RTR->fetch_class() (Look for it), the if statement block on line 246 is to check whether this class file exists.

Line 252: Set a benchmark end mark to mark the end of loading basic core classes (these tests will not be executed by default).

 Lines 256-292: Security check. First, obtain the class name and the method name to be executed through the Router class, and check three items in the if condition. 1. Lines 243-251 above find the script corresponding to the controller and load it, but what if this is just an empty script with a matching name? It won't work if nothing is written inside, so you need to check whether the definition of the class exists (class_exists). 2. Method names starting with underscore _ cannot be executed and an error will be reported directly. Of course, this is CI's own rule, which means that no matter you The methods starting with _ defined by the class will not work even if they are public access attributes (except for one _remap). 3. When the method in the class has the same name as the method in the core class of the root controller, it will not work. Just have an impression when defining the method name. Entering the if is likely to result in a 404.

Line 298: The Hooks class attempts to call a pre_controller (before the controller is executed) extension, which is not available by default.

Lines 301-309: The benchmark test class sets a starting point mark to test the execution time of the controller (test information is not displayed by default), and instantiates the previously loaded controller class. The default is Welcome.

Line 315: Hooks attempts to execute the extension of post_controller_constructor (after the called controller class is constructed), which is not available by default.

Lines 317-364: Start calling the specified method of the specified controller class (of course this is the default method index of the default controller Welcome). Take a look at this process. First, make an if judgment. If there is a method _remap in your controller class, just call it. So the methods starting with an underscore are except _remap. This is also the rule for a class method in CI. With this remapping method, just adjust it. DefaultWelcome

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn