Chinaunix首页 | 论坛 | 博客
  • 博客访问: 97451
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-11 22:44
个人简介

HUST16届准毕业生,发奋求职中...

文章分类

全部博文(21)

文章存档

2015年(17)

2014年(4)

我的朋友

分类: PHP

2015-07-23 23:48:28

  在阿里一面的时候,面试官问我知道php的设计模式吗,我在面试之前只匆匆看了下工厂模式,其他都没有看,没有答上来。

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

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


2  Common.php文件

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

点击(此处)折叠或打开

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

3 &load_class

   以下是该函数的定义。

点击(此处)折叠或打开

  1. // ------------------------------------------------------------------------

  2. if ( ! function_exists('load_class'))
  3. {
  4.     /**
  5.      * Class registry
  6.      *
  7.      * This function acts as a singleton. If the requested class does not
  8.      * exist it is instantiated and set to a static variable. If it has
  9.      * previously been instantiated the variable is returned.
  10.      *
  11.      * @param    string    the class name being requested
  12.      * @param    string    the directory where the class should be found
  13.      * @param    string    an optional argument to pass to the class constructor
  14.      * @return    object
  15.      */
  16.     function &load_class($class, $directory = 'libraries', $param = NULL)
  17.     {
  18.         static $_classes = array();

  19.         // Does the class exist? If so, we're done...
  20.         if (isset($_classes[$class]))
  21.         {
  22.             return $_classes[$class];
  23.         }

  24.         $name = FALSE;

  25.         // Look for the class first in the local application/libraries folder
  26.         // then in the native system/libraries folder
  27.         foreach (array(APPPATH, BASEPATH) as $path)
  28.         {
  29.             if (file_exists($path.$directory.'/'.$class.'.php'))
  30.             {
  31.                 $name = 'CI_'.$class;

  32.                 if (class_exists($name, FALSE) === FALSE)
  33.                 {
  34.                     require_once($path.$directory.'/'.$class.'.php');
  35.                 }

  36.                 break;
  37.             }
  38.         }

  39.         // Is the request a class extension? If so we load it too
  40.         if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
  41.         {
  42.             $name = config_item('subclass_prefix').$class;

  43.             if (class_exists($name, FALSE) === FALSE)
  44.             {
  45.                 require_once(APPPATH.$directory.'/'.$name.'.php');
  46.             }
  47.         }

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

点击(此处)折叠或打开

  1. if ( ! function_exists('is_loaded'))
  2. {
  3.     /**
  4.      * Keeps track of which libraries have been loaded. This function is
  5.      * called by the load_class() function above
  6.      *
  7.      * @param    string
  8.      * @return    array
  9.      */
  10.     function &is_loaded($class = '')
  11.     {
  12.         static $_is_loaded = array();

  13.         if ($class !== '')
  14.         {
  15.             $_is_loaded[strtolower($class)] = $class;
  16.         }

  17.         return $_is_loaded;
  18.     }
  19. }

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


阅读(1876) | 评论(0) | 转发(0) |
0

上一篇:TCP/IP详解——动态选路协议

下一篇:没有了

给主人留下些什么吧!~~