在CodeIgniter中使用PEAR类库的解决方法

一天在 CodeIgniter中国社区 看到如下的问题:
CodeIgniter下能不能用pear包里面的东西。
如果能,怎样在controllers里调用。

原文地址: http://codeigniter.org.cn/forums/viewthread.php?tid=1064&highlight=pear

我当时给出了一个基本的思路:

CI和PEAR的命名约定不一样,CI的类库都是独立类库,轻量小型化;而PEAR是系统树形结构,非常庞大,层层继承和关联,这和当初想构建PHP扩展和应用类库有关系。两者的出发点和目的均不一样。如果CI里面非要用PEAR类库,有两个途径:
1、按照CI的命名约定和方式来把PEAR的类库转化成自己的类库,需要解决原来类库的继承和关联;
2、在CI中添加PEAR类库导入通道,作为特例来处理或者修改CI载入类库的方式,使PEAR类库不做修改直接使用;
如果暂时急用某个PEAR类库,那就采用第一种方式,改成自己创建的CI类库,一时权宜之计;长远考虑如果想解决CI中使用PEAR类库的问题,只能是第二种方法,必须从CI下手,有可能是一劳永逸的。
后来利用一个下午的时间对个思路进行了实现,基本上完成了。然后在第一时间发布在 CodeIgniter中国社区 ,以下便是:

在CI中使用PEAR类库的解决方法

昨天看到有朋友询问如何在CI中使用PEAR类库的方法,当时提出了一个实现的思想。
原帖: http://codeigniter.org.cn/forums/thread-1064-1-1.html

现在基于第二个思路,添加PEAR类库载入通道,解决方法简单实现一下:

1、PEAR属于第三方类库,放在 application/libraries/PEAR 下面(当做自制类库对待);
2、PEAR类库平铺展开,取消子目录以及编辑包含路径;
3、继承扩展Loader类库,添加pear载入方法,并添加两个私有内置方法 _ci_load_pear 和 _ci_init_pear
4、默认先装载 PEAR.php基类(也可以取消,直接装载相应类库);
5、然后装载相应的应用类库,需要提供类库前缀(因和CI命名约定不同),参数采用数组传递,然后初始化的时候利用implode 展开参数;
6、需要修改Base4.php文件,替换成扩展Loader类库;

扩展Loader类库代码如下:


<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * CodeIgniter
 *
 * LEMON
 * QQ 83997439
 * <a href="mailto:lemonfz@gmail.com">lemonfz@gmail.com</a>
 *
 */

class FG_Loader extends CI_Loader {

 /**
  * Constructor
  *
  * Sets the path to the view files and gets the initial output buffering level
  *
  * @access public
  */
 function FG_Loader()
 {
  parent::CI_Loader();
 }

 // --------------------------------------------------------------------

 /**
  * Class Loader
  *
  * This function lets users load and instantiate classes.
  * It is designed to be called from a user's app controllers.
  *
  * @access public
  * @param string the name of the class
  * @param mixed the optional parameters
  * @return void
  */
 function pear ($library = '', $prefix = '', $params = NULL)
 {
  if ($library == '')
  {
   return FALSE;
  }

  if (is_array($library))
  {
   foreach ($library as $class)
   {
    $this->_ci_load_pear($class, $prefix, $params);
   }
  }
  else
  {
   $this->_ci_load_pear($library, $prefix, $params);
  }

  $this->_ci_assign_to_models();
 }

 // --------------------------------------------------------------------     

 /**
  * Load class
  *
  * This function loads the requested class.
  *
  * @access private
  * @param  string the item that is being loaded
  * @param mixed any additional parameters
  * @return  void
  */
 function _ci_load_pear($class, $prefix, $params = NULL)
 {
  // Get the class name

  $subclass = APPPATH . 'libraries/PEAR/' . $class . EXT;

  // Is this a class extension request?
  if ( file_exists ( $subclass ) ) {
   $baseclass = APPPATH . 'libraries/PEAR/PEAR' . EXT;

   if ( ! file_exists ( $baseclass ) ) {
    log_message ( 'error', "Unable to load the requested class: " . $baseclass );
    show_error ( "Unable to load the requested class: " . $baseclass );
    return;
   }

   require_once $baseclass;
   require_once $subclass;

   $this->_ci_classes[] = $subclass;

   return $this->_ci_init_pear($class, $prefix, $params);
  }

  log_message('error', "Unable to load the requested class: ".$class);
  show_error("Unable to load the requested class: ".$class);
 }

 // --------------------------------------------------------------------

 /**
  * Instantiates a class
  *
  * @access private
  * @param string
  * @param string
  * @return null
  */
 function _ci_init_pear($class, $prefix = '', $params = NULL)
 { 

  $name = $prefix . $class;

  $var = "pear_" . strtolower ( $class );

  // Set the variable name we will assign the class to
  $classvar = ( ! isset($this->_ci_varmap[$var])) ? $var : $this->_ci_varmap[$var];

  // Instantiate the class
  $CI =&amp;amp; get_instance();
  if ($params !== NULL)
  {
   $CI->$classvar = new $name ( implode ( ',', $params ) );
  }
  else
  {
   $CI->$classvar = new $name;
  }
 }  

 // --------------------------------------------------------------------  

}

/* End of file FG_Loader.php */
/* Location: ./application/libraries/FG_Loader.php */
载入PEAR类库:
$this->load->pear ('SMTP', 'Net_' );

if ( isset ($this->pear_smtp) ) {
	echo "pear load OK!";
}
else {
	echo "pear load faild!";
}
存在的问题:

1、PEAR的树形路径包含需要解决,以能够完整解决此问题;
2、需要硬性修改Base4.php文件,这是我不愿意的地方,很不爽,不知道有没有其他方式绕过去;
3、只是简单的载入类库,其他功能和细节没有严格测试;

最后,时间比较仓促,只是提供了一个思路的解决方法,希望有精力的朋友不断去完善,或者提出更好的方法。毕竟PEAR是一个非常丰富的类库,CI作为框架不可能实现自带很多类库,并做到功能很强大,所以直接引入PEAR类库未尝不是一个很好的办法。

Related posts:

Tags: , ,

One Response to “在CodeIgniter中使用PEAR类库的解决方法”

  1. 【转】將 PEAR 放進 CodeIgniter « LEMON’s BLOG - 黎明博客 Says:
    十二月 24th, 2008 at 11:36 下午

    [...] Posted by LEMON | Filed under CodeIgniter, PHP 之前写过一篇【 在CodeIgniter中使用PEAR类库的解决方法 】,今天又看到一篇文章,特地转过来。 [...]

Leave a Reply

You must be logged in to post a comment.

© Copyright 2010 LEMON’s BLOG - 黎明博客
Design by: styleshout | Colourise by: Theme Lab and Search Marketing | Customised by blog.lemonfz.com
Powered by WordPress 2.7 | Valid CSS | XHTML | 27 queries. 0.460 seconds.