<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>andery&#039;s blog</title>
	<atom:link href="http://www.zm17.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.zm17.com</link>
	<description>小小的天有大大的梦想 总有一天我有属于我的天</description>
	<lastBuildDate>Sat, 10 Jul 2010 06:10:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>PHP 截取字符串</title>
		<link>http://www.zm17.com/?p=307</link>
		<comments>http://www.zm17.com/?p=307#comments</comments>
		<pubDate>Sat, 10 Jul 2010 06:09:24 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[PHP 截取字符串]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=307</guid>
		<description><![CDATA[相信很多人都用PHP自带的substr();在截取中文字符串的时候遇到麻烦。 在这里贴一个把中文当作一个长度截取的函数 function cutstr($str, $len, $dot='...') { $i = $ti = 0; if (strlen($str) < $len) return $str; $charset = is_utf8($str); if ($charset) { while ($ti < $len) { $t = ord($str[$i]); if ($t >= 224) { $i += 3; } elseif ($t >= 192) { $i += 2; } else { $i++; } if [...]]]></description>
			<content:encoded><![CDATA[<p>相信很多人都用PHP自带的substr();在截取中文字符串的时候遇到麻烦。<br />
在这里贴一个把中文当作一个长度截取的函数</p>
<pre name='code' class='php'>
function cutstr($str, $len, $dot='...')
{
     $i = $ti = 0;
     if (strlen($str) < $len) return $str;
     $charset = is_utf8($str);
     if ($charset) {
         while ($ti < $len) {
         $t = ord($str[$i]);
         if ($t >= 224) {
             $i += 3;
         } elseif ($t >= 192) {
             $i += 2;
         } else {
             $i++;
         }
         if ($i>$len+1) break;
             $ti++;
         }
    } else {
        for($ti = 0; $ti < $len; $ti++) {
            $t = ord($str[$i]);
            if ($t > 127) {
                $i += 2;
            } else {
	   $i++;
            }
        }
    }
    $rt = substr($str, 0, $i);
    return $rt;
}
//识别字符串编码
function is_utf8($string) {
    return preg_match('%^(?:
        [\x09\x0A\x0D\x20-\x7E]            # ASCII
        | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
        |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
        |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
        |  \xF0[\x90-\xBF][\x80-\xBF]{2}    # planes 1-3
        | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}    # plane 16
   )*$%xs', $string);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=307</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>数据库设计原则-范式（2）</title>
		<link>http://www.zm17.com/?p=290</link>
		<comments>http://www.zm17.com/?p=290#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:33:00 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[数据库]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=290</guid>
		<description><![CDATA[第二范式（2NF） 1.在讲第二范式前，首先必须要保证符合第一范式的要求。 2.在前面文章中说到，每行都表示一个实体，不能重复，第二范式（2NF）要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列，以存储各个实例的惟一标识。比如我们前面给的电话本的例子，每个用户都有一个ID，这个ID是唯一的，因此每个用户可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。 3.属性完全依赖于主键。 例子：这个表设计符合第一范式，但是不符合第二范式。 OrderId Company ContactPerson Money 1 东明企业 andery 2347.00 2 德商网络 jack 5893.00 3 东明企业 andery 1506.00 4 东明企业 andery 6503.00 上表中订单号(OrderId)是主键，这里公司名字(Company)和订单金额(Money)都依赖于订单号。但是联络人(ContactPerson)则是依赖于公司名称的。 这样会出现的问题： 1.数据冗余，加入一个公司下了100个订单，联络人就会重复出现100次。 2.更新异常，若某公司的联络人有调整，相应的ContactPerson值都要更新，这么多重复的数据都需要更新，产生不需要的消耗。 这里就不符合第二范式，我们就需要分成2个表。 OrderId Company Money 1 东明企业 2347.00 2 德商网络 5893.00 3 东明企业 1506.00 4 东明企业 6503.00 Company ContactPerson 东明企业 andery 德商网络 jack 这样符合第二范式了，某公司联络人变更只需要更新第二张表中相应公司的联络人信息就可以了。]]></description>
			<content:encoded><![CDATA[<p><strong>第二范式（2NF）</strong></p>
<p>1.在讲第二范式前，首先必须要保证符合第一范式的要求。</p>
<p>2.在前面文章中说到，每行都表示一个实体，不能重复，第二范式（2NF）要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列，以存储各个实例的惟一标识。比如我们前面给的电话本的例子，每个用户都有一个ID，这个ID是唯一的，因此每个用户可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。</p>
<p>3.属性完全依赖于主键。</p>
<p>例子：这个表设计符合第一范式，但是不符合第二范式。</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>OrderId</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Company</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>ContactPerson</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Money</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">2347.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">德商网络</td>
<td bgcolor="#FFFFFF">jack</td>
<td bgcolor="#FFFFFF">5893.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">1506.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">4</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">6503.00</td>
</tr>
</tbody>
</table>
<p>上表中订单号(OrderId)是主键，这里公司名字(Company)和订单金额(Money)都依赖于订单号。但是联络人(ContactPerson)则是依赖于公司名称的。</p>
<p>这样会出现的问题：</p>
<p>1.数据冗余，加入一个公司下了100个订单，联络人就会重复出现100次。</p>
<p>2.更新异常，若某公司的联络人有调整，相应的ContactPerson值都要更新，这么多重复的数据都需要更新，产生不需要的消耗。<br />
这里就不符合第二范式，我们就需要分成2个表。</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>OrderId</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Company</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Money</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">2347.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">德商网络</td>
<td bgcolor="#FFFFFF">5893.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">1506.00</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">4</td>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">6503.00</td>
</tr>
</tbody>
</table>
<p></p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Company</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>ContactPerson</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">东明企业</td>
<td bgcolor="#FFFFFF">andery</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">德商网络</td>
<td bgcolor="#FFFFFF">jack</td>
</tr>
</tbody>
</table>
<p>这样符合第二范式了，某公司联络人变更只需要更新第二张表中相应公司的联络人信息就可以了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=290</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>数据库设计原则-范式（1）</title>
		<link>http://www.zm17.com/?p=238</link>
		<comments>http://www.zm17.com/?p=238#comments</comments>
		<pubDate>Thu, 17 Jun 2010 09:40:46 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[数据库 范式]]></category>
		<category><![CDATA[数据库范式]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=238</guid>
		<description><![CDATA[下面是八个范式的英文全称： 1NF : First normal form 2NF : Second normal form 3NF : Third normal form BCNF : Boyce-Codd normal form 4NF : Fourth normal form 5NF : Fifth normal form DKNF : Domain/key normal form 6NF : Sixth normal form 第一范式（1NF） 在任何一个关系数据库中，第一范式（1NF）是对关系模式的基本要求，不满足第一范式（1NF）的数据库就不是关系数据库。 所谓第一范式（1NF）是指数据库表的每一列都是不可分割的基本数据项，同一列中不能有多个值，即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性，就可能需要定义一个新的实体，新的实体由重复的属性构成，新实体与原实体之间为一对多关系。在第一范式（1NF）中表的每一行只包含一个实例的信息。简而言之，第一范式就是无重复的列。 第一范式具体分为下面5个条件： 1.数据表内的的每行没有前后之分。 2.数据表内的每列没有左右之分。 3.没有内容相同的重复行。 4.每个行和列交叉的地方只有一个适用的值，不会出现多个值。 5.每个列的作用都是固定的。 例子：一个电话本的数据表设计 Uid UserName TelNumber 1 [...]]]></description>
			<content:encoded><![CDATA[<p>下面是八个范式的英文全称：</p>
<blockquote><p><strong>1NF  : First normal form<br />
2NF  : Second normal form<br />
3NF  : Third normal form<br />
BCNF : Boyce-Codd normal form<br />
4NF  : Fourth normal form<br />
5NF  : Fifth normal form<br />
DKNF : Domain/key normal form<br />
6NF  : Sixth normal form</strong></p></blockquote>
<p><strong>第一范式（1NF）</strong></p>
<p>在任何一个关系数据库中，第一范式（1NF）是对关系模式的基本要求，不满足第一范式（1NF）的数据库就不是关系数据库。<br />
所谓第一范式（1NF）是指数据库表的每一列都是不可分割的基本数据项，同一列中不能有多个值，即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性，就可能需要定义一个新的实体，新的实体由重复的属性构成，新实体与原实体之间为一对多关系。在第一范式（1NF）中表的每一行只包含一个实例的信息。简而言之，第一范式就是无重复的列。<br />
<span id="more-238"></span><br />
<strong>第一范式具体分为下面5个条件：</strong></p>
<pre><span style="color: #3366ff;">1.数据表内的的每行没有前后之分。</span></pre>
<pre><span style="color: #3366ff;">2.数据表内的每列没有左右之分。</span></pre>
<pre><span style="color: #3366ff;">3.没有内容相同的重复行。</span></pre>
<pre><span style="color: #3366ff;">4.每个行和列交叉的地方只有一个适用的值，不会出现多个值。</span></pre>
<pre><span style="color: #3366ff;">5.每个列的作用都是固定的。</span></pre>
<p>例子：一个电话本的数据表设计</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>UserName</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">jack</td>
<td bgcolor="#FFFFFF">0571-77777777</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">sam</td>
<td bgcolor="#FFFFFF">0571-66666666</td>
</tr>
</tbody>
</table>
<p>假设jack拥有2个电话号码，我们这样写：</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>UserName</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">jack</td>
<td bgcolor="#FFFFFF">0571-77777777<br />
0571-555555555</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">sam</td>
<td bgcolor="#FFFFFF">0571-66666666</td>
</tr>
</tbody>
</table>
<p>这样写似乎就违反了上面第4条，jack这列的电话号码包含了多个值。同时影响到的还有字段类型和长度的定义。</p>
<p>然后考虑改进方法：给数据表增加一列来解决</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>UserName</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber_1</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber_2</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
<td bgcolor="#FFFFFF"></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">jack</td>
<td bgcolor="#FFFFFF">0571-77777777</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">sam</td>
<td bgcolor="#FFFFFF">0571-66666666</td>
<td bgcolor="#FFFFFF"></td>
</tr>
</tbody>
</table>
<p>这样又有问题：</p>
<pre>1.andery和sam的TelNumber_2是空的了，很显然不合理。

2.如果用户还有3个，4个或者更多的电话号码怎么办？一直增加列很显然不可取。

3.存放电话号码的属性完全一样，违反了上面的第5条。

4.我们需要查询一个用户电话号码的时候会带来麻烦，这么多列我们到底需要哪一列？并且还有可能为空。</pre>
<p>再回过头来考虑把电话号码还是放到一个字段中来，改变字段的数据类型和长度的限制，使他足够长能容纳多个电话号码组成的字符串：</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>UserName</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">andery</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">jack</td>
<td bgcolor="#FFFFFF">0571-77777777,0571-555555555</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">sam</td>
<td bgcolor="#FFFFFF">0571-66666666</td>
</tr>
</tbody>
</table>
<p>我见过不少这样设计的，如果数据表设计和产品设计还有程序都是你一个人干的，或者项目要求不高，电话号码可变性不是很大，还是可行的。老外评价这个是最糟糕的设计！</p>
<p>我的一点看法：</p>
<pre>1.字段作用不明确，这个字段到底是电话号码？2个电话组成的字符串？3个电话组成的字符串...

2.电话号码特别多怎么控制这个字段允许的长度？

3.查询的时候我不能预期他是单个电话号码还是多个电话号码。

4.用户需要修改号码的时候，这个就头疼了，不需要多解释了。</pre>
<p>下面给出一个符合第一范式的设计：<br />
用户表：</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>UserName</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">andery</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">jack</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">sam</td>
</tr>
</tbody>
</table>
<p>电话号码表：</p>
<table border="0" cellspacing="1" cellpadding="5" width="500" bgcolor="#0066FF">
<tbody>
<tr>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>Uid</strong></td>
<td style="text-align: center;" bgcolor="#FFFFFF"><strong>TelNumber</strong></td>
</tr>
<tr>
<td bgcolor="#FFFFFF">1</td>
<td bgcolor="#FFFFFF">0571-88888888</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">0571-77777777</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">2</td>
<td bgcolor="#FFFFFF">0571-555555555</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">3</td>
<td bgcolor="#FFFFFF">0571-66666666</td>
</tr>
</tbody>
</table>
<p>把电话号码单独出来一个数据表，这样重复的列（电话号码列）可以合并到一列中，通过用户的ID来和电话表进行连接。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=238</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP设计模式之观察者模式</title>
		<link>http://www.zm17.com/?p=236</link>
		<comments>http://www.zm17.com/?p=236#comments</comments>
		<pubDate>Mon, 14 Jun 2010 06:09:54 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[观察者模式 PHP]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=236</guid>
		<description><![CDATA[先抛出一个问题，你的网站有一个新用户注册，假设你需要给用户发送一条站内信，一封电子邮件，给用户分配一个宠物。 那么假定程序需要4个类，分别是用户类(User)，电子邮件类(Email)，站内信息类(Message)，宠物类(Pet)。 那么要解决上面的问题，我们可以直接在 用户对象中用户注册成功后面计入其他3个对象相应的处理方法。这样目的达到了，是否合理呢？ 试想，现在用户类需要改动，有可能就会导致注册成功后的动作不能正常启动，或者我改动了其他3个类，我就必须回到User类中寻找到相应的代码进行修改。这样会造成很多不必要的麻烦，如果是团队协作，那就真是头疼了。 在OOP编程中，我们一直在说一个东西就是避免组件之间紧密耦合。上面给出的解决办法就违反了这一原则。观察者模式提供了避免组件之间紧密耦合的一种方法。 用观察者来分析以上问题： User一个被观察的对象； Email，Message，Pet是观察者； 首先观察者需要注册为User的观察者。 一当被观察者有相应的动作，观察者就会作出相应的反映。 代码清单： //先定义一个用户注册观察者接口 interface IObserver{ public function onChanged(); } //同上我们需要定义一个被观察者抽象类 abstract class Observable{ //观察者集合 private $_observers; public function addObserver($observer) { $this->_observers=[] = $observer; } //通知各个观察者 public function notify(); } //用户类 class User extends Observable{ public function register() { //注册过程省略，这里假定注册成功返回用户ID号($uid); if($uid) $this->notify($uid); } public function notify($uid) [...]]]></description>
			<content:encoded><![CDATA[<p>先抛出一个问题，你的网站有一个新用户注册，假设你需要给用户发送一条站内信，一封电子邮件，给用户分配一个宠物。</p>
<p>那么假定程序需要4个类，分别是用户类(User)，电子邮件类(Email)，站内信息类(Message)，宠物类(Pet)。</p>
<p>那么要解决上面的问题，我们可以直接在 用户对象中用户注册成功后面计入其他3个对象相应的处理方法。这样目的达到了，是否合理呢？</p>
<p>试想，现在用户类需要改动，有可能就会导致注册成功后的动作不能正常启动，或者我改动了其他3个类，我就必须回到User类中寻找到相应的代码进行修改。这样会造成很多不必要的麻烦，如果是团队协作，那就真是头疼了。</p>
<p>在OOP编程中，我们一直在说一个东西就是避免组件之间紧密耦合。上面给出的解决办法就违反了这一原则。观察者模式提供了避免组件之间紧密耦合的一种方法。<br />
<span id="more-236"></span><br />
用观察者来分析以上问题：</p>
<p>User一个被观察的对象；<br />
Email，Message，Pet是观察者；<br />
首先观察者需要注册为User的观察者。<br />
一当被观察者有相应的动作，观察者就会作出相应的反映。</p>
<p>代码清单：</p>
<pre name="code" class="php">
//先定义一个用户注册观察者接口
interface IObserver{
    public function onChanged();
}

//同上我们需要定义一个被观察者抽象类
abstract class Observable{
    //观察者集合
    private $_observers;

    public function addObserver($observer)
    {
        $this->_observers=[] = $observer;
    }

    //通知各个观察者
    public function notify();
}

//用户类
class User extends Observable{
    public function register()
    {
        //注册过程省略，这里假定注册成功返回用户ID号($uid);
        if($uid) $this->notify($uid);
    }

    public function notify($uid)
    {
        foreach ($this->_observers as $os) {
            $os->onChanged($uid);
        }
    }

    //....
}

//邮件类
class Email implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        //根据$uid取得此函数需要的变量$email,$username
        //具体代码省略
        $this->setEmail($email);
        $this->setContent("{$username},欢迎您注册本站！");
        $this->send();
    }
}

//宠物类
class Pet implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        $this->setPet($uid);
    }
}

//信息类
class Message implements IObserver{

    //其余代码省略

    public function onChanged()
    {
        $uid = func_get_arg(1);
        $this->sendMsg($uid, '欢迎注册本站！');
    }
}

//驱动类
class Drive{
    public function main()
    {
        $user = new User;
        //注册观察者
        $user->addObserver( new Email() );
        $user->addObserver( new Message() );
        $user->addObserver( new Pet() );

        $user->register();
    }
}

$drive = new Drive;
$drive->main();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=236</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP设计模式之工厂模式</title>
		<link>http://www.zm17.com/?p=216</link>
		<comments>http://www.zm17.com/?p=216#comments</comments>
		<pubDate>Wed, 09 Jun 2010 16:02:24 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[工厂模式 PHP 设计模式]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=216</guid>
		<description><![CDATA[在讲之前先做一个比喻，现在我需要生产一批货。 我首先需要2000件上衣，那么我发单上写的是： 代工工厂名称：XX上衣厂 货物需求数量：2000件 货物种类：上衣 联系人：李先生 电话：123 我还需要3000条牛仔裤，那么我发单上写的是： 代工工厂名称：YY牛仔裤厂 货物需求数量：3000条 货物种类：牛仔裤 联系人：洪小姐 电话：123 XX上衣厂和YY牛仔裤厂的地址是不一样的，需要把这2个文件送到 2个不同的地址。 假如我还需要鞋子，帽子，围巾，那我就需要联系更多的工厂，需要的成本也增加不少，还需要维持每个产的关系，要是有个厂关闭了，等等头痛的问题。 我会想，要是有一个工厂(Z工厂)可以又做上衣又做裤子，那么我可以节约很多成本，首先联系人只有一个了，电话只有一个了，地址只有一个了。 那么我就只需要直接告诉Z工厂信息：2000件上衣 或者 3000条牛仔裤，由他们厂来把不同的货物种类分配到不同的车间进行生产。 那么我发单上写的是： 货物需求数量：2000件 货物种类：上衣 货物需求数量：3000条 货物种类：牛仔裤 简单快捷的发送信息，返回给我的是一样的货物(2000件上衣 或者 3000条牛仔裤). 回到主题中来，设置模式中的工厂模式就可以解决我们在程序中遇到的同类型的问题。 通常工厂类返回的也是一个符合类似接口的类，根据参数的不同或者配置信息的不同来创建一种专门用来实例化并且返回其他类的事例的类。 在程序中我们比较常见的就是数据库的操作问题，我们程序可以操作很多数据库，但是每种不同数据的操作函数，参数等等都不一样。当我们一个项目的数据要移植到另一个不同的数据库上的时候，我们就需要修改很多代码来位置应用程序的正常工作。工厂模式就在这里很有用了，用工厂模式来设置数据库操作模块，我们可以做到只需要修改一下配置文件中数据库的配置文件，或者修改一下操作数据库函数的参数就可以很方便的切换到另一个种完全不同的数据库，不需要对程序代码进行任何的修改。 代码清单：使用工厂模式解决数据库可移植问题 interface Idatabase { //定义数据库类的契约 } class Mysql { //some thing } class Mssql { //some thing } //还可以有更多种数据库... class DbFactory { public static [...]]]></description>
			<content:encoded><![CDATA[<p>在讲之前先做一个比喻，现在我需要生产一批货。</p>
<p>我首先需要2000件上衣，那么我发单上写的是：</p>
<blockquote><p><span style="color: #3366ff;">代工工厂名称：XX上衣厂<br />
货物需求数量：2000件<br />
货物种类：上衣<br />
联系人：李先生<br />
电话：123</span></p></blockquote>
<p><span id="more-216"></span><br />
我还需要3000条牛仔裤，那么我发单上写的是：</p>
<blockquote><p><span style="color: #3366ff;">代工工厂名称：YY牛仔裤厂<br />
货物需求数量：3000条<br />
货物种类：牛仔裤<br />
联系人：洪小姐<br />
电话：123</span></p></blockquote>
<p><span style="color: #3366ff;">XX上衣厂和YY牛仔裤厂的地址是不一样的，需要把这2个文件送到 2个不同的地址。<br />
假如我还需要鞋子，帽子，围巾，那我就需要联系更多的工厂，需要的成本也增加不少，还需要维持每个产的关系，要是有个厂关闭了，等等头痛的问题。</span></p>
<p>我会想，要是有一个工厂(Z工厂)可以又做上衣又做裤子，那么我可以节约很多成本，首先联系人只有一个了，电话只有一个了，地址只有一个了。<br />
那么我就只需要直接告诉Z工厂信息：2000件上衣 或者 3000条牛仔裤，由他们厂来把不同的货物种类分配到不同的车间进行生产。</p>
<p>那么我发单上写的是：</p>
<blockquote><p><span style="color: #3366ff;"><br />
货物需求数量：2000件<br />
货物种类：上衣</span></p></blockquote>
<blockquote><p><span style="color: #3366ff;"><br />
货物需求数量：3000条<br />
货物种类：牛仔裤</span></p></blockquote>
<p>简单快捷的发送信息，返回给我的是一样的货物(2000件上衣 或者 3000条牛仔裤).</p>
<p>回到主题中来，设置模式中的工厂模式就可以解决我们在程序中遇到的同类型的问题。</p>
<p><strong><span style="text-decoration: underline;">通常工厂类返回的也是一个符合类似接口的类，根据参数的不同或者配置信息的不同来创建一种专门用来实例化并且返回其他类的事例的类。</span></strong></p>
<p><span style="color: #ff0000;"><strong><span style="color: #000000;">在程序中我们比较常见的就是数据库的操作问题，我们程序可以操作很多数据库，但是每种不同数据的操作函数，参数等等都不一样。当我们一个项目的数据要移植到另一个不同的数据库上的时候，我们就需要修改很多代码来位置应用程序的正常工作。工厂模式就在这里很有用了，用工厂模式来设置数据库操作模块，我们可以做到只需要修改一下配置文件中数据库的配置文件，或者修改一下操作数据库函数的参数就可以很方便的切换到另一个种完全不同的数据库，不需要对程序代码进行任何的修改。</span></strong></span></p>
<p>代码清单：使用工厂模式解决数据库可移植问题</p>
<pre name="code" class="php">interface Idatabase
{
    //定义数据库类的契约
}

class Mysql
{
    //some thing
}

class Mssql
{
    //some thing
}

//还可以有更多种数据库...

class DbFactory
{
    public static function factory()
   {
        $type = getDatabaseType();
        switch () {
            case 'mysql' :
                return new Mysql();
                break;
            case 'mssql' :
                return new Mssql();
                break;
            //more...
        }
    }
}

//用法
$db = DbFactory::factory();</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=216</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcache与memcached的区别</title>
		<link>http://www.zm17.com/?p=212</link>
		<comments>http://www.zm17.com/?p=212#comments</comments>
		<pubDate>Wed, 09 Jun 2010 03:01:47 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[memcache memcached]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=212</guid>
		<description><![CDATA[memcache应该大家都很熟悉了。 但是经常会看到memcache和memcached，他们到底有什么区别呢？ 我们经常也会看到http，httpd，imap，imapd。 通常在linux中的应用，服务端被称为“守护”，守护进程一般的命名就是与客户端应用名称加上字母&#8221;D&#8221;。例如“imap”是一个客户端连接到“imapd”守护进程。 memcache作为php的扩展安装好之后，就可以访问memcached服务器。 但是到php的手册查看可以看到这两个扩展： http://php.net/manual/en/book.memcache.php http://php.net/manual/en/book.memcached.php 手册上memcached 会比 memcache 多几个方法，使用方式上都差不多。 搜索一下很多人给的答案都是我最开始说的那一段，没有其他的，然后找英文的，找到了一个 http://stackoverflow.com/questions/1825256/memcache-vs-memcached 按照他这里说的，首先肯定了我文章开头的是正确的。然后讲到其实有2个memcached。一个是服务端的守护进程。 还有一个可以看作是另一个版本的php扩展，和memcache一样作为客户端的角色，刚好又和 memcached同名，所以很容易让人弄糊涂。 memcached 的版本比较新，使用的是 libmemcached 库。libmemcached 被认为做过更好的优化，比 memcache 有着更高的性能。 附带一个他们2者的对比表：http://code.google.com/p/memcached/wiki/PHPClientComparison]]></description>
			<content:encoded><![CDATA[<p>memcache应该大家都很熟悉了。<br />
但是经常会看到memcache和memcached，他们到底有什么区别呢？<br />
我们经常也会看到http，httpd，imap，imapd。<br />
通常在linux中的应用，服务端被称为“守护”，守护进程一般的命名就是与客户端应用名称加上字母&#8221;D&#8221;。例如“imap”是一个客户端连接到“imapd”守护进程。<br />
memcache作为php的扩展安装好之后，就可以访问memcached服务器。<span id="more-212"></span></p>
<p>但是到php的手册查看可以看到这两个扩展：</p>
<p>http://php.net/manual/en/book.memcache.php</p>
<p>http://php.net/manual/en/book.memcached.php</p>
<p>手册上memcached 会比 memcache 多几个方法，使用方式上都差不多。</p>
<p>搜索一下很多人给的答案都是我最开始说的那一段，没有其他的，然后找英文的，找到了一个</p>
<p><a href="http://stackoverflow.com/questions/1825256/memcache-vs-memcached" target="_blank">http://stackoverflow.com/questions/1825256/memcache-vs-memcached</a></p>
<p>按照他这里说的，首先肯定了我文章开头的是正确的。然后讲到其实有2个memcached。一个是服务端的守护进程。<br />
还有一个可以看作是另一个版本的php扩展，和memcache一样作为客户端的角色，刚好又和 memcached同名，所以很容易让人弄糊涂。</p>
<p>memcached 的版本比较新，使用的是 libmemcached 库。libmemcached 被认为做过更好的优化，比 memcache 有着更高的性能。</p>
<p>附带一个他们2者的对比表：<a href="http://code.google.com/p/memcached/wiki/PHPClientComparison" target="_blank">http://code.google.com/p/memcached/wiki/PHPClientComparison</a></p>
<p><a href="http://www.zm17.com/wp-content/uploads/2010/06/33333333333333333.jpg"><img class="aligncenter size-full wp-image-213 colorbox-212" title="33333333333333333" src="http://www.zm17.com/wp-content/uploads/2010/06/33333333333333333.jpg" alt="" width="459" height="573" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=212</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vsftpd 安装与配置</title>
		<link>http://www.zm17.com/?p=159</link>
		<comments>http://www.zm17.com/?p=159#comments</comments>
		<pubDate>Mon, 07 Jun 2010 09:54:40 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[vsftp linux]]></category>

		<guid isPermaLink="false">http://www.zm17.com/?p=159</guid>
		<description><![CDATA[第一步：安装 打开ftp://vsftpd.beasts.org/users/cevans/ 选择一个你需要的版本，我在这里选择了vsftpd-2.2.2.tar.gz vsftpd下载 wget ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.2.2.tar.gz 然后解压这个文件包：tar zxvf vsftpd-2.2.2.tar.gz 然后输入命令 cd vsftpd-2.2.2 make 我在这里遇到一个错误 gcc -o vsftpd main.o utility.o prelogin.o ftpcmdio.o postlogin.o privsock.o tunables.o ftpdataio.o secbuf.o ls.o postprivparent.o logging.o str.o netstr.o sysstr.o strlist.o banner.o filestr.o parseconf.o secutil.o ascii.o oneprocess.o twoprocess.o privops.o standalone.o hash.o tcpwrap.o ipaddrparse.o access.o features.o readwrite.o opts.o ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o [...]]]></description>
			<content:encoded><![CDATA[<p><strong>第一步：安装</strong></p>
<p>打开ftp://vsftpd.beasts.org/users/cevans/ 选择一个你需要的版本，我在这里选择了vsftpd-2.2.2.tar.gz</p>
<p>vsftpd下载</p>
<blockquote><p><span style="color: #ff0000;">wget ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.2.2.tar.gz</span></p></blockquote>
<p>然后解压这个文件包：tar zxvf vsftpd-2.2.2.tar.gz</p>
<p>然后输入命令</p>
<blockquote><p><span style="color: #ff0000;">cd vsftpd-2.2.2</span></p></blockquote>
<blockquote><p><span style="color: #ff0000;">make</span></p></blockquote>
<p>我在这里遇到一个错误<span id="more-159"></span></p>
<blockquote><p><span style="color: #ff0000;">gcc -o vsftpd main.o utility.o prelogin.o ftpcmdio.o postlogin.o privsock.o tunables.o ftpdataio.o secbuf.o ls.o postprivparent.o logging.o str.o netstr.o sysstr.o strlist.o banner.o filestr.o parseconf.o secutil.o ascii.o oneprocess.o twoprocess.o privops.o standalone.o hash.o tcpwrap.o ipaddrparse.o access.o features.o readwrite.o opts.o ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o -Wl,-s `./vsf_findlibs.sh`<br />
/lib/libcap.so.1: could not read symbols: File in wrong format<br />
collect2: ld 返回 1<br />
make: *** [vsftpd] 错误 1</span></p></blockquote>
<p>打开vsf_findlibs.sh找到错误语句提示的地方然后修改</p>
<blockquote><p><span style="color: #ff0000;">vim vsf_findlibs.sh</span></p></blockquote>
<p>找到/lib/libcap.so.1 修改成 /lib64/libcap.so.1</p>
<blockquote><p><span style="color: #ff0000;">make</span></p></blockquote>
<blockquote><p><span style="color: #ff0000;">make install</span></p></blockquote>
<p>这里又出现2个错误</p>
<blockquote><p><span style="color: #ff0000;">install: 无法创建一般文件“/usr/local/man/man8/vsftpd.8”: 没有那个文件或目录</span></p></blockquote>
<blockquote><p><span style="color: #ff0000;">install: 无法创建一般文件“/usr/local/man/man5/vsftpd.conf.5”: 没有那个文件或目录</span></p></blockquote>
<p>不能自动创建就手动创建一下</p>
<blockquote><p><span style="color: #ff0000;">mkdir /usr/local/man/man8</span></p></blockquote>
<blockquote><p><span style="color: #ff0000;">mkdir /usr/local/man/man5</span></p></blockquote>
<blockquote><p><span style="color: #ff0000;">make install</span></p></blockquote>
<p>复制配置文件 vsftpd.conf 到 etc目录</p>
<blockquote><p><span style="color: #ff0000;">cp /etc/vsftpd/vsftp.conf /etc/vsftpd.conf</span></p></blockquote>
<p>然后运行vsftp</p>
<blockquote><p><span style="color: #ff0000;">/usr/sbin/vsftpd&amp;</span></p></blockquote>
<p>现在用netstat -tnl 查看一下，有21端口说明已经安装成功<br />
如果开启了匿名访问，FTP可以访问pub文件夹了</p>
<p>添加虚拟用户，我们要添加的用户是不能登陆系统，只能登陆FTP的帐号。</p>
<blockquote><p><span style="color: #ff0000;">useradd –s /sbin/nologin -g ftp –d path username<br />
passwd username<br />
Changing password for user beinan.<br />
New password: //在这里输入密码<br />
Retype new password: //再次输入密码<br />
passwd: all authentication tokens updated successfully.</span></p></blockquote>
<p>说明：<br />
-s /sbin/nologin 是让其不能登陆系统<br />
-g ftp 方便管理我们需要建立一个FTP用户组，后面创建的FTP用户都放到FTP用户组中<br />
-d path 是指定用户登陆FTP后进入的目录path</p>
<p><strong>第二步：配置</strong></p>
<p>现在去 /etc 目录可以看到关于vsftpd 的一些配置文件</p>
<p><span style="color: #ff0000;">vsftpd.conf</span></p>
<blockquote><p>#是否允许匿名登陆<br />
anonymous_enable=YES</p>
<p>#是否接受本地用户<br />
local_enable=YES</p>
<p>#是否开放写入权限<br />
write_enable=YES</p>
<p>#本地用户新增档案的权限<br />
local_umask=022</p>
<p>#是否允许匿名用户上传文件<br />
anon_upload_enable=YES</p>
<p>#是否允许匿名用户创建新目录<br />
anon_mkdir_write_enable=YES</p>
<p>#控制是否启用目录提示信息功能,此功能启用后,当用户进入某一个目录时,会检查该目录下是否有message_file选项所指定的文档,若是有,则会出现此文档的内容,通常这个档案会放置欢迎话语,或是对该目录的说明.<br />
dirmessage_enable=YES</p>
<p>#是开启日志功能<br />
xferlog_enable=YES</p>
<p>#控制以PORT模式进行数据传输时是否使用20端口(ftp-data).<br />
connect_from_port_20=YES</p>
<p>#是否修改匿名用户所上传文件的所有权,用户由chown_username参数指定<br />
chown_uploads=YES</p>
<p>#拥有匿名用户上传文件所有权的用户.<br />
chown_username=whoever</p>
<p>#日志文件位置<br />
xferlog_file=/var/log/vsftpd.log</p>
<p>#日志文件是否使用xferlog的标准格式<br />
xferlog_std_format=YES</p>
<p>#空闲用户会话的超时时间,单位为秒.<br />
idle_session_timeout=600</p>
<p>#空闲的数据连接的超时时间.<br />
data_connection_timeout=120</p>
<p>#当服务器运行于最底层时使用的用户名<br />
nopriv_user=ftpsecure</p>
<p>#是否可以用async ABOR命令<br />
async_abor_enable=YES</p>
<p>#是否可以用ASCII 模式上传<br />
ascii_upload_enable=YES</p>
<p>#是否可以用ASCII 模式下载<br />
ascii_download_enable=YES</p>
<p>#登陆时显示欢迎信息.如果设置了banner_file则此设置无效<br />
ftpd_banner=Welcome to blah FTP service.</p>
<p>#如果匿名用户需要密码,那么使用banned_email_file里面的电子邮件地址的用户不能登录<br />
deny_email_enable=YES</p>
<p>#禁止使用匿名用户登陆时作为密码的电子邮件地址<br />
banned_email_file=/etc/vsftpd.banned_emails</p>
<p>#将用户的HOME目录变为其FTP登录后的根目录<br />
chroot_local_user=YES</p>
<p>#chroot_list_file中的用户锁定在自家目录中.<br />
chroot_list_enable=YES</p>
<p>#定义锁定在自家目录的用户列表.<br />
chroot_list_file=/etc/vsftpd.chroot_list</p>
<p>#是否允许使用”ls -R” 指令<br />
ls_recurse_enable=YES</p>
<p>#控制standalone方式启动<br />
listen=YES</p></blockquote>
<p><span style="color: #ff0000;">vsftpd.ftpusers 和 vsftpd.user_list：</span><br />
vsftpd.ftpusers中指定了哪些用户不能访问FTP服务器。vsftpd.user_list中指定的用户默认情况（即在vsftpd.conf中设置了userlist_deny=YES）下也不能访问FTP服务器，当在vsftpd.conf中设置了userlist_deny=NO时，仅仅允许vsftpd.user_list中指定的用户访问FTP服务器。</p>
<p><span style="color: #ff0000;">vsftpd.chroot_list：</span><br />
上面提到的vsftpd中设置了chroot_list_enable=YES 后就会用到这个文件，文件里面是不能更换根目录的用户列表。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=159</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP设计模式之单例模式</title>
		<link>http://www.zm17.com/?p=152</link>
		<comments>http://www.zm17.com/?p=152#comments</comments>
		<pubDate>Sat, 05 Jun 2010 14:36:50 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[单例模式 PHP 设计模式]]></category>

		<guid isPermaLink="false">http://www.tti8.com/?p=152</guid>
		<description><![CDATA[有时候我们需要一个对象只做一个特定的事情，并且程序中只需要这一个对象，那么要保证这个对象只被实例化一次，很多情况下很多人的做事是用引用。这样整个程序在运行过程中只使用这一个对象。 在OOP中，这种做法可能不被允许，复杂的项目或者多人开发的应用中这样做可能会有很多头疼的问题，因为有可能在其他地方错误的将这个对象再次实例化，所以我们需要在这个对象本身就控制这个问题，这里就要将到一种常用的设计模式：单例模式。 见的比较多的就是数据库的访问，往往我们只需要并且只允许一个对象访问数据库，在任何时候，应用程序中都只会有这个类仅有的一个事例存在。这可以防止我们去打开数据库的多个连接或者不必要地使用多余的系统资源。在更加复杂的系统中，使用单例模式在维持应用程序状态的同步方面也尤其有用。 单例类至少拥有一下三种公共元素： 1.拥有一个构造函数，并且必须被标记为private（私有）。 2.拥有一个保存类的事例的静态变量。 3.拥有一个访问这个事例的公共静态方法。 因为构造函数被标记为私有，单例类不能在其地方直接被实例化，只能被自生实例化。 在限制外部实例化单例类的同时还必须防止此类被复制，所以必须在类中创建一个空的私有方法__clone()。 下面给个简单的例子： class Database ｛ private $_db; private $_instance; private function __construct() { $this-&#62;_db = mysql_connect('连接数据库参数'); } public static function getInstance() { if (!self::$_instance instanceof self) { self::$_instance = new self(); } else { return self::$_instance; } } //some code... private function __clone() {}; ｝]]></description>
			<content:encoded><![CDATA[<p>有时候我们需要一个对象只做一个特定的事情，并且程序中只需要这一个对象，那么要保证这个对象只被实例化一次，很多情况下很多人的做事是用引用。这样整个程序在运行过程中只使用这一个对象。</p>
<p>在OOP中，这种做法可能不被允许，复杂的项目或者多人开发的应用中这样做可能会有很多头疼的问题，因为有可能在其他地方错误的将这个对象再次实例化，所以我们需要在这个对象本身就控制这个问题，这里就要将到一种常用的设计模式：单例模式。<br />
<span id="more-152"></span><br />
见的比较多的就是数据库的访问，往往我们只需要并且只允许一个对象访问数据库，在任何时候，应用程序中都只会有这个类仅有的一个事例存在。这可以防止我们去打开数据库的多个连接或者不必要地使用多余的系统资源。在更加复杂的系统中，使用单例模式在维持应用程序状态的同步方面也尤其有用。</p>
<p>单例类至少拥有一下三种公共元素：</p>
<p><strong>1.拥有一个构造函数，并且必须被标记为private（私有）。</strong></p>
<p><strong>2.拥有一个保存类的事例的静态变量。</p>
<p></strong></p>
<p><strong>3.拥有一个访问这个事例的公共静态方法。</strong></p>
<p>因为构造函数被标记为私有，单例类不能在其地方直接被实例化，只能被自生实例化。</p>
<p>在限制外部实例化单例类的同时还必须防止此类被复制，所以必须在类中创建一个空的私有方法__clone()。</p>
<p>下面给个简单的例子：</p>
<pre name="code" class="php">class Database ｛
    private $_db;
    private $_instance;

    private function __construct()
    {
        $this-&gt;_db = mysql_connect('连接数据库参数');
    }

    public static function getInstance()
    {
        if (!self::$_instance instanceof self) {
            self::$_instance = new self();
        } else {
            return self::$_instance;
        }
    }

    //some code...

    private function __clone() {};
｝</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=152</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>URL缩短服务的实现(Bit.ly,j.mp,tinyURL,Go.ly&#8230;)</title>
		<link>http://www.zm17.com/?p=94</link>
		<comments>http://www.zm17.com/?p=94#comments</comments>
		<pubDate>Wed, 02 Jun 2010 05:18:32 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[PHP编程]]></category>
		<category><![CDATA[tinyurl bit.ly 域名缩短]]></category>

		<guid isPermaLink="false">http://www.tti8.com/?p=94</guid>
		<description><![CDATA[我所知道的URL缩短服务是从Twitter使用tinyurl.com来缩短微薄中的域名开始流行起来的，国内的新浪，腾讯微薄都使用了。 Twitter最开始使用tinyurl.com，现在在用的是Bit.ly。 为什么需要URL缩短业服务？ URL缩短服务简单的说就是把一个很长的url地址做成一个很短的url来跳转。这样的好处就是可以把原本一长串的URL地址变成很少的字符。 比如：http://www.google.com.hk/search?hl=zh-CN&#38;newwindow=1&#38;safe=strict&#38;q=baidu&#38;btnG=Google+%E6%90%9C%E7%B4%A2&#38;aq=f&#38;aqi=g10&#38;aql=&#38;oq=&#38;gs_rfai= 经过缩短之后就是(本文用bit.ly做例子)：http://bit.ly/c9gnGZ 这样节省了不少空间，并且看起来也工整很多。 其实还有个很重要的作用就是可以根据域名的流量对网站进行统计和分析，这个很多服务器提供商已经在做了。 为什么微薄上开始流行？ 我们都知道一篇微薄的内容都是很简短的，一般都控制在150字以内，但是有的一个URL地址可能都大于150字了，所以无法发送出去，就算小于规定长度，一篇微薄被一个URL就占用了大部分的位置也会很不划算。所以URL缩短服务在微薄中的作用尤为重要。 怎么实现呢？ 首先需要一个很短的域名，这个优势很重要，tinyURL.com和Bit.ly明显的劣势就是域名太长。 不管域名，我这里讨论下功能的实现。 1.生成地址的API 在发表这个URL(如http://www.zm17.com/?p=152)地址的时候需要调用提供的API来生成一个独一无二的缩短域名，例如http://bit.ly/abc。 这里需要保证http://bit.ly/abc的唯一性。 我们可以设想一个数据表，有3个字段分别是：(也可以不用shorturl，每次请求都处理一次ID值) id 自增长编号 shorturl 缩短处理后的URL rawurl 原URL 在接受到原URL后，查看最大ID号（为了提高效率我们可以先不用数据库来获得这数字，用文件来保存，这里最大编号假设为maxid） 那么此URL的编号应该是thisid = maxid+1 通过处理thisid得到一个短的独一无二的字符串，这里是abc。实现的算法很多，这里就不啰嗦了。 然后保存在数据库中去。 2.实现跳转 有用户请求http://bit.ly/abc这个地址的时候，去数据库中查询shorturl同行的rawurl，然后重定向。]]></description>
			<content:encoded><![CDATA[<p>我所知道的URL缩短服务是从Twitter使用tinyurl.com来缩短微薄中的域名开始流行起来的，国内的新浪，腾讯微薄都使用了。</p>
<p>Twitter最开始使用tinyurl.com，现在在用的是Bit.ly。</p>
<p><strong>为什么需要URL缩短业服务？</strong></p>
<p>URL缩短服务简单的说就是把一个很长的url地址做成一个很短的url来跳转。这样的好处就是可以把原本一长串的URL地址变成很少的字符。<br />
<span id="more-94"></span><br />
比如：http://www.google.com.hk/search?hl=zh-CN&amp;newwindow=1&amp;safe=strict&amp;q=baidu&amp;btnG=Google+%E6%90%9C%E7%B4%A2&amp;aq=f&amp;aqi=g10&amp;aql=&amp;oq=&amp;gs_rfai=</p>
<p>经过缩短之后就是(本文用bit.ly做例子)：http://bit.ly/c9gnGZ</p>
<p>这样节省了不少空间，并且看起来也工整很多。</p>
<p>其实还有个很重要的作用就是可以根据域名的流量对网站进行统计和分析，这个很多服务器提供商已经在做了。</p>
<p><strong>为什么微薄上开始流行？</strong></p>
<p>我们都知道一篇微薄的内容都是很简短的，一般都控制在150字以内，但是有的一个URL地址可能都大于150字了，所以无法发送出去，就算小于规定长度，一篇微薄被一个URL就占用了大部分的位置也会很不划算。所以URL缩短服务在微薄中的作用尤为重要。</p>
<p>怎么实现呢？</p>
<p>首先需要一个很短的域名，这个优势很重要，tinyURL.com和Bit.ly明显的劣势就是域名太长。</p>
<p>不管域名，我这里讨论下功能的实现。</p>
<p><strong>1.生成地址的API</strong></p>
<p>在发表这个URL(如http://www.zm17.com/?p=152)地址的时候需要调用提供的API来生成一个独一无二的缩短域名，例如http://bit.ly/abc。</p>
<p>这里需要保证http://bit.ly/abc的唯一性。</p>
<p>我们可以设想一个数据表，有3个字段分别是：(也可以不用shorturl，每次请求都处理一次ID值)</p>
<p>id 自增长编号</p>
<p>shorturl 缩短处理后的URL</p>
<p>rawurl 原URL</p>
<p>在接受到原URL后，查看最大ID号（为了提高效率我们可以先不用数据库来获得这数字，用文件来保存，这里最大编号假设为maxid）</p>
<p>那么此URL的编号应该是thisid = maxid+1</p>
<p>通过处理thisid得到一个短的独一无二的字符串，这里是abc。实现的算法很多，这里就不啰嗦了。</p>
<p>然后保存在数据库中去。</p>
<p><strong>2.实现跳转</strong></p>
<p>有用户请求http://bit.ly/abc这个地址的时候，去数据库中查询shorturl同行的rawurl，然后重定向。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=94</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>47个令人瞠目结舌的 CSS3动画</title>
		<link>http://www.zm17.com/?p=95</link>
		<comments>http://www.zm17.com/?p=95#comments</comments>
		<pubDate>Wed, 02 Jun 2010 03:18:24 +0000</pubDate>
		<dc:creator>andery</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[css3 效果 动画]]></category>

		<guid isPermaLink="false">http://www.tti8.com/?p=95</guid>
		<description><![CDATA[或许你已经看过很多关于CSS3动画的技术，包括前端观察之前发表的一些，那么现在就情看一看CSS3动画的魅力吧。这里是一辑47个令人瞠目结舌的 CSS3动画演示。他们演示了CSS3能给我们带来的巨大的可能性。]]></description>
			<content:encoded><![CDATA[<p>或许你已经看过很多关于CSS3动画的技术，包括前端观察之前发表的一些，那么现在就情看一看CSS3动画的魅力吧。这里是一辑47个令人瞠目结舌的 CSS3动画演示。他们演示了CSS3能给我们带来的巨大的可能性。</p>
<h3>1.使用jQuery的CSS3时钟</h3>
<p><a href="http://css-tricks.com/examples/CSS3Clock/" target="_blank"><img class="aligncenter size-full wp-image-99 colorbox-95" title="csstricks-clock" src="http://www.zm17.com/wp-content/uploads/2010/06/csstricks-clock1.jpg" alt="" width="470" height="260" /></a><br />
<span id="more-95"></span></p>
<h3>2.模拟时钟</h3>
<p><a href="http://www.fofronline.com/experiments/clock/#clock" target="_blank"><img class="aligncenter size-full wp-image-100 colorbox-95" title="analogue-clock" src="http://www.zm17.com/wp-content/uploads/2010/06/analogue-clock.jpg" alt="" width="470" height="260" /></a></p>
<h3>3.使用方向键旋转的3D盒子</h3>
<p><a href="http://www.fofronline.com/experiments/cube-3d/"><img class="aligncenter size-full wp-image-101 colorbox-95" title="3d-cube" src="http://www.zm17.com/wp-content/uploads/2010/06/3d-cube.jpg" alt="" width="470" height="260" /></a></p>
<h3>4.多个3D盒子(滑入/滑出)</h3>
<p><a href="http://www.fofronline.com/experiments/cube/multiCubes.html"><img class="aligncenter size-full wp-image-102 colorbox-95" title="multi-3d-cube" src="http://www.zm17.com/wp-content/uploads/2010/06/multi-3d-cube.jpg" alt="" width="470" height="260" /></a></p>
<h3>5. CSS3折叠</h3>
<p><a href="http://www.fofronline.com/experiments/accordion/#two"><img class="aligncenter size-full wp-image-103 colorbox-95" title="css3-accordion" src="http://www.zm17.com/wp-content/uploads/2010/06/css3-accordion.jpg" alt="" width="470" height="260" /></a></p>
<h3>6. 自动滚动的视差</h3>
<p><a href="http://www.fofronline.com/experiments/parallax/"><img class="aligncenter size-full wp-image-104 colorbox-95" title="auto-scrolling-parallax" src="http://www.zm17.com/wp-content/uploads/2010/06/auto-scrolling-parallax.jpg" alt="" width="470" height="260" /></a></p>
<h3>7. Isocube</h3>
<p><a href="http://www.zachstronaut.com/lab/isocube.html"><img class="aligncenter size-full wp-image-105 colorbox-95" title="isocube" src="http://www.zm17.com/wp-content/uploads/2010/06/isocube.jpg" alt="" width="470" height="260" /></a></p>
<h3>8. 图片画廊</h3>
<p><a href="http://devfiles.myopera.com/articles/1041/image-gallery.html"><img class="aligncenter size-full wp-image-106 colorbox-95" title="image-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/image-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>9. 矩阵</h3>
<p><a href="http://girliemac.com/sandbox/matrix.html"><img class="aligncenter size-full wp-image-107 colorbox-95" title="matrix" src="http://www.zm17.com/wp-content/uploads/2010/06/matrix.jpg" alt="" width="470" height="260" /></a></p>
<h3>10. 7个使用CSS3的Javascript效果替代</h3>
<h3><a href="http://webdeveloperjuice.com/demos/css/css3effects.html"><img class="aligncenter size-full wp-image-108 colorbox-95" title="javascript-effect-alternatives" src="http://www.zm17.com/wp-content/uploads/2010/06/javascript-effect-alternatives.jpg" alt="" width="470" height="260" /></a></h3>
<h3>11. 图片滑过效果</h3>
<p><a href="http://dinolatoga.com/demo/webkit-image-hover-effects/"><img class="aligncenter size-full wp-image-109 colorbox-95" title="image-hover-effects" src="http://www.zm17.com/wp-content/uploads/2010/06/image-hover-effects.jpg" alt="" width="470" height="260" /></a></p>
<h3>12. 转动的可乐罐 (通过滚动条控制)</h3>
<p><a href="http://www.romancortes.com/blog/pure-css-coke-can/" target="_blank"><img class="aligncenter size-full wp-image-110 colorbox-95" title="coke-can" src="http://www.zm17.com/wp-content/uploads/2010/06/coke-can.jpg" alt="" width="470" height="260" /></a></p>
<h3>13. 3D 房间</h3>
<p><a href="http://www.romancortes.com/blog/css-3d-meninas/"><img class="aligncenter size-full wp-image-111 colorbox-95" title="3d-meninas" src="http://www.zm17.com/wp-content/uploads/2010/06/3d-meninas.jpg" alt="" width="470" height="260" /></a></p>
<h3>14. 宝利来画廊</h3>
<p><a href="http://media.24ways.org/2009/14/5/index.html"><img class="aligncenter size-full wp-image-112 colorbox-95" title="polaroid-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/polaroid-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>15. 太空</h3>
<p><a href="http://media.24ways.org/2009/15/space.html"><img class="aligncenter size-full wp-image-113 colorbox-95" title="space" src="http://www.zm17.com/wp-content/uploads/2010/06/space.jpg" alt="" width="470" height="260" /></a></p>
<h3>16. Mac Dock</h3>
<p><a href="http://www.zurb.com/playground/osx-dock"><img class="aligncenter size-full wp-image-114 colorbox-95" title="mac-dock" src="http://www.zm17.com/wp-content/uploads/2010/06/mac-dock.jpg" alt="" width="470" height="260" /></a></p>
<h3>17. 滑入的模态窗口</h3>
<p><a href="http://www.zurb.com/playground/drop-in-modals"><img class="aligncenter size-full wp-image-115 colorbox-95" title="drop-in-modals" src="http://www.zm17.com/wp-content/uploads/2010/06/drop-in-modals.jpg" alt="" width="470" height="260" /></a></p>
<h3>18. 滑动的唱片</h3>
<p><a href="http://www.zurb.com/playground/sliding-vinyl"><img class="aligncenter size-full wp-image-116 colorbox-95" title="sliding-vinyl" src="http://www.zm17.com/wp-content/uploads/2010/06/sliding-vinyl.jpg" alt="" width="470" height="260" /></a></p>
<h3>19. 放大的宝利来画廊</h3>
<p><a href="http://www.zurb.com/playground/css3-polaroids"><img class="aligncenter size-full wp-image-117 colorbox-95" title="zooming-polaroids" src="http://www.zm17.com/wp-content/uploads/2010/06/zooming-polaroids.jpg" alt="" width="470" height="260" /></a></p>
<h3>20. 动画的火箭</h3>
<p><a href="http://www.the-art-of-web.com/css/css-animation/"><img class="aligncenter size-full wp-image-118 colorbox-95" title="animated-rocket" src="http://www.zm17.com/wp-content/uploads/2010/06/animated-rocket.jpg" alt="" width="470" height="260" /></a></p>
<h3>21. Poster Circle</h3>
<p><a href="http://webkit.org/blog-files/3d-transforms/poster-circle.html"><img class="aligncenter size-full wp-image-119 colorbox-95" title="poster-circle" src="http://www.zm17.com/wp-content/uploads/2010/06/poster-circle.jpg" alt="" width="470" height="260" /></a></p>
<h3>22. 变形的盒子</h3>
<p><a href="http://webkit.org/blog-files/3d-transforms/morphing-cubes.html"><img class="aligncenter size-full wp-image-120 colorbox-95" title="morphing-cubes" src="http://www.zm17.com/wp-content/uploads/2010/06/morphing-cubes.jpg" alt="" width="470" height="260" /></a></p>
<h3>23. 落叶</h3>
<p><a href="http://webkit.org/blog-files/leaves/index.html"><img class="aligncenter size-full wp-image-121 colorbox-95" title="falling-leaves" src="http://www.zm17.com/wp-content/uploads/2010/06/falling-leaves.jpg" alt="" width="470" height="260" /></a></p>
<h3>24. 动画效果宝利来画廊</h3>
<p><a href="http://www.3site.eu/examples/gallery/"><img class="aligncenter size-full wp-image-122 colorbox-95" title="another-polaroid-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/another-polaroid-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>25. 聚光灯投影</h3>
<p><a href="http://www.zachstronaut.com/lab/text-shadow-box/text-shadow-box.html"><img class="aligncenter size-full wp-image-123 colorbox-95" title="spotlight-cast-shadow" src="http://www.zm17.com/wp-content/uploads/2010/06/spotlight-cast-shadow.jpg" alt="" width="470" height="260" /></a></p>
<h3>26. 彩色时钟</h3>
<p><a href="http://demo.tutorialzine.com/2009/12/colorful-clock-jquery-css/demo.html"><img class="aligncenter size-full wp-image-124 colorbox-95" title="colorful-clock" src="http://www.zm17.com/wp-content/uploads/2010/06/colorful-clock.jpg" alt="" width="470" height="260" /></a></p>
<h3>27. Lightbox 画廊(可拖拽)</h3>
<p><a href="http://demo.tutorialzine.com/2009/11/hovering-gallery-css3-jquery/demo.php"><img class="aligncenter size-full wp-image-125 colorbox-95" title="lightbox-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/lightbox-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>28. 弹性所略图菜单</h3>
<p><a href="http://buildinternet.com/live/elasticthumbs/"><img class="aligncenter size-full wp-image-126 colorbox-95" title="elastic-thumb-menu" src="http://www.zm17.com/wp-content/uploads/2010/06/elastic-thumb-menu.jpg" alt="" width="470" height="260" /></a></p>
<h3>29. Coverflow</h3>
<p><a href="http://paulbakaus.com/lab/js/coverflow/"><img class="aligncenter size-full wp-image-127 colorbox-95" title="coverflow" src="http://www.zm17.com/wp-content/uploads/2010/06/coverflow.jpg" alt="" width="470" height="260" /></a></p>
<h3>30. 雪花</h3>
<p><a href="http://natbat.net/code/clientside/css/snowflakes/"><img class="aligncenter size-full wp-image-128 colorbox-95" title="snowflakes" src="http://www.zm17.com/wp-content/uploads/2010/06/snowflakes.jpg" alt="" width="470" height="260" /></a></p>
<h3>31. jQuery DJ Hero</h3>
<p><a href="http://demo.marcofolio.net/jquery_dj/"><img class="aligncenter size-full wp-image-129 colorbox-95" title="dj-hero" src="http://www.zm17.com/wp-content/uploads/2010/06/dj-hero.jpg" alt="" width="470" height="260" /></a></p>
<h3>32. 动态的堆叠卡</h3>
<p><a href="http://designlovr.com/examples/dynamic_stack_of_index_cards/"><img class="aligncenter size-full wp-image-130 colorbox-95" title="stacking-cards" src="http://www.zm17.com/wp-content/uploads/2010/06/stacking-cards.jpg" alt="" width="470" height="260" /></a></p>
<h3>33. 另一个图片画廊</h3>
<p><a href="http://www.alexandtheweb.com/demos/transitions-test.html"><img class="aligncenter size-full wp-image-131 colorbox-95" title="another-image-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/another-image-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>34. 雪栈 (用方向键控制)</h3>
<p><a href="http://www.satine.org/research/webkit/snowleopard/snowstack.html"><img class="aligncenter size-full wp-image-132 colorbox-95" title="snow-stack" src="http://www.zm17.com/wp-content/uploads/2010/06/snow-stack.jpg" alt="" width="470" height="260" /></a></p>
<h3>35. 动画的定价分组</h3>
<p><a href="http://stuffandnonsense.co.uk/content/demo/cannybill/21-10-2009/pricing.html"><img class="aligncenter size-full wp-image-133 colorbox-95" title="animated-pricing" src="http://www.zm17.com/wp-content/uploads/2010/06/animated-pricing.jpg" alt="" width="470" height="260" /></a></p>
<h3>36. 光滑的jQuery菜单</h3>
<p><a href="http://demo.marcofolio.net/slick_jquery_css3_menu/default.html"><img class="aligncenter size-full wp-image-134 colorbox-95" title="slick-jquery-menu" src="http://www.zm17.com/wp-content/uploads/2010/06/slick-jquery-menu.jpg" alt="" width="470" height="260" /></a></p>
<h3>37. CSS3</h3>
<p><a href="http://webkit.org/demos/sticky-notes/"><img class="aligncenter size-full wp-image-135 colorbox-95" title="sticky-notes" src="http://www.zm17.com/wp-content/uploads/2010/06/sticky-notes.jpg" alt="" width="470" height="260" /></a></p>
<h3>38. 不用Javascript的CSS Tabs</h3>
<p><a href="http://www.kamikazemusic.com/demo/csstabs.html"><img class="aligncenter size-full wp-image-136 colorbox-95" title="css-tabs" src="http://www.zm17.com/wp-content/uploads/2010/06/css-tabs.jpg" alt="" width="470" height="260" /></a></p>
<h3>39. 无JavaScript的Tab菜单</h3>
<p><a href="http://development.tobypitman.com/css/menu.html"><img class="aligncenter size-full wp-image-137 colorbox-95" title="tab-menus" src="http://www.zm17.com/wp-content/uploads/2010/06/tab-menus.jpg" alt="" width="470" height="260" /></a></p>
<h3>40. SVG Fisheye菜单</h3>
<p><a href="http://o.sitepen.com/labs/code/cssDock/"><img class="aligncenter size-full wp-image-138 colorbox-95" title="fisheye-menu" src="http://www.zm17.com/wp-content/uploads/2010/06/fisheye-menu.jpg" alt="" width="470" height="260" /></a></p>
<h3>41. 无Flash的动态演示</h3>
<p><a href="http://files.myopera.com/FataL/pres/pres.xml#name"><img class="aligncenter size-full wp-image-139 colorbox-95" title="dynamic-presentation" src="http://www.zm17.com/wp-content/uploads/2010/06/dynamic-presentation.jpg" alt="" width="470" height="260" /></a></p>
<h3>42. 旋转的画廊</h3>
<p><a href="http://samples.webmatze.de/rotating_image_gallery.htm"><img class="aligncenter size-full wp-image-140 colorbox-95" title="rotating-gallery" src="http://www.zm17.com/wp-content/uploads/2010/06/rotating-gallery.jpg" alt="" width="470" height="260" /></a></p>
<h3>43. 下拉菜单</h3>
<p><a href="http://www.newmediacampaigns.com/files/http://www.webdesignerwall.com/wp-content/uploads/2010/02/nicer-navigation-with-css-transitions/demo.html"><img class="aligncenter size-full wp-image-141 colorbox-95" title="dropdown-menu" src="http://www.zm17.com/wp-content/uploads/2010/06/dropdown-menu.jpg" alt="" width="470" height="260" /></a></p>
<h3>44. 另一个Fisheye效果</h3>
<p><a href="http://www.niquelao.net/wp-content/uploads/2009/12/example1.html"><img class="aligncenter size-full wp-image-142 colorbox-95" title="another-fisheye" src="http://www.zm17.com/wp-content/uploads/2010/06/another-fisheye.jpg" alt="" width="470" height="260" /></a></p>
<h3>45. 逐帧动画(鼠标经过时演示)</h3>
<p><a href="http://www.cssplay.co.uk/menu/css3-animation.html"><img class="aligncenter size-full wp-image-143 colorbox-95" title="css3-animation" src="http://www.zm17.com/wp-content/uploads/2010/06/css3-animation.jpg" alt="" width="470" height="260" /></a></p>
<h3>46. 另一个CSS3折叠</h3>
<p><a href="http://www.thecssninja.com/demo/css_accordion/#Section2"><img class="aligncenter size-full wp-image-144 colorbox-95" title="another-accordion" src="http://www.zm17.com/wp-content/uploads/2010/06/another-accordion.jpg" alt="" width="470" height="260" /></a></p>
<h3>47. AT-AT Walker (没有用Flash或JavaScript)</h3>
<p><a href="http://anthonycalzadilla.com/css3-ATAT/index-bones.html"><img class="aligncenter size-full wp-image-145 colorbox-95" title="css3-animation-at-walker" src="http://www.zm17.com/wp-content/uploads/2010/06/css3-animation-at-walker.jpg" alt="" width="470" height="260" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zm17.com/?feed=rss2&amp;p=95</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
