CI ロードプロセスの概要

WBOY
WBOYオリジナル
2016-08-08 09:28:291050ブラウズ

  无聊,决定水一把。

  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压缩类等等。或许你已经注意到这里返回的是引用而非值,就像它将加载的类作为静态变量一样,这些细节地方最终提高了整个系统的访问速度。

プロセスについて: まず静的配列を定義し、クラスがすでに配列に存在する場合はそれを直接返します。 APPPATH および BASEPATH (これら 2 つの定数値はすでにわかっています) フォルダーの下の $directory (デフォルト値は library) ディレクトリをスキャンして、$class.php ファイルが存在するかどうかを確認します。存在する場合は、CI の標準クラス プレフィックス CI_ ( 3番目は各パラメータのデフォルト値)、クラスが存在するかどうかを確認するときに、ファイルが存在する場合はそのファイルを要求します(ここから、class_exists()はクラスが存在するかどうかを判断するときに最初にクラスファイルをロードする必要がないことがわかります) 、ファイルが表示されたらそれをロードすると、breakが飛び出します。最初に APPPATH、次に BASEPATH というスキャン順序に注意してください。最初のパラメータ クラス名のみが渡された場合は、最初に自分で開発したアプリケーション ディレクトリのライブラリを検索し、次にシステム ディレクトリのライブラリに移動します。

CI のコア クラスを拡張 (継承) できるため、APPPATH と BASEPATH のコア クラス (名前の先頭に CI_ が付く) ディレクトリをスキャンした後、APPPATH クラス (先頭に CI_ の付く名前) のライブラリの下にカスタム拡張機能があるかどうかもスキャンする必要があります。デフォルトでは MY_)、存在する場合はそれらをロードし、対応するオブジェクト (拡張クラスがある場合は拡張クラス) をインスタンス化し、それを $_classes 静的配列に格納してオブジェクトを返します。

Common.php について一般的に理解したら、CodeIgniter.php スクリプトに戻ります。

54~66行目: APPPATH.'config/constants.php'スクリプトをロードします。Constants.phpには、名前が示すように、いくつかの定数を集中的に定義するフレームワーク定数が含まれているため、定数を追加するときにここに置くことができます。それらを定義します。

68~78行目:まず、カスタムエラー処理メソッド_Exception_handlerを定義しています。 PHP のバージョンを確認します。5.3 ではない場合は、セキュリティを向上させるために、この構成はバージョン 5.3 で非推奨になりました。

80行目から99行目:これは、前述の$assign_to_configカスタム構成情報配列を$_config配列に一時的に追加したもので、前述したように、$assign_to_configはデフォルトでは定義されていません。は実行されません。

101 ~ 109 行目: カスタム スクリプトの最大実行時間を 300 秒に設定します (わずかに長く、ログを実行する場合はさらに長くなります)

111 ~ 118 行目: コアクラス Benchmark をロードし、2 つのマークポイントを設定します。 Benchmark ベンチマーク テスト クラスは、特定の開始マークと終了マークの間に占有されているメモリ サイズや実行時間などの情報をテストするためのもので、テストには当然 CI でアナライザーと呼ばれるものと組み合わせて使用​​する必要があります。

120 ~ 132 行目: コアクラス Hooks をロードし、フックし、システムが実行を開始するようにフックを設定します (application/config/config.php 内のフックに関する構成情報がデフォルトで false に設定されているため、実際には実行されません)つまり、フックは有効になっていません)。これは、コントローラーがロードされる前、ロード後など、何かが実行される前に特定のコードの実行を開始し、コントローラーがロードされると指定されたコードを実行するトリガーと同等です。ここでは、デフォルトでは実行されない pre_system (システム実行前) 拡張機能の呼び出しを試みます。

134 ~ 145 行目: 他の必要な構成情報をロードするために使用される構成クラスであるコア クラス Config をロードします。配列が定義されている場合は、その構成情報を $assign_to_config 配列に再度ロードします。

147 ~ 159 行目: コア クラス Utf8、エンコーディング クラスをロードします。

161 ~ 166 行目: コアクラス URI、ルーティングをロードします。

168 ~ 180 行目: コアクラス Router、パス処理クラス、および _set_routing メソッドをロードして、アクセス パスを設定します。パス構成配列 $routing (デフォルトでコメントアウトされると記載) が定義されている場合、デフォルトのルーティング構成は上書きされます。存在しないスクリプト パスを入力すると、このステップで停止し、404 のレポートが開始されます。もちろん、ルーター内のメソッドで処理する必要があります。

