emLog的MVC框架、Cache及Plugin
index.php主要就是转到dispatcher那里,进行调度。
Dispatcher怎么调度呢?
在ZF里,dispatcher是有router的,router有它的route规则,根据这些route规则,dispatcher做dispatch的动作。
Emlog就简单多了。它有一个routing_table(在options.php里),直接搞定ZF用了一堆class实现的route功能,很实用、简洁的实现了调度规则。真的简单,也真的实用!ZF是框架,可能用到的功能都得做,复杂些是不可避免的;emLog则只是给本系统用,够用的前提下,自然越简单越好。
这个routing_table是个数组,每个元素主要包括三方面:1、model;2、method、3、匹配URL用的正则表达式。很明显,意思就是,对于匹配正则式的请求,直接转给$model->$method去处理,参数嘛,就在URL里面。
但需要注意的是,在这里,model并不是真正的model。看看routing_table,
1 $routingtable = array(
2 array(
3 'model' => 'calendar',
4 'method' => 'generate',
5 'reg_0' => '|^.*/\?action=cal|',
6 ),
7 array(
8 'model' => 'Log_Controller',
9 'method' => 'displayContent',
10 'reg_0' => '|^.*/\?(post)=(\d+)(&(comment-page)=(\d+))?([\?&].*)?$|',
11 'reg_1' => '|^.*/(post)-(\d+)\.html(/(comment-page)-(\d+))?/?([\?&].*)?$|',
12 'reg_2' => '|^.*/(post)/(\d+)(/(comment-page)-(\d+))?/?$|',
13 'reg_3' => '|^/([^\./\?=]+)(\.html)?(/(comment-page)-(\d+))?/?([\?&].*)?$|',
14 ),
15 array(
16 'model' => 'Record_Controller',
17 'method' => 'display',
18 'reg_0' => '|^.*/\?(record)=(\d{6,8})(&(page)=(\d+))?([\?&].*)?$|',
19 'reg' => '|^.*/(record)/(\d{6,8})/?((page)/(\d+))?/?([\?&].*)?$|',
20 ),
21 array(
22 'model' => 'Sort_Controller',
23 'method' => 'display',
24 'reg_0' => '|^.*/\?(sort)=(\d+)(&(page)=(\d+))?([\?&].*)?$|',
25 'reg' => '|^.*/(sort)/([^\./\?=]+)/?((page)/(\d+))?/?([\?&].*)?$|',
26 ),
27 array(
28 'model' => 'Tag_Controller',
29 'method' => 'display',
30 'reg_0' => '|^.*/\?(tag)=([^&]+)(&(page)=(\d+))?([\?&].*)?$|',
31 'reg' => '|^.*/(tag)/([^/?]+)/?((page)/(\d+))?/?([\?&].*)?$|',
32 ),
33 array(
34 'model' => 'Author_Controller',
35 'method' => 'display',
36 'reg_0' => '|^.*/\?(author)=(\d+)(&(page)=(\d+))?([\?&].*)?$|',
37 'reg' => '|^.*/(author)/(\d+)/?((page)/(\d+))?/?([\?&].*)?$|',
38 ),
39 array(
40 'model' => 'Log_Controller',
41 'method' => 'display',
42 'reg_0' => '|^.*/\?(page)=(\d+)([\?&].*)?$|',
43 'reg' => '|^.*/(page)/(\d+)/?([\?&].*)?$|',
44 ),
45 array(
46 'model' => 'Search_Controller',
47 'method' =>'display',
48 'reg_0' => '|^.*/\?(keyword)=([^/&]+)(&(page)=(\d+))?([\?&].*)?$|',
49 ),
50 array(
51 'model' => 'Comment_Controller',
52 'method' => 'addComment',
53 'reg_0' => '|^.*/\?(action)=(addcom)([\?&].*)?$|',
54 ),
55 array(
56 'model' => 'Plugin_Controller',
57 'method' => 'loadPluginShow',
58 'reg_0' => '|^.*/\?(plugin)=([\w\-]+).*([\?&].*)?$|',
59 ),
60 array(
61 'model' => 'Log_Controller',
62 'method' => 'displayContent',
63 'reg_0' => '|^.*?/([^/\.=\?]+)(\.html)?(/(comment-page)-(\d+))?/?([\?&].*)?$|',
64 ),
65 array(
66 'model' => 'Log_Controller',
67 'method' => 'display',
68 'reg_0' => '|^/?([\?&].*)?$|',
69 ),
70
71 );
里面的model几乎都是controller,而不是MVC概念中的M(Model)!
那么,真正的Model在哪儿呢?
当然在model目录下。对着DB下的tables,基本上就是一个对一个,User有user的model,log有log的model。这也正常。PHP下,没有常驻程序,每个php运行完就完了,MVC中的M往往就只能是数据库(或者文件、session、cookie)。
上面说的是M和C。那么,view在哪儿呢?
在m/view目录下。很自然的,通常都是在Controller中,通过View::getView()的方式调用。
于是,整个emLog的MVC框架就起来了!
【Cache】
emLog中,每次都会去看Cache文件是否存在,所需要的数据是否在Cache中,如果否,那么就从数据库中取出,并放到Cache里,同时更新Cache文件。
如果这部分内容出现在Java Servlet,我毫不奇怪。但这是PHP啊,每次都起一块Cache,从数据库或Cache文件中取得一大堆数据,但对每一次请求而言,多数数据自己都用不上!别人则根本用不上。除了浪费时间和空间之外,实在不觉得有什么大用。需要的时候直接去数据库拿就行了呗!这样做,在用户量较大的情景下,确实可以减轻对数据库的压力。但Cache数据的同步问题怎么解决?暂时还没看到。后面需要再仔细瞧瞧。
【Plugin】
对于插件,emLog实现的也很轻巧。在emLog中,很多地方都有doAction(),参数呢,是一个数组,里面会有一串函数名。如果需要加plugin,就调用addAction(),把你的插件函数塞到需要的数组里,这样就行了。问题是,我好像还没见到哪里有完整介绍这些入口地方的文档。要对相关代码有所熟悉才好做plugin。还好,emLog也不大。