찾다
백엔드 개발PHP 튜토리얼CI 로딩 프로세스 요약

  无聊,决定水一把。

  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>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(이 두 상수 값은 이전에 알려져 있음) 폴더 아래의 $directory(기본값은 라이브러리) 디렉터리를 스캔하여 $class.php 파일이 있는지 확인합니다. 존재하는 경우 표준 클래스 접두사 CI_를 추가합니다. (세번째) 각 매개변수의 기본값), 클래스 존재 여부를 확인할 때 파일이 존재하면 require로 합니다. (여기서 보면 class_exists()가 클래스 파일을 먼저 로드할 필요가 없음을 알 수 있습니다. 클래스가 존재함), 파일이 나타나면 로드하고 break가 튀어나옵니다. 스캔 순서에 주의하세요. 먼저 APPPATH, 그 다음 BASEPATH입니다. 첫 번째 매개변수 클래스 이름만 전달되면 먼저 자체 개발한 애플리케이션 디렉터리의 라이브러리에서 검색한 다음 시스템 디렉터리의 라이브러리로 이동합니다.

CI의 핵심 클래스를 확장(상속)할 수 있으므로 APPPATH 및 BASEPATH의 핵심 클래스(CI_ 접두사가 붙은 이름) ​​디렉터리를 스캔한 후 APPPATH 확장 클래스 라이브러리 아래에 사용자 정의가 있는지도 스캔해야 합니다( 기본적으로 MY_ 접두사가 붙음), 해당 객체가 있으면 로드한 다음 해당 객체를 인스턴스화하고(확장 클래스가 있으면 확장 클래스입니다) $_classes 정적 배열에 저장하고 객체를 반환합니다.

Common.php에 대한 전반적인 이해를 마친 후 CodeIgniter.php 스크립트로 돌아갑니다.

54-66행: APPPATH.'config/constants.php' 스크립트를 로드합니다. 이름에서 알 수 있듯이 Constants.php에는 일부 상수를 중앙에서 정의하는 프레임워크 상수가 포함되어 있으므로 상수를 추가할 때 여기에 넣을 수 있습니다. 정의하다.

 

68-78행: 먼저 사용자 정의 오류 처리 방법인 _Exception_handler가 정의됩니다. PHP 버전을 확인하십시오. 5.3이 아닌 경우에는 Magic_quotes 참조를 끄십시오. 이 구성은 보안 향상을 위해 버전 5.3에서 더 이상 사용되지 않습니다.

80-99행: 앞서 언급한 $_config 배열에 앞서 언급한 $sign_to_config 사용자 정의 구성 정보 배열을 임시로 추가한 내용입니다. 앞서 언급한 것처럼 $sign_to_config는 기본적으로 정의되지 않습니다. 여기서도 실행되지 않습니다.

101-109행: 사용자 정의 스크립트의 최대 실행 시간을 300초로 설정합니다(약간 더 길며 로그를 실행하는 경우 더 길어짐)

111-118행: 핵심 클래스 Benchmark를 로드하고 두 개의 표시 지점을 설정합니다. 벤치마크 테스트 클래스는 특정 시작 표시와 끝 표시 사이에 차지하는 메모리 크기, 실행 시간 및 기타 정보를 테스트하는 것입니다. 테스트를 위해서는 물론 CI에서 분석기라는 것과 함께 사용해야 합니다.

120-132행: 핵심 클래스 Hooks를 로드하고, 후크하고, 시스템이 실행을 시작하는 후크를 설정합니다. (application/config/config.php의 구성 정보가 기본적으로 false로 설정되어 있기 때문에 실제로는 실행되지 않습니다.) , 즉 후크가 활성화되지 않습니다)). 이는 컨트롤러가 로드되기 전, 로드된 후 등 무언가가 실행되기 전에 특정 코드 실행을 시작하고 컨트롤러가 로드되면 지정된 코드를 실행하는 트리거와 동일합니다. 여기서는 기본적으로 실행되지 않는 pre_system(시스템 실행 전) 확장을 호출하려고 시도합니다.