Routerクラスには、そのメンバーとしてURIが存在しており、実際の処理メソッドはURIクラス内にありますが、CIのアクセスメソッドはデフォルトでsegment形式になっているといわれています。検索エンジンに有利になります。単純なアクセス メソッドは、localhost/ci/index.php/Controller/Function/Arguments です。これらは、アクセス フォームを解析して、必要なコントローラ、呼び出されるメソッド、および提供されたパラメータ リストを取得します。もちろん、従来のメソッドも有効にすることができます。 . クエリ文字列形式。具体的な方法は少し複雑です。

187 行目: コアクラスの出力をロードします。

189 ~ 200 行目: Hooks クラスと Output クラスを使用して、キャッシュがあるかどうかを検出します。キャッシュがある場合は、キャッシュ ページが直接出力され、スクリプトが飛び出します。 CI導入のアプリケーションフローチャート部分でパス処理後、キャッシュがあればそのまま出力するのもこれが理由です。

207 行目: コアクラス Security をロードします。

214 行目: コアクラスの入力をロードします。

221 行目: コアクラス Lang、言語処理をロードしています。

行 229 ~ 235: すべてのコントローラーの基本クラスであるコア クラス Controller をロードします。また、get_instance グローバル メソッドはそのインスタンスも取得できます。Controller の優れた点は、load_calss (デフォルトのディレクトリ (APPPATH および BASEPATH) 内のツール ライブラリはすべて、オブジェクトおよびそのプロパティ メンバーとしてインスタンス化されます。したがって、ここで get_instance メソッドで取得したインスタンスは、CI ではスーパーオブジェクトとも呼ばれます (この名前のようです)。これは、このオブジェクトを通じて、以前にロードされたオブジェクトのインスタンスをすべて取得できるためです。

行 238 ~ 242: 前のステップでコア クラス CI_Controller のカスタマイズされた拡張クラス ファイルをロードします (拡張した場合、デフォルトは MY_Controller です)。

行 243 ~ 251: コア クラス Router のインスタンスを通じて、現在アクセスされているコントローラーのディレクトリとクラス名を抽出します。存在する場合は、デフォルトのウェルカムがロードされます。コントローラーファイルはここにロードされます。もちろん、コントローラー クラス ファイルを自分で定義してそれにアクセスする場合、それもここに含まれます (Router クラスを通じてサブディレクトリ $RTR->fetch_directory() を抽出します。存在する場合は、クラス名 $RTR-> を抽出します) ;fetch_class() (探してください)、246 行目の if ステートメント ブロックは、このクラス ファイルが存在するかどうかを確認します。

252 行目: 基本コアクラスのロードの終了を示すベンチマーク終了マークを設定します (これらのテストはデフォルトでは実行されません)。

256~292行目:セキュリティチェック。まず、Routerクラスで実行するクラス名とメソッド名を取得し、if条件の3つの項目を確認します。 1. 上記の行 243 ~ 251 では、コントローラーに対応するスクリプトを見つけてロードしていますが、これが一致する名前を持つ単なる空のスクリプトである場合はどうなるでしょうか。内部に何も書かれていない場合は動作しないので、クラスの定義が存在するかどうかを確認する必要があります (class_exists)。 2. アンダースコア _ で始まるメソッド名は実行できず、直接エラーが報告されます。は CI 独自のルールです。つまり、クラスで定義された _ で始まるメソッドは、パブリック アクセス属性であっても機能しません (1 つの _remap を除く) 3. クラス内のメソッドが同じである場合。 name をルート コントローラーのコア クラスのメソッドとして使用すると、機能しません。メソッド名を定義するときは、イメージだけを持ってください。 if を入力すると 404 が発生する可能性があります。

298 行目: Hooks クラスは、pre_controller (コントローラーが実行される前) 拡張機能を呼び出そうとしますが、これはデフォルトでは使用できません。

行 301 ~ 309: ベンチマーク テスト クラスは、コントローラーの実行時間をテストするための開始点マークを設定し (デフォルトではテスト情報は表示されません)、以前にロードされたコントローラー クラスをインスタンス化します。デフォルトは Welcome です。

315 行目: フックは、(呼び出されたコントローラー クラスが構築された後) post_controller_constructor の拡張機能を実行しようとしますが、これはデフォルトでは利用できません。

行 317 ~ 364: 指定されたコントローラー クラスの指定されたメソッドの呼び出しを開始します (もちろん、これはデフォルト コントローラーのデフォルトのメソッド インデックスです)。このプロセスを見てください。まず、コントローラー クラスに _remap メソッドがある場合は、それを呼び出します。これは _remap 以外のメソッドです。この再マッピング方法では、それを調整するだけです。デフォルトようこそ

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。