CodeIgniter(以下简称CI、官网、中国站)是一个流行的PHP框架,它紧凑、强大、简单、轻量、可扩展,在国内也很流行。另一方面,CI不与时俱进,不支持PHP5.3之后的一些特性,这使得它更适合较老的项目。尽管如此,CI仍然是一个优秀的框架,而且内核小,源代码优雅,适合学习。
CI易于使用,并且便于开发web应用程序。我们来看看CI的工作流程图(这里的内容引用自http://codeigniter.org.cn/user_guide/overview/appflow.html)
1.index.php被用作前端控制器来初始化运行CodeIgniter所需的基本资源。2.2。路由器检查HTTP请求,以确定谁将处理该请求。3.如果缓存文件存在,它将绕过通常的系统执行顺序,直接发送到浏览器。4.保安。在加载应用程序控制器之前,将过滤用户提交的HTTP请求和任何数据。5.控制器加载模型、核心库、辅助函数以及处理特定请求所需的任何其他资源。6.最终视图呈现发送到网络浏览器的内容。如果打开了缓存,视图将首先被缓存,因此它将可用于将来的请求。
以上给出了一个大概的过程。那么当你看到浏览器中呈现的页面时,程序是如何工作的呢?下面按执行顺序列出了CI框架加载的主要文件,并简要介绍了它们的功能:
01.index.php定义了使用环境、框架路径(system_path、BASEPATH)、应用目录(application_folder)、应用路径(APPPATH)等。需要配置项来加载配置项核心文件02.basepath/core/codeigniter.php。BASEPATH实际上包含最后一个文件分隔符'/',这里添加了'/'以便更清晰地显示)。系统初始化文件是整个框架的核心部分,它在这里加载了一系列基类。为了执行这个请求,03.basepath/core/common.phpcommon文件包含一系列供全局使用的基本和通用函数,比如load_class(),get_config(),等等。04.BASEPATH/core/Benchmark是一个基准测试类,默认标记应用程序每个阶段的执行点,以获取其执行时间。它还允许您定义自己的监控点。05.base path/core/hooks . phpci _ hooks是一个hook类,是扩展框架的核心。它可以在程序允许的各个阶段插入钩子点,并执行自己定制的类、函数等06。BASEPATH/core/Config.php配置文件管理类。07 uri类。basepath/core/uri。PHP加载、读取或设置配置,帮助您解析请求的uri,并为路由器类提供一组分离uri的函数来使用08。BASEPATH/core/Router.php路由类,即通过请求的uri和用户配置的路由(APPPATH/config/routes.php),并将用户请求分发到指定的处理函数(通常是Controller实例中的一个操作函数)。09.basepath/core/output.php, base path/core/input . PHP输入类,即用于处理请求的输入参数,提供了一种安全的获取方法。输出类发出最终的执行结果,它还负责缓存功能。10.基本路径/核心/控制器。控制器基类PHP用singleton模式向外界提供示例,这是整个应用程序的核心。它是一个Super Object,应用程序中加载的所有类都可以成为控制器的成员变量,这一点非常重要,后面会讲到。11.app path/controllers/$ RTR-fetch _ directory()。$ RTR-fetch _ class()。“PHP”通过路由函数获取控制器名称。实例化实控制器类(子类)。12.Basepath/core/loader。phpci _ loader用于加载各种类库、模型、视图、数据库、文件等。并将它们设置为控制器的成员变量。13.call_user_func_array调用处理函数,通过路由获取动作函数名。调用Controller-action()函数处理应用程序逻辑。实际的业务处理逻辑是14。$OUT-_display()写入动作函数输出内容
这是整个应用最基本的处理流程。选择以下核心内容代码进行进一步解释,以增强对竞争情报的理解:
?PHP//* BASEPATH/system/core/common。PHP//引导文件中基准、挂钩、配置等都是通过这个函数进行加载的函数load_class($class,$directory='libraries ',$prefix='CI_'){//记录加载过的类static $ _ class=array();//已经加载过,直接读取并返回if(isset($ _ class[$ class]){ return $ _ class[$ class];} $ name=FALSE//在指定目录寻找要加载的类foreach(数组(应用路径,基本路径)作为$path){if (file_exists($path).$目录.'/'.$ class . PHP '){ $ name=$ prefix .$ class if(class _ exists($ name)=FALSE){ require($ path).$directory ./'.$ class . PHP ');} break}}//没有找到if ($name===FALSE){exit('找不到指定的类: '。$ class . PHP ');}//追踪记录下刚才加载的类,is_loaded()函数在下面is _ loaded($ class);$ _ class[$ class]=new $ name();返回$ _ class[$ class];}//记录已经加载过的类。函数返回所有加载过的类函数is _ loaded($ class=' '){ static $ _ is _ loaded=array();if ($class!=' '){ $ _ is _ loaded[strtolow($ class)]=$ class;} return $ _ is _ loaded }////* BASEPATH/系统/内核/控制器。phpclass CI _ Controller { private static $实例;public function _ _ construct(){ self : $ instance=$ this;//将所有在引导文件中(CodeIgniter.php)初始化的类对象(即刚才4,5,6,7,8,9等步骤),//注册成为控制器类的成员变量,就使得这个控制器成为一个超级对象(super object)foreach(is _ loaded()as $ var=$ class){ $ this-$ var=load _ class($ class);} span style='空白: pre '/span/加载装货设备对象,再利用装货设备对象对程序内一系列资源进行加载span style='空白: pre '/span $ this-load=load _ class(' Loader ',' core ');$ this-load-initialize();log_message('debug ','控制器类已初始化');}//这个函数对外提供了控制器的单一实例公共静态函数get _ instance(){ return self : $ instance;} }////* BASEPATH/system/core/code igniter。PHP//加载基本控制器类需要BASEPATH .核心/控制器;//通过这个全局函数就得到了控制器的实例,得到了这个超级对象,//意味着在程序其他地方调用这个函数,就能得到整个框架的控制权函数get _ instance(){ 0返回CI _ controller : get _ instance();}//加载对应的控制器类//注意:路由器类会自动使用路由器-_验证_请求()验证控制器路径if(!file_exists(APPPATH .控制器/'。$RTR-fetch_directory().$ RTR-fetch _ class(). PHP '){ show _ error('无法加载您的默认控制器。请确保您的Routes.php文件中指定的控制器有效);}包含(APPPATH .控制器/'。$RTR-fetch_directory().$ RTR-fetch _ class(). PHP’;$ class=$ RTR-fetch _ class();//控制器类名$ method=$ RTR-fetch _ method();//操作名称/.//调用请求的函数//uri中除了类别/功能之外的段也会被传递给调用的函数call_user_func_array(array($CI,$method),array_slice($URI-rsegments,2));//输出最终的内容到浏览器if($ EXT-_ call _ hook(' display _ override ')==FALSE){ $ OUT-_ display();}////* BASEPATH/system/core/Loader。PHP//看一个装货设备类加载模型的例子。这里只列出了部分代码公共函数模型($model,$name=' ',$ db _ conn=FALSE){ $ CI=get _ instance();if(isset($ CI-$ name)){ show _ error('您正在加载的模型名称是已经在使用的资源的名称: '。$ name);} $ model=strtolow($ model);//依次根据模型类的小路进行匹配,如果找到了就加载foreach($ this-_ ci _ model _ path as $ mod _ path){ if(!file_exists($mod_path).模型/' .$path .$模型. PHP '){ 0继续;}if ($db_conn!==假与!class _ exists(' CI _ DB '){ if($ DB _ conn===TRUE){ $ DB _ conn=' ';}$CI-load-database($db_conn,FALSE,TRUE);}if(!class _ exists(' CI _ Model '){ load _ class(' Model ',' core ');}需要一次($mod_path).模型/' .$path .$模型. PHP ');$ model=UC first($ model);//这里依然将模型对象注册成控制器类的成员变量。
加载程序在加载其他资源时也会这样做。$ CI-$ name=new $ model();$ this-_ ci _ models[]=$ name;返回;}//找不到modelshow _ error('找不到您指定的模型: '。$ model);}///* base path/system/core/model . PHP/_ _ get()是一个神奇的方法,在读取未定义变量的值时会被调用。//下面是model基类对_ _ get()函数的实现,这样就可以像直接在控制器类中一样进入Model类(例如,$this-var)返回$ CI-$ key;}