Kohana的Cache

Kohana里有个Cache Library,我今天就测试了一下。

首先要配置,将system/config下的cache.php复制到application/config下,打开cache.php文件,我们看一下内容

1
2
3
4
5
6
7
$config['default'] = array
(
    'driver'   => 'file',
    'params'   => APPPATH.'cache',
    'lifetime' => 1800,
    'requests' => 1000
);

这是一个默认配置,’driver’为驱动的缓存方式,Kohana支持6种不同的驱动,分别是File、SQlite、Memcache、APC、Eaccelerator、Xcache,配置文件默认使用的file,其原理是,写缓存时把对象序列化写入文件,读缓存时从文件读出文本反序列化,所以在文件方式下,缓存是基于I/O的,在文件多而且大的时候,性能会有下降, ‘params’是驱动参数,在file驱动模式下,就是cache文件路径,’lifetime’是cache的生命周期,单位为秒,超过这个时间,内容将被清除(设置为0代表不自动清除),’requests’为在达到请求数量之前自动垃圾回收。

在应用中,可能需要不止一个缓存,所以可以配置多个缓存,增加$config数组即可,还有在file方式下可以为每个缓存设置单独文件路径,但前提是文件路径要存在,例如我们增加一个

1
2
3
4
5
6
7
$config['my'] = array
(
    'driver'   => 'file',
    'params'   => APPPATH.'cache/my',
    'lifetime' => 1800,
    'requests' => 1000
);

接下来我们在Controller里调用cache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Mycache_Controller extends Controller {
 
    public function index() {
        $mychache = Cache::instance("my");
        $mychache->set("name","laoer");
        echo "OK";   
    }
 
    public function name() {
        $mychache= Cache::instance("my");
        $name = $mychache->get("name");
        echo $name;
    }   
}

Cache::instance(“my”)实例化配置里$config[‘my’]的cache,如果用Cache::instance()就是实例化配置里$config[‘default’]的cache,在浏览器里执行,已经可以存取了,在application/cache/my/文件下可以看到一个名为”name~~0″的文件,里面就是序列化的数据。

文件cache还是有一定的局限性,现在越来越的网站开始使用Memcached所谓缓存的解决方案,Kohana的缓存驱动里,有Memcached的支持,但它的文档却没有给出Memcached的配置例子,看来要自己摸索一下。

将system/config下的cache_memcache.php复制到application/config下,cache_memcache.php的内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * @package  Cache:Memcache
 *
 * memcache server configuration.
 */
$config['servers'] = array
(
	array
	(
		'host' => '127.0.0.1',
		'port' => 11211,
		'persistent' => FALSE,
	)
);
 
/**
 * Enable cache data compression.
 */
$config['compression'] = FALSE;

根据你自己的情况修改Memcached的服务地址和端口,在application/config/cache.php里再加一段

1
2
3
4
5
6
7
$config['mem'] = array
(
	'driver'   => 'memcache',
	'params'   => '',
	'lifetime' => 1800,
	'requests' => 1000
);

在Controller里把Cache::instance(“my”)改为Cache::instance(“mem”),运行看看结果,已经可以从Memcahced里存取了。

Kohana的Memcached驱动还是有些缺陷,现在只能使用一组Memcached,即$config[‘servers’]这个参数,我觉得Memcacahed组也应该是多个,因为从业务角度会根据功能对cache做划分,我大概看了一下system/libraries/drivers/Cache/Memcache.php文件,应该是可以改造的,还有一点,编译PHP的时候要安装Memcached的支持。

Kohana的Events和Hooks研究

Kohana是一个使用PHP5的面向对象的MVC框架,是从CodeIgniter衍生出来,研究了几天,感觉还不错,就是它的文档实在太简陋了,在看到它的Events机制和Hooks机制时,确实有点不明白,文档上说的实在太简单了,后来我在Google上搜索了一下,找到两篇文章《Events and hooks in Kohana》《Practical Kohana Hooks example: PHPIDS》,上面讲了一下Kohana的Events和Hooks,并举了例子,我也开始慢慢理解了它的含义。

在Kohana的Events中,默认定义了很多的Events(例如system.ready、system.pre_controller等等),中文理解就是事件,也就是触发点,在程序在运行到某个位置时,会被触发,具体就是调用Event::run方法,我们在Kohana.php里可以看到在不同的位置执行了不同的Event::run方法,那么Hooks的意义在于当一个事件被触发之前,可以通过已加载的Hooks来修改事件的回调,有点绕口,说白了就是在事件发生之前,做点事情,举个例子,你安排了今天的日程,下午3点要开会,那么在3点开会就是一个Event(事件),那么到3点的时刻,你希望提醒你一下,你在你的手机里定了一个闹钟,在3点的时候会响,这就是一个Hook,可以看出Hook是基于Event的。