134-145행: 기타 필수 구성 정보를 로드하는 데 사용되는 구성 클래스인 핵심 클래스 Config를 로드하고, 배열이 정의된 경우 $sign_to_config 배열의 구성 정보를 다시 로드합니다.

147-159행: 코어 클래스 Utf8, 인코딩 클래스를 로드합니다.

161-166행: 핵심 클래스 URI 로드, 라우팅.

168-180행: 액세스 경로를 설정하기 위한 핵심 클래스인 Router, 경로 처리 클래스 및 _set_routing 메소드를 로드합니다. 경로 구성 배열 $routing(기본적으로 주석 처리되어 언급됨)이 정의된 경우 기본 라우팅 구성이 재정의됩니다. 존재하지 않는 스크립트 경로를 입력하면 이 단계에서 멈추고 404 보고가 시작됩니다. 물론 라우터에서 메소드로 처리해야 합니다.

Router 클래스에는 URI가 그 멤버로 존재합니다. 실제 처리 방법은 URI 클래스에 있습니다. CI의 액세스 방법이 기본적으로 세그먼트 형식이라는 것을 잘 아시는 분은 아실 것입니다. 검색 엔진에 더 도움이 된다고 합니다. 간단한 액세스 방법은 localhost/ci/index.php/Controller/Function/Arguments입니다. 액세스 형식을 필수 컨트롤러, 호출할 메서드 및 제공된 매개변수 목록으로 구문 분석합니다. 물론 기존 메서드도 활성화할 수 있습니다. . 쿼리 문자열 형식. 구체적인 방법은 약간 복잡합니다.

187행: 핵심 클래스 출력을 로드합니다.

189-200행: Hooks 클래스와 Output 클래스를 사용하여 캐시가 있는지 감지합니다. 캐시가 있는 경우 캐시 페이지가 직접 출력되고 스크립트가 튀어나옵니다. CI 소개 중 애플리케이션 흐름도 부분에서 해당 경로를 처리한 후 캐시가 있으면 바로 출력하는 이유이기도 합니다.

 

207행: 핵심 클래스 Security를 ​​로드합니다.

214행: 핵심 클래스 입력을 로드합니다.

221행: 언어 처리 핵심 클래스인 Lang을 로드합니다.

229-235행: 모든 컨트롤러의 기본 클래스인 Controller 핵심 클래스를 로드하고, get_instance 전역 메소드도 해당 인스턴스를 가져올 수 있습니다. Controller의 멋진 점은 이전에 로드된 클래스를 모두 로드한다는 것입니다. load_calss 라이브러리(기본) 디렉터리(APPPATH 및 BASEPATH)의 도구 라이브러리는 모두 개체 및 해당 속성 멤버로 인스턴스화됩니다. 따라서 여기서 get_instance 메소드로 얻은 인스턴스를 CI에서는 슈퍼객체(이 이름인 듯)라고도 부르는데, 이 객체를 통해서는 이전에 로드된 모든 객체 인스턴스를 얻을 수 있기 때문이다.

238-242행: 이전 단계에서 핵심 클래스 CI_Controller에 대한 사용자 정의 확장 클래스 파일을 로드합니다. 물론 확장한 경우 기본값은 MY_Controller입니다.

243-251행: 코어 클래스 Router의 인스턴스를 통해 현재 액세스된 컨트롤러의 디렉터리 및 클래스 이름을 추출합니다. 존재하지 않으면 오류가 보고됩니다. 기본 환영 컨트롤러 파일이 여기에 로드됩니다. 물론, 컨트롤러 클래스 파일을 직접 정의하고 접근하면 여기에도 포함되게 됩니다(Router 클래스를 통해 서브디렉토리 $RTR->fetch_directory()를 추출하고, 존재한다면 클래스명 $RTR->를 추출합니다) ;fetch_class() (찾아보세요), 246행의 if 문 블록은 이 클래스 파일이 존재하는지 확인하는 것입니다.

