<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-32548984</id><updated>2011-04-22T09:30:22.904+08:00</updated><category term='php5'/><category term='MVC'/><category term='php'/><category term='概念'/><category term='Console'/><category term='Zend Framework'/><category term='SPL'/><category term='设计模式'/><category term='应用'/><category term='oop'/><category term='多进程'/><category term='phpUnit'/><category term='安装'/><title type='text'>PHP Laboratory</title><subtitle type='html'>Architecture, construction and engineering</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-32548984.post-6542402072076746406</id><published>2009-06-01T15:26:00.004+08:00</published><updated>2009-06-01T15:30:08.208+08:00</updated><title type='text'>Zend_Paginator 空适配器 bug</title><content type='html'>Zend_Paginator_Adapter_Null 可以让你不使用 Zend_Paginator 来管理数据而仍然能够使用 分页控制。但zf 1.6-1.8.2 存在最后一页数据不对的情况。&lt;br /&gt;&lt;br /&gt;Test code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$paginator = Zend_Paginator::factory(2);&lt;br /&gt;$paginator-&gt;setCurrentPageNumber(1);&lt;br /&gt;$paginator-&gt;setItemCountPerPage(5);&lt;br /&gt;&lt;br /&gt;$pages = $paginator-&gt;getPages();&lt;br /&gt;var_dump($pages);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;期望结果:&lt;br /&gt;["currentItemCount"]=&gt;2&lt;br /&gt;["lastItemNumber"]=&gt;2&lt;br /&gt;实际结果：&lt;br /&gt;["currentItemCount"]=&gt;5&lt;br /&gt;["lastItemNumber"]=&gt;5&lt;br /&gt;&lt;br /&gt;修正方法：&lt;br /&gt;&lt;code&gt;    public function getItems($offset, $itemCountPerPage)&lt;br /&gt;    {&lt;br /&gt;        if ($this-&gt;_count &lt;= $offset) return array();&lt;br /&gt;        $remainItemCount = $this-&gt;_count - $offset;&lt;br /&gt;        $currentItemCount = $remainItemCount &gt; $itemCountPerPage ? $itemCountPerPage : $remainItemCount;&lt;br /&gt;        return array_fill(0, $currentItemCount, null);&lt;br /&gt;    }&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-6542402072076746406?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/6542402072076746406/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=6542402072076746406' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6542402072076746406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6542402072076746406'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/06/zendpaginator-bug.html' title='Zend_Paginator 空适配器 bug'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-595773803134399958</id><published>2009-04-23T18:30:00.000+08:00</published><updated>2009-04-23T23:47:08.521+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='应用'/><title type='text'>Zend Framework Plugin: 不同模块(Module)使用不同的错误控制器(ErrorController)</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Zend Framework 的错误控制器提供了统一的错误处理方式, 参阅 http://framework.zend.com/manual/en/zend.controller.html#zend.controller.quickstart.go.errorhandler&lt;br/&gt;  当我们工作于模块方式时，常常希望不同模块使用不同的错误处理，比如 default 模块使用默认ErrorController, 后台管理模块 admin 使用 Admin_ErrorController 提供不同的布局和更详细的错误显示。&lt;br/&gt;&lt;br/&gt;Plugin 方式为我们提供了方便的设置途径，以下 plugin 设置每个 module 使用 模块里的 ErrorController, 如果模块不提供 ErrorController 则使用默认的 ErrorController：&lt;br/&gt;&lt;code&gt;require_once ('Zend/Controller/Plugin/Abstract.php');&lt;br/&gt;class Mezi_Controller_Plugin_ErrorControllerSelector extends Zend_Controller_Plugin_Abstract&lt;br/&gt;{&lt;br/&gt;    public function routeShutdown(Zend_Controller_Request_Abstract $request)&lt;br/&gt;    {&lt;br/&gt;        $front = Zend_Controller_Front::getInstance();&lt;br/&gt;&lt;br/&gt;        //If the ErrorHandler plugin is not registered, bail out&lt;br/&gt;        if( !($front-&amp;gt;getPlugin('Zend_Controller_Plugin_ErrorHandler') instanceof Zend_Controller_Plugin_ErrorHandler) )&lt;br/&gt;            return;&lt;br/&gt;&lt;br/&gt;        $error = $front-&amp;gt;getPlugin('Zend_Controller_Plugin_ErrorHandler');&lt;br/&gt;&lt;br/&gt;        //Generate a test request to use to determine if the error controller in our module exists&lt;br/&gt;        $testRequest = new Zend_Controller_Request_HTTP();&lt;br/&gt;        $testRequest-&amp;gt;setModuleName($request-&amp;gt;getModuleName())&lt;br/&gt;                    -&amp;gt;setControllerName($error-&amp;gt;getErrorHandlerController())&lt;br/&gt;                    -&amp;gt;setActionName($error-&amp;gt;getErrorHandlerAction());&lt;br/&gt;&lt;br/&gt;        //Does the controller even exist?&lt;br/&gt;        if ($front-&amp;gt;getDispatcher()-&amp;gt;isDispatchable($testRequest)) {&lt;br/&gt;            $error-&amp;gt;setErrorHandlerModule($request-&amp;gt;getModuleName());&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;启动时安装 plugin:&lt;br/&gt;&lt;code&gt;$front = Zend_Controller_Front::getInstance();&lt;br/&gt;$front-&amp;gt;registerPlugin(new Mezi_Controller_Plugin_ErrorControllerSelector());&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='blogger-post-footer'&gt;--- end of text ---&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=0a13c4a9-031c-8b16-b11d-667f8f8bcaa9' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-595773803134399958?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/595773803134399958/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=595773803134399958' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/595773803134399958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/595773803134399958'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/04/zend-framework-plugin.html' title='Zend Framework Plugin: 不同模块(Module)使用不同的错误控制器(ErrorController)'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-3603875391583273336</id><published>2009-04-23T18:16:00.000+08:00</published><updated>2009-04-23T18:17:47.695+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='应用'/><title type='text'>Zend Framework Plugin:自适应 magic_quotes_gpc 环境</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;推荐关闭 php.ini 的 magic_quotes_gpc 选项，一来可以提升性能，二来可以保证得到的原始数据，Zend_Db 会自动转义数据入库。并且新版本的 php 推荐配置都是默认关闭 magic_quotes_gpc 选项。&lt;br/&gt;  当然某些系统打开了 magic_quotes_gpc 选项，并且你也没有足够权限去修改这个配置，这些反斜杠可能给你造成困扰，我们可以用代码抵消修改。&lt;br/&gt;  Zend Framework 的 plugin 提供了很好的方式来做这些事情，而不需要改动我们去参数的每段代码。&lt;br/&gt;&lt;code&gt;&lt;br/&gt;/**&lt;br/&gt; * A Zend Controller Plugin dedicated to undoing the damage of magic_quotes_gpc&lt;br/&gt; * in systems where it is on.&lt;br/&gt; *&lt;br/&gt; * @author  Ken&lt;br/&gt; * @version $Id:$&lt;br/&gt; */&lt;br/&gt;require_once ('Zend/Controller/Plugin/Abstract.php');&lt;br/&gt;class Mezi_Controller_Plugin_StripMagicQuotes extends Zend_Controller_Plugin_Abstract&lt;br/&gt;{&lt;br/&gt;    /**&lt;br/&gt;     * strip all slashes off $request parameters&lt;br/&gt;     *&lt;br/&gt;     * @param Zend_Controller_Request_Abstract $request&lt;br/&gt;     */&lt;br/&gt;    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)&lt;br/&gt;    {&lt;br/&gt;        $params = $request-&amp;gt;getParams();&lt;br/&gt;        array_walk_recursive($params, array($this , '_stripSlashes'));&lt;br/&gt;        $request-&amp;gt;setParams($params);&lt;br/&gt;&lt;br/&gt;        if ($request instanceof Zend_Controller_Request_Http) {&lt;br/&gt;            $this-&amp;gt;_stripSlashesGPC();&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /**&lt;br/&gt;     * strip all slashes from GPC&lt;br/&gt;     */&lt;br/&gt;    protected function _stripSlashesGPC()&lt;br/&gt;    {&lt;br/&gt;        array_walk_recursive($_GET, array($this , '_stripSlashes'));&lt;br/&gt;        array_walk_recursive($_POST, array($this , '_stripSlashes'));&lt;br/&gt;        array_walk_recursive($_COOKIE, array($this , '_stripSlashes'));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /**&lt;br/&gt;     * callback strip the slashes off an item in the Params array&lt;br/&gt;     *&lt;br/&gt;     * @param string $value&lt;br/&gt;     * @param string $key&lt;br/&gt;     */&lt;br/&gt;    protected function _stripSlashes (&amp;amp;$value, $key)&lt;br/&gt;    {&lt;br/&gt;        $value = stripslashes($value);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;然后启动时安装 plugin， 仅在 magic_quotes_gpc 打开时需要处理：&lt;br/&gt;&lt;code&gt;&lt;br/&gt;$front = Zend_Controller_Front::getInstance();&lt;br/&gt;&lt;br/&gt;if (get_magic_quotes_gpc()) {&lt;br/&gt;    require_once 'Mezi/Controller/Plugin/StripMagicQuotes.php';&lt;br/&gt;    $this-&amp;gt;_front-&amp;gt;registerPlugin(new Mezi_Controller_Plugin_StripMagicQuotes());&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;Plugin 非常漂亮的实现了我们的需求，以前写好的代码都无须改动。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-3603875391583273336?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/3603875391583273336/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=3603875391583273336' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/3603875391583273336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/3603875391583273336'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/04/zend-framework-plugin-magicquotesgpc.html' title='Zend Framework Plugin:自适应 magic_quotes_gpc 环境'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-327543140233018520</id><published>2009-03-23T10:32:00.001+08:00</published><updated>2009-03-23T10:32:36.351+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><title type='text'>PHP 中的 UTF8 和 Mysql</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;很多人在 Mysql 默认为非 UTF8 但要使用 UTF8 编码的时候会使用 "SET NAMES UTF8" 语句去设置正确的编码方式。通常为了方便在初始化 Db 对象或者创建连接后就去执行，虽然这种方式可以正确工作，但会导致一次连接和查询，即使初始化之后并无需要数据库。这也破坏了很多数据库对象提供的 lazy connect 特性。&lt;br/&gt;PHP 手册不推荐使用 query() 去执行 SET NAMES&lt;br/&gt;&lt;br/&gt;更好的方法是使用数据库驱动自身提供的特性去初始化编码。&lt;br/&gt;&lt;br/&gt;mysql:&lt;br/&gt;&lt;code&gt;mysql_set_charset('utf8');&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;mysqli:&lt;br/&gt;&lt;code&gt;mysqli_set_charset($link, 'utf8'); //面向过程风格&lt;br/&gt;$mysql-&amp;gt;set_charset('utf8'); //或者面向对象风格&lt;br/&gt;//也可以使用初始化命令&lt;br/&gt;mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET NAMES utf8'); //面向过程&lt;br/&gt;$mysql-&amp;gt;options(MYSQLI_INIT_COMMAND, 'SET NAMES utf8'); //面向对象&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;PDO:&lt;br/&gt;&lt;code&gt;//使用连接参数，MYSQL_ATTR_INIT_COMMAND 在连接后执行初始化命令，类似于 query 好处是仅在连接后执行一次&lt;br/&gt;$pdo = new PDO("mysql:host=localhost;dbname=dbname",&lt;br/&gt;    'username', 'password', &lt;br/&gt;    array(PDO::MYSQL_ATTR_INIT_COMMAND =&amp;gt; "SET NAMES utf8"));&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;b&gt;Zend_Db&lt;/b&gt;,Zend_Db 没有提供特殊的设置参数，只能使用初始化命令参数, 见 Mysqli 和 PDO 的 INIT_COMMAND:&lt;br/&gt;&lt;code&gt;//PDO 驱动&lt;br/&gt;$params = array(&lt;br/&gt;    'host' =&amp;gt; 'localhost',&lt;br/&gt;    'username' =&amp;gt; 'username',&lt;br/&gt;    'password' =&amp;gt; 'password',&lt;br/&gt;    'dbname' =&amp;gt; 'dbname',&lt;br/&gt;    'driver_options' =&amp;gt; array(PDO::MYSQL_ATTR_INIT_COMMAND =&amp;gt; 'SET NAMES UTF8');&lt;br/&gt;);&lt;br/&gt;$db = Zend_Db::factory('Pdo_Mysql', $params);&lt;br/&gt;&lt;br/&gt;//Mysqli 驱动:&lt;br/&gt;$params = array(&lt;br/&gt;    'host' =&amp;gt; 'localhost',&lt;br/&gt;    'username' =&amp;gt; 'username',&lt;br/&gt;    'password' =&amp;gt; 'password',&lt;br/&gt;    'dbname' =&amp;gt; 'dbname',&lt;br/&gt;    'driver_options' =&amp;gt; array(MYSQLI_INIT_COMMAND =&amp;gt; 'SET NAMES UTF8');&lt;br/&gt;);&lt;br/&gt;$db = Zend_Db::factory('Mysqli', $params);&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=c3da3066-bfbb-442b-87a7-a921d2442f45' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-327543140233018520?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/327543140233018520/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=327543140233018520' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/327543140233018520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/327543140233018520'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/03/php-utf8-mysql.html' title='PHP 中的 UTF8 和 Mysql'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-6924391074188511679</id><published>2009-02-25T15:57:00.001+08:00</published><updated>2009-02-25T16:00:43.544+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>Smarty and Zend_View integrantion</title><content type='html'>聚合使用 smarty&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;require_once ('Zend/View/Abstract.php');&lt;br /&gt;class SmartyView extends Zend_View_Abstract&lt;br /&gt;{&lt;br /&gt;    protected $_smarty;&lt;br /&gt;&lt;br /&gt;    public function __construct($config = array())&lt;br /&gt;    {&lt;br /&gt;        $this-&amp;gt;_smarty = new Smarty();&lt;br /&gt;&lt;br /&gt;        if(!isset($config['compileDir']))&lt;br /&gt;            throw new Exception('compileDir is not set for '.get_class($this));&lt;br /&gt;        else&lt;br /&gt;            $this-&amp;gt;_smarty-&amp;gt;compile_dir = $config['compileDir'];&lt;br /&gt;&lt;br /&gt;        if(isset($config['configDir']))&lt;br /&gt;            $this-&amp;gt;_smarty-&amp;gt;config_dir = $config['configDir'];&lt;br /&gt;&lt;br /&gt;        if(isset($config['pluginsDir']))&lt;br /&gt;            $this-&amp;gt;_smarty-&amp;gt;plugins_dir[] = $config['pluginsDir'];&lt;br /&gt;&lt;br /&gt;        parent::__construct($config);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function __set($key,$val)&lt;br /&gt;    {&lt;br /&gt;        parent::__set($key, $val);&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;assign($key,$val);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function __isset($key)&lt;br /&gt;    {&lt;br /&gt;        $var = $this-&amp;gt;_smarty-&amp;gt;get_template_vars($key);&lt;br /&gt;        if($var)&lt;br /&gt;            return true;&lt;br /&gt;&lt;br /&gt;        return false;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function __unset($key)&lt;br /&gt;    {&lt;br /&gt;        parent::__unset($key);&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;clear_assign($key);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function assign($spec,$value = null)&lt;br /&gt;    {&lt;br /&gt;        if($value === null)&lt;br /&gt;            $this-&amp;gt;_smarty-&amp;gt;assign($spec);&lt;br /&gt;        else&lt;br /&gt;            $this-&amp;gt;_smarty-&amp;gt;assign($spec,$value);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    public function clearVars()&lt;br /&gt;    {&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;clear_all_assign();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected function _run()&lt;br /&gt;    {&lt;br /&gt;        $this-&amp;gt;strictVars(true);&lt;br /&gt;&lt;br /&gt;        //why 'this'?&lt;br /&gt;        //to emulate standard zend view functionality&lt;br /&gt;        //doesn't mess up smarty in any way&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;assign_by_ref('this',$this);&lt;br /&gt;&lt;br /&gt;        $fileFullname = func_get_arg(0);&lt;br /&gt;        $templateDirs = $this-&amp;gt;getScriptPaths();&lt;br /&gt;&lt;br /&gt;        //TODO: find more effective way to get correct template dir&lt;br /&gt;        $templateDir = $templateDirs[0];&lt;br /&gt;        $file = $fileFullname;&lt;br /&gt;        foreach ($templateDirs as $dir) {&lt;br /&gt;            if (preg_match("|^$dir|", $fileFullname)) {&lt;br /&gt;                $templateDir = $dir;&lt;br /&gt;                $file = substr($fileFullname,strlen($templateDir));&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        //$file = substr(func_get_arg(0),strlen($templateDir));&lt;br /&gt;        //var_dump($templateDir, $file);&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;template_dir = $templateDir;&lt;br /&gt;        $this-&amp;gt;_smarty-&amp;gt;compile_id = $templateDir;&lt;br /&gt;&lt;br /&gt;        echo $this-&amp;gt;_smarty-&amp;gt;fetch($file);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;初始化脚本中设置 view&lt;br /&gt;&lt;code&gt;&lt;br /&gt;//Create the view and set the compile dir to template_c&lt;br /&gt;$view = new SmartyView(array(&lt;br /&gt;                'compileDir' =&amp;gt; './template_c'&lt;br /&gt;                ));&lt;br /&gt;&lt;br /&gt;//Create a new ViewRenderer helper and assign our newly&lt;br /&gt;//created SmartyView object as the view instance&lt;br /&gt;$viewHelper = new Zend_Controller_Action_Helper_ViewRenderer($view);&lt;br /&gt;$viewHelper-&amp;gt;setViewSuffix('tpl');&lt;br /&gt;&lt;br /&gt;//Save the helper to the HelperBroker&lt;br /&gt;Zend_Controller_Action_HelperBroker::addHelper($viewHelper);&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-6924391074188511679?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/6924391074188511679/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=6924391074188511679' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6924391074188511679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6924391074188511679'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/02/smarty-and-zendview-integrantion.html' title='Smarty and Zend_View integrantion'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-1122649581106377106</id><published>2009-01-19T00:17:00.003+08:00</published><updated>2009-01-19T00:21:25.863+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPL'/><category scheme='http://www.blogger.com/atom/ns#' term='php5'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>SPL DirectoryIterator</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;DirectoryIterator 提供目录迭代功能。可替换 opendir() 和 dir 伪类功能。&lt;br /&gt;&lt;br /&gt;opendir() 写法:&lt;br /&gt;&lt;code&gt;$path = '.';&lt;br /&gt;if (is_dir($path)) {&lt;br /&gt;    if ($dh = opendir($path)) {&lt;br /&gt;        while (false !== ($file = readdir($dh))) {&lt;br /&gt;            echo "filename: $file \tfiletype: ", filetype($path . $file), "\n";&lt;br /&gt;        }&lt;br /&gt;        closedir($dh);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;dir 伪类写法：&lt;br /&gt;&lt;code&gt;$path = '.';&lt;br /&gt;$dir = dir($path);&lt;br /&gt;while (false !== ($entry = $dir-&amp;gt;read())) {&lt;br /&gt;    echo $entry, "\n";&lt;br /&gt;}&lt;br /&gt;$dir-&amp;gt;close();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;主角出场:&lt;br /&gt;&lt;code&gt;$path = '.';&lt;br /&gt;$dir = new DirectoryIterator($path);&lt;br /&gt;foreach ($dir as $fileinfo) {&lt;br /&gt;    echo 'filename:', $fileinfo-&amp;gt;getFilename(), "\tfiletype:", $fileinfo-&amp;gt;getType(), "\n";&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;参考资料:&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/class.directoryiterator.php"&gt;http://www.php.net/manual/en/class.directoryiterator.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/class.splfileinfo.php"&gt;http://www.php.net/manual/en/class.splfileinfo.php&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.php.net/%7Ehelly/php/ext/spl/"&gt;http://www.php.net/~helly/php/ext/spl/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-1122649581106377106?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/1122649581106377106/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=1122649581106377106' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1122649581106377106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1122649581106377106'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/01/spl-directoryiterator.html' title='SPL DirectoryIterator'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-1887124864094181741</id><published>2009-01-08T23:57:00.003+08:00</published><updated>2009-01-19T00:21:04.696+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPL'/><category scheme='http://www.blogger.com/atom/ns#' term='php5'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>SPL File Object</title><content type='html'>class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIterator&lt;br /&gt;SPL 文件对象继承自 SplFileInfo, 实现了 RecursiveIterator, SeekableIterator 接口。&lt;br /&gt;&lt;br /&gt;一般我们访问文件方式：&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$filename = '/path/ to/file';&lt;br /&gt;$fp = fopen($filename, 'r');&lt;br /&gt;if ($fp) {&lt;br /&gt;    while (!feof($fp)) {&lt;br /&gt;        $text = fgets($fp);&lt;br /&gt;        echo $text;&lt;br /&gt;    }&lt;br /&gt;    fclose($fp);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;利用 SplFileObject 我们可以这么写:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$filename = '/path/ to/file';&lt;br /&gt;$file = new SplFileObject($filename);&lt;br /&gt;$file-&amp;gt;openFile();&lt;br /&gt;foreach ($file as $line) {&lt;br /&gt;    echo $line;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;因为 SplFileObject 实现了RecursiveIterator 迭代器接口， foreach 可以很方便的访问到它。&lt;br /&gt;&lt;br /&gt;写文件:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$filename = '/path/to/file';&lt;br /&gt;$file = new SplFileObject($filename);&lt;br /&gt;$file-&amp;gt;openFile('w');&lt;br /&gt;$file-&amp;gt;fwrite('some text');&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;继承自 SplFileInfo 的一些方法:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;echo '修改时间:', $file-&amp;gt;getMTime(), "\n";&lt;br /&gt;echo '所在路径:', $file-&amp;gt;getPath(), "\n";&lt;br /&gt;echo '文件名:', $file-&amp;gt;getFilename(), "\n";&lt;br /&gt;echo '全路径(路径+文件名):', $file-&amp;gt;getPathname(), "\n";&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;更多方法请参考 &lt;a href="http://www.php.net/%7Ehelly/php/ext/spl/"&gt;Spl 文档&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-1887124864094181741?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/1887124864094181741/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=1887124864094181741' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1887124864094181741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1887124864094181741'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2009/01/spl-file-object.html' title='SPL File Object'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-8841442049770856609</id><published>2008-11-24T00:38:00.001+08:00</published><updated>2008-11-24T23:01:10.835+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='多进程'/><category scheme='http://www.blogger.com/atom/ns#' term='Console'/><title type='text'>PHP 命令行 fork 多进程处理</title><content type='html'>很多人认为 PHP 没有多线程和多进程处理能力，其实 PHP 有多种运行模式。作为在作 web 应用的时候通常运行于 cgi 或者 web api 模块模式，web 服务器本身多进程或线程方式运行。而 PHP 在 cli 命令行模式下则有能力使用 fork 产生子进程(Windows 环境不可用)。本文将论述这种情况。&lt;br /&gt;&lt;br /&gt;PHP 的进程控制支持实现了 Unix 类型的进程创建、程序执行、信号处理和进程终止。在 web 服务环境中不应该启用进程控制，如果在 web 服务环境中使用进程控制功能可能导致不可预料的结果。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;int pcntl_fork(void)&lt;/code&gt;&lt;br /&gt;fork 的意思是叉子，分岔路口。同样程序在这里分叉 ^_^。fork() 函数执行后，系统会将当前进程复制一份，子进程和父进程的差别只有 PID(进程号) 和 PPID(父进程号)不同。也就是说，这一点开始除了PID和PPID，子进程和父进程有同样的数据，也正在同样的控制流程中。所以注意一点，如果父进程在循环中fork(), 那么子进程也在循环中。&lt;br /&gt;分叉点在这儿，fork()返回值：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;父进程从 fork() 得到的返回值是子进程的PID，&amp;nbsp;&lt;/li&gt;&lt;li&gt;子进程从 fork() 得到的返回值是 0，&lt;/li&gt;&lt;li&gt;如果父进程得到返回值是 -1 表示有错误发生，比如系统资源耗尽导致无法创建子进程。&lt;/li&gt;&lt;/ul&gt;因为创建的是进程，而每个进程的空间是相互独立的，所以在fork()这一刻子进程和父进程拥有相同的数据和状态，随后各自独立运行，改变的数据和状态不会相互影响。&lt;br /&gt;&lt;code&gt;$pid = pcntl_fork();&lt;br /&gt;if ($pid == -1) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; die('could not fork');&lt;br /&gt;} else if ($pid) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // we are the parent&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pcntl_wait($status); //Protect against Zombie children&lt;br /&gt;} else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // we are the child&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;［未完待续……］&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-8841442049770856609?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/8841442049770856609/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=8841442049770856609' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/8841442049770856609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/8841442049770856609'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2008/11/php-fork.html' title='PHP 命令行 fork 多进程处理'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-2900642107724613770</id><published>2008-08-18T22:31:00.005+08:00</published><updated>2008-08-18T23:20:43.956+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Type Casting in PHP</title><content type='html'>&lt;h3&gt;PHP 中的类型声明&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;允许的声明有:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;(int), (integer) - cast to &lt;a href="http://www.php.net/manual/en/language.types.integer.php"&gt;integer&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(bool), (boolean) - cast to &lt;a href="http://www.php.net/manual/en/language.types.boolean.php"&gt;boolean&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(float), (double), (real) - cast to &lt;a href="http://www.php.net/manual/en/language.types.float.php"&gt;float&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(string) - cast to &lt;a href="http://www.php.net/manual/en/language.types.string.php"&gt;string&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(binary) - cast to binary &lt;a href="http://www.php.net/manual/en/language.types.string.php"&gt;string&lt;/a&gt; (PHP 6)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(array) - cast to &lt;a href="http://www.php.net/manual/en/language.types.array.php"&gt;array&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(object) - cast to &lt;a href="http://www.php.net/manual/en/language.types.object.php"&gt;object&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;(unset) - cast to &lt;a href="http://www.php.net/manual/en/language.types.null.php"&gt;NULL&lt;/a&gt; (PHP 5)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;一些有用(有趣)的特性:&lt;br /&gt;(bool),(boolean), 当然，这个通常不用去显示声明，在需要的时候自动会转换。这里要说的是值如何转换：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;布尔值&lt;strong&gt;&lt;tt&gt;FALSE&lt;/tt&gt;&lt;/strong&gt;本身&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;整数 0 (零)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;浮点数 0.0 (零)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;空字符串 '' 和 字符串 '0' (零)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;空数组(没有任何元素的数组)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;没有任何成员的对象(仅 PHP 4)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;特殊类型 NULL (包括 unset 的变量)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;从空标记创建的 SimpleXML 对象 (也就是不会有任何节点)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;除此以外的任何值都是 TRUE&lt;br /&gt;&lt;br /&gt;(string), 用于对象时，会调用对象的 __toString() 魔术方法（PHP5.2+可以正确调用， 更早版本不会）&lt;br /&gt;(object), 用于数组时，可以把数组转化为对象，键作为对象的属性&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$foo = array('bar' =&amp;gt; 'foobar');                                 &lt;br /&gt;var_dump((object)$foo);&lt;br /&gt;&lt;br /&gt;//输出&lt;br /&gt;object(stdClass)#1 (1) {&lt;br /&gt; ["bar"]=&amp;gt; string(6) "foobar"&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(array), 作用于对象时&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$foo = new stdClass();&lt;br /&gt;$foo-&amp;gt;bar = 'foobar';&lt;br /&gt;var_dump((array)$foo);&lt;br /&gt;&lt;br /&gt;//输出&lt;br /&gt;array(1) {&lt;br /&gt; ["bar"]=&amp;gt; string(6) "foobar"&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-2900642107724613770?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/2900642107724613770/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=2900642107724613770' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/2900642107724613770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/2900642107724613770'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2008/08/type-casting-in-php.html' title='Type Casting in PHP'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-6427990405276696205</id><published>2008-07-24T22:08:00.008+08:00</published><updated>2008-07-25T00:43:40.498+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='应用'/><title type='text'>Obfuscate e-mail addresses</title><content type='html'>&lt;h3&gt;防止e-mail地址被垃圾邮件收集的方法&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;原文的作者 Silvan Mühlemann 花了一年半的时间收集数据比较九种不同的方法。&lt;br /&gt;&lt;br /&gt;以下是3中有效的方法：&lt;br /&gt;&lt;br /&gt;1. 用 CSS 改变文字方向&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt; &lt;br /&gt;span.codedirection { unicode-bidi:bidi-override; direction: rtl; } &lt;br /&gt;&amp;lt;/style&amp;gt; &lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;span class="codedirection"&amp;gt;moc.liamg@77uohcnek&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2. 用 CSS display:none&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt; &lt;br /&gt;p span.displaynone { display:none; } &lt;br /&gt;&amp;lt;/style&amp;gt; &lt;br /&gt;&amp;lt;p&amp;gt;kenchou77@&amp;lt;span class="displaynone"&amp;gt;null&amp;lt;/span&amp;gt;gmail.com&amp;lt;/p&amp;gt;&lt;br /&gt;或者直接 inline css&lt;br /&gt;&amp;lt;p&amp;gt;kenchou77@&amp;lt;span style="display:none"&amp;gt;null&amp;lt;/span&amp;gt;gmail.com&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;3. ROT13 加密&lt;br /&gt;&lt;br /&gt;ROT13 简单的位移13个字母，加密和解密方法相同。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;  &lt;br /&gt;document.write("xrapubh77@tznvy.pbz".replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c&amp;lt;="Z"?90:122)&amp;gt;=(c=c.charCodeAt(0)+13)?c:c-26);}));&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;原文地址：http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-6427990405276696205?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/' title='Obfuscate e-mail addresses'/><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/6427990405276696205/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=6427990405276696205' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6427990405276696205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6427990405276696205'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2008/07/obfuscate-e-mail-addresses.html' title='Obfuscate e-mail addresses'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-2458970223502259763</id><published>2008-03-18T10:34:00.001+08:00</published><updated>2008-03-18T10:34:13.884+08:00</updated><title type='text'>Zend Framework 1.5 is now available!</title><content type='html'>&lt;p&gt;We couldn't be happier to announce that Zend Framework 1.5 is now   &lt;br /&gt;available    &lt;br /&gt;from the Zend Framework download site!    &lt;br /&gt;&lt;a href="http://framework.zend.com/download"&gt;http://framework.zend.com/download&lt;/a&gt;    &lt;br /&gt;An overview of new features in 1.5:    &lt;br /&gt;* New Zend_Form component with support for AJAX-enabled form elements    &lt;br /&gt;* New action and view helpers for automating and facilitating AJAX    &lt;br /&gt;requests and alternate response formats    &lt;br /&gt;* Infocard, OpenID, and LDAP authentication adapters    &lt;br /&gt;* Support for complex Lucene searches, including fuzzy, date-range, and    &lt;br /&gt;wildcard queries    &lt;br /&gt;* Support for Lucene 2.1 index file format    &lt;br /&gt;* Partial, Placeholder, Action, and Header view helpers for advanced    &lt;br /&gt;view composition and rendering    &lt;br /&gt;* New Zend_Layout component for automating and facilitating site layouts    &lt;br /&gt;* UTF-8 support for PDF documents    &lt;br /&gt;* New Nirvanix, Technorati, and SlideShare web services    &lt;br /&gt;There are a lot of people to thank, since there are a lot of people who    &lt;br /&gt;worked very hard to make this happen. First of all, thanks to all the    &lt;br /&gt;Zend Framework contributors who helped in all kinds of ways to make this    &lt;br /&gt;a truly great, high-quality release. I would personally like to thank    &lt;br /&gt;the Zend Framework team here at Zend for working the long hours this    &lt;br /&gt;weekend to make sure everything came together on Monday morning. There    &lt;br /&gt;were also some very selfless souls in marketing who stayed up late over    &lt;br /&gt;the last few days to make sure the site was at its best in both style    &lt;br /&gt;and substance for the big day. Finally we'd like to thank all the ZF    &lt;br /&gt;users out there who inspire us to continue improving Zend Framework and    &lt;br /&gt;who never fail to keep us on our toes. :) We hope this release not only    &lt;br /&gt;lives up to your high expectations but goes beyond them.    &lt;br /&gt;Now we can finally say that we wholeheartedly recommend the 1.5 release    &lt;br /&gt;for production use.    &lt;br /&gt;Enjoy ZF 1.5!&lt;/p&gt;  &lt;p&gt;,Wil&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-2458970223502259763?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/2458970223502259763/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=2458970223502259763' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/2458970223502259763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/2458970223502259763'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2008/03/zend-framework-15-is-now-available.html' title='Zend Framework 1.5 is now available!'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-7495209530967098180</id><published>2007-08-14T22:45:00.002+08:00</published><updated>2008-11-20T12:02:58.573+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phpUnit'/><title type='text'>PHP Unit 安装</title><content type='html'>1. 安装&lt;br /&gt;  方法一：通过 PEAR 安装&lt;br /&gt;pear channel-discover pear.phpunit.de&lt;br /&gt;pear install phpunit/PHPUnit&lt;br /&gt;&lt;br /&gt;  方法二：&lt;br /&gt;  1.下载压缩包，解压，设置 include_path&lt;br /&gt;  2. 将 pear-phpunit 脚本改名为 phpunit&lt;br /&gt;  3. 将脚本中 @php_bin@ 替换为 php 命令行解析器&lt;br /&gt;  4. 拷贝到 PATH 能搜索到的目录，或者 在 PATH 添加相应目录。&lt;br /&gt;  5. linux下添加执行属性 (chmod +x phpunit)&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-7495209530967098180?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/7495209530967098180/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=7495209530967098180' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/7495209530967098180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/7495209530967098180'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/08/php-unit.html' title='PHP Unit 安装'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-4790535637791769437</id><published>2007-07-09T10:52:00.007+08:00</published><updated>2009-01-19T00:20:16.784+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPL'/><category scheme='http://www.blogger.com/atom/ns#' term='php5'/><category scheme='http://www.blogger.com/atom/ns#' term='设计模式'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>Observer pattern</title><content type='html'>&lt;h3&gt;观察者模式 Observer Pattern&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单：一个对象通过添加一个方法（该方法允许另一个对象，即&lt;i&gt;观察者&lt;/i&gt; 注册自己）使本身变得可观察。当可观察的对象更改时，它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话，而不必了解原因。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;SPL 提供的 Observer 接口:&lt;br /&gt;观察者：&lt;br /&gt;&lt;code&gt;SplObserver::update(SplSubject $subject)&lt;br /&gt;观察者接口，由被观察对象调用。&lt;/code&gt;&lt;br /&gt;主题（被观察者）：&lt;br /&gt;&lt;code&gt;SplSubject::attach(SplObserver $observer)&lt;br /&gt;参数:&lt;br /&gt;        $observer 要添加的观察者&lt;br /&gt;&lt;br /&gt;SplSubject::detach(SplObserver $observer)&lt;br /&gt;参数:&lt;br /&gt;        $observer 要删除的观察者&lt;br /&gt;&lt;br /&gt;SplSubject::notify()&lt;br /&gt;  通知所有观察者.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-4790535637791769437?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/4790535637791769437/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=4790535637791769437' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/4790535637791769437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/4790535637791769437'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/07/observer-pattern.html' title='Observer pattern'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-7113043461579416827</id><published>2007-06-13T20:46:00.001+08:00</published><updated>2008-07-25T00:09:00.588+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php5'/><category scheme='http://www.blogger.com/atom/ns#' term='设计模式'/><title type='text'>The Template Method Pattern in PHP 5</title><content type='html'>&lt;h2&gt;php5模板方法模式&lt;/h2&gt;&lt;br /&gt;节选翻译，原文: http://www.zend.com/zend/php5/php5-OOP.php&lt;br /&gt;&lt;br /&gt;什么是模板方法模式？定义一个操作中算法的骨架,将一些步骤的执行放到其子类中.&lt;br /&gt;这是一种重要的代码重用技术。模板方法模式通常用在类库中提取类的共同的行为。&lt;br /&gt;模板方法设计模式可以让子类去重新定义一个操作中的某些步骤，而不用去改变这个操作的结构。&lt;br /&gt;这些可重新定义的步骤可以在基类中标为强制的或者可选的。由于这些步骤都会归于单独的方法，所以子类必须为强制的步骤提供一个实现方法，可选的则可以忽略。&lt;br /&gt;&lt;br /&gt;模板方法可以实现一个操作中不变的部分，把那些可能变化的行为留给子类实现。也可以用于仅在在指定点提供hook操作来给子类扩展行为。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;例子&lt;/h3&gt;&lt;br /&gt;&lt;h4&gt;Listing 1. AbstractClass.php&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Listing 1 显示了一个迷你的模板方法，叫做 templateMethod()。它使用了两个方法：mandatoryOperation() 和 optionalOperation(), 这两个可以在子类中重定义。&lt;br /&gt;&lt;code&gt;    abstract class AbstractClass {&lt;br /&gt;        public final function templateMethod() {&lt;br /&gt;            print "AbstractClass::templateMethod() called.\n";&lt;br /&gt;            &lt;br /&gt;            $this-&gt;mandatoryOperation();&lt;br /&gt;            $this-&gt;optionalOperation();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected abstract function mandatoryOperation();&lt;br /&gt;&lt;br /&gt;        protected function optionalOperation() {&lt;br /&gt;        }&lt;br /&gt;    }&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Listing 2: ConcreteClass.php&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Listing 2 显示了一个和 AbstractClass 类对应的子类。 ConcreteClass 重定义了mandatoryOperation() 和 optionalOperation() 方法。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;    require_once 'AbstractClass.php';&lt;br /&gt;&lt;br /&gt;    class ConcreteClass extends AbstractClass {&lt;br /&gt;        protected function mandatoryOperation() {&lt;br /&gt;            print "ConcreteClass::mandatoryOperation() called.\n";&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected function optionalOperation() {&lt;br /&gt;            print "ConcreteClass::optionalOperation() called.\n";&lt;br /&gt;        }&lt;br /&gt;    }&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Listing 3: example.php&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;最后, Listing 3 显示了如何调用 ConcreteClass 。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;    require_once 'ConcreteClass.php';&lt;br /&gt;&lt;br /&gt;    $o = new ConcreteClass;&lt;br /&gt;    $o-&gt;templateMethod();&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;输出：&lt;br /&gt;&lt;code&gt;AbstractClass::templateMethod() called.&lt;br /&gt;ConcreteClass::mandatoryOperation() called.&lt;br /&gt;ConcreteClass::optionalOperation() called. &lt;/code&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-7113043461579416827?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.zend.com/zend/php5/php5-OOP.php' title='The Template Method Pattern in PHP 5'/><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/7113043461579416827/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=7113043461579416827' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/7113043461579416827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/7113043461579416827'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/06/template-method-pattern-in-php-5.html' title='The Template Method Pattern in PHP 5'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-5865498055511524221</id><published>2007-06-03T11:30:00.000+08:00</published><updated>2007-06-03T11:39:55.392+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Console'/><title type='text'>使用 Zend_Console_Getopt 处理 PHP 命令行</title><content type='html'>Linux 下写Shell只要在第一行加上&lt;br /&gt;#!/path/to/php&lt;br /&gt;然后将脚本加上执行属性即可 chmod +x&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;注意:Windows下编程再上传的朋友要注意。换行必须以linux格式，否则脚本会报错&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;require_once 'Zend/Console/Getopt.php';&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;定义规则:&lt;br /&gt;&lt;br /&gt;使用短语&lt;br /&gt;&lt;code&gt;$opts = new Zend_Console_Getopt('abp:');&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;使用长语法&lt;br /&gt;&lt;code&gt;$opts = new Zend_Console_Getopt(&lt;br /&gt;    array(&lt;br /&gt;        'apple|a'    =&gt; 'This option chooses apple, with no parameter',&lt;br /&gt;        'banana|b=i' =&gt; 'This option chooses banana, with required integer parameter',&lt;br /&gt;        'pear|p-s'   =&gt; 'This option chooses pear, with optional string parameter'&lt;br /&gt;)&lt;br /&gt;);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;捕获异常&lt;br /&gt;&lt;code&gt;try {&lt;br /&gt;    $opts = new Zend_Console_Getopt('abp:');&lt;br /&gt;    $opts-&gt;parse();&lt;br /&gt;} catch (Zend_Console_Getopt_Exception $e) {&lt;br /&gt;    echo $e-&gt;getUsageMessage();&lt;br /&gt;    exit;&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;获取命令行选项和参数&lt;br /&gt;&lt;code&gt;$b = $opts-&gt;getOption('b');&lt;br /&gt;$p = $opts-&gt;getOption('p');&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;另一种方法是使用 __get() and __isset() 魔术方法&lt;br /&gt;&lt;code&gt;if (isset($opts-&gt;b)) {&lt;br /&gt;   echo "I got the b option.\n";&lt;br /&gt;}&lt;br /&gt;$p = $opts-&gt;p; // null if not set&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-5865498055511524221?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/5865498055511524221/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=5865498055511524221' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/5865498055511524221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/5865498055511524221'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/06/zendconsolegetopt-php.html' title='使用 Zend_Console_Getopt 处理 PHP 命令行'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-1591563080757777572</id><published>2007-04-21T10:16:00.000+08:00</published><updated>2007-04-21T11:50:57.086+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='概念'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>概念: interface 和 abstract class 的区别</title><content type='html'>&lt;span style="font-weight: bold;"&gt;什么是 abstract class&lt;/span&gt;&lt;br /&gt;PHP 5 引入抽象类和方法。抽象类不能被实例化。任何类只要包含有抽象方法（即使只有一个抽象方法）就必须也被定义为抽象。定义为抽象的方法只需要简单的声明而不用实现。&lt;br /&gt;从抽象类继承的时候，所有父类中标记为抽象方法的声明都必须在子类中定义；此外，这些方法还必须用相同的（或更弱的）访问控制。比如，如果抽象方法定义为保护(protected)，函数实现必须被定义为protected或者public&lt;br /&gt;&lt;br /&gt;抽象类例子：&lt;br /&gt;&lt;code&gt;abstract class AbstractClass&lt;br /&gt;{&lt;br /&gt;    // Force Extending class to define this method&lt;br /&gt;    abstract protected function getValue();&lt;br /&gt;    abstract protected function prefixValue($prefix);&lt;br /&gt;&lt;br /&gt;    // Common method&lt;br /&gt;    public function printOut() {&lt;br /&gt;        print $this-&amp;gt;getValue() . "\n";&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class ConcreteClass1 extends AbstractClass&lt;br /&gt;{&lt;br /&gt;    protected function getValue() {&lt;br /&gt;        return "ConcreteClass1";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function prefixValue($prefix) {&lt;br /&gt;        return "{$prefix}ConcreteClass1";&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class ConcreteClass2 extends AbstractClass&lt;br /&gt;{&lt;br /&gt;    public function getValue() {&lt;br /&gt;        return "ConcreteClass2";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function prefixValue($prefix) {&lt;br /&gt;        return "{$prefix}ConcreteClass2";&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$class1 = new ConcreteClass1;&lt;br /&gt;$class1-&amp;gt;printOut();&lt;br /&gt;echo $class1-&amp;gt;prefixValue('FOO_') ."\n";&lt;br /&gt;&lt;br /&gt;$class2 = new ConcreteClass2;&lt;br /&gt;$class2-&amp;gt;printOut();&lt;br /&gt;echo $class2-&amp;gt;prefixValue('FOO_') ."\n";&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;什么是 interface&lt;/span&gt;&lt;br /&gt;Object Interface 对象接口允许你创建这种代码，一个类必须实现的指定方法，而又不必定义这些方法如何处理。接口使用interface关键字定义，和标准类定义一样，但是任何方法都没有内容。接口内所有的方法声明都必须为公开(public)，这是接口的本质（呵呵，所谓接口嘛，就是用于交互的）。&lt;br /&gt;实现&lt;br /&gt;要实现一个接口，使用 implements 操作符。接口中的所有方法都必须在一个类中实现；不这么做会导致一个致命错误(fatal error)。 如果想要的话，使用逗号分隔每个接口，一个类可以实现多个接口。&lt;br /&gt;注意：一个类不能实现两个有同样函数名的接口，因为这导致这个函数的含义模糊。&lt;br /&gt;&lt;br /&gt;接口的例子:&lt;br /&gt;&lt;code&gt;// Declare the interface 'iTemplate'&lt;br /&gt;interface iTemplate&lt;br /&gt;{&lt;br /&gt;  public function setVariable($name, $var);&lt;br /&gt;  public function getHtml($template);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Implement the interface&lt;br /&gt;// This will work&lt;br /&gt;class Template implements iTemplate&lt;br /&gt;{&lt;br /&gt;  private $vars = array();&lt;br /&gt;&lt;br /&gt;  public function setVariable($name, $var)&lt;br /&gt;  {&lt;br /&gt;    $this-&amp;gt;vars[$name] = $var;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public function getHtml($template)&lt;br /&gt;  {&lt;br /&gt;    foreach($this-&amp;gt;vars as $name =&amp;gt; $value) {&lt;br /&gt;        $template = str_replace('{' . $name . '}', $value, $template);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return $template;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// This will not work&lt;br /&gt;// Fatal error: Class BadTemplate contains 1 abstract methods&lt;br /&gt;// and must therefore be declared abstract (iTemplate::getHtml)&lt;br /&gt;class BadTemplate implements iTemplate&lt;br /&gt;{&lt;br /&gt;  private $vars = array();&lt;br /&gt;&lt;br /&gt;  public function setVariable($name, $var)&lt;br /&gt;  {&lt;br /&gt;    $this-&amp;gt;vars[$name] = $var;&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;实现多个接口：&lt;br /&gt;&lt;code&gt;class MyClass implements anInterface, anotherInterface {&lt;br /&gt;  //...&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;如果想要继承一个类并实现一个接口，先使用“extends”然后“implements”:&lt;br /&gt;&lt;code&gt;class MyChildClass extends MyParentClass implements MyInterface&lt;br /&gt;{&lt;br /&gt;  // definition&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;interface 和 abstract class 的区别&lt;/span&gt;&lt;br /&gt;PHP 5 中类没有多重继承，但可以实现多个接口。这应该是接口的主要用途。这点和Java类似，和C++不同。应该是学java，对多重继承的一种解决方式吧。&lt;br /&gt;&lt;br /&gt;代码形式上来说，接口只是一个声明，其方法没有任何实现代码；抽象类的方法既可以没有实现代码，也可以拥有实现代码。&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-1591563080757777572?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/1591563080757777572/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=1591563080757777572' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1591563080757777572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/1591563080757777572'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/04/interface-abstract-class.html' title='概念: interface 和 abstract class 的区别'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-547672304067118884</id><published>2007-04-10T16:54:00.000+08:00</published><updated>2007-06-03T11:40:54.096+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zend Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>使用模块设计 Zend Framework 控制器</title><content type='html'>启动文件：基本上一样，唯一的区别：&lt;br /&gt;&lt;code&gt;//$frontController-&gt;setControllerDirectory('./application/controllers');&lt;br /&gt;//将原来的设置控制器目录改成以下方式：&lt;br /&gt;$frontController-&gt;setControllerDirectory(array(&lt;br /&gt; 'default' =&gt; './application/controllers/',&lt;br /&gt; 'admin'   =&gt; './application/controllers/admin/')&lt;br /&gt;);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;index.php&lt;br /&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt; * Bootstrap file&lt;br /&gt; */&lt;br /&gt;error_reporting(E_ALL|E_STRICT);&lt;br /&gt;date_default_timezone_set('Asia/Shanghai');&lt;br /&gt;&lt;br /&gt;set_include_path('.' . PATH_SEPARATOR . '../library/'&lt;br /&gt;. PATH_SEPARATOR . './application/models'&lt;br /&gt;. get_include_path());&lt;br /&gt;&lt;br /&gt;require_once "Zend/Loader.php";&lt;br /&gt;// autoload class&lt;br /&gt;spl_autoload_register(array('Zend_Loader', 'autoload'));&lt;br /&gt;&lt;br /&gt;// load configuration&lt;br /&gt;$config = new Zend_Config_Ini('./application/config.ini', 'general');&lt;br /&gt;Zend_Registry::set('config', $config);&lt;br /&gt;&lt;br /&gt;// setup database&lt;br /&gt;$db = Zend_Db::factory($config-&gt;db-&gt;adapter, $config-&gt;db-&gt;config-&gt;asArray());&lt;br /&gt;&lt;br /&gt;Zend_Db_Table::setDefaultAdapter($db);&lt;br /&gt;&lt;br /&gt;// register the view we are going to use&lt;br /&gt;$view = new Zend_View();&lt;br /&gt;$view-&gt;setScriptPath('./application/views');&lt;br /&gt;Zend_Registry::set('view', $view);&lt;br /&gt;&lt;br /&gt;$auth = Zend_Auth::getInstance();&lt;br /&gt;&lt;br /&gt;// setup controller&lt;br /&gt;$baseUrl = substr($_SERVER['PHP_SELF'], 0,&lt;br /&gt;strpos($_SERVER['PHP_SELF'], '/index.php'));&lt;br /&gt;$frontController = Zend_Controller_Front::getInstance();&lt;br /&gt;$frontController-&gt;setBaseUrl($baseUrl);&lt;br /&gt;$frontController-&gt;throwExceptions(true);&lt;br /&gt;&lt;br /&gt;$frontController-&gt;setControllerDirectory(array(&lt;br /&gt; 'default' =&gt; './application/controllers/',&lt;br /&gt; 'admin'   =&gt; './application/controllers/admin/')&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// run!&lt;br /&gt;$frontController-&gt;dispatch();&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;default模块:&lt;br /&gt;在application/controllers目录下的IndexController.php原来一样设计，不需要改动:&lt;br /&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class IndexController extends Zend_Controller_Action&lt;br /&gt;{&lt;br /&gt;    public function init()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function indexAction()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function otherAction()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;admin模块：&lt;br /&gt;在application/controllers/admin目录下的IndexController.php是这样的。注意类名:admin_IndexController, 这符合目录-类名转换的约定。&lt;br /&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class admin_IndexController extends Zend_Controller_Action&lt;br /&gt;{&lt;br /&gt;    public function init()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function indexAction()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function otherAction()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;好了，大功告成，就这么多。&lt;br /&gt;访问的时候和原来是一样的。&lt;br /&gt;http://localhost/  访问默认模块index控制器indexAction() application/controllers/IndexController.php&lt;br /&gt;http://localhost/admin 访问admin模块index控制器indexAction() application/controllers/admin/IndexController.php&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-547672304067118884?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/547672304067118884/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=547672304067118884' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/547672304067118884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/547672304067118884'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/04/zend-framework.html' title='使用模块设计 Zend Framework 控制器'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-6691043847188261475</id><published>2007-03-20T12:20:00.000+08:00</published><updated>2007-03-20T12:33:58.443+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='安装'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP 安装</title><content type='html'>PHP 安装&lt;br /&gt;这篇文章为新手准备。&lt;br /&gt;其实详细信息PHP安装文档中都已经详细说明了。&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Unix下安装：&lt;br /&gt;&lt;code&gt;&lt;br /&gt;1.  gzip -d httpd-2_0_NN.tar.gz&lt;br /&gt;2.  tar xvf httpd-2_0_NN.tar&lt;br /&gt;3.  gunzip php-NN.tar.gz&lt;br /&gt;4.  tar -xvf php-NN.tar&lt;br /&gt;5.  cd httpd-2_0_NN&lt;br /&gt;6.  ./configure --enable-so&lt;br /&gt;7.  make&lt;br /&gt;8.  make install&lt;br /&gt;&lt;br /&gt;  现在已经将 Apache 2.0.NN 安装在 /usr/local/apache。本安装支持可装载模块&lt;br /&gt;  和标准的 MPM prefork。之后，可以使用如下命令启动 Apache 服务器：&lt;br /&gt;  /usr/local/apache2/bin/apachectl start&lt;br /&gt;  如果成功，可以停止 Apache 服务器并继续安装 PHP：&lt;br /&gt;  /usr/local/apache2/bin/apachectl stop.&lt;br /&gt;&lt;br /&gt;9.  cd ../php4-NN&lt;br /&gt;&lt;br /&gt;10. 现在需要配置 PHP。在这里可以用各种各样的参数来自定义PHP，例如启动哪些&lt;br /&gt;  扩展功能包的支持等。用 ./configure --help 命令可以列出当前可用的所有参&lt;br /&gt;  数。在此例中，将给出一个在有 MySQL 支持的 Apache 2 上进行配置的范例。&lt;br /&gt;  用户本地的 apxs 的路径可能会不同，事实上，在用户的系统中，它可能被命名为&lt;br /&gt;  apxs2。&lt;br /&gt;&lt;br /&gt;  ./configure --with-apxs2=/usr/local/apache2/bin/apxs&lt;br /&gt;&lt;br /&gt;11. make&lt;br /&gt;12. make install&lt;br /&gt;&lt;br /&gt;  如果决定在安装后改变配置选项，只需重复最后的三步，然后需要重新启动 Apache&lt;br /&gt;  使新模块生效。无需重新编译。&lt;br /&gt;&lt;br /&gt;  请注意，除非明确有提示，否则“make install”命令将安装 PEAR、各种 PHP 工具&lt;br /&gt;  诸如 phpize，安装 PHP CLI 等等。&lt;br /&gt;&lt;br /&gt;13. 配置 php.ini&lt;br /&gt;&lt;br /&gt;  cp php.ini-dist /usr/local/lib/php.ini&lt;br /&gt;&lt;br /&gt;  可以编辑 php.ini 文件以修改 PHP 的选项。如果想要把此文件放到另外的位置，&lt;br /&gt;  需要在步骤 10 添加 --with-config-file-path=/path 选项。&lt;br /&gt;&lt;br /&gt;  如果选择 php.ini -recommended，请务必阅读其中的变更的列表，它们将影响&lt;br /&gt;  PHP 的执行。&lt;br /&gt;&lt;br /&gt;14. 编辑 httpd.conf 文件以调用 PHP 模块。LoadMolude 表达式右边的路径必须指向&lt;br /&gt;  系统中的 PHP。以上的 make install 命令可能已经完成了这些，但务必要检查。&lt;br /&gt;&lt;br /&gt;  对于 PHP 4：&lt;br /&gt;     LoadModule php4_module modules/libphp4.so&lt;br /&gt;&lt;br /&gt;  对于 PHP 5：&lt;br /&gt;     LoadModule php5_module modules/libphp5.so&lt;br /&gt;&lt;br /&gt;15. 告知 Apache 将特定的扩展名解析成 PHP，例如，让 Apache 将扩展名 .php&lt;br /&gt;  解析成 PHP。可以将任何扩展名指定为 PHP，只需添加它们，每一个用空格分隔。&lt;br /&gt;  例如，要添加 .phtml：&lt;br /&gt;&lt;br /&gt;  AddType application/x-httpd-php .php .phtml&lt;br /&gt;&lt;br /&gt;  通常还将 .phps 扩展名设置成显示高亮的 PHP 源文件，可以这样来完成：&lt;br /&gt;&lt;br /&gt;  AddType application/x-httpd-php-source .phps&lt;br /&gt;&lt;br /&gt;16. 启动 Apache 服务器：&lt;br /&gt; /usr/local/apache2/bin/apachectl start&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Windows下安装:&lt;br /&gt;将以下两行加入到 Apache 的 httpd.conf 配置文件中设定 Apache 2.0 的 PHP 模块&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# 对 PHP 4 用这两行：&lt;br /&gt;LoadModule php4_module "c:/php/php4apache2.dll"&lt;br /&gt;# 别忘了从 sapi 目录中把 php4apache2.dll 拷贝出来！&lt;br /&gt;AddType application/x-httpd-php .php&lt;br /&gt;&lt;br /&gt;# 对 PHP 5 用这两行：&lt;br /&gt;LoadModule php5_module "c:/php/php5apache2.dll"&lt;br /&gt;AddType application/x-httpd-php .php&lt;br /&gt;&lt;br /&gt;# 配置 php.ini 的路径&lt;br /&gt;PHPIniDir "C:/php"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;参考资料：&lt;br /&gt;&lt;a href="http://www.php.net/manual/zh/install.php"&gt;http://www.php.net/manual/zh/install.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-6691043847188261475?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/6691043847188261475/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=6691043847188261475' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6691043847188261475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6691043847188261475'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/03/php.html' title='PHP 安装'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-6885024539603878175</id><published>2007-03-18T14:30:00.000+08:00</published><updated>2007-04-21T11:50:07.009+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='概念'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>概念: 构造函数和析构函数</title><content type='html'>构造函数和析构函数&lt;br /&gt;构造函数&lt;br /&gt;void __construct ( [mixed args [, ...]] )&lt;br /&gt;&lt;br /&gt;PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建对象时先调用此方法，所以非常适合在使用对象之前做一些初始化工作。&lt;br /&gt;&lt;br /&gt;  注: 如果子类中定义了构造函数则不会暗中调用其父类的构造函数。要执行父类的构造函数，需要在子类的构造函数中调用 parent::__construct()。&lt;br /&gt;&lt;br /&gt;例子 19-6. 使用新标准的构造函数&lt;br /&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class BaseClass {&lt;br /&gt; function __construct() {&lt;br /&gt;     print "In BaseClass constructor\n";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class SubClass extends BaseClass {&lt;br /&gt; function __construct() {&lt;br /&gt;     parent::__construct();&lt;br /&gt;     print "In SubClass constructor\n";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$obj = new BaseClass();&lt;br /&gt;$obj = new SubClass();&lt;br /&gt;?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;为了实现向后兼容性，如果 PHP 5 在类中找不到 __construct() 函数，它就会尝试寻找旧式的构造函数，也就是和类同名的函数。因此唯一会产生兼容性问题的情况是：类中已有一个名为 __construct() 的方法，但它却又不是构造函数。&lt;br /&gt;析构函数&lt;br /&gt;void __destruct ( void )&lt;br /&gt;&lt;br /&gt;PHP 5 引入了析构函数的概念，这类似于其它面向对象的语言，如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。&lt;br /&gt;&lt;br /&gt;例子 19-7. 析构函数示例&lt;br /&gt;&lt;code&gt;&amp;lt;?php&lt;br /&gt;class MyDestructableClass {&lt;br /&gt; function __construct() {&lt;br /&gt;     print "In constructor\n";&lt;br /&gt;     $this-&gt;name = "MyDestructableClass";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; function __destruct() {&lt;br /&gt;     print "Destroying " . $this-&gt;name . "\n";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$obj = new MyDestructableClass();&lt;br /&gt;?&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;和构造函数一样，父类的析构函数不会被引擎暗中调用。要执行父类的析构函数，必须在子类的析构函数体中显式调用 parent::__destruct()。&lt;br /&gt;&lt;br /&gt;  注: 析构函数在脚本关闭时调用，此时所有的头信息已经发出。&lt;br /&gt;&lt;br /&gt;  注: 试图在析构函数中抛出一个异常会导致致命错误。&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-6885024539603878175?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/6885024539603878175/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=6885024539603878175' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6885024539603878175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/6885024539603878175'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/03/blog-post.html' title='概念: 构造函数和析构函数'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-32548984.post-5295149629026252199</id><published>2007-01-29T18:36:00.001+08:00</published><updated>2007-01-29T18:36:43.225+08:00</updated><title type='text'>转换到新版Blogger</title><content type='html'>Hello, world!&lt;div class="blogger-post-footer"&gt;--- end of text ---&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32548984-5295149629026252199?l=phplab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://phplab.blogspot.com/feeds/5295149629026252199/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=32548984&amp;postID=5295149629026252199' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/5295149629026252199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/32548984/posts/default/5295149629026252199'/><link rel='alternate' type='text/html' href='http://phplab.blogspot.com/2007/01/blogger.html' title='转换到新版Blogger'/><author><name>Ken</name><uri>http://www.blogger.com/profile/06430691123919018834</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_s4Vg-1g_MuU/R7Lg1-6IaWI/AAAAAAAAAcw/V1c0sM7Cto0/S220/HitchhikersGuideMarvin_128x128.jpg'/></author><thr:total>0</thr:total></entry></feed>