我们可以创建自己的Hook程序,并加载如默认的Events里,但是默认的Events不一定能满足我们的需要,比如我们在Web应用中经常使用的权限校验,判断这个用户是否登陆过,我们虽然可以使用默认Events里的system.pre_controller,但是这个Event是针对所有的Controller的,有些Controller是不需要校验用户的,还好Kohana允许自己定义Event,下面我们还是举例说明吧。

要使用Hooks,首先要在application/config/config.php里将$config[‘enable_hooks’]置为TRUE。

之后我们定义自己的Event,我们在application/controllers目录下建立base.php,代码如下:

1
2
3
4
5
6
7
class Base_Controller extends Controller  {
 
	public function __construct() {
		parent::__construct();
		Event::run("base.construct");
	}	
}

我们继承了Kohana的Controller,在构造函数里定义了Event,名字叫“base.construct”,以后我们的Controller都继承自Base_Controller,那么在对象创建的时候都会触发base.construct事件。

Hook的文件放在application/hooks下,我们就创建一个hook文件sessioncheck.php,代码如下:

1
2
3
4
5
6
7
8
9
class SessionCheck {
 
	public function check() {
		echo "check session ...";
	}
 
}
 
Event::add('base.construct', array('SessionCheck','check'));

我们将SessionCheck的check方法加载到了base.construct事件上,也就是在触发base.construct事件之前,会执行SessionCheck的check方法。

接下来我们写一个Controller,在application/controllers目录下建立first.php,代码如下:

1
2
3
4
5
6
7
class First_Controller extends Base_Controller  {
 
	public function index() {
		echo "First - index";
		exit();
	}
}

我们执行一下看看会有什么提示,http://localhost/kohana/first,显示

check session …First – index

没问题了,在Controller构造时,执行了Hook里的方法。

PHP框架选择

离最初用PHP编程序已经有8、9年时间了,后来这6、7年的时间一直研究Java,对PHP有些生疏了,但PHP的生命力却依旧顽强,对于面向Web开发时Java的繁琐,我最近又将注意力集中到了PHP上,但已经习惯了Struts这样的MVC框架,我也要寻找一个适合的PHP MVC框架,选择的标准有几个:1、性能;2、易用性;3、文档;4、长期支持度

我最开始看了Zend Framework,Zend的东西,毕竟带有官方特性,他的framework应该是代表着主流,看了之后,Zend Framework可以说是纷繁复杂,但是面面俱到,Web应用方面的问题基本都可以解决,我唯一担心的就是性能,虽没有做过测试,但也确实担心。

后来有一天在JavaEye上逛,看到一篇帖子《PHP框架的繁荣是正确的发展方向吗?》,讨论了PHP的运行机制、与ROR的比较、性能等等,非常热闹,同时也列举出了一些PHP的框架,特别是一些性能比较,让我很吃惊,CakePHP、Symfony可以不用考虑了。

接下来我看了看CodeIgniter,感觉不错,简单,相比Zend Framework要简单得多,大多数问题也都能解决,性能在一些资料描述中也表现的尚可(比Zend Framework要快几倍),而且其文档比较细,学习起来不难,后来又发现了Kohana,Kohana是从CodeIgniter衍生出来,由于CodeIgniter是兼容PHP4和5的,而Kohana只支持PHP5,是完全的OO方式,其文档并还没有仔细研究,看到了一个比较的文章《Notes on Choosing a PHP Framework: A Quick Comparison of CodeIgniter and Kohana》,看上去Kohana有些特性还是很优秀的,但不知道Kohana社区对于这个开源产品的支持有多好。

后来又看到文章《Performance of Yii》,发现Yii这个框架的性能更强劲啊,比CodeIgniter还要好几倍,不可思议,看了看Yii的文档,它也是完全OO的,要PHP5以上,核心应该也比较简单,能保持比较好的性能,但我觉得它的Guide文档比较粗,学习起来似乎要费点功夫,其性能应该是我最感兴趣的地方。

再说说国内的PHP框架,在JavaEye的文章里,QeePHP的作者也在推荐自己的框架,简单测试下比Yii还要快,好NB啊,但从社区反应出来其文档不够详细,其代码我也没有细看,似乎和Yii有很多相近的地方,另一个国内的PHP框架ThinkPHP文档比较详尽,但没有测试报告,不知道性能如何,而且在PHPChina的社区里和QeePHP有激烈的争论,挺有意思的。

看了一大圈,我也没有决定采用何种PHP的框架,他们各有长处,也各有缺陷,但综合考虑,我还是应该会在CodeIgniter、Kohana和Yii中选择最终的方案。