252행: 기본 핵심 클래스 로드의 끝을 표시하기 위해 벤치마크 종료 표시를 설정합니다(이러한 테스트는 기본적으로 실행되지 않습니다).

256-292행: 보안 검사. 먼저 Router 클래스를 통해 실행할 클래스명과 메소드명을 구하고, if 조건에서 3가지 항목을 확인합니다. 1. 위의 243~251번째 줄은 컨트롤러에 해당하는 스크립트를 찾아서 로드하는데, 이것이 이름이 일치하는 빈 스크립트일 뿐이라면 어떻게 될까요? 내부에 아무것도 쓰지 않으면 동작하지 않으므로 해당 클래스의 정의(class_exists)가 있는지 확인해야 합니다. 2. 밑줄 _로 시작하는 메소드 이름은 실행할 수 없으며, 당연히 오류가 직접 보고됩니다. 이는 CI 자체 규칙입니다. 즉, 클래스에서 정의한 _로 시작하는 메서드는 공개 액세스 속성인 경우에도 작동하지 않습니다(_remap 중 하나 제외). 클래스가 루트 컨트롤러의 핵심 클래스에 있는 메서드와 이름이 같으면 작동하지 않습니다. 메소드 이름을 정의할 때 인상을 남겨보세요. if를 입력하면 404가 발생할 가능성이 높습니다.

298행: Hooks 클래스는 기본적으로 사용할 수 없는 pre_controller(컨트롤러가 실행되기 전) 확장을 호출하려고 시도합니다.

301-309행: 벤치마크 클래스는 컨트롤러의 실행 시간을 테스트하기 위해 시작점 표시를 설정하고(테스트 정보는 기본적으로 표시되지 않음) 이전에 로드된 컨트롤러 클래스를 인스턴스화합니다. 기본값은 Welcome입니다.

315행: Hooks는 기본적으로 사용할 수 없는 post_controller_constructor의 확장(호출된 컨트롤러 클래스가 생성된 후)을 실행하려고 시도합니다.

317-364행: 지정된 컨트롤러 클래스의 지정된 메서드 호출을 시작합니다(물론 이는 기본 컨트롤러 Welcome의 기본 메서드 인덱스입니다). 먼저 이 프로세스를 살펴보세요. 컨트롤러 클래스에 _remap 메서드가 있으면 이를 호출하면 됩니다. 따라서 밑줄로 시작하는 메서드는 _remap을 제외합니다. 이 재매핑 방법을 사용하면 조정하기만 하면 됩니다. 기본환영

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP 세션에 저장된 데이터를 어떻게 수정합니까?PHP 세션에 저장된 데이터를 어떻게 수정합니까?Apr 27, 2025 am 12:23 AM

tomodifyDatainAphPessess, startSessionstession_start (), 그런 다음 $ _sessionToset, modify, orremovevariables.

PHP 세션에 배열을 저장하는 예를 제시하십시오.PHP 세션에 배열을 저장하는 예를 제시하십시오.Apr 27, 2025 am 12:20 AM

배열은 PHP 세션에 저장할 수 있습니다. 1. 세션을 시작하고 session_start ()를 사용하십시오. 2. 배열을 만들고 $ _session에 저장하십시오. 3. $ _session을 통해 배열을 검색하십시오. 4. 세션 데이터를 최적화하여 성능을 향상시킵니다.

Garbage Collection은 PHP 세션에 어떻게 효과가 있습니까?Garbage Collection은 PHP 세션에 어떻게 효과가 있습니까?Apr 27, 2025 am 12:19 AM

