CI加载流程小结

Aug 08, 2016 am 09:28 AM
class config controller php the

  无聊,决定水一把。

  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>
Copier après la connexion
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>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' =&gt; <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> =&amp; load_class('Benchmark', 'core'<span>);
</span><span>117</span>     <span>$BM</span>-&gt;mark('total_execution_time_start'<span>);
</span><span>118</span>     <span>$BM</span>-&gt;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> =&amp; 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>-&gt;_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> =&amp; 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>-&gt;_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> =&amp; 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> =&amp; 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> =&amp; load_class('Router', 'core'<span>);
</span><span>174</span>     <span>$RTR</span>-&gt;<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>-&gt;_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> =&amp; 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>-&gt;_call_hook('cache_override') === <span>FALSE</span><span>)
</span><span>195</span> <span>    {
</span><span>196</span>         <span>if</span> (<span>$OUT</span>-&gt;_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> =&amp; 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>    =&amp; 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> =&amp; 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> &amp;<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>-&gt;config['subclass_prefix'].'Controller.php'<span>))
</span><span>239</span> <span>    {
</span><span>240</span>         <span>require</span> APPPATH.'core/'.<span>$CFG</span>-&gt;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-&gt;_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>-&gt;fetch_directory().<span>$RTR</span>-&gt;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>-&gt;fetch_directory().<span>$RTR</span>-&gt;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>-&gt;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>-&gt;<span>fetch_class();
</span><span>266</span>     <span>$method</span> = <span>$RTR</span>-&gt;<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>-&gt;routes['404_override'<span>]))
</span><span>274</span> <span>        {
</span><span>275</span>             <span>$x</span> = <span>explode</span>('/', <span>$RTR</span>-&gt;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>-&gt;_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>-&gt;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>-&gt;_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>-&gt;_remap(<span>$method</span>, <span>array_slice</span>(<span>$URI</span>-&gt;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>-&gt;routes['404_override'<span>]))
</span><span>336</span> <span>            {
</span><span>337</span>                 <span>$x</span> = <span>explode</span>('/', <span>$RTR</span>-&gt;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>(&amp;<span>$CI</span>, <span>$method</span>), <span>array_slice</span>(<span>$URI</span>-&gt;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>-&gt;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>-&gt;_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>-&gt;_call_hook('display_override') === <span>FALSE</span><span>)
</span><span>380</span> <span>    {
</span><span>381</span>         <span>$OUT</span>-&gt;<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>-&gt;_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>-&gt;<span>db))
</span><span>397</span> <span>    {
</span><span>398</span>         <span>$CI</span>-&gt;db-&gt;<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>
Copier après la connexion
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> &amp;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>) &gt; 0<span>)
</span><span>44</span> <span>        {
</span><span>45</span>             <span>foreach</span> (<span>$replace</span> <span>as</span> <span>$key</span> =&gt; <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] =&amp; <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> }
Copier après la connexion
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> &amp;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> }
Copier après la connexion
View Code

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

  大致流程:先定义一个静态数组,若数组中已有该类直接返回。先后扫描APPPATH和BASEPATH(前面已知这俩常量值)文件夹下的$directory(默认值是libraries)目录下的$class.php文件是否存在,存在则加上CI的标准类前缀CI_(第三个参数的默认值),在检查类存在与否,存在则require该文件(从这里可知,class_exists()在判断类是否存在时并不需要先加载该类文件),一旦文件出现则加载它,并break跳出。注意扫描顺序,先APPPATH后BASEPATH,假如只传第一个参数类名,则优先在我们自己开发的application目录libraries中寻找,然后才去system目录的libraries下边。

  由于我们可以对CI的核心类进行扩展(继承它们),所以在扫描完APPPATH和BASEPATH的核心类(名称以CI_为前缀)目录后,还要扫描APPPATH的libraries下边是否有自定义的扩展类(默认以MY_为前缀),有的话也要加载它们,然后实例化一个对应对象(有扩展类是扩展类)存入$_classes静态数组并返回该对象。

  对Common.php有大致了解后回到CodeIgniter.php脚本。

  54-66行:加载APPPATH.'config/constants.php'脚本,constants.php如同名字一样放的是framework constants,集中定义了一些常量,所以我们在添加常量时就可以放到这里边来定义。

    

  68-78行:首先定义了一个自定义错误处理方法_exception_handler。判断php版本,非5.3关闭magic_quotes引用,这个配置在5.3版本已弃用,提高安全性。

  80-99行:这里就是将前面说过的$assign_to_config自定义配置信息数组临时加到$_config数组中,通过get_config方法实现,前面说过$assign_to_config默认是没有定义的,这里的if语句也不会运行。

  101-109行:设置自定义脚本最大执行时间为300秒(略长,跑日志的话得更长)

  111-118行:加载核心类Benchmark,设置两个标记点。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里边的方法处理。

  Router类里面,URI作为它的一个成员存在,实际处理方法在URI类中,熟悉点的都知道CI的访问方式默认是段(segment)的形式,据说更有利于搜索引擎。一个简单的访问方式是这样的localhost/ci/index.php/Controller/Function/Arguments,它们将访问的形式解析为需要的控制器,调用的方法,以及提供的参数列表,当然也可启用传统的查询字符串形式。具体方法略复杂。

  187行:加载核心类Output。

  189-200行:通过Hooks类和Output类检测有无缓存,有的话直接输出缓存页面,跳出脚本了。这也是在CI的介绍中应用程序流程图部分,当路径处理完后,若有缓存直接输出的原因。

   

  207行:加载核心类Security。

  214行:加载核心类Input。

  221行:加载核心类Lang,语言处理。

  229-235行:加载核心类Controller,它是所有控制器的基类,而get_instance全局方法也能得到它的实例,Controller的牛逼之处在于,它将前面所有通过load_calss载入的libraries(默认)目录(APPPATH和BASEPATH)中的工具库全部实例化为对象,并作为它的属性成员。所以这里的get_instance方法得到的实例也被CI称为超对象(好像是这个名字),因为通过这个对象就可以获取所有通过前面加载的对象实例。

  238-242行:加载自定义的,对上一步的核心类CI_Controller的扩展类的文件,默认就是MY_Controller,当然前提是如果你扩展了的的话。

  243-251行:通过核心类Router的实例,提取当前访问的控制器所在的目录和类名,不存在则报错,存在则加载它,这里就加载了默认的welcome控制器文件。当然如果你自己定义了控制器类文件并访问,也是在这里被include进来的(通过Router类提取子目录$RTR->fetch_directory(),若存在,提取类名$RTR->fetch_class()来找),大概在246行的if语句块,就是检查这个类文件是否存在。

  252行:设置一个基准测试结束标记,标记加载基本核心类结束(这些测试默认不会执行)。

  256-292行:安全检查。先通过Router类取得类名和要执行的方法名,if条件检查3项内容。1. 上面的243-251行是找到了控制器对应的脚本,并且加载了它,但是假如这只是一个名字匹配的空脚本呢?里边什么都没写就不行了,于是要检查类的定义是否存在(class_exists),2. 以下划线_开头的方法名不能执行,直接报错,当然这是CI自己的的规则,也就是说无论你的类定义的以_开头的方法即使是公有访问属性也不行(除了一个_remap),3. 当类中的方法根控制器核心类中的方法同名时也不行。定义方法名时有个印象就行了。进入if中就很可能会404了。

  298行:Hooks类尝试调用一个pre_controller(控制器执行前)的扩展,默认没有。

  301-309行:基准测试类设置一个起点标记,目的在于测试控制器执行的时长(默认不显示测试信息),并且实例化前面加载的控制器类,默认的就是Welcome。

  315行:Hooks尝试执行post_controller_constructor(所调用的控制器类构造完成后)的扩展,默认没有。

  317-364行:开始调用指定的控制器类的指定方法(当然这里是默认控制器Welcome的默认方法index)。看看这个流程,首先一个if判断,如果你的控制器类中有方法_remap,只调用它了,所以前面说以下划线开头的方法除了_remap,这也是CI的一个类的方法的规则,有了这个重映射方法,只调它。默认的Welcome

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Article chaud

Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Date et heure de CakePHP

Configuration du projet CakePHP Configuration du projet CakePHP Sep 10, 2024 pm 05:25 PM

Configuration du projet CakePHP

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Téléchargement de fichiers CakePHP

Routage CakePHP Routage CakePHP Sep 10, 2024 pm 05:25 PM

Routage CakePHP

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

Discuter de CakePHP

Guide rapide CakePHP Guide rapide CakePHP Sep 10, 2024 pm 05:27 PM

Guide rapide CakePHP

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Comment configurer Visual Studio Code (VS Code) pour le développement PHP

See all articles