设为首页 收藏本站
查看: 1135|回复: 0

[经验分享] CodeIgniter源码解析——/system/core/Common.php

[复制链接]

尚未签到

发表于 2015-12-23 16:00:10 | 显示全部楼层 |阅读模式
在阿里一面的时候,面试官问我知道php的设计模式吗,我在面试之前只匆匆看了下工厂模式,其他都没有看,没有答上来。

  面试结束后,我Google到一篇讲php设计模式很好的博客,大家感兴趣的可以看下。链接是:http://yansu.org/2014/04/19/design-patterns-of-php.html。
  距离二面的时间有限,我只看了工厂模式,单例模式,适配器模式,和观察者模式。在看完这几个后,我突然感觉可以去尝试看下大二使用的ci框架的源码。之前因为赶项目和自己水平有限的原因,尝试查看源代码的时候,完全搞不懂框架的设计者这么写代码的意图为何。
  即将大四的今天,在初步看了几个设计模式之后,我发现自己渐渐能窥探出一丝框架设计者代码的艺术感,虽然感觉自己可能是管中窥豹,但还是压抑不住这种有些豁然开朗的激动,想把这个感觉很棒的部分记录下来。

1 CodeIgniter(以下简称ci)的运行流程

    ci在启动的第一步,是执行index.php文件,该文件定义了许多变量以及需要加载的模块的路径的设置,并在最后引入了/core/CodeIgniter.php,
这个文件可以说是整个ci运行的流程,有位分析ci源代码的大牛说,将这个文件运行一遍,基本上算是完成了整个CI框架的一次完成运行过程,但我在1个小时之前才去分析源代码,运行整个CI的具体流程我还不知,但是在/core/CodeIgniter.php中引用了一个公共函数文件,位于/core/Common.php

2  Common.php文件

可以看下该文件中的官方介绍:




  • /**

  • * Common Functions
  • *
  • * Loads the base classes and executes the request.
  • *
  • * @package        CodeIgniter
  • * @subpackage    CodeIgniter
  • * @category    Common Functions
  • * @author        EllisLab Dev Team
  • * @link        http://codeigniter.com/user_guide/
  • */
    意思是说该文件定义了一些公共函数,用来加载基本的类和执行请求。
    其中有一个&load_class的函数是整个文件的核心。

3 &load_class

   以下是该函数的定义。



  • // ------------------------------------------------------------------------


  • if ( ! function_exists('load_class'))
  • {
  •     /**
  •      * Class registry
  •      *
  •      * This function acts as a singleton. If the requested class does not
  •      * exist it is instantiated and set to a static variable. If it has
  •      * previously been instantiated the variable is returned.
  •      *
  •      * @param    string    the class name being requested
  •      * @param    string    the directory where the class should be found
  •      * @param    string    an optional argument to pass to the class constructor
  •      * @return    object
  •      */
  •     function &load_class($class, $directory = 'libraries', $param = NULL)
  •     {
  •         static $_classes = array();

  •         // Does the class exist? If so, we're done...

  •         if (isset($_classes[$class]))
  •         {
  •             return $_classes[$class];
  •         }

  •         $name = FALSE;

  •         // Look for the class first in the local application/libraries folder
  •         // then in the native system/libraries folder
  •         foreach (array(APPPATH, BASEPATH) as $path)
  •         {
  •             if (file_exists($path.$directory.'/'.$class.'.php'))

  •             {
  •                 $name = 'CI_'.$class;


  •                 if (class_exists($name, FALSE) === FALSE)
  •                 {
  •                     require_once($path.$directory.'/'.$class.'.php');

  •                 }

  •                 break;
  •             }
  •         }

  •         // Is the request a class extension? If so we load it too
  •         if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))

  •         {
  •             $name = config_item('subclass_prefix').$class;


  •             if (class_exists($name, FALSE) === FALSE)
  •             {
  •                 require_once(APPPATH.$directory.'/'.$name.'.php');

  •             }
  •         }

  •         // Did we find the class?
  •         if ($name === FALSE)
  •         {
  •             // Note: We use exit() rather then show_error() in order to avoid a
  •             // self-referencing loop with the Exceptions class
  •             set_status_header(503);
  •             echo 'Unable to locate the specified class: '.$class.'.php
该函数首先是一个单例模式的模型,当静态变量的数组中已经加载了该类,则返回引用,如果没有则引入类文件并初始化该类。调用这个函数时自始至终都是返回那个静态数组是单例的。
    其次,对需要加载并且实例化的类,并不是在哪里需要的时候require_once来引入,并用new来实例化,而是类似工厂的模式,统一的进行实例化,并且存储在静态数组里,这就使得在ci运行过程中同样一个类只被实例化了一次。
    最后,Common.php中还定义了一个&is_loaded的函数,用来记录已经被初始化的类,代码如下:




  • if ( ! function_exists('is_loaded'))

  • {
  •     /**
  •      * Keeps track of which libraries have been loaded. This function is
  •      * called by the load_class() function above
  •      *
  •      * @param    string
  •      * @return    array
  •      */
  •     function &is_loaded($class = '')
  •     {
  •         static $_is_loaded = array();

  •         if ($class !== '')
  •         {
  •             $_is_loaded[strtolower($class)] = $class;
  •         }

  •         return $_is_loaded;
  •     }
  • }

该方法也是使用一个单例,使用静态数组保存已经加载的类,我感觉有些观察者模式的思想。它跟踪着已经加载的类的状态。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-155385-1-1.html 上篇帖子: rhel 5 x86_64下编译php出现错误(Try adding --with-zlib-)解决 下篇帖子: phpwind8.7整站压缩
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表