PHP 세션 쓰레기 수집은 만료 된 세션 데이터를 정리하기위한 확률 메커니즘을 통해 트리거됩니다. 1) 구성 파일에서 트리거 확률 및 세션 수명주기를 설정합니다. 2) CRON 작업을 사용하여 고재 응용 프로그램을 최적화 할 수 있습니다. 3) 데이터 손실을 피하기 위해 쓰레기 수집 빈도 및 성능의 균형을 맞춰야합니다.

PHP에서 세션 활동을 어떻게 추적 할 수 있습니까?PHP에서 세션 활동을 어떻게 추적 할 수 있습니까?Apr 27, 2025 am 12:10 AM

PHP의 사용자 세션 활동 추적은 세션 관리를 통해 구현됩니다. 1) Session_start ()를 사용하여 세션을 시작하십시오. 2) $ _session 배열을 통해 데이터를 저장하고 액세스하십시오. 3) 세션 _destroy ()를 호출하여 세션을 종료합니다. 세션 추적은 사용자 행동 분석, 보안 모니터링 및 성능 최적화에 사용됩니다.

데이터베이스를 사용하여 PHP 세션 데이터를 저장할 수있는 방법은 무엇입니까?데이터베이스를 사용하여 PHP 세션 데이터를 저장할 수있는 방법은 무엇입니까?Apr 27, 2025 am 12:02 AM

데이터베이스를 사용하여 PHP 세션 데이터를 저장하면 성능 및 확장 성을 향상시킬 수 있습니다. 1) 세션 데이터를 저장하기 위해 MySQL 구성 : php.ini 또는 php 코드에서 세션 프로세서를 설정하십시오. 2) 사용자 정의 세션 프로세서 구현 : 데이터베이스와 상호 작용하기 위해 열린, 닫기, 읽기, 쓰기 및 기타 기능을 정의합니다. 3) 최적화 및 모범 사례 : 인덱싱, 캐싱, 데이터 압축 및 분산 스토리지를 사용하여 성능을 향상시킵니다.

PHP 세션의 개념을 간단한 용어로 설명하십시오.PHP 세션의 개념을 간단한 용어로 설명하십시오.Apr 26, 2025 am 12:09 AM

phpsessionstrackuserdataacrossmultiplepagerequestsususingauniqueIdStoredInAcookie.here'showtomanagetheMeftically : 1) STARTASESSIONSTART_START () andSTAREDATAIN $ _SESSION.2) RegenerATERATESSESSIDIDAFTERLOGINWITHSESSION_RATERATERATES (True) TopreventSES

PHP 세션에 저장된 모든 값을 어떻게 반복합니까?PHP 세션에 저장된 모든 값을 어떻게 반복합니까?Apr 26, 2025 am 12:06 AM

PHP에서 세션 데이터를 통한 반복은 다음 단계를 통해 달성 할 수 있습니다. 1. Session_start ()를 사용하여 세션을 시작하십시오. 2. $ _session 배열의 모든 키 값 쌍을 통해 Foreach 루프를 통과합니다. 3. 복잡한 데이터 구조를 처리 할 때 is_array () 또는 is_object () 함수를 사용하고 print_r ()를 사용하여 자세한 정보를 출력하십시오. 4. Traversal을 최적화 할 때 페이징을 사용하여 한 번에 많은 양의 데이터를 처리하지 않도록 할 수 있습니다. 이를 통해 실제 프로젝트에서 PHP 세션 데이터를보다 효율적으로 관리하고 사용하는 데 도움이됩니다.

사용자 인증에 세션을 사용하는 방법을 설명하십시오.사용자 인증에 세션을 사용하는 방법을 설명하십시오.Apr 26, 2025 am 12:04 AM

이 세션은 서버 측 상태 관리 메커니즘을 통해 사용자 인증을 인식합니다. 1) 세션 생성 및 고유 ID의 세션 생성, 2) ID는 쿠키를 통해 전달됩니다. 3) ID를 통해 서버 저장 및 세션 데이터에 액세스합니다. 4) 사용자 인증 및 상태 관리가 실현되어 응용 프로그램 보안 및 사용자 경험이 향상됩니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!