<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[[框架核心]kohana框架controller/action/view原理，在很多时候反射也是唯一的选择：为什么我们会选择使用反射？找不到action和对应方法时调用404。直接访问Url里的一个controler下用action直接输出调用forward时在调核心request类里的函数返回$this是什么的理解。错误报告，文件缓存等实现， 自制session，web端打开写SQL日志及分析，单例模式，观察者模式，加载外部modules方法及入口文件，model+service+controller中间加上server层的原因，为何getCache得在services目录里的base.php和library目录下的model.php里有。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Tue, 20 Oct 2009 03:25:07 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	[root@my htdocs]# php -v<br/>PHP 5.3.27 (cli) (built: Aug 12 2013 12:22:48) <br/>升级后：<br/>[root@iZ25z0ugwgtZ ~]# php -v<br/>PHP 5.6.18 (cli) (built: Feb 13 2016 13:05:48) <br/>升级后，出现：<br/>ErrorException [ 2 ]: fopen(Unknown): failed to open stream: No such file or directory ~ SYS_PATH/core.php [ 865 ]<br/>===================================================================<br/>回退回5.3版本，如下：<br/>[ZendGuardLoader-php-5.3-linux-glibc23-x86_64.tar.gz] found<br/>ZendGuardLoader module install successfully! <br/>Gracefully shutting down php-fpm . done<br/>Starting php-fpm&nbsp;&nbsp;done<br/>####################Congratulations########################<br/><br/>PHP install dir:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/usr/local/php<br/>eAccelerator Control Panel url: http://101.200.189.210/control.php<br/>eAccelerator user:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;admin<br/>eAccelerator password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eAccelerator<br/>——————————————————————————————————————————————————————————<br/><br/>第一较大步骤：<br/>学习这个Kohana这个框架的真正在于它就像雨燕一样的灵活，所以，先了解一下这个是怎么通过路由实现了其多域名共用一套完整代码的松耦合，且以mvc的高内聚的框架思想是首页步骤，如下：<br/>只要三个步骤实现一套代码两套域名，还可实现看似一套代码且可独立部署，且还实现了域名的分离，这也是Kohana这个框架的灵活之处，更多请看：<br/>http://jackxiang.com/post/7122/<br/>http://jackxiang.com/post/5977/<br/>____________________________________在controller里建立interface目录____________________________________<br/>步骤一：mkdir /data/htdocs/boosh.com/application/controllers/internal&nbsp;&nbsp;（注意controller调用里面的类名前缀和路由保持一致。）<br/>问题：框架controller层层调用情况,以新加一个接口域名internal.boosh.com，但代码还得放一块，而这个域名不一致，怎么办？<br/>解决办法，先看框架controller层层调用情况：<br/>./application/controllers/internal/base.php:abstract class internal_BaseController extends InitController //类名和文件夹名一样第一个字大写是规范，而和前面建立的目录对应的前缀表明这个类是在这个目录下的，这块的目录internal定后，其下面的类名必须以目录名且首字母大写作为前缀，这是因为request.php里定死了的，如下代码:<br/>$prefix .= ucfirst($directory) . &#039;_&#039;;//形成Internal_<br/>$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);//这个controller也就是文件名如/internal/user.php里也就是User，class Internal_UserController extends Internal_BaseController ，user里的U大写即可。<br/>——————————————————————————————————————————————————<br/>./application/controllers/global.php:class InitController extends Controller<br/>./libraries/controller.php abstract class Controller<br/><br/>再次对这个<br/>./application/controllers/internal/base.php:abstract class internal_BaseController extends InitController //类名和文件夹名一样？这个是和路由的php代码设置及nginx的转写规则有关。<br/>require_once dirname(dirname(__FILE__)) . &#039;/global.php&#039;;<br/><br/>继承自：<br/>./application/controllers/global.php:class InitController extends Controller<br/>继承自：<br/>./libraries/controller.php abstract class Controller<br/><br/>这个名称都可随便写，如base.php，但里面的类前缀部分也得变得有关联更符合要求，这块不规范像这样：<br/>如：./application/controllers/internal/my.php<br/>require_once &#039;base.php&#039;;<br/>class Internal_MyController extends Internal2_BaseController<br/>//class Internal_MyController extends Internal_BaseController&nbsp;&nbsp;<br/><br/>./application/controllers/internal/base.php也一样得有关联：<br/> require_once dirname(dirname(__FILE__)) . &#039;/global.php&#039;;//前面上一层目录的global.php<br/>//abstract class Internal_BaseController extends InitController <br/>abstract class Internal2_BaseController extends InitController&nbsp;&nbsp;//加个2后，在my.php里也加个2继承下，也没关系运行没有问题，只是不规范罢了。<br/><br/>为何直接写没有自己写那个new 这个controller类就运行了呢？是因为两个地方：<br/>1）&#92;libraries&#92;request.php里的execute对目录进行分析，对controller类进行反射类实例化：<br/>（1）internal目录进行处理：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;directory) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Add the directory name to the class prefix<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directory = str_replace (array(&#039;&#92;&#92;&#039;, &#039;/&#039;, &#039;//&#039;), &#039;_&#039;, trim($this-&gt;directory, &#039;/&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directories = explode(&#039;_&#039;, $directory);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($directories as $directory) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$prefix .= ucfirst($directory) . &#039;_&#039;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>（2）对反射类进行处理，找不到文件则到core.php来进行查找定位处理：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the controller using reflection<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($class-&gt;isAbstract()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException(&#039;Cannot create instances of abstract controller: :error&#039;, array(&#039;:error&#039; =&gt; ucfirst($this-&gt;controller) . &#039;Controller&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (Exception $e) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($e instanceof ReflectionException) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;status = 404;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;status = 500;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;sendHeaders();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>用了do while串连起这个反射类，如知识点如下：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><textarea name="code" class="php" rows="15" cols="100">
$class = new ReflectionClass(&#039;Person&#039;); // 建立 Person这个类的反射类 
$instance&nbsp;&nbsp;= $class-&gt;newInstanceArgs($args); // 相当于实例化Person 类 
public stdclass newInstance(mixed* args)//测试传入的对象是否为该类的一个实例
</textarea><br/>(3)为何不同的目录可以实现根据nginx里的d参数两个不同的域名呢，是因为下面这块实现的levoo.com/openapi&nbsp;&nbsp;=== api.levoo.com：<br/><textarea name="code" class="php" rows="15" cols="100">
 rewrite &quot;^/api/(time&#124;album&#124;general&#124;partner&#124;rank&#124;search&#124;user&#124;video&#124;stb&#124;navigation&#124;app&#124;mobile&#124;public&#124;oauth&#124;my&#124;activity&#124;manage&#124;oauth2&#124;favorite)&#92;.([a-zA-Z]&#123;4,&#125;)$&quot; /index.php?d=openapi&amp;c=$1&amp;a=$2&amp;$args last;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rewrite &quot;^/(time&#124;album&#124;general&#124;partner&#124;rank&#124;search&#124;user&#124;video&#124;stb&#124;navigation&#124;app&#124;mobile&#124;public&#124;oauth&#124;my&#124;activity&#124;manage&#124;oauth2&#124;favorite)/([a-zA-Z]&#123;4,&#125;)$&quot; /index.php?d=openapi&amp;c=$1&amp;a=$2&amp;$args last;
</textarea><br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;$prefix = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;directory) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Add the directory name to the class prefix
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directory = str_replace (array(&#039;&#92;&#92;&#039;, &#039;/&#039;, &#039;//&#039;), &#039;_&#039;, trim($this-&gt;directory, &#039;/&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directories = explode(&#039;_&#039;, $directory);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($directories as $directory) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$prefix .= ucfirst($directory) . &#039;_&#039;;//Openapi_
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);//加上这个目录的前缀形成：Openapi_BaseController
</textarea><br/>一套代码通过nginx转写d到不同目录后，最终调用的都是：global.php，如下:<br/><br/>/data/htdocs/levoo.com/application/controllers/manage.php//class ManageController extends FrontController<br/>/data/htdocs/xiyou.cntv.cn/application/controllers/front.php//class FrontController extends InitController<br/>/data/htdocs/xiyou.cntv.cn/application/controllers/global.php//class FrontController extends InitController<br/><br/>/data/htdocs/levoo.com/application/controllers/openapi/manage.php<br/>class Openapi_ManageController extends Openapi_BaseController //它们最终都直接继承了global.php文件<br/>require_once dirname(dirname(__FILE__)) . &#039;/global.php&#039;; //class InitController extends Controller<br/><br/>最后，execute全部代码如下,试图调度控制器/动作。如果要求表示它需要被调度，移动到下一个请求行动。<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;protected function execute ()
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;Attempt to dispatch the controller/action. If the $request
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;indicates that it needs to be dispatched, move to the next
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;action in the request.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setDispatched(true);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create the class prefix
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$prefix = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;directory) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Add the directory name to the class prefix
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directory = str_replace (array(&#039;&#92;&#92;&#039;, &#039;/&#039;, &#039;//&#039;), &#039;_&#039;, trim($this-&gt;directory, &#039;/&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directories = explode(&#039;_&#039;, $directory);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($directories as $directory) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$prefix .= ucfirst($directory) . &#039;_&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ko::log(&#039;debug&#039;, __FUNCTION__);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Dispatch request
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the controller using reflection
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($class-&gt;isAbstract()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException(&#039;Cannot create instances of abstract controller: :error&#039;, array(&#039;:error&#039; =&gt; ucfirst($this-&gt;controller) . &#039;Controller&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (Exception $e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($e instanceof ReflectionException) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;status = 404;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;status = 500;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;sendHeaders();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create a new instance of the controller, Interrupted by dispatcher anytime
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$controller = $class-&gt;newInstance($this);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;before&#039;)-&gt;invoke($controller);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$action = empty($this-&gt;action) ? Route::$default_action : $this-&gt;action;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod($action)-&gt;invokeArgs($controller, $this-&gt;params);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;after&#039;)-&gt;invoke($controller);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (ReflectionException $e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;__call&#039;)-&gt;invokeArgs($controller, array($this-&gt;getAction(), $this-&gt;params));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; while (!$this-&gt;isDispatched());
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/>（2）core.php的autoload和findFile找文件这个查找的core.php是在fontend里的index.php包含bootstrap.php再包含core.php引入的，给反射类的查找文件指名了方向，在bootstrap.php最后一行（Request::instance()-&gt;dispatch();）便是自动根据core.php里的__autoload，找到request.php文件进行操作里面的相关函数的一个立即体现（这块的core.php直接引入太关键了），&#92;application&#92;bootstrap.php：<br/><textarea name="code" class="php" rows="15" cols="100">
// Load the core Ko class
require_once SYS_PATH . &#039;core.php&#039;;
...
Request::instance()-&gt;dispatch();
</textarea><br/>自己重新定了autoload，而不是__autoload：<br/>将__autoload换成loadprint函数。但是loadprint不会像__autoload自动触发，这时spl_autoload_register()就起作用了，它告诉PHP碰到没有定义的类就执行loadprint()。 <br/>/data/htdocs/xiyou.cntv.cn/application/bootstrap.php:spl_autoload_register(array(&#039;Ko&#039;, &#039;autoload&#039;)); //这个是调用静态的方法：<br/>spl_autoload_register() 调用静态方法 <br/><textarea name="code" class="php" rows="15" cols="100">
&lt;?&nbsp;&nbsp;
class test &#123;
 public static function loadprint( $class ) &#123;
&nbsp;&nbsp;$file = $class . &#039;.class.php&#039;;&nbsp;&nbsp;
&nbsp;&nbsp;if (is_file($file)) &#123;&nbsp;&nbsp;
&nbsp;&nbsp; require_once($file);&nbsp;&nbsp;
&nbsp;&nbsp;&#125; 
 &#125;
&#125;&nbsp;&nbsp;
spl_autoload_register(&nbsp;&nbsp;array(&#039;test&#039;,&#039;loadprint&#039;)&nbsp;&nbsp;);
//另一种写法：spl_autoload_register(&nbsp;&nbsp;&quot;test::loadprint&quot;&nbsp;&nbsp;); 
 $obj = new PRINTIT();
$obj-&gt;doPrint();
?&gt;
</textarea><br/>摘自：http://blog.csdn.net/panpan639944806/article/details/23192267<br/>更多分析再参考自己写的这篇文章：http://jackxiang.com/post/5877/<br/><br/>步骤二：路由配置如下<br/>/data/htdocs/my.boosh.com/application/bootstrap.php&nbsp;&nbsp;//把internal的路由指向前面建立的目录<br/>Route::set(&#039;internal_route&#039;, &#039;internal(/&lt;controller&gt;(/&lt;action&gt;(/&lt;__KO_VARS__&gt;)))&#039;, array(&#039;__KO_VARS__&#039; =&gt; &#039;.+&#039;))<br/>&nbsp;&nbsp;&nbsp;&nbsp;-&gt;defaults(array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;directory&#039;&nbsp;&nbsp;=&gt; &#039;internal&#039;,//下面配置的Nginx指向这个目录并作转写即可：d=internal。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;controller&#039; =&gt; isset($default_controller) ? $default_controller : &#039;index&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;action&#039;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; isset($default_action) ? $default_action : &#039;index&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;));<br/><br/>这块路由的名称其实不重要，加个2也是可以的：<br/>Route::set(&#039;internal2_route&#039;, &#039;internal(/&lt;controller&gt;(/&lt;action&gt;(/&lt;__KO_VARS__&gt;)))&#039;, array(&#039;__KO_VARS__&#039; =&gt; &#039;.+&#039;)) <br/><br/>为何配置这个bootstrap.php呢？htdocs的入口查看：<br/>/data/htdocs/my.boosh.com/frontend/index.php <br/>// Bootstrap the application<br/>require_once APP_PATH . &#039;bootstrap.php&#039;;&nbsp;&nbsp; <br/><br/>步骤三：Nginx的配置文件<br/>&nbsp;&nbsp;&nbsp;&nbsp;server<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 80;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server_name&nbsp;&nbsp;i.boosh.com boosh.com;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index index.html index.htm index.php;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;&nbsp;/data/htdocs/my.boosh.com/frontend;///data/htdocs/boosh.com/frontend;被域名www.boosh.com用了，所以，my.boosh.com用作http://boosh.com使用。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location / &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rewrite &quot;^/api/(album&#124;general&#124;partner&#124;rank&#124;search&#124;user&#124;video&#124;stb&#124;navigation&#124;app&#124;mobile&#124;public&#124;oauth&#124;my&#124;activity&#124;manage&#124;oauth2&#124;favorite)&#92;.([a-zA-Z]&#123;4,&#125;)$&quot; /index.php?d=internal&amp;c=$1&amp;a=$2&amp;$args last;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rewrite &quot;^/(album&#124;general&#124;partner&#124;rank&#124;search&#124;user&#124;video&#124;stb&#124;navigation&#124;app&#124;mobile&#124;public&#124;oauth&#124;my&#124;activity&#124;manage&#124;oauth2&#124;favorite)/([a-zA-Z]&#123;4,&#125;)$&quot; /index.php?d=internal&amp;c=$1&amp;a=$2&amp;$args last; //这一行必须要有，否则就没法通过get的d参数实现路由，也就是说即使后面分离后，前面新加的internal目录不用挪动，是nginx转写时加上了d，对album这些写死在nginx配置里的action进行加上d=internal，进而框架里的bootstrap.php进行了路由设置且支持路由。<br/><br/><br/>前端访问情况:<br/>直接通过api的接口访问：<br/>http://i.boosh.com/album/addalbum&nbsp;&nbsp;（新加的域名访问A接口）<br/>直接通过主站进行加上一个api进行访问：<br/>http://boosh.com/api/album/addalbum（主站直接也可访问这个A接口）<br/><br/>对于接口输出比如ajax的json示例，此时一般都是关闭了模板，直接用自带函数进行输出，如下：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!$rzt)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage(array(&#039;status&#039; =&gt; &#039;fail&#039;, &#039;code&#039;=&gt;&#039;4010&#039;,&#039;msg&#039; =&gt; &#039;视频已经存在&#039;),$this-&gt;format);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$res = $albumService-&gt;addVideosToAlbum($uuids,$params[&#039;user_id&#039;], $params[&#039;albumid&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;successMessage(&#039;success&#039;,$this-&gt;format);
</textarea><br/>http://levoo.com/activityvideo/getactivityvideo/eid/14544893367247/typeid/1/pagenum/11/pagesize/20/sortby/new/format/jsonp/jsoncallback/cmscallback<br/><br/>=================View与smarty的一个接合问题=======================<br/>前面新的一个interface没有和主站一个目录，而是另一个目录里，如何与smarty搭上边呢？<br/> vi base.php <br/>require_once dirname(dirname(__FILE__)) . &#039;/global.php&#039;; //与上一层目录的global.php进行引用，也就是主站的global.php<br/><br/>这个global.php主要干些啥？<br/>1）获取进来的各种jsonP参数：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;varname = trim($this-&gt;getRequest()-&gt;getParam(&#039;varname&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;jsoncallback = trim($this-&gt;getRequest()-&gt;getParam(&#039;jsoncallback&#039;));<br/><br/>2）失败输出json/输出xml。<br/><br/>3）读取写入配置文件。<br/><br/>4）设置语言包位置及路径：css/js/images。<br/><br/>5）是否自动输出模板。<br/><br/>6) 一些共性的函数操作放里面，特别是像登录啥的。<br/><br/>interface/my.php<br/>这就是真正的controller了，里面写这个页面特别的一些输出及模板渲染，经典的controller/action。<br/><br/>总之，就是通过view的工厂类， $this-&gt;autoRender(FALSE); 这个是不输出模板不需要smarty。要输出刚好是True，输出用了smarty，主站需要用，它是写在/controller/front.php里的，$this-&gt;view = View::factory($this-&gt;themesPath[&#039;themePath&#039;] . &#039;/&#039; . $this-&gt;request-&gt;getController() . &#039;/&#039; . $this-&gt;request-&gt;getAction());，这一行调用了：&#92;libraries&#92;view.php，它引入了：require_once &#039;smarty/Smarty.class.php&#039;;且view.php初始化了smarty这个类，如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function __construct ($file = NULL, array $data = NULL)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! empty($file)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setView($file);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty = new Smarty();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($data !== NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty-&gt;assign($data);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty-&gt;template_dir&nbsp;&nbsp; = Ko::config(&#039;smarty.template_path&#039;);//这个是绝对路径前缀读取的是./smarty.php:&nbsp;&nbsp; &#039;template_path&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; APP_PATH. &#039;views/&#039;,静态的KO类实现读取配置文件，Nginx指向-&gt;&#92;frontend&#92;index.php 包含=》&#92;application&#92;bootstrap.php=》它里面引用：require_once SYS_PATH . &#039;core.php&#039;; =》public static function config ($group)静态函数实现。。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty-&gt;cache_dir&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Ko::config(&#039;smarty.cache_path&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty-&gt;compile_dir&nbsp;&nbsp;&nbsp;&nbsp;= Ko::config(&#039;smarty.compile_path&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_smarty-&gt;config_dir&nbsp;&nbsp;&nbsp;&nbsp; = Ko::config(&#039;smarty.configs_path&#039;);<br/><br/>并提供了，__set ，__get，render这些基础函数的二次根据这个view类的smarty封装。实现了smarty模板类。<br/>模板问题再细一点：<br/>出现模板找不到：The requested view themes/zh/my/video.html could not be found ~ SYS_PATH/view.php [ 174 ]<br/>（这里的view.php并没有被直接包含，而是框架core.php里autoload和findFile经过在new类时查找到&#92;libraries&#92;目录并引入：public static function autoload ($class)，根据文件名及类名引入的， Ko::autoload(&#039;My_Class_Name&#039;);class_exists找不到则去findFile查找并引入：require_once $path;。）<br/>这就是这些类查找也好，命名也好的规范，对Controller Model&nbsp;&nbsp;Service，影响了其类名的写法必须符合，否则找不到，见libraries/core.php：<br/>controller和Models和server分层在类名上体现是必要的,<br/>无聊咔咔(5**773145)&nbsp;&nbsp;17:52:56<br/>__autoload<br/>回忆未来-向东-Jàck(372647693)&nbsp;&nbsp;17:53:21<br/>加上findFile<br/>一般框架都这样，MVC啥的全是这样搞的，有谁有新方法找我。<br/>把找到的文件目录给缓存起来，下次就不用去再找一次了。<br/>再把controller /action的类名加上比如Controller之类，<br/>规范规范，加个smarty，一个PHP的架子就搭建起来了嘛要。<br/>回忆未来-向东-Jàck(372647693)&nbsp;&nbsp;17:57:30<br/>controller和Models和server分层在类名上体现是必要的，如下：<br/>class EventModel extends Model<br/>class NewsService extends AdminBaseService<br/>class ActController extends FrontController&nbsp;&nbsp;<br/><br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp; public static function autoload ($class)&nbsp;&nbsp; //自动加载机制的规范：http://jackxiang.com/post/5877/&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (class_exists($class, FALSE))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($class !== &#039;Controller&#039; &amp;&amp; substr($class, -10) === &#039;Controller&#039;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$type = &#039;controllers&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$file = strtolower(substr($class, 0, -10));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; elseif ($class !== &#039;Model&#039; &amp;&amp; substr($class, -5) === &#039;Model&#039;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$type = &#039;models&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$file = strtolower(substr($class, 0, -5));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; elseif ($class !== &#039;Service&#039; &amp;&amp; substr($class, -7) === &#039;Service&#039;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$type = &#039;services&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$file = strtolower(substr($class, 0, -7));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$type = &#039;.&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$file = strtolower($class);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($class==&quot;View&quot;)&#123;//对View这个类作文件查找入口单独调试
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &quot;&lt;pre&gt;type=&quot;.$type.&quot;&lt;/pre&gt;&quot;;//打印出来是：type=.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &quot;&lt;pre&gt;file=&quot;.$file.&quot;&lt;/pre&gt;&quot;;&nbsp;&nbsp;&nbsp;&nbsp;//打印出来是：file=view
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo&nbsp;&nbsp;self::findFile($type, $file); //下面对这个findFile单独说明。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (($path = self::findFile($type, $file)) !== false) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require_once $path;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;

</textarea><br/><br/>findFile这个是围绕着环境变量且伴随是否caching进行编写的，主要是这两个核心的全局数组，步骤如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp; private static $_paths = array(APP_PATH , SYS_PATH);// Include paths that are used to find files<br/>&nbsp;&nbsp;&nbsp;&nbsp;private static $_files = array();&nbsp;&nbsp;&nbsp;&nbsp;// File path cache<br/>1）如果是Cahceing就在self::$_files就是一个一个的文件以文件名为key，值就是文件绝对路径的数组里根据传入的文件名进行查找对应的路径，有则直接返回。<br/>2）没有则对&#039;config&#039; &#039;i18n&#039;&nbsp;&nbsp;&#039;messages&#039;进行查找，这三个地方估计没法cache进来，得特殊处理。<br/>3）还找不到，则self::$_paths ，这个是一堆的路径数组，一个一个去把文件名放进去拼成绝对路径，再用is_file去循环所有路径判断这个文件到底在哪儿，直到找到这个文件的绝对路径。<br/>4）对这个文件的路径再放回到第1部里的self::$_files里去，同时返回这个文件的绝对路径，autoload 里的require_once $path;就是引入经过一堆查找到的文件，真心不容易啊。<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;public static function findFile ($dir, $file, $ext = &#039;php&#039;)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($file=&quot;view&quot;)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;file=&quot;.$file.&quot;&lt;br&gt;&quot;; //打印出来是：file=view
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;dir=&quot;.$dir.&quot;&lt;br&gt;&quot;; // 打印出来是：dir=.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $path = $dir . DIRECTORY_SEPARATOR . str_replace(&#039;_&#039;, DIRECTORY_SEPARATOR, $file) . &#039;.&#039; .$ext;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$path = $dir . DIRECTORY_SEPARATOR . str_replace(&#039;_&#039;, DIRECTORY_SEPARATOR, $file) . &#039;.&#039; .$ext;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (self::$caching === TRUE and isset(self::$_files[$path])) &#123;//如果是要对这些文件作cache，再找一次在不在以文件名为key的数组里面，在就直接返回。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self::$_files[$path];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($dir === &#039;config&#039; OR $dir === &#039;i18n&#039; OR $dir === &#039;messages&#039;) &#123;//对config和i18n和messages作单独处理。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Array of files that have been found
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$found = array();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (is_file(DATA_PATH . $path)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// This path has a file, add it to the list
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$found[] = DATA_PATH . $path;//先加入到数组里。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// The file has not been found yet
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$found = FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach (self::$_paths as $dir) &#123;//在自己的path目录里面一个一个拼接并看是否在各个存在，存在就算找到了。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (is_file($dir . $path)) &#123;//View.php也是在这里才找到的：/data/htdocs/i.levoo.com/libraries/./view.php
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// A path has been found
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$found = $dir . $path;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (self::$caching === TRUE) &#123;//假如需要缓存
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Add the path to the cache
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$_files[$path] = $found;//把上面找到的给放到一次http请求的全局数组里。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Files have been changed
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$_files_changed = TRUE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $found;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/><br/><br/>__上面描述为何能自动找到这个View.php，Smarty被它重新封装并形成factory进行重新对象化，如何使用smarty如下：______<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function video()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$themesPath = $this-&gt;getLang();&nbsp;&nbsp;&nbsp;&nbsp;//global.php里写好路径，且是相对路径，所以报错也是相对的，但输入smarty时拼成一个绝对路径,如下：<br/>//[root@iZ25z0ugwgtZ config]# grep -r &quot;views&quot; ./<br/>//./smarty.php:&nbsp;&nbsp; &#039;template_path&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; APP_PATH. &#039;views/&#039;,<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;themesPath = $themesPath;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view = View::factory($this-&gt;themesPath[&#039;themePath&#039;] . &#039;/&#039; . $this-&gt;request-&gt;getController() . &#039;/&#039; . $this-&gt;request-&gt;getAction());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view-&gt;textlinkhotmax = &quot;jackxiang&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view-&gt;specialmax&nbsp;&nbsp;&nbsp;&nbsp;= &quot;xiangdong&quot;;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setFile(&quot;my/video&quot;);//如果不写，默认则是http://xxx.com/controller/funciton.html为模板。 https://boosh.com/my/video =&gt;my目录下的video.html。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>模板路径：/application/views/themes/zh/my/video.html&nbsp;&nbsp;前面的这个路径是从/application/controllers/global.php 里写死一数组定义的：<br/><textarea name="code" class="php" rows="15" cols="100">
protected function getLang()&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$lang = $this-&gt;getLanguage();
&nbsp;&nbsp;&nbsp;&nbsp;if($lang == &#039;zh&#039;)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//$jsPath = &#039;themes/zh&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cssPath = &#039;themes/zh&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;else&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//$jsPath = &#039;themes/&#039;.$lang;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cssPath = &#039;themes/&#039;.$lang;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;$themePath = &#039;themes/zh&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;$publicPath = &#039;themes/common&#039;;&nbsp;&nbsp;//公共css、js、和images文件存放目录
&nbsp;&nbsp;&nbsp;&nbsp;$themesPath[&#039;publicPath&#039;] = $publicPath;
&nbsp;&nbsp;&nbsp;&nbsp;//$themesPath[&#039;jsPath&#039;] = $jsPath;
&nbsp;&nbsp;&nbsp;&nbsp;$themesPath[&#039;themePath&#039;] = $themePath;
&nbsp;&nbsp;&nbsp;&nbsp;$themesPath[&#039;cssPath&#039;] = $cssPath;
&nbsp;&nbsp;&nbsp;&nbsp;$themesPath[&#039;code&#039;] = $lang;
&nbsp;&nbsp;&nbsp;&nbsp;return $themesPath;
&nbsp;&nbsp;&#125;
</textarea><br/>[root@iZ25z0ugwgtZ my]# cat ~+/video.html&nbsp;&nbsp; <br/>jack<br/>&lt;&#123;$textlinkhotmax&#125;&gt;<br/>&lt;&#123;$specialmax&#125;&gt;&nbsp;&nbsp;<br/><br/>访问输出：<br/>jack jackxiang xiangdong<br/><br/>下面主要是core.php和request.php两个，core.php主要是autoload和findFile的一个结合，及reques.php是路由Route和反射类ReflectionClass的一个集合，最后是两个文件对新纳入文件的文件命名和类命名的的约束，形成KO的核心的框架。<br/><br/><br/><br/><br/>第二大步，再谈一谈其高内聚合、低耦合的一些设计模式，如下：<br/>　　在很多时候反射也是唯一的选择。为什么我们会选择使用反射？因为我们没有办法在编译期通过静态绑定的方式来确定我们要调用的对象。例如一个ORM框架，它要面对的是通用的模型，此时无论是方法也好属性也罢都是随应用场景而改变的，这种完全需要动态绑定的场景下自然需要运用反射。还例如插件系统，在完全不知道外部插件究竟是什么东西的情况下，是一定无法在编译期确定的，因此会使用反射进行加载。其实，包同学的反驳文章里也是持这种观点的：<br/><br/>&nbsp;&nbsp; 什么是php反射类，顾名思义，可以理解为一个类的映射。<br/>举个例子：<br/>class fuc &#123;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定义一个类<br/>&nbsp;&nbsp;static function ec() &#123;<br/>&nbsp;&nbsp;echo &#039;我是一个类&#039;;<br/>&#125;<br/>&#125;<br/>$class=new ReflectionClass(&#039;fuc&#039;);&nbsp;&nbsp;&nbsp;&nbsp;//建立 fuc这个类的反射类<br/>echo $class; //输出这反射类<br/>Class [ class A ] &#123; @@ F:&#92;phpweb&#92;myPHP&#92;test.php 23-30 - Constants [0] &#123; &#125; - Static properties [0] &#123; &#125; - Static methods [0] &#123; &#125; - Properties [0] &#123; &#125; - Methods [1] &#123; Method [ public method __construct ] &#123; @@ F:&#92;phpweb&#92;myPHP&#92;test.php 26 - 29 &#125; &#125; &#125;<br/>$fuc=$class-&gt;newInstance();&nbsp;&nbsp;//相当于实例化 fuc 类<br/>$fuc-&gt;ec(); //执行 fuc 里的方法ec<br/>/*最后输出:我是一个类*/<br/>其中还有一些更高级的用法<br/>$ec=$class-&gt;getmethod(&#039;ec&#039;);&nbsp;&nbsp;//获取fuc 类中的ec方法<br/>$fuc=$class-&gt;newInstance();&nbsp;&nbsp;//实例化<br/>$ec-&gt;invoke($fuc);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//执行ec 方法<br/>----------------------------------------------------------------------------------------------------------------------------------------------------------------------<br/>$class-&gt;getmethod(&#039;ec&#039;)-&gt; invokeArgs($fuc, $params); //有点绕：class是反射类，获取这个反射类里的ec方法，用实例化后的$fuc，并传入相关ec的参数。<br/>对该方法的传入参数及调用的方法实践OK如下：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php
&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApiController &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private $actions = array(&#039;getrankalbum&#039; =&gt; &#039;rank.album&#039;,);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public function getAPI($apiNO,$apiInfoArr=array(),$otherPara)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo __FUNCTION__.&quot;函数里的apiNO参数:&quot;.$apiNO.&quot;&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_r($apiInfoArr);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;是通过数组进行扩展多个参数的测试：&quot;.$otherPara;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;$obj&nbsp;&nbsp;&nbsp;&nbsp; = new ReflectionClass(&#039;ApiController&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;$fuc=$obj-&gt;newInstance(); //实例化
&nbsp;&nbsp;&nbsp;&nbsp;$apiNO = 1;
&nbsp;&nbsp;&nbsp;&nbsp;$apiInfoArr = array(&quot;apiName&quot;=&gt;&quot;getVideo&quot;,&quot;apiIntro&quot;=&gt;&quot;getVideo from Server&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;$apiFunParaIn = array($apiNO,$apiInfoArr,&quot;第三个参数&quot;);//参数是以数组传入的，一个参数0，1，2...

&nbsp;&nbsp;&nbsp;&nbsp;$ApiRetArr = $obj-&gt;getMethod(&quot;getAPI&quot;)-&gt;invokeArgs($fuc, $apiFunParaIn);;
&nbsp;&nbsp;&nbsp;&nbsp;print_r($ApiRetArr);

&nbsp;&nbsp;&nbsp;&nbsp;//Reflection::export($obj);//通过此方法可以看到ReflectionClass中所有的属性和方法
&nbsp;&nbsp;&nbsp;&nbsp;?&gt;
</textarea><br/>输出：<br/>---------- 调试PHP ----------<br/>getAPI函数里的apiNO参数:1<br/>Array<br/>(<br/>&nbsp;&nbsp;&nbsp;&nbsp;[apiName] =&gt; getVideo<br/>&nbsp;&nbsp;&nbsp;&nbsp;[apiIntro] =&gt; getVideo from Server<br/>)<br/>是通过数组进行扩展多个参数的测试：第三个参数<br/>------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<br/>$methodsArrAll = $class-&gt;getMethods();&nbsp;&nbsp; //获取所有的方法名<br/>Reflection::export($class);//通过此方法可以看到ReflectionClass也就是fuc类中所有的属性和方法<br/>上面的过程很熟悉吧。其实和调用对象的方法类似<br/>只不过这里是反着来的，方法在前，对象在后<br/><br/>举例： 这样的方法实现在面像对象的框架里有这样的用法，见：http://kohanaframework.org/&nbsp;&nbsp; request.php<br/><textarea name="code" class="php" rows="15" cols="100">
try&#123;
//如果存在控制器名字的类
if(class_exists($this-&gt;getController())) &#123;
//利用反射api构造一个控制器类对应的反射类
$rc = new ReflectionClass($this-&gt;getController());
//如果该类实现 了IController接口
if($rc-&gt;implementsInterface(&#039;IController&#039;)) &#123;
//该类拥有解析后的action字符串所指向的方法名
if($rc-&gt;hasMethod($this-&gt;getAction())) &#123;
//构造一个控制器类的实例
$controller = $rc-&gt;newInstance();
//获取该类$action参数所指向的方法对象
$method = $rc-&gt;getMethod($this-&gt;getAction());
//反射类方法对象的调用方式：
$method-&gt;invoke($controller);
&#125; else &#123;
//以下为可能抛出异常
throw new Exception(&quot;Action&quot;);
&#125;
&#125; else &#123;
throw new Exception(&quot;Interface&quot;);
&#125;
&#125; else &#123;
throw new Exception(&quot;Controller&quot;);
&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;catch(exception $e)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $e;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>框架核心摘录解析&#92;libraries&#92;request.php,涉及到before/after（写日志）函数的先后，特别注意：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);//构造类名称
&nbsp;&nbsp;if ($class-&gt;isAbstract()) &#123;//如Contrller写成一个abstract类是会卡在这儿：abstract&nbsp;&nbsp;class ApiController extends InitController
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;errorPage(&#039;Cannot create instances of abstract controller: :error&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(&#039;:error&#039; =&gt; $prefix . ucfirst($this-&gt;controller) . &#039;Controller&#039;));
&nbsp;&nbsp;&#125;

&nbsp;&nbsp;// Create a new instance of the controller, Interrupted by dispatcher anytime
&nbsp;&nbsp;$controller = $class-&gt;newInstance($this);//实例化类$class：创建的控制器的一个新实例，通过dispatcher变量随时中断调度这个类

&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;before&#039;)-&gt;invoke($controller); //获取$class类中的before方法后，通过invoke执行$controller（$class）里的before方法。
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$action = empty($this-&gt;action) ? Route::$default_action : $this-&gt;action;//获取到Url里的action（就是方法名），如有路由先执行路由里的默认action
&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod($action)-&gt;invokeArgs($controller, $this-&gt;params);//动态获取action方法，并执行这个方法，把方法的参数也通过invokeArgs一并传入。
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125; catch (ReflectionException $e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;__call&#039;)-&gt;invokeArgs($controller, array($this-&gt;getAction() , $this-&gt;params));//如果contrller的类里没有方法法调用的__call函数.
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;after&#039;)-&gt;invoke($controller);
&nbsp;&nbsp;&#125;



</textarea><br/><br/>来自：http://blog.csdn.net/21aspnet/article/details/6952432<br/>给redirect函数里加上日志：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;public function redirect ($url, $code = 302)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;// TODO
&nbsp;&nbsp;&nbsp;&nbsp;$referer = $this-&gt;getServer(&#039;REQUEST_URI&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;$data = $code . &#039;: &#039; . $referer . &#039; --&gt; &#039; . $url . PHP_EOL;
&nbsp;&nbsp;&nbsp;&nbsp;file_put_contents(DATA_PATH . &#039;/logs/&#039; . date(&#039;Ymd&#039;) . &#039;/redirect-&#039; . date(&#039;Ymd&#039;) . &#039;.log&#039;, $data, FILE_APPEND );

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (strpos($url, &#039;://&#039;) === FALSE) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Make the URI into a URL
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$url = URL::site($url);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set the response status
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;status = $code;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set the location header
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;headers[&#039;Location&#039;] = $url;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Send headers
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;sendHeaders();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Stop execution
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit();
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/><br/>找不到action和对应方法时调用404.<br/>/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * 当调用的action不存在时调用该方法<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Overload<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @see application/controllers/InitController::__call()<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function __call($method, $arguments=NULL)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;redirect(KO::config(&#039;url.main_url&#039;) . &#039;error.html&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>———————————直接访问Url里的一个controler下用action直接输出调用forward时在调核心request类里的函数返回$this是什么的理解。—————————<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;private $actions = array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;getcategory&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &#039;general.getCategory&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;）
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (array_key_exists(strtolower($method), $this-&gt;actions)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$api_forwards = explode(&#039;.&#039;, $this-&gt;actions[strtolower($method)]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;request-&gt;forward($api_forwards[1], $api_forwards[0], &#039;openapi&#039;, $arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/>这里的 $this-&gt;request是从controller.php里继承来的：<br/>class ApiController extends InitController，class InitController extends Controller。<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function __construct (Request $request)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Assign the request to the controller<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;request = $request;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>而forward函数是request.php里的：<br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Forward to another controller/action.<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param string $action<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param string $controller<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param string $directory<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param array $params<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @return void<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function forward($action, $controller = null, $directory = null, array $params = null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;//方法，文件类名，文件路径（默认是框架路径，这儿可在框架路径下建立自己的路径），参数（是通过__call： public function __call($method, $arguments = null) 传入的）<br/>。。。。。。<br/>这些都是教简单，而return正是在request.php里函数常用到，如下：<br/>&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Set parameters<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Set one or more parameters. Parameters are set as userland parameters,<br/>&nbsp;&nbsp;&nbsp;&nbsp; * using the keys specified in the array.<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param array $params<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @return Request<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function setParams(array $params)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($params as $key =&gt; $value) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setParam($key, $value);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Set request directory<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param&nbsp;&nbsp; string<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;Request<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function setDirectory ($directory)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;&lt;br&gt;&quot;.__FILE__.__LINE__.$directory.&quot;&lt;br&gt;&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;directory = $directory;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>setParams和setDirectory都是forward里的，如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function forward($action, $controller = null, $directory = null, array $params = null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $params &amp;&amp; is_array($params)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setParams($params);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $controller) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setController($controller);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Directory should only be reset if controller has been specified<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $directory) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;Here,Jack...&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setDirectory($directory);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setAction($action)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;setDispatched(false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>这里的return this如何理解：<br/>http://zhidao.baidu.com/link?url=QU-yClJDjln0YRwEZr8nO2wBLUIqDx4oPeYL6BykgCZvrclh78YpY9qnsfRaYWZam87QCaMEdmk06ZGd_DKY2q<br/><br/>这是类里面的一个函数，没有形参，函数里最后一句是return $this; 请问这个是返回了什么东西啊？返回了谁的自身？<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;public function getmodule() &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;cache-&gt;key = &#039;sdmodule&#039;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$result;<br/>.....<br/>....//中间很多句子。<br/>....<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;smarty-&gt;assign(&quot;modules&quot;, $result);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>就是返回这个对象，在PHP类里面$this关键字就是代表这个类内部的引用。如你上面所说的return $this;就是相当于把该对象返回到方法getmodule() 中。<br/>比如：<br/>$abc=new class;&nbsp;&nbsp;//class是指你那个类<br/>echo $abc-&gt;getmodule()-&gt;cache-&gt;key;&nbsp;&nbsp; //输出sdmodule<br/><br/>也就是getmodule() 拥有了该类的所有的成员和方法。<br/><br/>—————————通过forward方法传入和通过Request::instance()-&gt;dispatch();的区别（instance获取uri后调__construct进行action，controller，路径path的类变量赋值实现了类似forward的传参）—————————<br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Main request singleton instance. If no URI is provided, the URI will<br/>&nbsp;&nbsp;&nbsp;&nbsp; * be automatically detected using PATH_INFO, REQUEST_URI, or PHP_SELF.<br/>&nbsp;&nbsp;&nbsp;&nbsp; *<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param&nbsp;&nbsp; string&nbsp;&nbsp; URI of the request<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;Request<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public static function instance ($uri = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static $instance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($instance === NULL) &#123;<br/>&nbsp;&nbsp;.......//各种获取Uri的方法<br/>&nbsp;&nbsp;$instance = new self($uri);//把uri传入类中，下面：<br/>&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;public function __construct ($uri)//它就是用来对uri进行解析得到forward里的a,c,d。forward只是直接传入罢了，不用在这儿初始化就在于此，直接传入修改了类需要运行的相关变量，除开get参数外，都在这里进行分析并写入类全局变量，通过this作为句柄作操作。<br/>&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;return $instance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>forward和__construct的相同点和不同点：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;public function __construct ($uri)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ko::log(&#039;debug&#039;, __CLASS__ . &#039; Library loaded&#039;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Are query strings enabled in the config file?<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// If so, we&#039;re done since segment based URIs are not used with query strings.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Ko::$enable_query_strings &amp;&amp; isset($_GET[&#039;c&#039;])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setController(Security::xss_clean($_GET[&#039;c&#039;]));<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_GET[&#039;a&#039;])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setAction(Security::xss_clean($_GET[&#039;a&#039;]));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_GET[&#039;d&#039;])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setDirectory(Security::xss_clean($_GET[&#039;d&#039;]));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;params = array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;......对接受到的变量赋值到类变量后立即进行安全检查并过滤......<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($routes as $route) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (($params = $route-&gt;matches($uri)) !== false) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;directory = Security::xss_clean($params[&#039;directory&#039;]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;controller = Security::xss_clean($params[&#039;controller&#039;]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;action = Security::xss_clean($params[&#039;action&#039;]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;params = $params;//变量从uri里获取到的<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;//上面找不到的则进行404处理并输出找不到的头页面处理<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;而在执行时这个this-;&gt;params还会用到：<br/>&nbsp;&nbsp;&nbsp;&nbsp;function excute()&#123;<br/>&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod($action)-&gt;invokeArgs($controller, $this-&gt;params);//这儿<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;你会问这个POST，GET参数去哪儿了？在request;.php里有：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function getParam ($key, $default = NULL)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;//对各种变量都作了xss检测<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isset($this-&gt;params[$key])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Security::xss_clean($this-&gt;params[$key]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; elseif (isset($_GET[$key])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Security::xss_clean($_GET[$key]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; elseif (isset($_POST[$key])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Security::xss_clean($_POST[$key]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $default;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;再就是通过_set,_get进行属性读取，参看：php面向对象_get(),_set()的用法，http://blog.sina.com.cn/s/blog_4565cc770100bv2u.html<br/>&nbsp;&nbsp;&nbsp;&nbsp;http://jackxiang.com/post/2766/&nbsp;&nbsp;里面有代码对其实践和论述。<br/>&nbsp;&nbsp;&nbsp;&nbsp;在实际编写代码调用：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function minialbum()&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$uuid = $this-&gt;getRequest()-&gt;getParam(&#039;uuid&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function setController ($controller)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;controller = $controller;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;//而forward是自己写的，所以就不用进行安全的xss检测<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function forward($action, $controller = null, $directory = null, array $params = null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $params &amp;&amp; is_array($params)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setParams($params);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $controller) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setController($controller);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Directory should only be reset if controller has been specified<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (null !== $directory) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setDirectory($directory);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setAction($action)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;setDispatched(false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/><br/><br/>六：错误报告：<br/>$show_debug_errors = false;<br/>在配置文件：/data/htdocs/jackxiang.com/application/bootstrap.php<br/>Ko::init( array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;base_url&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; &#039;/&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;errors&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; isset($show_debug_errors) &amp;&amp; $show_debug_errors,<br/>后赋值给Library/core.php里的：Ko::$errors，后在/library里的request;.php里面决定是否输出错误：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function errorPage($msg = null, $data = array())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(Ko::$errors === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException($msg, $data);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;forward(&#039;index&#039;, &#039;error&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/><br/>七：文件位置缓存实现：<br/>查找文件路径的缓存：&#039;caching&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; TRUE,<br/>core.php<br/>isset($settings[&#039;caching&#039;]) &amp;&amp; self::$caching = (bool) $settings[&#039;caching&#039;];<br/><br/>if (self::$caching === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Use the default cache directory<br/>&nbsp;&nbsp;&nbsp;&nbsp;self::$cache_dir = DATA_PATH . &#039;cache&#039;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;self::$_files = self::cache(&#039;Ko::findFile()&#039;);<br/>&#125;<br/><br/> <br/> self::$_files = self::cache(&#039;Ko::findFile()&#039;);<br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; public static function cache ($name, $data = NULL, $lifetime = 3600)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Cache file is a hash of the name<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$file = sha1($name) . &#039;.txt&#039;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Cache directories are split by keys to prevent filesystem overload<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$dir = self::$cache_dir . DIRECTORY_SEPARATOR . &quot;&#123;$file[0]&#125;&#123;$f<br/><br/>配置文件：<br/>/data/htdocs/jackxiang.com/application/bootstrap.php<br/>Ko::init( array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;base_url&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; &#039;/&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;errors&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; isset($show_debug_errors) &amp;&amp; $show_debug_errors,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;index_file&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; isset($index_file) ? $index_file : &#039;index.php&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;caching&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; TRUE,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;enable_query_strings&#039;&nbsp;&nbsp;=&gt; TRUE,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;threshold&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; isset($log_threshold) ? $log_threshold : 0,<br/>));<br/><br/><br/>——————————————————————————————————————————<br/>八.自制session：<br/>protected $session;<br/>$this-&gt;session = Session::instance();<br/>操作session：<br/>&nbsp;&nbsp;&nbsp;&nbsp;protected function checkLogin ()//检查登录<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;if ($verifycode != $this-&gt;session-&gt;verifycode &#124;&#124; !$this-&gt;session-&gt;userinfo ) &#123;//从session里取不到<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;session-&gt;userinfo = $this-&gt;ssoCheck($verifycode);//从接口里取并存入session<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;session-&gt;verifycode = $verifycode;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;session-&gt;userinfo;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;protected function ssoCheck($verifycode)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......//查接口返回数据:&#039;passport_url&#039;=&gt; &#039;http://passport.cntv.cn/ssocheck.jsp&#039;,Curl<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$userinfo = json_decode($ret,true);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $userinfo;//返回<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/><br/><br/><br/>九：写错误日志函数及错误的统一捕获：<br/>场景:问，最近我做了一个日志系统，PHP在调用时出现因为异常错误导致没有运行到日志函数就退出了，<br/>请问：怎么实现对这个错误的捕获？还问：PHP里的try catch可能并不能捕获里面的所有错误的实际情况。<br/>这个问题其实是想问对PHP的set_error_handler函数，及错误处理函数，它捕获能导致php脚本停止运行的严重错误(这类错误是不能被set_error_handler ()捕获的)，<br/>一旦脚本停止运行，customend（）函数就会被调用，在customend（）函数中通过error_get_last()来判断脚本是正常结束还是发生严重错误而中断，如果是发生严重错误而中断，则运行错误处理程序。try-catch 无法在类的自动加载函数 __autoload() 内生效。try-catch 用于捕获异常，无法捕获错误，例如 trigger_error() 触发的错误，异常和错误是不一样的。<br/>摘自：http://jingyan.baidu.com/article/046a7b3ed5e233f9c37fa969.html<br/><textarea name="code" class="php" rows="15" cols="100">
register_shutdown_function(array(&#039;Ko&#039; , &#039;shutdown_handler&#039;));
set_error_handler(array(&#039;Ko&#039; , &#039;error_handler&#039;));
set_exception_handler(array(&#039;Ko&#039; , &#039;exception_handler&#039;));
</textarea><br/>参考：PHP 的异常处理、错误处理:error_reporting,try-catch,trigger_error,set_error_handler,set_exception_handler,register_shutdown_function<br/>http://www.php-note.com/article/detail/779<br/><br/>******web端打开写SQL日志及分析。———show_debug_errors是前端错误打开于否的开关，<br/>而那个threshold是分开关，如果要写Mysql日志则：$log_threshold = 3;小于3的threshold则不打印日志的，<br/>上面两变量均在index.php入口配置，在application下的bootopen.php进行init()函数的赋值。******<br/>如果等于threshold的值等于4则：debug: Request Library loaded ，也就是相当于debug的日志可打印到日志里来了，等于1只报error错误日志，如等于0则全关闭了即使有错。<br/> * Log Thresholds:<br/> *&nbsp;&nbsp;0 - Disables logging completely<br/> *&nbsp;&nbsp;1 - Error Messages (including PHP errors)<br/> *&nbsp;&nbsp;2 - Alert Messages<br/> *&nbsp;&nbsp;3 - Informational Messages<br/> *&nbsp;&nbsp;4 - Debug Messages<br/> */<br/>$log_threshold = 3;<br/><br/>对于这个；show_debug_errors这个值，则应该用Nginx给屏蔽掉，当然上线后关闭是最好的，提高运行效率及稳定性，Nginx配置如下：<br/>实践Ok如下：<br/>如错误页面在这儿：http://my.jackxiang.com/error<br/>vi my.cnf<br/>在server里添加：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error_page&nbsp;&nbsp;404 = ./error;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error_page&nbsp;&nbsp; 500 502 503 504 = ./error;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#下面也行：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error_page&nbsp;&nbsp;404 = http://my.jackxiang.com/error.html;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error_page&nbsp;&nbsp; 500 502 503 504 = http://my.jackxiang.com/error.html;<br/>来自自己的参考：http://jackxiang.com/post/6769/<br/><br/><br/>要想写日志得满足三个条件：<br/>1./application/bootopen.php 里的&#039;errors&#039; 是TRUE，这样就注册了register_shutdown_function函数，进而在log.php里写日志<br/>2.如果是后台程序立即触发就写，前台程序是关闭的写的。<br/><br/>register_shutdown_function这个的用法见，好多单例都给整了这个东东在上面：http://jackxiang.com/post/6784/<br/>例1：核心都有用到register_shutdown_function<br/>/libraries/core.php<br/>// Enable the Ko shutdown handler, which catches E_FATAL errors.<br/>register_shutdown_function(array(&#039;Ko&#039; , &#039;shutdown_handler&#039;));<br/>if (self::$errors === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Enable the Ko shutdown handler, which catches E_FATAL errors.<br/>&nbsp;&nbsp;&nbsp;&nbsp;register_shutdown_function(array(&#039;Ko&#039; , &#039;shutdown_handler&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Enable Ko exception handling, adds stack traces and error source.<br/>&nbsp;&nbsp;&nbsp;&nbsp;set_exception_handler(array(&#039;Ko&#039; , &#039;exception_handler&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Enable Ko error handling, converts all PHP errors to exceptions.<br/>&nbsp;&nbsp;&nbsp;&nbsp;set_error_handler(array(&#039;Ko&#039; , &#039;error_handler&#039;));<br/>&#125;<br/><br/>例2：web运行完再写日志更是常用：<br/>/libraries/log.php&nbsp;&nbsp;<br/>// Write the logs at shutdown<br/>register_shutdown_function(array(self::$_instance[$group], &#039;write&#039;));<br/><br/><br/><br/>frontend/index.php //这儿打开的******（这块打开如果action类和方法不存在则会直接报错）<br/>// Define wether show debug message.<br/>$show_debug_errors = true;<br/><br/>/application/bootopen.php<br/><br/>Ko::init( array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;base_url&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; &#039;/&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;errors&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; isset($show_debug_errors) &amp;&amp; $show_debug_errors,<br/><br/><br/>/libraries/core.php<br/>&nbsp;&nbsp;if (self::$errors === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Enable the Ko shutdown handler, which catches E_FATAL errors.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register_shutdown_function(array(&#039;Ko&#039; , &#039;shutdown_handler&#039;));<br/><br/><br/>&nbsp;&nbsp;/libraries/log.php&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public static function instance($group =&#039;default&#039;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!isset(self::$_instance[$group]) &#124;&#124;self::$_instance[$group] === NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create a new instance<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$_instance[$group] = new self($group);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Write the logs at shutdown<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register_shutdown_function(array(self::$_instance[$group], &#039;write&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self::$_instance[$group];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/>&#92;libraries&#92;database.php<br/>&nbsp;&nbsp;// Log levels<br/>&nbsp;&nbsp;private static $log_levels = array (<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;error&#039; =&gt; 1,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;alert&#039; =&gt; 2,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;info&#039;&nbsp;&nbsp;=&gt; 3,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;debug&#039; =&gt; 4,<br/>&nbsp;&nbsp;);<br/><br/>&nbsp;&nbsp;public static function log($type, $message)<br/>&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Should we log these to file?<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (self::$log_levels[$type] &lt;= self::$threshold) &#123;//type==debug&lt;====4&lt;=2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$log-&gt;add($type, $message);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&#125;<br/>&#92;libraries&#92;database.php<br/>// Log query<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ko::log(&#039;info&#039;, str_replace(array(&quot;&#92;r&#92;n&quot;, &quot;&#92;r&quot;, &quot;&#92;n&quot;), &quot; &quot;, $sql));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$log-&gt;add($type, $message);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&#125;<br/><br/><br/>十：上完静态文件，要改config.php里的version，以防止那个CDN了旧的，没法查看。<br/>&lt;?php<br/>defined(&#039;SYS_PATH&#039;) or die(&#039;No direct access allowed.&#039;);<br/>return array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;version&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &#039;2.005&#039;,<br/>————————————————————————————<br/>jquery.Jcrop.js?ver=&lt;?php echo $this-&gt;_tpl_vars[&#039;version&#039;]; ?&gt;<br/>直接在框架初始化时赋值比较方便编写些，多层继承的最上层写上：<br/>class Site_PartinController extends FrontBaseController <br/>class FrontBaseController extends FrontController&nbsp;&nbsp;<br/>class FrontController extends InitController&nbsp;&nbsp;<br/>class InitController extends Controller(init.php里进行模板赋值的)<br/><br/>/application/controllers/init.php<br/>/**<br/>* Overload<br/>*/<br/>public function after ()<br/>&#123;<br/>&nbsp;&nbsp;$this-&gt;view-&gt;version = KO::config(&#039;config.version&#039;);<br/><br/>模板里：<br/>&lt;script src=&quot;&lt;&#123;$staticUrl&#125;&gt;js/My97TimePicker/WdatePicker_time.js?ver=&lt;&#123;$version&#125;&gt;&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;<br/>flashvars[&quot;config&quot;] =&quot;&lt;&#123;$flashXmlUrl&#125;&gt;?ver=&lt;&#123;$version&#125;&gt;&quot;;// 如上传组件初始化参数的读取加上版本号<br/><br/>十一：单例模式,一些常规操人作，多用单例模式，这种模式不适合用于写PHP的daemon，容易出现内存不够，如不及时释放：<br/>尽管PHP退出后就释放了，不像Java，但好处还是有的：http://blog.csdn.net/jungsagacity/article/details/7618587<br/>http://blog.sina.com.cn/s/blog_6f49a3c30100qgiy.html<br/>&#92;libraries&#92;session.php<br/>public static function instance ($group = &#039;default&#039;)<br/>protected function __construct ($group = &#039;default&#039;)<br/>register_shutdown_function(array($this , &#039;write_close&#039;));<br/>public function sessionid ()<br/>public function create ()<br/>public function regenerate ()<br/>public function unsetAll()<br/>public function destroy ()<br/>public function write_close ()<br/>public function delete ($keys)<br/>使用方法：<br/>// Init Session<br/>$this-&gt;session = Session::instance();<br/>$this-&gt;session-&gt;set(&#039;findemail&#039;,$userInfo[&#039;email&#039;]);<br/>$findemail = $this-&gt;session-&gt;get(&#039;findemail&#039;);<br/>$this-&gt;session-&gt;unsetAll();<br/><br/>&#92;libraries&#92;config.php<br/>public static function instance ($group = &#039;default&#039;)<br/>final private function __construct ($group = &#039;default&#039;)<br/>public function attach (Config_Driver $reader, $first = TRUE)<br/>public function detach (Config_Driver $reader)<br/>public function load ($group)<br/>public function save ($file, $config = NULL)<br/>public function copy ($group)<br/>final private function __clone ()<br/>使用方法：<br/>$config[$group] = Config::instance(&#039;messages&#039;)-&gt;attach(new Config_File(&#039;messages&#039;))-&gt;load($group);<br/>Config::instance(&#039;lang&#039;)-&gt;attach(new Config_File(&#039;i18n&#039;))-&gt;load($lang . DIRECTORY_SEPARATOR . $group);<br/>Config::instance(&#039;messages&#039;)-&gt;attach(new Config_File(&#039;messages&#039;))-&gt;save($file, $data);<br/>更高级别封装readConfig：$this-&gt;_pbConfig&nbsp;&nbsp;= $this-&gt;readConfig(&#039;pbconfig&#039;);<br/>controllers/global.php <br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * 读取数组配置文件信息<br/>&nbsp;&nbsp;&nbsp;&nbsp; * $this-&gt;readConfig(&#039;config&#039;);&nbsp;&nbsp;==&gt; data/messages/config.php<br/>&nbsp;&nbsp;&nbsp;&nbsp; * @param string $group&nbsp;&nbsp;配置文件名，不带扩展名.php<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;protected function readConfig($group)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/><br/><br/>&#92;libraries&#92;log.php<br/>public static function instance($group =&#039;default&#039;)<br/>final private function __construct()<br/>register_shutdown_function(array(self::$_instance[$group], &#039;write&#039;));<br/>public function attach(Log_Writer $writer, $types = NULL)<br/>public function detach(Log_Writer $writer)<br/>public function add($type, $message)<br/>public function write ()<br/>private function __clone()<br/>使用方法：<br/>$returnlog = Log::instance(&#039;videoreturn&#039;)-&gt;attach(new Log_File(DATA_PATH . &#039;logs/&#039; . date(&#039;Ymd&#039;) . &#039;/&#039;, &#039;setCheckVideoreturn-&#039; . date(&#039;Ymd&#039;) . &#039;.php&#039;));<br/>&nbsp;&nbsp; $logger = Log::instance(strtoupper($prefix))-&gt;attach(new Log_File(DATA_PATH . &#039;logs/&#039; . date(&#039;Ymd&#039;) . &#039;/&#039;, $prefix . &#039;_&#039; . date(&#039;Ymd&#039;) . &#039;.php&#039;));<br/> $sharelog = Log::instance(&#039;share&#039;)-&gt;attach(new Log_File(DATA_PATH . &#039;logs/&#039; . date(&#039;Ymd&#039;) . &#039;/&#039;,&nbsp;&nbsp; &#039;share-&#039; . date(&#039;Ymd&#039;) . &#039;.php&#039;));<br/> $sharelog-&gt;add(&#039;succ:&#039;,&#039; from vid:&#039;.$vid.&#039; to uuid :&#039;.$videoData[&#039;video&#039;][&#039;uuid&#039;]);<br/><br/>分析该写日志的实现：<br/>$log = Log::instance(__CLASS__)-&gt;attach(new Log_File(DATA_PATH . &#039;/logs/&#039; . date(&#039;Ymd&#039;) . &#039;/mysql-error-&#039; . date(&#039;Ymd&#039;) . &#039;.log&#039;));<br/>1）文件及目录都是777：<br/>new Log_File:&#92;libraries&#92;log&#92;file.php, 分析文件函数：<br/>（1）目录777：__construct里直接创建目录： if (! mkdir($directory, 0777, TRUE) &#124;&#124; ! is_writable($directory)) &#123;<br/>（2）文件777：public function write()&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;if (is_null($this-&gt;_filename)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directory = $this-&gt;_directory . date(&#039;Y/m&#039;) . &#039;/&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! is_dir($directory)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;mkdir($directory, 0777, TRUE);
&nbsp;&nbsp;&nbsp;&nbsp;chmod($directory, 0777);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filename = $directory . date(&#039;d&#039;) . &#039;.php&#039;;
&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filename = $this-&gt;_directory . $this-&gt;_filename;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if (! file_exists($filename)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create the log file
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_put_contents($filename, Ko::FILE_SECURITY . &#039; ?&gt;&#039; . PHP_EOL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Allow anyone to write to log files
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chmod($filename, 0777);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </textarea><br/><br/><br/>&#92;libraries&#92;cookie.php<br/>final private function __construct ()<br/>public static function get ($key, $default = NULL)<br/>public static function set ($name, $value, $expiration = NULL)<br/>public static function delete ($name)<br/>使用方法：<br/>Cookie::set(&#039;language1&#039;,$language);<br/>$lang = Cookie::get(&#039;language1&#039;);<br/><br/><br/>十二：关于前端代码的路径等配置:前端Js/css静态域名版本号（反CDNl:version）的配置：<br/>/controllers/site/preview.php<br/>关于版本号及前端，每个controller下都有一个preview.php层层去继承InitController在具体的controller下配置相关前端Js输出及CSS输出的路径：<br/>$this-&gt;view-&gt;version&nbsp;&nbsp; = KO::config(&#039;config.version&#039;);<br/>public function after()<br/>&#123;<br/>&nbsp;&nbsp;//$this-&gt;getwatch();<br/>&nbsp;&nbsp;$this-&gt;view-&gt;themePath = $this-&gt;themePath;<br/>&nbsp;&nbsp;$this-&gt;view-&gt;publicPath = &#039;themes/common&#039;;<br/>&nbsp;&nbsp;$this-&gt;view-&gt;cssPath = &#039;themes/zh&#039;;<br/>&nbsp;&nbsp;$this-&gt;view-&gt;jsPath = &#039;themes/zh&#039;;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;$this-&gt;view-&gt;lang = (array)Ko::lang(&#039;common&#039;,&#039;zh&#039;);<br/>&nbsp;&nbsp;$this-&gt;view-&gt;staticURL = KO::config(&#039;url.static_url&#039;);<br/>&nbsp;&nbsp;$this-&gt;view-&gt;mainURL&nbsp;&nbsp; = KO::config(&#039;url.main_url&#039;);<br/>&nbsp;&nbsp;$this-&gt;view-&gt;flashURL&nbsp;&nbsp;= KO::config(&#039;url.flash_player_url&#039;);<br/>&nbsp;&nbsp;$this-&gt;view-&gt;basePath&nbsp;&nbsp;= $this-&gt;getBaseUrl();<br/>&nbsp;&nbsp;$this-&gt;view-&gt;version&nbsp;&nbsp; = KO::config(&#039;config.version&#039;);<br/>&nbsp;&nbsp;$this-&gt;view-&gt;render();<br/>&#125;<br/><br/>十三：smarty模板输出：<br/>最上层的controller下的before还负责smarty模板的指定：<br/>&#92;libraries&#92;controller.php<br/>public function before ()<br/>&#123;<br/>&nbsp;&nbsp;if ($this-&gt;auto_render === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the template<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;template = $this-&gt;request-&gt;getController() . &#039;/&#039; . $this-&gt;request-&gt;getAction();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view = View::factory($this-&gt;template);<br/>&nbsp;&nbsp;&#125;<br/>&#125;<br/>继承后再重写：<br/>public function before ()<br/>&#123;<br/>&nbsp;&nbsp;//&nbsp;&nbsp;Auto render , use user defined template.<br/>&nbsp;&nbsp;$this-&gt;autoRender(TRUE);<br/>&nbsp;&nbsp;parent::before();<br/><br/>———————上面的before，下面的after都是在Library/request.php里进行按before在前，action在中间,after在后面处理的__________<br/>Before处理如下前期问题，参数获取/模板工厂（smarty）等层层继承，层层parent::before();：<br/>//Overload:英文是重载,国人：同名函数，叫&nbsp;&nbsp;方法重写<br/>class ActController extends FrontController <br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function before()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::before();//访问InitController里的after<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&#125;<br/><br/>class FrontController extends InitController<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Overload<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function before()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;$lang = &#039;&#039;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::before();// 初始化模板等...<br/><br/>class InitController extends Controller<br/>&#123;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;public function before()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Init Session<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;session = Session::instance();//获取参数等全局逻辑准备<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;varname = trim($this-&gt;getRequest()-&gt;getParam(&#039;varname&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;jsoncallback = trim($this-&gt;getRequest()-&gt;getParam(&#039;jsoncallback&#039;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>abstract class Controller<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function before ()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;auto_render === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the template<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;template = $this-&gt;request-&gt;getController() . &#039;/&#039; . $this-&gt;request-&gt;getAction();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view = View::factory($this-&gt;template);//模板进入工厂<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/>十四：关于after：<br/>这块输出头也是放after里的：<br/>&#92;controllers&#92;global.php<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function after()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Send headers: Cache-Control &amp; Expire.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$max_age = $this-&gt;getRequest()-&gt;getParam(&#039;max_age&#039;, 0);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($max_age &gt; 0) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;getRequest()-&gt;addHeader(&#039;Cache-Control&#039;, &#039;max-age=&#039; . $max_age);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;getRequest()-&gt;addHeader(&#039;Expires&#039;, gmdate(&#039;D, d M Y H:i:s&#039;, time() + $max_age) . &#039; GMT&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;getRequest()-&gt;addHeader(&#039;Cache-Control&#039;, &#039;no-cache&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;getRequest()-&gt;addHeader(&#039;Expires&#039;, &#039;0&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;getRequest()-&gt;addHeader(&#039;Pragma&#039;, &#039;No-cache&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::after();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>上面的after函数被：&#92;controllers&#92;front.php重写并parent调用之：<br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Overload<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function after()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view-&gt;version = KO::config(&#039;config.version&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;view-&gt;pageCode = $this-&gt;getPageCode();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;autoRender(TRUE);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::after();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>它也是在后面才输出的,调用在Library/request.php:<br/><br/>上面的日志在后面after写的：<br/>libraries&#92;request.php<br/>$class-&gt;getMethod(&#039;after&#039;)-&gt;invoke($controller);<br/>摘录自： &#92;libraries&#92;request.php<br/>try &#123;<br/>&nbsp;&nbsp;// Load the controller using reflection<br/>&nbsp;&nbsp;$class = new ReflectionClass(ucfirst($prefix) . ucfirst($this-&gt;controller) . &#039;Controller&#039;);<br/>&nbsp;&nbsp;if ($class-&gt;isAbstract()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;errorPage(&#039;Cannot create instances of abstract controller: :error&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(&#039;:error&#039; =&gt; $prefix . ucfirst($this-&gt;controller) . &#039;Controller&#039;));<br/>&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;// Create a new instance of the controller, Interrupted by dispatcher anytime<br/>&nbsp;&nbsp;$controller = $class-&gt;newInstance($this);<br/><br/>&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;before&#039;)-&gt;invoke($controller);<br/>&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;try &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$action = empty($this-&gt;action) ? Route::$default_action : $this-&gt;action;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod($action)-&gt;invokeArgs($controller, $this-&gt;params);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&#125; catch (ReflectionException $e) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;__call&#039;)-&gt;invokeArgs($controller, array($this-&gt;getAction() , $this-&gt;params));<br/>&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;if ($this-&gt;isDispatched()) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;getMethod(&#039;after&#039;)-&gt;invoke($controller);<br/>&nbsp;&nbsp;&#125;<br/><br/>&#125;<br/><br/><br/><br/>十五：关于日志(新加daemon日志实现立即写，不用注册的退出时才写：register_shutdown_function)：<br/>日志输出在web时是执行完后再输出,而cli模式是立即输出，（关于错误级别$type定义在第九有备注到，如info级别：Ko::log(&#039;info&#039;, str_replace(array(&quot;&#92;r&#92;n&quot;, &quot;&#92;r&quot;, &quot;&#92;n&quot;), &quot; &quot;, $sql));），如下：<br/>&#92;libraries&#92;log.php<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function add($type, $message)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create a new message and timestamp it<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_messages[] = array (<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;time&#039; =&gt; date(self::$timestamp),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;type&#039; =&gt; $type,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;body&#039; =&gt; is_string($message) ? $message : var_export($message, true),<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(Ko::$is_cli === TRUE) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;write();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>WEB没有立即写，而是后面才写，并没有在request中的after里，而是注册了shutdown函数write：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public static function instance($group =&#039;default&#039;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;......<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Write the logs at shutdown<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register_shutdown_function(array(self::$_instance[$group], &#039;write&#039;));//这儿调用写<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self::$_instance[$group];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/><br/><br/>调用：&#92;controllers&#92;audit.php<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$returnlog-&gt;add(&#039;check start&#039;, &#039;-----------------&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$returnlog-&gt;add(&#039;data post&#039;, $post);<br/><br/><br/>这种实现方法在如果用php做daemon时会遇到从不退出就没有调用写导致里面的数据太大出现php内存不够并意外退出问题：<br/>遇到问题，当守护进程时写日志时往往会出现因为框架是web的，在最后退出才写，而daemon是不退出的，导致内存暴增，解决办法如下：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;if(Ko::$is_cli === TRUE) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;write();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><textarea name="code" class="php" rows="15" cols="100">

&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp; * Get the singleton instance of this class and enable writing at shutdown.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;Log
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;public static function instance($group =&#039;default&#039;)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!isset(self::$_instance[$group]) &#124;&#124;self::$_instance[$group] === NULL) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create a new instance
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$_instance[$group] = new self($group);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Write the logs at shutdown
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register_shutdown_function(array(self::$_instance[$group], &#039;write&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self::$_instance[$group];
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
 </textarea><br/> 修改为，如果是cli模式立即就写了得了：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp; * Adds a message to the log.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * @param&nbsp;&nbsp; string&nbsp;&nbsp;type of message
&nbsp;&nbsp;&nbsp;&nbsp; * @param&nbsp;&nbsp; string&nbsp;&nbsp;message body
&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;$this
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;public function add($type, $message)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create a new message and timestamp it
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_messages[] = array (
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;time&#039; =&gt; date(self::$timestamp),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;type&#039; =&gt; $type,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;body&#039; =&gt; is_string($message) ? $message : var_export($message, true),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(Ko::$is_cli === TRUE) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;write();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/><br/><br/>十六：使用modules外挂模块方法：<br/>Ko::modules( array(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;weibo&#039; =&gt; &#039;weibo&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;libspace&#039; =&gt; &#039;libspace&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;face&#039; =&gt; &#039;face&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;nusoap&#039; =&gt; &#039;nusoap&#039;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#039;sdk&#039; =&gt; &#039;sdk&#039;,<br/>));<br/><br/> jackxiang.com/modules/&nbsp;&nbsp;&nbsp;&nbsp;//jackxiang.com是根目录<br/>face/&nbsp;&nbsp;&nbsp;&nbsp; libspace/ nusoap/&nbsp;&nbsp; sdk/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;weibo/<br/>ls modules/sdk/&nbsp;&nbsp;&nbsp;&nbsp;//init.php文件名是必须要有的。<br/>common.php&nbsp;&nbsp;init.php&nbsp;&nbsp;justwinitapi.ex.class.php<br/>调用：<br/>./application/models/app.php:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$justwinit = new justwinit();<br/>./application/controllers/front/front.php:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$justwinit = new justwinit();<br/>/**<br/>* Overload<br/>*/<br/>public function before()<br/>&#123;<br/>&nbsp;&nbsp;$this-&gt;checkToken();<br/>&#125;<br/>public function checkToken()<br/>&#123;<br/>&nbsp;&nbsp;$justwinit = new justwinit();<br/>&nbsp;&nbsp;.......<br/>&#125;<br/><br/>十七：框架扩展：在&#92;libraries&#92;core.php里加一个写日志函数，以给daemon程序写当是cli模式时写：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp; * 静态写日志方法
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;public static function writeLog($type ,$logFile ,$message )&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (self::$log_levels[$type] &lt;= self::$threshold) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!is_dir(dirname($logFile))) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mkdir(dirname($logFile), 0777, true);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@chmod(dirname($logFile), 0777);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_put_contents($logFile, date(&quot;Y/m/d H:i:s&quot;) . &quot;&#92;t&quot; . $type . &quot;&#92;t&quot; . var_export($msg, true) . &quot;&#92;n&quot;, FILE_APPEND);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@chmod($logFile, 0777);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>十八：图片缩放之gd，示例：<br/> 关于图片上传及缩小，用到上传类libraries//upload.php,缩小gd类libraries/image.php ,<br/> 这儿遇到一个问题是上传后缀是大写的JPG时会报错，最后用strtolower($ext)保存为小写就没这个问题,<br/>我从其它博客试了一下确实存在警告，最好还是小写的jpg后缀为好：http://jackxiang.com/post/3022/<br/> 缩小为148.148的等比例缩放，其使用方法如下：<br/><textarea name="code" class="php" rows="15" cols="100">
/*
 * Upload action
*/
&nbsp;&nbsp;public function upload ()
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output = array(&#039;ret&#039; =&gt; &#039;fail&#039;,&#039;msg&#039; =&gt; &quot;上传文件失败,发生错误&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this-&gt;request-&gt;isPost()) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_FILES[&#039;upload&#039;])) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$allowed_types = Ko::config(&#039;config.upload.allowed_image_types&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$max_size = Ko::config(&#039;config.upload.max_filesize&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$directory = Ko::config(&#039;config.upload.directory&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filename = $_FILES[&#039;upload&#039;][&#039;name&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ext = substr($filename, strripos($filename, &#039;.&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filename = date(&#039;YmdHis&#039;) . rand(0, 9999) . strtolower($ext);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$attach = &#039;temp/&#039; . $filename;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Upload::$html5 = (bool) $html5;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!Upload::type(&#039;upload&#039;, $allowed_types)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output[&#039;msg&#039;] = &quot;上传文件格式不正确&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage($output);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!Upload::size(&#039;upload&#039;, $max_size)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output[&#039;msg&#039;] = &quot;上传文件大小不要超过2M&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage($output);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!Upload::valid(&#039;upload&#039;)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output[&#039;msg&#039;] = &quot;上传文件失败,发生错误&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage($output);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!Upload::required(&#039;upload&#039;)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output[&#039;msg&#039;] = &quot;上传文件失败,发生错误&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage($output);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($attach = Upload::save(&#039;upload&#039;, $attach, $directory)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$image = Image::factory($directory.&#039;/&#039;.$attach);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$image-&gt;resize(148, 148);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$image-&gt;save();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage(array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;ret&#039; =&gt; &#039;succ&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;msg&#039; =&gt; &#039;文件上传成功&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;filename&#039; =&gt; $filename,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;attach&#039; =&gt; $attach
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; catch (Exception $e) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage(array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;ret&#039; =&gt; &#039;fail&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;msg&#039; =&gt; &quot;文件上传失败,发生错误：&#123;$e-&gt;getMessage()&#125;&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;outputMessage($output);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;</textarea><br/><br/>十九：关于单例模式里和观察者模式一块用的问题：<br/>1）写法于传统的PHP写法背离，不像C了，在写得少的人看来很是怪异：<br/>$log = Log::instance(__CLASS__)-&gt;attach(new Log_File(DATA_PATH . &#039;logs/&#039; . date(&#039;Ymd&#039;), __CLASS__.&#039;-&#039; . date(&#039;Ymd&#039;) . &#039;.log&#039;)); <br/>2）这种单例与观察模式在代码提示时出现无法跳转，因为再智能的编辑器也没法知道前面这个数组是哪个具体对象了：<br/> $writer[&#039;object&#039;]-&gt;write($messages);//这样当于一个写的类句柄通过观察者数组中取出后：Log_File-&gt;write($messages);<br/>3）但为了什么耦合，为了少几个句柄，为了提高效率等，还得用，自己作下分析性参考：http://jackxiang.com/post/6825/ 。<br/><br/>二十：观察者模式：<br/>http://www.cnblogs.com/baochuan/archive/2012/02/22/2362668.html<br/><textarea name="code" class="php" rows="15" cols="100">

&lt;?php
/**
 * 观察者模式
 * @author: Mac
 * @date: 2012/02/22
 */

class Paper&#123; /* 主题&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;private $_observers = array();

&nbsp;&nbsp;&nbsp;&nbsp;public function register($sub)&#123; /*&nbsp;&nbsp;注册观察者 */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_observers[] = $sub;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;


&nbsp;&nbsp;&nbsp;&nbsp;public function trigger()&#123;&nbsp;&nbsp;/*&nbsp;&nbsp;外部统一访问&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!empty($this-&gt;_observers))&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach($this-&gt;_observers as $observer)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$observer-&gt;update();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&#125;

/**
 * 观察者要实现的接口
 */
interface Observerable&#123;
&nbsp;&nbsp;&nbsp;&nbsp;public function update();
&#125;

class Subscriber implements Observerable&#123;
&nbsp;&nbsp;&nbsp;&nbsp;public function update()&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;Callback&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&#125;


下面是测试代码

/*&nbsp;&nbsp;测试&nbsp;&nbsp;&nbsp;&nbsp;*/
$paper = new Paper();
$paper-&gt;register(new Subscriber());
//$paper-&gt;register(new Subscriber1());
//$paper-&gt;register(new Subscriber2());
$paper-&gt;trigger();
</textarea><br/>框架里的观察者模式：<br/>/libraries/log.php<br/>片段如下，这里的writer就是一个进来的类对象数组的一个集合（全是对象），这个：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;// List of added messages
&nbsp;&nbsp;&nbsp;&nbsp;private $_messages = array();

&nbsp;&nbsp;&nbsp;&nbsp;// List of log writers
&nbsp;&nbsp;&nbsp;&nbsp;private $_writers = array();

&nbsp;&nbsp;&nbsp;&nbsp;public function attach(Log_Writer $writer, $types = NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_writers[&quot;&#123;$writer&#125;&quot;] = array (
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;object&#039; =&gt; $writer,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;types&#039; =&gt; $types
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/>这个对象去分别调用对象类里的方法，和上面的原始摘录Url里的示例一样的，如下用foreach去一个个的调用write方法，$writer[&#039;object&#039;]-&gt;write($messages);：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;public function write ()
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (empty($this-&gt;_messages)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// There is nothing to write, move along
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Import all messages locally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$messages = $this-&gt;_messages;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Reset the messages array
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_messages = array();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($this-&gt;_writers as $writer) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (empty($writer[&#039;types&#039;])) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Write all of the messages
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$writer[&#039;object&#039;]-&gt;write($messages);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Filtered messages
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filtered = array();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($messages as $message) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (in_array($message[&#039;type&#039;], $writer[&#039;types&#039;])) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Writer accepts this kind of message
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filtered[] = $message;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Write the filtered messages
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$writer[&#039;object&#039;]-&gt;write($filtered);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>二十一：关于memcache或ttserver的缓存实现及配置：<br/>配置文件这样写：<br/>config/cache.php<br/><textarea name="code" class="php" rows="15" cols="100">
&lt;?php defined(&#039;SYS_PATH&#039;) or die(&#039;No direct script access.&#039;);
return array (
&nbsp;&nbsp;&nbsp;&nbsp;&#039;default&#039;&nbsp;&nbsp; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;driver&#039;&nbsp;&nbsp; =&gt; &#039;memcache&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;servers&#039;&nbsp;&nbsp; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;host&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; &#039;10.70.32.42&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;port&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; 11211,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;persistent&#039;&nbsp;&nbsp;=&gt; false,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;compression&#039; =&gt; false,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#039;lifetime&#039;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; 3600,
&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&#039;tt_server&#039;&nbsp;&nbsp; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;driver&#039;&nbsp;&nbsp; =&gt; &#039;ttcache&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;servers&#039;&nbsp;&nbsp; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;host&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; &#039;10.70.32.42&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;port&#039;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; 21211,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;persistent&#039;&nbsp;&nbsp;=&gt; false,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;compression&#039; =&gt; false,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;lifetime&#039;&nbsp;&nbsp;&nbsp;&nbsp;=&gt; 0 ,
&nbsp;&nbsp;&nbsp;&nbsp;),
</textarea><br/>使用时要这样用：<br/>class TagModel extends Model<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;protected $cachePermanent = &#039;tt_server&#039;;// Permanent Cache KEY,来自配置文件的数组key，及config/cache.php tt_server对应。<br/>&nbsp;&nbsp;&nbsp;&nbsp;return (array)$this-&gt;getPermanentCache($userid);<br/>&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;setPermanentCache($userid, $tags);<br/><br/>为什么可以这样用，因为前面的extends Model这个类的libraries/model.php里有：<br/>[root@iZ25z0ugwgtZ libraries]# grep -r &quot;setPermanentCache&quot; ./&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>./model.php:&nbsp;&nbsp;&nbsp;&nbsp;protected function setPermanentCache($key, $data)<br/>&nbsp;&nbsp; // Cache KEY<br/>&nbsp;&nbsp; protected $cacheConfig = &#039;default&#039;;<br/>&nbsp;&nbsp; protected function getCache($key)<br/>&nbsp;&nbsp; &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Cache::instance($this-&gt;cacheConfig)-&gt;get($this-&gt;makeCacheKey($key));//静态调用instance方法获取该类的实例<br/>&nbsp;&nbsp; &#125;<br/><br/>这个cache是有各种cache，这个是ttserver，我们来看它是如何实现这个实例的文件，libraries/cache/ttcache.php ：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;public static function &amp;instance ($config = FALSE)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$name = (string) $config;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! isset(self::$instances[$name])) &#123;//self::$instances是一个以config为key的类实例数组。
&nbsp;&nbsp;//&amp;简单点可以理解成C语言的&amp;但是有点差别,$this实例化的这个类.static instance指向的这个实例.
&nbsp;&nbsp;//这就是一个单例模式.所有的代码只要调用classname::getInstance()就可以获得这个类的实例.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$instances[$name] = new Cache($config);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self::$instances[$name];
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>我都说这个直接传入一个string的tt_server，是怎么从前面配置文件里读取到这个数组的，不仅仅是前面的这个instance函数对这各种cache设备<br/>类进行实例化外，还有对这个下面挂的设备本身的相关配置进行初始化，代码如下：<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;public function __construct ($config = FALSE)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (is_string($config)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$name = $config;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Test the config group name
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (($config = Ko::config(&#039;cache&#039;)-&gt;$config) === NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException(&#039;Cache: Undefined group :name.&#039;, array(&#039;:name&#039; =&gt; $name));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! is_array($config)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the default group
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$config = Ko::config(&#039;cache&#039;)-&gt;default;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Cache the config in the object
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_config = $config;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set driver name
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$driver = &#039;Cache_&#039; . ucfirst($this-&gt;_config[&#039;driver&#039;]);//$driver = Cache_[tt_server[&quot;driver&quot;]=ttcache]=Cache_TTcache,ucfirst首字母大写。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load the driver
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! Ko::autoload($driver))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException(&#039;Class :name not found.&#039;, array(&#039;:name&#039; =&gt; $driver));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Initialize the driver
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_driver = new $driver($this-&gt;_config);//Cache_TTcache 或new Cache_Memcache。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Validate the driver
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (! ($this-&gt;_driver instanceof Cache_Driver))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new KoException(&#039;Cache: Not valid driver &#039; . $this-&gt;_config[&#039;driver&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>框架分析到此完结。EOF<br/><br/>AddTime：2016-05-28<br/>加载外部modules方法及入口文件：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set the current module list<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self::$_modules = $modules;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach (self::$_modules as $path) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$init = $path . DIRECTORY_SEPARATOR . &#039;init.php&#039;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (is_file($init)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require_once $init;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><textarea name="code" class="php" rows="15" cols="100">

</textarea><br/><br/>也就是说会核心框架会自动加载这个init.php<br/>D:&#92;www&#92;xiyou.cntv.cn[新svn代码]&#92;trunk&#92;codes&#92;modules下的OAuth weibo qiniu 里面都有一个init.php，而这前面三个目录是怎么找的呢？<br/>D:&#92;www&#92;xiyou.cntv.cn[新svn代码]&#92;trunk&#92;codes&#92;application&#92;bootstrap.php 里有让modules相对或绝对路径。 relative or absolute path.：<br/><textarea name="code" class="php" rows="15" cols="100">
/**
 * Enable modules. Modules are referenced by a relative or absolute path.
 */
$used_modules = array(&#039;qiniu&#039; =&gt; &#039;qiniu&#039;);

Ko::modules(isset($used_modules) ? $used_modules : array());
</textarea><br/><br/><br/>==================================<br/>概述以上分析,从更高层次来分析其入口的调用层次分析：<br/>model独立，model目录里文件均无互相调用（缓存也在这层，也就是数据层），<br/>service加上业务调用model model/open，service之前也可相互调用给application提供数据。<br/>application可以有多个目录，如多了个openapi的目录，这个目录可通过路由来配置指向即可：<br/>./bootstrap.php:Route::set(&#039;openapi_route&#039;, &#039;openapi(/&lt;controller&gt;(/&lt;action&gt;(/&lt;__KO_VARS__&gt;)))&#039;, array(&#039;__KO_VARS__&#039; =&gt; &#039;.+&#039;))<br/>这个对像是传入/libraries/request.php，它又和/libraries/core.php接合，接合autoload和反射类到上面这些model、service、controller里找对应，<br/>找不到时用try..catch出来错即可，而这个bootstrap.php,则被./frontend/index.php ./open/index.php包含进来（它里面有错谴责级别设置）后，进行：<br/>// Bootstrap the application<br/>require_once APP_PATH . &#039;bootopen.php&#039;;&nbsp;&nbsp;，于是对外可呈现出多个域名，因为在nginx里直接配置：root&nbsp;&nbsp;/data/htdocs/xiyou_alpha/frontend;就会从<br/>fronted/index.php单入口里穿透并进入到各个层里，运行了，在层次上清晰，在代码上可灵活配置，这就是Ko的优势了，MVC加server层次间的调用规定如下：<br/><br/>一）model目录一个目录：open<br/>二）service目录里调model的open里的类用前面加Open_,调open一级的就不用了。<br/>三）controller里有open openapi两个目录，均调用了service里的open目录：<br/>比如：<br/>controller<br/>./openapi/partner.php:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Open_OpenService = new Open_OpenService();<br/>./open/usercenter.php:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$open_OpenService = new Open_OpenService();<br/><br/>_________Model_________<br/>.........//主站的model<br/>/model/open/...开放平台<br/>也就是说model最好是简单一点，service文件间可互相调用：<br/>vi services/open/open.php&nbsp;&nbsp;Open_OpenService 原型可被同级的server其它文件调用如下：<br/>vi services/audit.php:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Open_OpenService = new Open_OpenService();<br/>而这个service呢，也调用了model层里的open目录下的modle：<br/>$tokenModel = new Open_TokensModel();<br/>$info = $tokenModel-&gt;getTokenInfoByToken($token);<br/>上面两行的位置在哪儿？能通过类前面加上Open知道是model/open/位置：<br/>/application/models/open/tokens.php class Open_TokensModel extends Model<br/><br/><br/>为何getCache得在services目录里的base.php和library目录下的model.php里有:<br/>&nbsp;&nbsp;&nbsp;&nbsp;protected function getCache($key)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Cache::instance($this-&gt;cacheConfig)-&gt;get($this-&gt;makeCacheKey($key));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;<br/><br/>getCurrentPageVideosFromDB在model里不需要cache，但是getCurrentPageVideos就需要cache了：<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function getVideosByUserId($userId)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$userVideos = $this-&gt;getCache($userId);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($userVideos) &#123;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $userVideos;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$userVideos = $this-&gt;getVideosByUserIdFromDB($userId);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($userVideos &amp;&amp; count($userVideos) &gt; 0) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setCache($userId, $userVideos);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $userVideos;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp; <br/><br/>同样，在service里有些变量也需要cache，如cookie变量从cache里读取，为何需要专门函数实现？因为怕cache重复了，结合函数名，查询参数确保唯一。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/**<br/>&nbsp;&nbsp;&nbsp;&nbsp; * 写入cookie - 您最近看过的<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;public function setCookieHistoryVideoList($uuid)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置显示“您最近看过的”视频的个数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$MAX_COUNT = 5;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cookieId = Cookie::get(&#039;xiyou_ck_id&#039;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cookieData = $this-&gt;getCache($cookieId);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!$cookieData)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cookieData = array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$videolist =&nbsp;&nbsp;isset($cookieData[&#039;history_list&#039;]) ? $cookieData[&#039;history_list&#039;] :false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!is_array($videolist))&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$videolist = array();
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [框架核心]kohana框架controller/action/view原理，在很多时候反射也是唯一的选择：为什么我们会选择使用反射？找不到action和对应方法时调用404。直接访问Url里的一个controler下用action直接输出调用forward时在调核心request类里的函数返回$this是什么的理解。错误报告，文件缓存等实现， 自制session，web端打开写SQL日志及分析，单例模式，观察者模式，加载外部modules方法及入口文件，model+service+controller中间加上server层的原因，为何getCache得在services目录里的base.php和library目录下的model.php里有。]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>