text: -- phpMyAdmin SQL Dump
  -- version 4.4.15.10
  -- https://www.phpmyadmin.net
  --
  -- Host: localhost
  -- Generation Time: 2017-08-22 11:46:17
  -- 服务器版本： 5.6.36-log
  -- PHP Version: 5.6.30
  
  SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
  SET time_zone = "+00:00";
  
  
  /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  /*!40101 SET NAMES utf8mb4 */;
  
  --
  -- Database: `blog`
  --
  
  -- --------------------------------------------------------
  
  --
  -- 表的结构 `article_content`
  --
  
  CREATE TABLE IF NOT EXISTS `article_content` (
    `id` int(11) NOT NULL,
    `content_id` int(11) DEFAULT NULL,
    `content` text COLLATE utf8_unicode_ci
  ) ENGINE=MyISAM AUTO_INCREMENT=164 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  
  --
  -- 转存表中的数据 `article_content`
  --
  
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (24, 230, '<p>			<span style="color: rgb(255, 0, 0);">分布式缓存出于如下考虑，首先是缓存本身的水平线性扩展问题，其次是缓存大并发下的本身的性能问题，再次避免缓存的单点故障问题(多副本和副本一致性)。分布式缓存的核心技术包括首先是内存本身的管理问题，包括了内存的分配，管理和回收机制。其次是分布式管理和分布式算法，其次是缓存键值管理和路由。</span></p><p>原文：<a href="http://wenku.baidu.com/view/8686d46c7e21af45b307a8c3.html" target="_blank">http://wenku.baidu.com/view/8686d46c7e21af45b307a8c3.html</a></p><p>什么是Memcached</p><p>许多Web应用程序都将数据保存到RDBMS中，应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大，访问的集中，就会出现REBMS的负担加重，数据库响应恶化，网站显示延迟等重大影响。Memcached是高性能的分布式内存缓存服务器。一般的使用目的是通过缓存数据库查询结果，减少数据库的访问次数，以提高动态Web应用的速度、提高扩展性。如图：</p><p>&nbsp;<img width="442" height="351" alt="分布式缓存-Memcached" src="http://s13.sinaimg.cn/middle/493a8455tbc5dfbbcb90c&amp;690"></p><p>Memcached作为高速运行的分布式缓存服务器具有以下特点。</p><ul><li>协议简单：memcached的服务器客户端通信并不使用复杂的MXL等格式，而是使用简单的基于文本的协议。</li><li>基于libevent的事件处理：libevent是个程序库，他将Linux的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口。memcached使用这个libevent库，因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。</li><li>内置内存存储方式：为了提高性能，memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中，因此重启memcached，重启操作系统会导致全部数据消失。另外，内容容量达到指定的值之后memcached回自动删除不适用的缓存。</li><li>Memcached不互通信的分布式：memcached尽管是“分布式”缓存服务器，但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。他的分布式主要是通过客户端实现的。</li></ul><p>Memcached的内存管理</p><p>&nbsp;&nbsp;&nbsp;</p><p>最近的memcached默认情况下采用了名为SlabAllocatoion的机制分配，管理内存。在改机制出现以前，内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是这中方式会导致内存碎片，加重操作系统内存管理器的负担。</p><p>Slab Allocator的基本原理是按照预先规定的大小，将分配的内存分割成特定长度的块，已完全解决内存碎片问题。SlabAllocation&nbsp;的原理相当简单。将分配的内存分割成各种尺寸的块（chucnk），并把尺寸相同的块分成组（chucnk的集合）如图：</p><p><img width="368" height="265" alt="分布式缓存-Memcached" src="http://s5.sinaimg.cn/middle/493a8455tbc5dfe9eab04&amp;690"></p><p>而且slab allocator 还有重复使用已分配内存的目的。也就是说，分配到的内存不会释放，而是重复利用。</p><p>Slab Allocation 的主要术语</p><ul><li>&nbsp;&nbsp; &nbsp;Page:分配给Slab 的内存空间，默认是1MB。分配给Slab 之后根据slab 的大小切分成chunk.</li><li>&nbsp;&nbsp; &nbsp;Chunk :用于缓存记录的内存空间。</li><li>&nbsp;&nbsp; &nbsp;SlabClass:特定大小的chunk 的组。</li></ul><p>在Slab 中缓存记录的原理</p><p>Memcached根据收到的数据的大小，选择最合适数据大小的Slab (图2)memcached中保存着slab内空闲chunk的列表，根据该列表选择chunk,然后将数据缓存于其中。</p><p>&nbsp;</p><p><img width="313" height="228" alt="分布式缓存-Memcached" src="http://s7.sinaimg.cn/middle/493a8455tbc5e029298d6&amp;690"></p><p>Memcached在数据删除方面有效里利用资源</p><p>&nbsp;&nbsp;&nbsp;</p><p>Memcached删除数据时数据不会真正从memcached中消失。Memcached不会释放已分配的内存。记录超时后，客户端就无法再看见该记录（invisible透明），其存储空间即可重复使用。</p><p>LazyExpriationmemcached内部不会监视记录是否过期，而是在get时查看记录的时间戳，检查记录是否过期。这种技术称为lazyexpiration.因此memcached不会再过期监视上耗费CPU时间。</p><p><span style="color: rgb(255, 0, 0);">对于缓存存储容量满的情况下的删除需要考虑多种机制，一方面是按队列机制，一方面应该对应缓存对象本身的优先级，根据缓存对象的优先级进行对象的删除。</span></p><p>LRU:从缓存中有效删除数据的原理</p><p>&nbsp;&nbsp;&nbsp;</p><p>Memcached会优先使用已超时的记录空间，但即使如此，也会发生追加新纪录时空间不足的情况。此时就要使用名为LeastRecently Used(LRU)机制来分配空间。这就是删除最少使用的记录的机制。因此当memcached的内存空间不足时（无法从slabclass）获取到新空间时，就从最近未使用的记录中搜索，并将空间分配给新的记录。</p><p>Memcached分布式</p><p>Memcached虽然称为“分布式“缓存服务器，但服务器端并没有“分布式”的功能。Memcached的分布式完全是有客户端实现的。现在我们就看一下memcached是怎么实现分布式缓存的。</p><p>例如下面假设memcached服务器有node1～node3三台，应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma”的数据。</p><p>&nbsp;</p><p>首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后，客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后，即命令它保存“tokyo”及其值。</p><p>&nbsp;</p><p>同样，“kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。</p><p>接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法，根据“键”选择服务器。使用的算法相同，就能选中与保存时相同的服务器，然后发送get命令。只要数据没有因为某些原因被删除，就能获得保存的值。</p><p>&nbsp;<img width="412" height="422" alt="分布式缓存-Memcached" src="http://s15.sinaimg.cn/middle/493a8455tbc5e06fbbcde&amp;690"></p><p>这样，将不同的键保存到不同的服务器上，就实现了memcached的分布式。memcached服务器增多后，键就会分散，即使一台memcached服务器发生故障无法连接，也不会影响其他的缓存，系统依然能继续运行。</p><p>Memcached的缓存分布策略：<a href="http://blog.csdn.net/bintime/article/details/6259133" target="_blank">http://blog.csdn.net/bintime/article/details/6259133</a></p><p>ConsistentHashing的简单说明</p><p>Consistent Hashing如下所示：首先求出memcached服务器（节点）的哈希值，并将其配置到0～232的圆（continuum）上。 然后用同样的方法求出存储数据的键的哈希值，并映射到圆上。然后从数据映射到的位置开始顺时针查找，将数据保存到找到的第一个服务器上。如果超过232仍然找不到服务器，就会保存到第一台memcached服务器上。</p><p><img width="518" height="439" alt="分布式缓存-Memcached" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif"></p><p>从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化而影响缓存的命中率，但Consistent Hashing中，只有在continuum上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响。</p><p><img width="518" height="439" alt="分布式缓存-Memcached" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif"></p><p>因此，Consistent Hashing最大限度地抑制了键的重新分布。 而且，有的ConsistentHashing的实现方法还采用了虚拟节点的思想。 使用一般的hash函数的话，服务器的映射地点的分布非常不均匀。因此，使用虚拟节点的思想，为每个物理节点（服务器） 在continuum上分配100～200个点。这样就能抑制分布不均匀，最大限度地减小服务器增减时的缓存重新分布。</p><p>缓存多副本</p><p>缓存多副本主要是用于在缓存数据存放时存储缓存数据的多个副本，以防止缓存失效。缓存失效发生在以下几种情况：</p><ul><li>1.&nbsp;&nbsp;&nbsp;缓存超时被移除（正常失效）</li><li>2.&nbsp;&nbsp;&nbsp;缓存由于存储空间限制被移除（异常失效）</li><li>3.&nbsp;&nbsp;&nbsp;由于缓存节点变化而导致的缓存失效（异常失效）</li></ul><p>在缓存多副本的情况下，需要重新考虑缓存的分布式分布策略。其次缓存的多个副本实际本身是可能的多个读的节点，可以做为分布式的并行读，这是另外一个可以考虑的问题。</p><p>缓存数据的一致性问题</p><p>缓存数据尽量只读，因此缓存本身是不适合大量写和更新操作的数据场景的。对于读的情况下，如果存在数据变化，一种是同时更新缓存和数据库。一种是直接对缓存数据进行失效处理。</p><p>									</p>'),
  (23, 229, '<p>                        </p><pre><code><span class="hljs-keyword"><span class="hljs-keyword">var</span></span>&nbsp;num&nbsp;=&nbsp;[<span class="hljs-number"><span class="hljs-number">1</span></span>,<span class="hljs-number"><span class="hljs-number">10</span></span>,<span class="hljs-number"><span class="hljs-number">13</span></span>,<span class="hljs-number"><span class="hljs-number">5</span></span>,<span class="hljs-number"><span class="hljs-number">9</span></span>];\r\nnum.<span class="hljs-built_in"><span class="hljs-built_in">sort</span></span>();\r\nalert(num.<span class="hljs-built_in"><span class="hljs-built_in">toString</span></span>());&nbsp;<span class="hljs-comment"><span class="hljs-comment">//错误的排序1,10,13,5,9</span></span>\r\nnum.<span class="hljs-built_in"><span class="hljs-built_in">sort</span></span>(compare);\r\nalert(num.<span class="hljs-built_in"><span class="hljs-built_in">toString</span></span>());&nbsp;<span class="hljs-comment"><span class="hljs-comment">//正确的排序13,10,9，5,1</span></span>\r\n\r\n<span class="hljs-comment"><span class="hljs-comment">//比较函数</span></span>\r\nfunction&nbsp;compare(value1,value2){\r\n&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(value1&nbsp;==&nbsp;value2)&nbsp;{\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>&nbsp;<span class="hljs-number"><span class="hljs-number">0</span></span>;\r\n&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(value1&nbsp;&gt;&nbsp;value2)&nbsp;{\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>&nbsp;-<span class="hljs-number"><span class="hljs-number">1</span></span>;\r\n&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(value1&nbsp;&lt;&nbsp;value2)&nbsp;{\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>&nbsp;<span class="hljs-number"><span class="hljs-number">1</span></span>;\r\n&nbsp;&nbsp;&nbsp;&nbsp;}\r\n}</code></pre><p>&nbsp;</p><p>说明：数组排序sort本身会对数组每一项调用toSring()方法，所以比较数字时，数组中每一项数字都会被转化为为字符串，sort（）根据字符串来排序，所以会出现13比5小的情况，正确的做法是使用一个比较函数做为参数</p><p>&nbsp;sort（）返回值是经过排序后的数组<br></p><p>                    </p>'),
  (20, 226, '<p><a href="/sites/vQZRB3" target="_blank">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p><p>                            <i>原文</i>&nbsp;                 <a href="http://blog.csdn.net/magicharvey/article/details/21372813?utm_source=tuicool&amp;utm_medium=referral">http://blog.csdn.net/magicharvey/article/details/21372813</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p><pre><code>mysql&gt; select * from test;\r\n+----+-------+------+-------+\r\n| id | name  | age  | <span class="class"><span class="keyword">class</span> |\r\n+----+-------+------+-------+\r\n|  1 | <span class="title">qiu</span>   |   22 |     1 | \r\n|  2 | <span class="title">liu</span>   |   42 |     1 | \r\n|  4 | <span class="title">zheng</span> |   20 |     2 | \r\n|  3 | <span class="title">qian</span>  |   20 |     2 | \r\n|  0 | <span class="title">wang</span>  |   11 |     3 | \r\n|  6 | <span class="title">li</span>    |   33 |     3 | \r\n+----+-------+------+-------+\r\n6 <span class="title">rows</span> <span class="title">in</span> <span class="title">set</span> (0.00 <span class="title">sec</span>)</span></code></pre><p>如果想找到每个class里面的最大的age，则需要使用group by和max。</p><p>&nbsp;如下的sql语句，则输出结果有错误：</p><pre><code>mysql&gt; select id,name,max(age),<span class="class"><span class="keyword">class</span> <span class="title">from</span> <span class="title">test</span> <span class="title">group</span> <span class="title">by</span> <span class="title">class</span>;\r\n+----+-------+----------+-------+\r\n| <span class="title">id</span> | <span class="title">name</span>  | <span class="title">max</span>(<span class="title">age</span>) | <span class="title">class</span> |\r\n+----+-------+----------+-------+\r\n|  1 | <span class="title">qiu</span>   |       42 |     1 | \r\n|  4 | <span class="title">zheng</span> |       20 |     2 | \r\n|  0 | <span class="title">wang</span>  |       33 |     3 | \r\n+----+-------+----------+-------+\r\n3 <span class="title">rows</span> <span class="title">in</span> <span class="title">set</span> (0.00 <span class="title">sec</span>)</span></code></pre><p>  虽然找到的age是最大的age，但是与之匹配的用户信息却不是真实的信息，而是group by分组后的第一条记录的基本信息。  </p><p>如果我使用以下的语句进行查找，则可以返回真实的结果。</p><pre><code>mysql&gt; <span class="operator"><span class="keyword">select</span> * <span class="keyword">from</span> (\r\n<span class="indent">  </span>-&gt; <span class="keyword">select</span> * <span class="keyword">from</span> test <span class="keyword">order</span> <span class="keyword">by</span> age <span class="keyword">desc</span>) <span class="keyword">as</span> b\r\n<span class="indent">  </span>-&gt; <span class="keyword">group</span> <span class="keyword">by</span> class;</span>\r\n+<span class="comment">----+-------+------+-------+</span>\r\n| id | name  | age  | class |\r\n+<span class="comment">----+-------+------+-------+</span>\r\n|  2 | liu   |   42 |	 1 | \r\n|  4 | zheng |   20 |	 2 | \r\n|  6 | li	|   33 |	 3 | \r\n+<span class="comment">----+-------+------+-------+</span>\r\n3 rows in <span class="operator"><span class="keyword">set</span> (<span class="number">0.00</span> sec)</span></code></pre><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>'),
  (21, 227, '<p><a href="#">?</a></p><table><tbody><tr><td>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br></td><td><code class="javascript plain">(</code><code class="javascript keyword">function</code><code class="javascript plain">($) {</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">$.extend({</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">myTime: {</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">/**</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* 当前时间戳</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @return &lt;int&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unix时间戳(秒)&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">*/</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">CurTime: </code><code class="javascript keyword">function</code><code class="javascript plain">(){</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">return</code> <code class="javascript plain">Date.parse(</code><code class="javascript keyword">new</code> <code class="javascript plain">Date())/1000;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">},</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">/**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* 日期 转换为 Unix时间戳 </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @param &lt;string&gt; 2014-01-01 20:20:20&nbsp; 日期格式&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @return &lt;int&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unix时间戳(秒)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">*/</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">DateToUnix: </code><code class="javascript keyword">function</code><code class="javascript plain">(string) {</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">var</code> <code class="javascript plain">f = string.split(</code><code class="javascript string">'' ''</code><code class="javascript plain">, 2);</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">var</code> <code class="javascript plain">d = (f[0] ? f[0] : </code><code class="javascript string">''''</code><code class="javascript plain">).split(</code><code class="javascript string">''-''</code><code class="javascript plain">, 3);</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">var</code> <code class="javascript plain">t = (f[1] ? f[1] : </code><code class="javascript string">''''</code><code class="javascript plain">).split(</code><code class="javascript string">'':''</code><code class="javascript plain">, 3);</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">return</code> <code class="javascript plain">(</code><code class="javascript keyword">new</code> <code class="javascript plain">Date(</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">parseInt(d[0], 10) || </code><code class="javascript keyword">null</code><code class="javascript plain">,</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">(parseInt(d[1], 10) || 1) - 1,</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">parseInt(d[2], 10) || </code><code class="javascript keyword">null</code><code class="javascript plain">,</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">parseInt(t[0], 10) || </code><code class="javascript keyword">null</code><code class="javascript plain">,</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">parseInt(t[1], 10) || </code><code class="javascript keyword">null</code><code class="javascript plain">,</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">parseInt(t[2], 10) || </code><code class="javascript keyword">null</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">)).getTime() / 1000;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">},</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">/**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* 时间戳转换日期&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @param &lt;int&gt; unixTime&nbsp;&nbsp;&nbsp; 待时间戳(秒)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @param &lt;bool&gt; isFull&nbsp;&nbsp;&nbsp; 返回完整时间(Y-m-d 或者 Y-m-d H:i:s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">* @param &lt;int&gt;&nbsp; timeZone&nbsp;&nbsp; 时区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript comments">*/</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">UnixToDate: </code><code class="javascript keyword">function</code><code class="javascript plain">(unixTime, isFull, timeZone) {</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">if</code> <code class="javascript plain">(</code><code class="javascript keyword">typeof</code> <code class="javascript plain">(timeZone) == </code><code class="javascript string">''number''</code><code class="javascript plain">)</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">{</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">unixTime = parseInt(unixTime) + parseInt(timeZone) * 60 * 60;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">}</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">var</code> <code class="javascript plain">time = </code><code class="javascript keyword">new</code> <code class="javascript plain">Date(unixTime * 1000);</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">var</code> <code class="javascript plain">ymdhis = </code><code class="javascript string">""</code><code class="javascript plain">;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += time.getUTCFullYear() + </code><code class="javascript string">"-"</code><code class="javascript plain">;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += (time.getUTCMonth()+1) + </code><code class="javascript string">"-"</code><code class="javascript plain">;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += time.getUTCDate();</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">if</code> <code class="javascript plain">(isFull === </code><code class="javascript keyword">true</code><code class="javascript plain">)</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">{</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += </code><code class="javascript string">" "</code> <code class="javascript plain">+ time.getUTCHours() + </code><code class="javascript string">":"</code><code class="javascript plain">;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += time.getUTCMinutes() + </code><code class="javascript string">":"</code><code class="javascript plain">;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">ymdhis += time.getUTCSeconds();</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">}</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript keyword">return</code> <code class="javascript plain">ymdhis;</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">}</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">}</code><br><code class="javascript spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="javascript plain">});</code><br><code class="javascript plain">})(jQuery); </code><br><br></td></tr></tbody></table><p>　　</p><p>使用方法</p><p>console.log($.myTime.DateToUnix(''2014-5-15 20:20:20''));<br>console.log($.myTime.UnixToDate(1325347200));</p>'),
  (19, 225, '<p>很多朋友在用github管理项目的时候，都是直接使用https url克隆到本地，当然也有有些人使用 SSH url 克隆到本地。然而，为什么绝大多数人会使用https url克隆呢？</p><p>这是因为，使用https url克隆对初学者来说会比较方便，复制https url 然后到 <a href="http://lib.csdn.net/base/git" target="_blank">Git</a> Bash 里面直接用clone命令克隆到本地就好了。而使用 SSH url 克隆却需要在克隆之前先配置和添加好 SSH key 。</p><p>因此，如果你想要使用 SSH url 克隆的话，你必须是这个项目的拥有者。否则你是无法添加 SSH key 的。</p><p>&nbsp;</p><h2>https 和 SSH 的区别：</h2><p><span style="color: rgb(153, 51, 0);">1、</span>前者可以随意克隆github上的项目，而不管是谁的；而后者则是你必须是你要克隆的项目的拥有者或管理员，且需要先添加 SSH key ，否则无法克隆。</p><p><span style="color: rgb(153, 51, 0);">2、</span>https url 在push的时候是需要验证用户名和密码的；而 SSH 在push的时候，是不需要输入用户名的，如果配置SSH key的时候设置了密码，则需要输入密码的，否则直接是不需要输入密码的。</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><h2>在 github 上添加 SSH key 的步骤：</h2><h4>1、首先需要检查你电脑是否已经有 SSH key&nbsp;</h4><p>运行 git Bash 客户端，输入如下代码：</p><pre><code>$ cd ~/<span style="margin: 0px; padding: 0px; line-height: 1.5;">.ssh\r\n$ ls</span></code></pre><p>这两个命令就是检查是否已经存在 id_rsa.pub 或 id_dsa.pub 文件，如果文件已经存在，那么你可以跳过步骤2，直接进入步骤3。</p><p>&nbsp;</p><h4>2、创建一个 SSH key&nbsp;</h4><pre><code>$ ssh-keygen -t rsa -C <span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">"</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">your_email@example.com</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">"</span></code></pre><p>代码参数含义：</p><p>-t 指定密钥类型，默认是 rsa ，可以省略。<br>-C 设置注释文字，比如邮箱。<br>-f 指定密钥文件存储文件名。</p><p>以上代码省略了 -f 参数，因此，运行上面那条命令后会让你输入一个文件名，用于保存刚才生成的 SSH key 代码，如：</p><pre><code>Generating <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">public</span>/<span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">private</span><span style="margin: 0px; padding: 0px; line-height: 1.5;"> rsa key pair.\r\n# Enter file </span><span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">in</span> which to save the key (/c/Users/you/.ssh/id_rsa): [Press enter]</code></pre><p>当然，你也可以不输入文件名，使用默认文件名（推荐），那么就会生成 id_rsa 和 id_rsa.pub 两个秘钥文件。</p><p>&nbsp;</p><p>接着又会提示你输入两次密码（该密码是你push文件的时候要输入的密码，而不是github管理者的密码），</p><p>当然，你也可以不输入密码，直接按回车。那么push的时候就不需要输入密码，直接提交到github上了，如：</p><pre><code>Enter passphrase (empty <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">for</span><span style="margin: 0px; padding: 0px; line-height: 1.5;"> no passphrase): \r\n# Enter same passphrase again:</span></code></pre><p>接下来，就会显示如下代码提示，如：</p><pre><code>Your identification has been saved <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">in</span> /c/Users/you/.ssh/<span style="margin: 0px; padding: 0px; line-height: 1.5;">id_rsa.\r\n# Your </span><span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">public</span> key has been saved <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">in</span> /c/Users/you/.ssh/<span style="margin: 0px; padding: 0px; line-height: 1.5;">id_rsa.pub.\r\n# The key fingerprint </span><span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">is</span><span style="margin: 0px; padding: 0px; line-height: 1.5;">:\r\n# </span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">01</span>:0f:f4:3b:ca:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">85</span>:d6:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">17</span>:a1:7d:f0:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">68</span>:9d:f0:a2:db your_email@example.com</code></pre><p>当你看到上面这段代码的收，那就说明，你的 SSH key 已经创建成功，你只需要添加到github的SSH key上就可以了。</p><p>&nbsp;</p><h4>3、添加你的 SSH key 到 github上面去</h4><p><span style="color: rgb(153, 51, 0);">a、</span>首先你需要拷贝 id_rsa.pub 文件的内容，你可以用编辑器打开文件复制，也可以用git命令复制该文件的内容，如：</p><pre><code>$ clip &lt; ~/.ssh/id_rsa.pub</code></pre><p><span style="color: rgb(153, 51, 0);">b、</span>登录你的github账号，从又上角的设置（&nbsp;<a href="https://github.com/settings" target="_blank">Account Settings</a>&nbsp;）进入，然后点击菜单栏的 SSH key 进入页面添加 SSH key。</p><p><span style="color: rgb(153, 51, 0);">c、</span>点击 Add SSH key 按钮添加一个 SSH key 。把你复制的 SSH key 代码粘贴到 key 所对应的输入框中，记得 SSH key 代码的前后不要留有空格或者回车。当然，上面的 Title 所对应的输入框你也可以输入一个该 SSH key 显示在 github 上的一个别名。默认的会使用你的邮件名称。</p><p>&nbsp;</p><h3>4、测试一下该SSH key</h3><p>在git Bash 中输入以下代码</p><pre><code>$ ssh -T git@github.com</code></pre><p>当你输入以上代码时，会有一段警告代码，如：</p><pre><code>The authenticity of host <span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">github.com (207.97.227.239)</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span> can<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">t be established.</span>\r\n# RSA key fingerprint <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">is</span> <span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">16</span>:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">27</span>:ac:a5:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">76</span>:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">28</span>:2d:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">36</span>:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">63</span>:1b:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">56</span>:4d:eb:df:a6:<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 128); line-height: 1.5;">48</span><span style="margin: 0px; padding: 0px; line-height: 1.5;">.\r\n# Are you sure you want to </span><span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">continue</span> connecting (yes/no)?</code></pre><p>这是正常的，你输入 yes 回车既可。如果你创建 SSH key 的时候设置了密码，接下来就会提示你输入密码，如：</p><pre><code>Enter passphrase <span style="margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5;">for</span> key <span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">/c/Users/Administrator/.ssh/id_rsa</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span>:</code></pre><p>当然如果你密码输错了，会再要求你输入，知道对了为止。</p><p>注意：输入密码时如果输错一个字就会不正确，使用删除键是无法更正的。</p><p>密码正确后你会看到下面这段话，如：</p><pre><code>Hi username! You<span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">''</span><span style="margin: 0px; padding: 0px; color: rgb(128, 0, 0); line-height: 1.5;">ve successfully authenticated, but GitHub does not</span>\r\n# provide shell access.</code></pre><p>如果用户名是正确的,你已经成功设置SSH密钥。如果你看到 “access denied” ，者表示拒绝访问，那么你就需要使用 https 去访问，而不是 SSH 。</p><p>&nbsp;</p><p>如果你有什么疑问或指正，请留言。</p><p>&nbsp;</p><p>产考文档：<a href="https://help.github.com/articles/generating-ssh-keys" rel="nofollow">https://help.github.com/articles/generating-ssh-keys</a></p><p>   </p>'),
  (16, 222, '<p>var intDiff = parseInt(60);//倒计时总秒数量</p><p>function timer(intDiff){ </p><p>&nbsp;&nbsp; window.setInterval(function(){ </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; var day=0,        hour=0,        minute=0,        second=0;//时间默认值 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(intDiff &gt; 0){</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; day = Math.floor(intDiff / (60 * 60 * 24)); </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hour = Math.floor(intDiff / (60 * 60)) - (day * 24); </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minute = Math.floor(intDiff / 60) - (day * 24 * 60) - (hour * 60);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; second = Math.floor(intDiff) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60); </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; }</p><p>&nbsp;&nbsp;&nbsp; if (minute &lt;= 9) minute = ''0'' + minute;</p><p>&nbsp;&nbsp;&nbsp; if (second &lt;= 9) second = ''0'' + second; </p><p>&nbsp;&nbsp; $(''#day_show'').html(day+"天"); </p><p>&nbsp;&nbsp; $(''#hour_show'').html(''&lt;s id="h"&gt;&lt;/s&gt;''+hour+''时''); </p><p>&nbsp;&nbsp; $(''#minute_show'').html(''&lt;s&gt;&lt;/s&gt;''+minute+''分''); </p><p>&nbsp;&nbsp; $(''#second_show'').html(''&lt;s&gt;&lt;/s&gt;''+second+''秒'');    intDiff--;    }, 1000);</p><p>}</p><p>&nbsp;$(function(){    timer(intDiff);});    </p>'),
  (17, 223, '<p>  <a href="http://blog.csdn.net/MONKEY_D_MENG/article/details/6647488" target="_blank">http://blog.csdn.net/MONKEY_D_MENG/article/details/6647488</a></p>'),
  (18, 224, '<p>&nbsp;Yii Framework使用spl_autoload_register实现类的自动加载，这个很大的方便我们不用每次都要手动的去include一些类和函数。不过这样会导致一些问题，比如说，有一些extension，如，使用taobao，它自己内部也使用了spl_autoload_register来实现自动加载类，由于在框架的执行顺序里面，首先是执行了spl_autoload_register(array(''YiiBase'',''autoload''))，这样会导致smarty里面的spl_autoload_register不会执行，这样就会出现使用taobao过程中，找不到它里面的类。这种情况解决方法有两种</p><p>&nbsp;1. 先卸载yii的，再注册yii的autoload，如以下代码，修改taobao的SDK的 Autoloader.php文件</p><p>&nbsp;&nbsp;spl_autoload_unregister(array(''YiiBase'',''autoload''));</p><p>&nbsp;spl_autoload_register(array($this, "loadClass"));</p><p>&nbsp;spl_autoload_register(array(''YiiBase'',''autoload''));</p><p>不过这种方法是要修改taobao的代码的，这样不利于taobao的升级，这时候，可以考虑使用第二种情况。</p><p>&nbsp;</p><p>2. 优先注册了自己的autoload，如以下代码，是加在index.php里面的。</p><p>require_once(dirname(__FILE__).''/protected/extensions/taobao/TopSdk.php'');</p><p>require_once($yii);</p><p>Yii::createWebApplication($config)-&gt;run();</p><p>&nbsp;</p><p>这样的话，所有的autoload都会优先使用taobao的autoloader，可以避免找不到taobao的类，不过这样会导致一些性能上的小损失。</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; </p><p>&nbsp;</p><p>&nbsp;</p>'),
  (13, 219, '<h4>create a new repository on the command line</h4><p>echo “# test” &gt;&gt; README.md<br>git init<br>git add README.md<br>git commit -m “first commit”<br>git remote add origin <a href="https://github.com/wuzhc/test.git">https://github.com/wuzhc/test.git</a><br>git push -u origin master</p><h4>push an existing repository from the command line</h4><p>git remote add origin <a href="https://github.com/wuzhc/test.git">https://github.com/wuzhc/test.git</a><br>git push -u origin master</p><h4>import code from another repository</h4><p>You can initialize this repository with code from a Subversion, Mercurial, or TFS project.</p>'),
  (14, 220, '<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.重启 apache</strong></p><p>　　service httpd restrat</p><p>　　/etc/init.d/httpd stop</p><p>　　/etc/init.d/httpd start</p><p>　　<strong>2.重启 mysql</strong></p><p>　　service mysql restart</p><p>　　/etc/init.d/mysqld stop</p><p>　　/etc/init.d/mysqld start</p><p>　　<strong>3.重启Nginx</strong></p><p>　　service nginx restart</p><p>　　/etc/init.d/nginx stop</p><p>　　/etc/init.d/nginx start</p>'),
  (15, 221, '<p><code class="html plain">定义和用法：</code></p><p><code class="html plain">error_reporting() 设置 PHP 的报错级别并返回当前级别。</code></p><p>&nbsp;</p><p><code class="html plain">函数语法：</code></p><p><code class="html plain">error_reporting(report_level)</code></p><p>&nbsp;</p><p><code class="html plain">如果参数 level 未指定，当前报错级别将被返回。下面几项是 level 可能的值：</code></p><p><code class="html plain">值 常量 描述</code></p><p><code class="html plain">1 E_ERROR 致命的运行错误。错误无法恢复，暂停执行脚本。</code></p><p><code class="html plain">2 E_WARNING 运行时警告(非致命性错误)。非致命的运行错误，脚本执行不会停止。</code></p><p><code class="html plain">4 E_PARSE 编译时解析错误。解析错误只由分析器产生。</code></p><p><code class="html plain">8 E_NOTICE 运行时提醒(这些经常是你代码中的bug引起的，也可能是有意的行为造成的。)</code></p><p><code class="html plain">16 E_CORE_ERROR PHP启动时初始化过程中的致命错误。</code></p><p><code class="html plain">32 E_CORE_WARNING PHP启动时初始化过程中的警告(非致命性错)。</code></p><p><code class="html plain">64 E_COMPILE_ERROR 编译时致命性错。这就像由Zend脚本引擎生成了一个E_ERROR。</code></p><p><code class="html plain">128 E_COMPILE_WARNING 编译时警告(非致命性错)。这就像由Zend脚本引擎生成了一个E_WARNING警告。</code></p><p><code class="html plain">256 E_USER_ERROR 用户自定义的错误消息。这就像由使用PHP函数trigger_error（程序员设置E_ERROR）</code></p><p><code class="html plain">512 E_USER_WARNING 用户自定义的警告消息。这就像由使用PHP函数trigger_error（程序员设定的一个E_WARNING警告）</code></p><p><code class="html plain">1024 E_USER_NOTICE 用户自定义的提醒消息。这就像一个由使用PHP函数trigger_error（程序员一个E_NOTICE集）</code></p><p><code class="html plain">2048 E_STRICT 编码标准化警告。允许PHP建议如何修改代码以确保最佳的互操作性向前兼容性。</code></p><p><code class="html plain">4096 E_RECOVERABLE_ERROR 开捕致命错误。这就像一个E_ERROR，但可以通过用户定义的处理捕获（又见set_error_handler（））</code></p><p><code class="html plain">8191 E_ALL 所有的错误和警告(不包括 E_STRICT) (E_STRICT will be part of E_ALL as of PHP 6.0)</code></p><p>&nbsp;</p><p>例子：<br>任意数目的以上选项都可以用“或”来连接(用 OR 或 |)，这样可以报告所有需要的各级别错误。<br>例如，下面的代码关闭了用户自定义的错误和警告，执行了某些操作，然后恢复到原始的报错级别：</p><p><code class="php plain">&lt;?php</code></p><p><code class="php comments">//禁用错误报告</code></p><p><code class="php functions">error_reporting</code><code class="php plain">(0);</code></p><p>&nbsp;<code class="php comments">//报告运行时错误</code></p><p><code class="php functions">error_reporting</code><code class="php plain">(E_ERROR | E_WARNING | E_PARSE);</code></p><p><code class="php comments">//报告所有错误</code></p><p><code class="php functions">error_reporting</code><code class="php plain">(E_ALL);</code></p><p><code class="php plain">?&gt;</code></p>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (26, 232, '<blockquote><p>原文：SamarRizvi&nbsp;</p><p>译文：ictlyh</p><p>网址：linux.cn/article-5868-1.html</p></blockquote><p><span style="color: rgb(255, 0, 0);"><strong>简介</strong></span></p><p>要提供互联网服务，当你在开发代码的时候必须时刻保持安全意识。可能大部分 PHP 脚本都对安全问题都不在意，这很大程度上是因为有大量的无经验程序员在使用这门语言。但是，没有理由让你因为对你的代码的不确定性而导致不一致的安全策略。当你在服务器上放任何涉及到钱的东西时，就有可能会有人尝试破解它。创建一个论坛程序或者任何形式的购物车，被攻击的可能性就上升到了无穷大。</p><p><span style="color: rgb(255, 0, 0);"><strong>背景</strong></span></p><p>为了确保你的 web 内容安全，这里有一些常规的安全准则：</p><p><strong>别相信表单</strong></p><p>攻击表单很简单。通过使用一个简单的 JavaScript 技巧，你可以限制你的表单只允许在评分域中填写 1 到 5 的数字。如果有人关闭了他们浏览器的 JavaScript 功能或者提交自定义的表单数据，你客户端的验证就失败了。</p><p>用户主要通过表单参数和你的脚本交互，因此他们是最大的安全风险。你应该学到什么呢？在 PHP 脚本中，总是要验证 传递给任何 PHP 脚本的数据。在本文中，我们向你演示了如何分析和防范跨站脚本（XSS）攻击，它可能会劫持用户凭据（甚至更严重）。你也会看到如何防止会玷污或毁坏你数据的 MySQL 注入攻击。</p><p><strong>别相信用户</strong></p><p>假定你网站获取的每一份数据都充满了有害的代码。清理每一部分，即便你相信没有人会尝试攻击你的站点。</p><p><strong>关闭全局变量</strong></p><p>你可能会有的最大安全漏洞是启用了 register_globals 配置参数。幸运的是，PHP 4.2 及以后版本默认关闭了这个配置。如果打开了 register_globals，你可以在你的 php.ini 文件中通过改变 register_globals 变量为 Off 关闭该功能：</p><blockquote><p>register_globals = Off</p></blockquote><p>新手程序员觉得注册全局变量很方便，但他们不会意识到这个设置有多么危险。一个启用了全局变量的服务器会自动为全局变量赋任何形式的参数。为了了解它如何工作以及为什么有危险，让我们来看一个例子。</p><p>假设你有一个称为 process.php 的脚本，它会向你的数据库插入表单数据。初始的表单像下面这样：</p><blockquote><p>&lt;input name="username" type="text" size="15" maxlength="64"&gt;</p></blockquote><p>运行 process.php 的时候，启用了注册全局变量的 PHP 会将该参数赋值到 $username 变量。这会比通过 $_POST[‘username’]或 $_GET[‘username’] 访问它节省击键次数。不幸的是，这也会给你留下安全问题，因为 PHP 会设置该变量的值为通过 GET 或 POST 的参数发送到脚本的任何值，如果你没有显示地初始化该变量并且你不希望任何人去操作它，这就会有一个大问题。</p><p>看下面的脚本，假如 $authorized 变量的值为 true，它会给用户显示通过验证的数据。正常情况下，只有当用户正确通过了这个假想的 authenticated_user() 函数验证，$authorized 变量的值才会被设置为真。但是如果你启用了 register_globals，任何人都可以发送一个 GET 参数，例如 authorized=1 去覆盖它：</p><blockquote><p><span style="">&lt;?php</span></p><p><span style="">// Define $authorized = true only if user is authenticated</span></p><p>if<span style=""> </span><span style="">(</span><span style="">authenticated_user</span><span style="">())</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$authorized</span><span style=""> = </span><span style="">true</span><span style="">;</span></p><p><span style="">}</span></p><p><span style="">?&gt;</span></p></blockquote><p>这个故事的寓意是，你应该从预定义的服务器变量中获取表单数据。所有通过 post 表单传递到你 web 页面的数据都会自动保存到一个称为 $_POST 的大数组中，所有的 GET 数据都保存在 $_GET 大数组中。文件上传信息保存在一个称为 $_FILES 的特殊数据中。另外，还有一个称为 $_REQUEST 的复合变量。</p><p>要从一个 POST 方法表单中访问 username 字段，可以使用 $_POST[‘username’]。如果 username 在 URL 中就使用$_GET[‘username’]。如果你不确定值来自哪里，用 $_REQUEST[‘username’]。</p><blockquote><p><span style="">&lt;?php</span></p><p><span style="">$post_value</span><span style=""> = </span><span style="">$_POST</span><span style="">[</span><span style="">''post_value''</span><span style="">];</span></p><p><span style="">$get_value</span><span style=""> = </span><span style="">$_GET</span><span style="">[</span><span style="">''get_value''</span><span style="">];</span></p><p><span style="">$some_variable</span><span style=""> = </span><span style="">$_REQUEST</span><span style="">[</span><span style="">''some_value''</span><span style="">];</span><span style=""> </span></p><p><span style="">?&gt;</span></p></blockquote><p>$_REQUEST 是 $_GET、$_POST、和 $_COOKIE 数组的结合。如果你有两个或多个值有相同的参数名称，注意 PHP 会使用哪个。默认的顺序是 cookie、POST、然后是 GET。</p><p><strong>推荐安全配置选项</strong></p><p>这里有几个会影响安全功能的 PHP 配置设置。下面是一些显然应该用于生产服务器的：</p><ul><li><p>register_globals 设置为 off</p></li><li><p>safe_mode 设置为 off</p></li><li><p>error_reporting 设置为 off。如果出现错误了，这会向用户浏览器发送可见的错误报告信息。对于生产服务器，使用错误日志代替。开发服务器如果在防火墙后面就可以启用错误日志。（LCTT 译注：此处据原文逻辑和常识，应该是“开发服务器如果在防火墙后面就可以启用错误报告，即 on。”）</p></li><li><p>停用这些函数：system()、exec()、passthru()、shell_exec()、proc_open()、和 popen()。</p></li><li><p>open_basedir 为 /tmp（以便保存会话信息）目录和 web 根目录，以便脚本不能访问这些选定区域外的文件。</p></li><li><p>expose_php 设置为 off。该功能会向 Apache 头添加包含版本号的 PHP 签名。</p></li><li><p>allow_url_fopen 设置为 off。如果你能够注意你代码中访问文件的方式-也就是你验证所有输入参数，这并不严格需要。</p></li><li><p>allow_url_include 设置为 off。对于任何人来说，实在没有明智的理由会想要访问通过 HTTP 包含的文件。</p></li></ul><p>一般来说，如果你发现想要使用这些功能的代码，你就不应该相信它。尤其要小心会使用类似 system() 函数的代码-它几乎肯定有缺陷。</p><p>启用了这些设置后，让我们来看看一些特定的攻击以及能帮助你保护你服务器的方法。</p><p><span style="color: rgb(255, 0, 0);"><strong>SQL 注入攻击</strong></span></p><p>由于 PHP 传递到 MySQL 数据库的查询语句是用强大的 SQL 编程语言编写的，就有了某些人通过在 web 查询参数中使用 MySQL 语句尝试 SQL 注入攻击的风险。通过在参数中插入有害的 SQL 代码片段，攻击者会尝试进入（或破坏）你的服务器。</p><p>假如说你有一个最终会放入变量 $product 的表单参数，你使用了类似下面的 SQL 语句：</p><blockquote><p>$sql = "select * from pinfo where product = ''$product''";</p></blockquote><p>如果参数是直接从表单中获得的，应该使用 PHP 自带的数据库特定转义函数，类似：</p><blockquote><p><span style="">$</span><span style="">sql</span><span style=""> = </span><span style="">''Select * from pinfo where product = ''"'' </span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mysql_real_escape_string($product) . ''"</span>''<span style="">;</span></p></blockquote><p>如果不这样做的话，有人也许会把下面的代码段放到表单参数中：</p><blockquote><p>39''; DROP pinfo; SELECT ''FOO</p></blockquote><p>那么 $sql 的结果就是：</p><blockquote><p>select product from pinfo where product = ''39''; DROP pinfo; SELECT ''FOO''</p></blockquote><p>由于分号是 MySQL 的语句分隔符，数据库会运行下面三条语句：</p><blockquote><p><span style="">select *</span><span style=""> </span><span style="">from pinfo where </span><span style="">product</span><span style=""> = </span><span style="">''39''</span></p><p><span style="">DROP pinfo</span></p><p>SELECT<span style=""> </span><span style="">''FOO''</span></p></blockquote><p>好了，你丢失了你的表。</p><p>注意实际上 PHP 和 MySQL 不会运行这种特殊语法，因为 mysql_query() 函数只允许每个请求处理一个语句。但是，一个子查询仍然会生效。</p><p>要防止 SQL 注入攻击，做这两件事：</p><ul><li><p>总是验证所有参数。例如，如果需要一个数字，就要确保它是一个数字。</p></li><li><p>总是对数据使用 mysql_real_escape_string() 函数转义数据中的任何引号和双引号。</p></li></ul><p>注意：要自动转义任何表单数据，可以启用魔术引号（Magic Quotes）。</p><p>一些 MySQL 破坏可以通过限制 MySQL 用户权限避免。任何 MySQL 账户可以限制为只允许对选定的表进行特定类型的查询。例如，你可以创建只能选择行的 MySQL 用户。但是，这对于动态数据并不十分有用，另外，如果你有敏感的用户信息，可能某些人能访问其中一些数据，但你并不希望如此。例如，一个访问账户数据的用户可能会尝试注入访问另一个人的账户号码的代码，而不是为当前会话指定的号码。</p><p><span style="color: rgb(255, 0, 0);"><strong>防止基本的 XSS 攻击</strong></span></p><p>XSS 表示跨站脚本。不像大部分攻击，该漏洞发生在客户端。XSS 最常见的基本形式是在用户提交的内容中放入 JavaScript 以便偷取用户 cookie 中的数据。由于大部分站点使用 cookie 和 session 验证访客，偷取的数据可用于模拟该用户-如果是一个常见的用户账户就会深受麻烦，如果是管理员账户甚至是彻底的惨败。如果你不在站点中使用 cookie 和 session ID，你的用户就不容易被攻击，但你仍然应该明白这种攻击是如何工作的。</p><p>不像 MySQL 注入攻击，XSS 攻击很难预防。Yahoo、eBay、Apple、以及 Microsoft 都曾经受 XSS 影响。尽管攻击不包含 PHP，但你可以使用 PHP 来剥离用户数据以防止攻击。为了防止 XSS 攻击，你应该限制和过滤用户提交给你站点的数据。正是因为这个原因，大部分在线公告板都不允许在提交的数据中使用 HTML 标签，而是用自定义的标签格式代替，例如 [b] 和 [linkto]。</p><p>让我们来看一个如何防止这类攻击的简单脚本。对于更完善的解决办法，可以使用 SafeHTML，本文的后面部分会讨论到。</p><blockquote><p><span style="">function</span><span style=""> </span><span style="">transform_HTML</span><span style="">(</span><span style="">$string</span><span style="">,</span><span style=""> </span><span style="">$length</span><span style=""> = </span><span style="">null</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">// Helps prevent XSS attacks</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">// Remove dead space.</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">trim</span><span style="">(</span><span style="">$string</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">// Prevent potential Unicode codec problems.</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">utf8_decode</span><span style="">(</span><span style="">$string</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">// HTMLize HTML-specific characters.</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">htmlentities</span><span style="">(</span><span style="">$string</span><span style="">,</span><span style=""> </span><span style="">ENT_NOQUOTES</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">str_replace</span><span style="">(</span><span style="">"#"</span><span style="">,</span><span style=""> </span><span style="">"#"</span><span style="">,</span><span style=""> </span><span style="">$string</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">str_replace</span><span style="">(</span><span style="">"%"</span><span style="">,</span><span style=""> </span><span style="">"%"</span><span style="">,</span><span style=""> </span><span style="">$string</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$length</span><span style=""> = </span><span style="">intval</span><span style="">(</span><span style="">$length</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span>if<span style=""> </span><span style="">(</span><span style="">$length</span><span style=""> &gt; </span><span style="">0</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$string</span><span style=""> = </span><span style="">substr</span><span style="">(</span><span style="">$string</span><span style="">,</span><span style=""> </span><span style="">0</span><span style="">,</span><span style=""> </span><span style="">$length</span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">}</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">return</span><span style=""> </span><span style="">$string</span><span style="">;</span></p><p><span style="">}</span></p></blockquote><p>这个函数将 HTML 特定的字符转换为 HTML 字面字符。一个浏览器对任何通过这个脚本的 HTML 以非标记的文本呈现。例如，考虑下面的 HTML 字符串：</p><blockquote><p>&lt;STRONG&gt;Bold Text&lt;/STRONG&gt;</p></blockquote><p>一般情况下，HTML 会显示为：Bold Text</p><p>但是，通过 transform_HTML() 后，它就像原始输入一样呈现。原因是处理的字符串中的标签字符串转换为 HTML 实体。transform_HTML() 的结果字符串的纯文本看起来像下面这样：</p><blockquote><p>&lt;STRONG&gt;Bold Text&lt;/STRONG&gt;</p></blockquote><p>该函数的实质是 htmlentities() 函数调用，它会将 &lt;、&gt;、和 &amp; 转换为 &amp;lt;、&amp;gt;、和 &amp;amp;。尽管这会处理大部分的普通攻击，但有经验的 XSS 攻击者有另一种把戏：用十六进制或 UTF-8 编码恶意脚本，而不是采用普通的 ASCII 文本，从而希望能绕过你的过滤器。他们可以在 URL 的 GET 变量中发送代码，告诉浏览器，“这是十六进制代码，你能帮我运行吗？” 一个十六进制例子看起来像这样：</p><blockquote><p>&lt;a href="<a href="http://host/a.php?variable=%22%3e" rel="nofollow">http://host/a.php?variable=%22%3e</a> %3c%53%43%52%49%50%54%3e%44%6f%73%6f%6d%65%74%68%69%6e%67%6d%61%6c%69%63%69%6f%75%73%3c%2f%53%43%52%49%50%54%3e"&gt;</p></blockquote><p>浏览器渲染这个信息的时候，结果就是：</p><blockquote><p>&lt;a href="<a href="http://host/a.php?variable=" rel="nofollow">http://host/a.php?variable=</a>"&gt; &lt;SCRIPT&gt;Dosomethingmalicious&lt;/SCRIPT&gt;</p></blockquote><p>为了防止这种情况，transform_HTML() 采用额外的步骤把 # 和 % 符号转换为它们的实体，从而避免十六进制攻击，并转换 UTF-8 编码的数据。</p><p>最后，为了防止某些人用很长的输入超载字符串从而导致某些东西崩溃，你可以添加一个可选的 $length 参数来截取你指定最大长度的字符串。</p><p><strong>使用 SafeHTML</strong></p><p>之前脚本的问题比较简单，它不允许任何类型的用户标记。不幸的是，这里有上百种方法能使 JavaScript 跳过用户的过滤器，并且要从用户输入中剥离全部 HTML，还没有方法可以防止这种情况。</p><p>当前，没有任何一个脚本能保证无法被破解，尽管有一些确实比大部分要好。有白名单和黑名单两种方法加固安全，白名单比较简单而且更加有效。</p><p>一个白名单解决方案是 PixelApes 的 SafeHTML 反跨站脚本解析器。</p><p>SafeHTML 能识别有效 HTML，能追踪并剥离任何危险标签。它用另一个称为 HTMLSax 的软件包进行解析。</p><p>按照下面步骤安装和使用 SafeHTML：</p><ol><li><p>到 <a href="http://pixel-apes.com/safehtml/?page=safehtml" rel="nofollow">http://pixel-apes.com/safehtml/?page=safehtml</a> 下载最新版本的 SafeHTML。</p></li><li><p>把文件放到你服务器的类文件夹。该文件夹包括 SafeHTML 和 HTMLSax 功能所需的所有东西。</p></li><li><p>在脚本中 include SafeHTML 类文件（safehtml.php）。</p></li><li><p>创建一个名为 $safehtml 的新 SafeHTML 对象。</p></li><li><p>用 $safehtml-&gt;parse() 方法清理你的数据。</p></li></ol><p>这是一个完整的例子：</p><blockquote><p><span style="">&lt;?php</span></p><p><span style="">/* If you''re storing the HTMLSax3.php in the /classes directory, along</span></p><p><span style="">&nbsp;&nbsp; with the safehtml.php script, define XML_HTMLSAX3 as a null string. */</span></p><p><span style="">define</span><span style="">(</span>XML_HTMLSAX3<span style="">,</span><span style=""> </span><span style="">''''</span><span style="">);</span></p><p><span style="">// Include the class file.</span></p><p><span style="">require_once</span><span style="">(</span><span style="">''classes/safehtml.php''</span><span style="">);</span></p><p><span style="">// Define some sample bad code.</span></p><p><span style="">$data</span><span style=""> = </span><span style="">"This data would raise an alert &lt;script&gt;alert(''XSS Attack'')&lt;/script&gt;"</span><span style="">;</span></p><p><span style="">// Create a safehtml object.</span></p><p><span style="">$safehtml</span><span style=""> = </span>new<span style=""> </span><span style="">safehtml</span><span style="">();</span></p><p><span style="">// Parse and sanitize the data.</span></p><p><span style="">$safe_data</span><span style=""> = </span><span style="">$safehtml</span><span style="">-&gt;</span><span style="">parse</span><span style="">(</span><span style="">$data</span><span style="">);</span></p><p><span style="">// Display result.</span></p><p><span style="">echo</span><span style=""> </span><span style="">''The sanitized data is &lt;br /&gt;''</span><span style=""> </span><span style="">.</span><span style=""> </span><span style="">$safe_data</span><span style="">;</span></p><p><span style="">?&gt;</span></p></blockquote><p>如果你想清理脚本中的任何其它数据，你不需要创建一个新的对象；在你的整个脚本中只需要使用 $safehtml-&gt;parse() 方法。</p><p><strong>什么可能会出现问题？</strong></p><p>你可能犯的最大错误是假设这个类能完全避免 XSS 攻击。SafeHTML 是一个相当复杂的脚本，几乎能检查所有事情，但没有什么是能保证的。你仍然需要对你的站点做参数验证。例如，该类不能检查给定变量的长度以确保能适应数据库的字段。它也不检查缓冲溢出问题。</p><p>XSS 攻击者很有创造力，他们使用各种各样的方法来尝试达到他们的目标。可以阅读 RSnake 的 XSS 教程<a href="http://ha.ckers.org/xss.html" rel="nofollow">http://ha.ckers.org/xss.html</a> ，看一下这里有多少种方法尝试使代码跳过过滤器。SafeHTML 项目有很好的程序员一直在尝试阻止 XSS 攻击，但无法保证某些人不会想起一些奇怪和新奇的方法来跳过过滤器。</p><p>注意：XSS 攻击严重影响的一个例子 <a href="http://namb.la/popular/tech.html" rel="nofollow">http://namb.la/popular/tech.html</a>，其中显示了如何一步一步创建一个让 MySpace 服务器过载的 JavaScript XSS 蠕虫。</p><p><span style="color: rgb(255, 0, 0);"><strong>用单向哈希保护数据</strong></span></p><p>该脚本对输入的数据进行单向转换，换句话说，它能对某人的密码产生哈希签名，但不能解码获得原始密码。为什么你希望这样呢？应用程序会存储密码。一个管理员不需要知道用户的密码，事实上，只有用户知道他/她自己的密码是个好主意。系统（也仅有系统）应该能识别一个正确的密码；这是 Unix 多年来的密码安全模型。单向密码安全按照下面的方式工作：</p><ol><li><p>当一个用户或管理员创建或更改一个账户密码时，系统对密码进行哈希并保存结果。主机系统会丢弃明文密码。</p></li><li><p>当用户通过任何方式登录到系统时，再次对输入的密码进行哈希。</p></li><li><p>主机系统丢弃输入的明文密码。</p></li><li><p>当前新哈希的密码和之前保存的哈希相比较。</p></li><li><p>如果哈希的密码相匹配，系统就会授予访问权限。</p></li></ol><p>主机系统完成这些并不需要知道原始密码；事实上，原始密码完全无所谓。一个副作用是，如果某人侵入系统并盗取了密码数据库，入侵者会获得很多哈希后的密码，但无法把它们反向转换为原始密码。当然，给足够时间、计算能力，以及弱用户密码，一个攻击者还是有可能采用字典攻击找出密码。因此，别轻易让人碰你的密码数据库，如果确实有人这样做了，让每个用户更改他们的密码。</p><p><strong>加密 Vs 哈希</strong></p><p>技术上来来说，哈希过程并不是加密。哈希和加密是不同的，这有两个理由：</p><p>不像加密，哈希数据不能被解密。</p><p>是有可能（但非常罕见）两个不同的字符串会产生相同的哈希。并不能保证哈希是唯一的，因此别像数据库中的唯一键那样使用哈希。</p><blockquote><p><span style="">function</span><span style=""> </span><span style="">hash_ish</span><span style="">($</span><span style="">string</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span>return<span style=""> </span><span style="">md5</span><span style="">($</span><span style="">string</span><span style="">);</span></p><p><span style="">}</span></p></blockquote><p>上面的 md5() 函数基于 RSA 数据安全公司的消息摘要算法（即 MD5）返回一个由 32 个字符组成的十六进制串。然后你可以将那个 32 位字符串插入到数据库中和另一个 md5 字符串相比较，或者直接用这 32 个字符。</p><p><strong>破解脚本</strong></p><p>几乎不可能解密 MD5 数据。或者说很难。但是，你仍然需要好的密码，因为用一整个字典生成哈希数据库仍然很简单。有一些在线 MD5 字典，当你输入 06d80eb0c50b49a509b49f2424e8c805 后会得到结果 “dog”。因此，尽管技术上 MD5 不能被解密，这里仍然有漏洞，如果某人获得了你的密码数据库，你可以肯定他们肯定会使用 MD5 字典破译。因此，当你创建基于密码的系统的时候尤其要注意密码长度（最小 6 个字符，8 个或许会更好）和包括字母和数字。并确保这个密码不在字典中。</p><p><span style="color: rgb(255, 0, 0);"><strong>用 Mcrypt 加密数据</strong></span></p><p>如果你不需要以可阅读形式查看密码，采用 MD5 就足够了。不幸的是，这里并不总是有可选项，如果你提供以加密形式存储某人的信用卡信息，你可能需要在后面的某个地方进行解密。</p><p>最早的一个解决方案是 Mcrypt 模块，这是一个用于允许 PHP 高速加密的插件。Mcrypt 库提供了超过 30 种用于加密的计算方法，并且提供口令确保只有你（或者你的用户）可以解密数据。</p><p>让我们来看看使用方法。下面的脚本包含了使用 Mcrypt 加密和解密数据的函数：</p><blockquote><p><span style="">&lt;?php</span></p><p><span style="">$data</span><span style=""> = </span><span style="">"Stuff you want encrypted"</span><span style="">;</span></p><p><span style="">$key</span><span style=""> = </span><span style="">"Secret passphrase used to encrypt your data"</span><span style="">;</span></p><p><span style="">$cipher</span><span style=""> = </span><span style="">"MCRYPT_SERPENT_256"</span><span style="">;</span></p><p><span style="">$mode</span><span style=""> = </span><span style="">"MCRYPT_MODE_CBC"</span><span style="">;</span></p><p><span style="">function</span><span style=""> </span><span style="">encrypt</span><span style="">(</span><span style="">$data</span><span style="">,</span><span style=""> </span><span style="">$key</span><span style="">,</span><span style=""> </span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">// Encrypt data</span></p><p><span style="">return</span><span style=""> </span><span style="">(</span><span style="">string</span><span style="">)</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">base64_encode</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">(</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">mcrypt_encrypt</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">(</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$cipher</span><span style="">,</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">substr</span><span style="">(</span><span style="">md5</span><span style="">(</span><span style="">$key</span><span style="">),</span><span style="">0</span><span style="">,</span><span style="">mcrypt_get_key_size</span><span style="">(</span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">)),</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$data</span><span style="">,</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$mode</span><span style="">,</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">substr</span><span style="">(</span><span style="">md5</span><span style="">(</span><span style="">$key</span><span style="">),</span><span style="">0</span><span style="">,</span><span style="">mcrypt_get_block_size</span><span style="">(</span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">))</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">)</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">);</span></p><p><span style="">}</span></p><p><span style="">function</span><span style=""> </span><span style="">decrypt</span><span style="">(</span><span style="">$data</span><span style="">,</span><span style=""> </span><span style="">$key</span><span style="">,</span><span style=""> </span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">// Decrypt data</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">return</span><span style=""> </span><span style="">(</span><span style="">string</span><span style="">)</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">mcrypt_decrypt</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">(</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$cipher</span><span style="">,</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">substr</span><span style="">(</span><span style="">md5</span><span style="">(</span><span style="">$key</span><span style="">),</span><span style="">0</span><span style="">,</span><span style="">mcrypt_get_key_size</span><span style="">(</span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">)),</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">base64_decode</span><span style="">(</span><span style="">$data</span><span style="">),</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$mode</span><span style="">,</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">substr</span><span style="">(</span><span style="">md5</span><span style="">(</span><span style="">$key</span><span style="">),</span><span style="">0</span><span style="">,</span><span style="">mcrypt_get_block_size</span><span style="">(</span><span style="">$cipher</span><span style="">,</span><span style=""> </span><span style="">$mode</span><span style="">))</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">);</span></p><p><span style="">}</span></p><p><span style="">?&gt;</span></p></blockquote><p>mcrypt() 函数需要几个信息：</p><ul><li><p>需要加密的数据</p></li><li><p>用于加密和解锁数据的口令，也称为键。</p></li><li><p>用于加密数据的计算方法，也就是用于加密数据的算法。该脚本使用了 MCRYPT_SERPENT_256，但你可以从很多算法中选择，包括 MCRYPT_TWOFISH192、MCRYPT_RC2、MCRYPT_DES、和 MCRYPT_LOKI97。</p></li><li><p>加密数据的模式。这里有几个你可以使用的模式，包括电子密码本（Electronic Codebook） 和加密反馈（Cipher Feedback）。该脚本使用 MCRYPT_MODE_CBC 密码块链接。</p></li><li><p>一个 初始化向量-也称为 IV 或者种子，用于为加密算法设置种子的额外二进制位。也就是使算法更难于破解的额外信息。</p></li><li><p>键和 IV 字符串的长度，这可能随着加密和块而不同。使用 mcrypt_get_key_size() 和 mcrypt_get_block_size() 函数获取合适的长度；然后用 substr() 函数将键的值截取为合适的长度。（如果键的长度比要求的短，别担心，Mcrypt 会用 0 填充。）</p></li></ul><p>如果有人窃取了你的数据和短语，他们只能一个个尝试加密算法直到找到正确的那一个。因此，在使用它之前我们通过对键使用md5() 函数增加安全，就算他们获取了数据和短语，入侵者也不能获得想要的东西。</p><p>入侵者同时需要函数，数据和口令，如果真是如此，他们可能获得了对你服务器的完整访问，你只能大清洗了。</p><p>这里还有一个数据存储格式的小问题。Mcrypt 以难懂的二进制形式返回加密后的数据，这使得当你将其存储到 MySQL 字段的时候可能出现可怕错误。因此，我们使用 base64encode() 和 base64decode() 函数转换为和 SQL 兼容的字母格式和可检索行。</p><p><strong>破解脚本</strong></p><p>除了实验多种加密方法，你还可以在脚本中添加一些便利。例如，不用每次都提供键和模式，而是在包含的文件中声明为全局常量。</p><p><span style="color: rgb(255, 0, 0);"><strong>生成随机密码</strong></span></p><p>随机（但难以猜测）字符串在用户安全中很重要。例如，如果某人丢失了密码并且你使用 MD5 哈希，你不可能，也不希望查找回来。而是应该生成一个安全的随机密码并发送给用户。为了访问你站点的服务，另外一个用于生成随机数字的应用程序会创建有效链接。下面是创建密码的一个函数：</p><blockquote><p><span style="">&lt;?php</span></p><p><span style=""> </span><span style="">function</span><span style=""> </span><span style="">make_password</span><span style="">(</span><span style="">$num_chars</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span>if<span style=""> </span><span style="">((</span><span style="">is_numeric</span><span style="">(</span><span style="">$num_chars</span><span style="">))</span><span style=""> &amp;&amp;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">(</span><span style="">$num_chars</span><span style=""> &gt; </span><span style="">0</span><span style="">)</span><span style=""> &amp;&amp;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">(</span><span style="">! </span><span style="">is_null</span><span style="">(</span><span style="">$num_chars</span><span style="">)))</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$password</span><span style=""> = </span><span style="">''''</span><span style="">;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$accepted_chars</span><span style=""> = </span><span style="">''abcdefghijklmnopqrstuvwxyz1234567890''</span><span style="">;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">// Seed the generator if necessary.</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">srand</span><span style="">(((</span><span style="">int</span><span style="">)((</span><span style="">double</span><span style="">)</span><span style="">microtime</span><span style="">()</span><span style="">*</span><span style="">1000003</span><span style="">))</span><span style=""> </span><span style="">);</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>for<span style=""> </span><span style="">(</span><span style="">$i</span><span style="">=</span><span style="">0</span><span style="">;</span><span style=""> </span><span style="">$i</span><span style="">&lt;=</span><span style="">$num_chars</span><span style="">;</span><span style=""> </span><span style="">$i</span><span style="">++</span><span style="">)</span><span style=""> </span><span style="">{</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$random_number</span><span style=""> = </span><span style="">rand</span><span style="">(</span><span style="">0</span><span style="">,</span><span style=""> </span><span style="">(</span><span style="">strlen</span><span style="">(</span><span style="">$accepted_chars</span><span style="">)</span><span style=""> -</span><span style="">1</span><span style="">));</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">$password</span><span style=""> </span><span style="">.</span><span style="">= </span><span style="">$accepted_chars</span><span style="">[</span><span style="">$random_number</span><span style="">]</span><span style=""> </span><span style="">;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">}</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="">return</span><span style=""> </span><span style="">$password</span><span style="">;</span></p><p><span style="">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="">}</span></p><p><span style="">}</span></p><p><span style="">?&gt;</span></p></blockquote><p><strong>使用脚本</strong></p><p>make_password() 函数返回一个字符串，因此你需要做的就是提供字符串的长度作为参数：</p><blockquote><p><span style="">&lt;?php</span></p><p><span style="">$fifteen_character_password</span><span style=""> = </span><span style="">make_password</span><span style="">(</span><span style="">15</span><span style="">);</span></p><p><span style="">?&gt;</span></p></blockquote><p>函数按照下面步骤工作：</p><ul><li><p>函数确保 $num_chars 是非零的正整数。</p></li><li><p>函数初始化 $accepted_chars 变量为密码可能包含的字符列表。该脚本使用所有小写字母和数字 0 到 9，但你可以使用你喜欢的任何字符集合。（LCTT 译注：有时候为了便于肉眼识别，你可以将其中的 0 和 O，1 和 l 之类的都去掉。）</p></li><li><p>随机数生成器需要一个种子，从而获得一系列类随机值（PHP 4.2 及之后版本中并不需要，会自动播种）。</p></li><li><p>函数循环 $num_chars 次，每次迭代生成密码中的一个字符。</p></li><li><p>对于每个新字符，脚本查看 $accepted_chars 的长度，选择 0 和长度之间的一个数字，然后添加 $accepted_chars中该数字为索引值的字符到 $password。</p></li><li><p>循环结束后，函数返回 $password。</p></li></ul>'),
  (27, 233, '<p>使用关键字 <span style="color: rgb(0, 128, 0);"><strong>typedef</strong></span> 可以为类型起一个新的别名，语法格式为：typedef &nbsp;oldName &nbsp;newName;</p><p>typedef char ARRAY20[20];表示 ARRAY20 是类型<code>char [20]</code>的别名</p><p>它等价于：</p><p>	char a1[20], a2[20], s1[20], s2[20];</p><p>C语言允许为一个数据类型起一个新的别名，就像给人起“绰号”一样。</p><p>起别名的目的不是为了提高程序运行效率，而是为了编码方便。例如有一个结构体的名字是 stu，要想定义一个结构体变量就得这样写：</p><p>	struct stu stu1;</p><p>struct 看起来就是多余的，但不写又会报错。如果为 struct stu 起了一个别名 STU，书写起来就简单了：</p><p>	STU stu1;</p><p>这种写法更加简练，意义也非常明确，不管是在标准头文件中还是以后的编程实践中，都会大量使用这种别名。</p><p>使用关键字 <span style="color: rgb(0, 128, 0);"><strong>typedef</strong></span> 可以为类型起一个新的别名，语法格式为：</p><p>	typedef &nbsp;oldName &nbsp;newName;</p><p>oldName 是类型原来的名字，newName 是类型新的名字。例如：</p><pre><code><ol class="snippet-num"><li><span class="sh_keyword">typedef</span> <span class="sh_type">int</span> INTEGER<span class="sh_symbol">;</span></li><li><span class="sh_usertype">INTEGER</span><span class="sh_normal"> </span>a<span class="sh_symbol">,</span> b<span class="sh_symbol">;</span></li><li>a <span class="sh_symbol">=</span> <span class="sh_number">1</span><span class="sh_symbol">;</span></li><li>b <span class="sh_symbol">=</span> <span class="sh_number">2</span><span class="sh_symbol">;</span></li></ol></code></pre><p><code>INTEGER a, b;</code>等效于<code>int a, b;</code>。</p><p>typedef 还可以给数组、指针、结构体等类型定义别名。先来看一个给数组类型定义别名的例子：</p><p>	typedef char ARRAY20[20];</p><p>表示 ARRAY20 是类型<code>char [20]</code>的别名。它是一个长度为 20 的数组类型。接着可以用 ARRAY20 定义数组：</p><p>	ARRAY20 a1, a2, s1, s2;</p><p>它等价于：</p><p>	char a1[20], a2[20], s1[20], s2[20];</p><p>注意，数组也是有类型的。例如<code>char a1[20];</code>定义了一个数组 a1，它的类型就是 char [20]，这一点已在VIP教程《<a href="http://c.biancheng.net/cpp/html/3244.html" target="_blank">数组和指针绝不等价，数组是另外一种类型</a>》中讲解过。</p><p>又如，为结构体类型定义别名：</p><pre><code><ol class="snippet-num"><li><span class="sh_keyword">typedef</span> <span class="sh_keyword">struct</span><span class="sh_normal"> </span><span class="sh_classname">stu</span><span class="sh_cbracket">{</span></li><li>    <span class="sh_type">char</span> name<span class="sh_symbol">[</span><span class="sh_number">20</span><span class="sh_symbol">];</span></li><li>    <span class="sh_type">int</span> age<span class="sh_symbol">;</span></li><li>    <span class="sh_type">char</span> sex<span class="sh_symbol">;</span></li><li><span class="sh_cbracket">}</span> STU<span class="sh_symbol">;</span></li></ol></code></pre><p>STU 是 struct stu 的别名，可以用 STU 定义结构体变量：</p><p>	STU body1,body2;</p><p>它等价于：</p><p>	struct stu body1, body2;</p><p>再如，为指针类型定义别名：</p><p>	typedef&nbsp;int (*PTR_TO_ARR)[4];</p><p>表示 PTR_TO_ARR 是类型<code>int * [4]</code>的别名，它是一个二维数组指针类型。接着可以使用 PTR_TO_ARR 定义二维数组指针：</p><p>	PTR_TO_ARR p1, p2;</p><p>按照类似的写法，还可以为函数指针类型定义别名：</p><p>	typedef int (*PTR_TO_FUNC)(int, int);<br>	PTR_TO_FUNC pfunc;</p><p>【示例】为指针定义别名。</p><pre><code><ol class="snippet-num"><li><span class="sh_preproc">#include</span> <span class="sh_string">&lt;stdio.h&gt;</span></li><li><br></li><li><span class="sh_keyword">typedef</span> <span class="sh_type">char</span> <span class="sh_symbol">(*</span>PTR_TO_ARR<span class="sh_symbol">)[</span><span class="sh_number">30</span><span class="sh_symbol">];</span></li><li><span class="sh_keyword">typedef</span> <span class="sh_type">int</span> <span class="sh_symbol">(*</span>PTR_TO_FUNC<span class="sh_symbol">)(</span><span class="sh_type">int</span><span class="sh_symbol">,</span> <span class="sh_type">int</span><span class="sh_symbol">);</span></li><li><br></li><li><span class="sh_type">int</span> <span class="sh_function">max</span><span class="sh_symbol">(</span><span class="sh_type">int</span> a<span class="sh_symbol">,</span> <span class="sh_type">int</span> b<span class="sh_symbol">)</span><span class="sh_cbracket">{</span></li><li>    <span class="sh_keyword">return</span> a<span class="sh_symbol">&gt;</span>b <span class="sh_symbol">?</span> a <span class="sh_symbol">:</span> b<span class="sh_symbol">;</span></li><li><span class="sh_cbracket">}</span></li><li><br></li><li><span class="sh_type">char</span> str<span class="sh_symbol">[</span><span class="sh_number">3</span><span class="sh_symbol">][</span><span class="sh_number">30</span><span class="sh_symbol">]</span> <span class="sh_symbol">=</span> <span class="sh_cbracket">{</span></li><li>    <span class="sh_string">"http://c.biancheng.net"</span><span class="sh_symbol">,</span></li><li>    <span class="sh_string">"C语言中文网"</span><span class="sh_symbol">,</span></li><li>    <span class="sh_string">"C-Language"</span></li><li><span class="sh_cbracket">}</span><span class="sh_symbol">;</span></li><li><br></li><li><span class="sh_type">int</span> <span class="sh_function">main</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>    <span class="sh_usertype">PTR_TO_ARR</span><span class="sh_normal"> </span>parr <span class="sh_symbol">=</span> str<span class="sh_symbol">;</span></li><li>    <span class="sh_usertype">PTR_TO_FUNC</span><span class="sh_normal"> </span>pfunc <span class="sh_symbol">=</span> max<span class="sh_symbol">;</span></li><li>    <span class="sh_type">int</span> i<span class="sh_symbol">;</span></li><li>   </li><li>    <span class="sh_function">printf</span><span class="sh_symbol">(</span><span class="sh_string">"max: %d</span><span class="sh_specialchar">\\n</span><span class="sh_string">"</span><span class="sh_symbol">,</span> <span class="sh_symbol">(*</span>pfunc<span class="sh_symbol">)(</span><span class="sh_number">10</span><span class="sh_symbol">,</span> <span class="sh_number">20</span><span class="sh_symbol">));</span></li><li>    <span class="sh_keyword">for</span><span class="sh_symbol">(</span>i<span class="sh_symbol">=</span><span class="sh_number">0</span><span class="sh_symbol">;</span> i<span class="sh_symbol">&lt;</span><span class="sh_number">3</span><span class="sh_symbol">;</span> i<span class="sh_symbol">++)</span><span class="sh_cbracket">{</span></li><li>        <span class="sh_function">printf</span><span class="sh_symbol">(</span><span class="sh_string">"str[%d]: %s</span><span class="sh_specialchar">\\n</span><span class="sh_string">"</span><span class="sh_symbol">,</span> i<span class="sh_symbol">,</span> <span class="sh_symbol">*(</span>parr<span class="sh_symbol">+</span>i<span class="sh_symbol">));</span></li><li>    <span class="sh_cbracket">}</span></li><li><br></li><li>    <span class="sh_keyword">return</span> <span class="sh_number">0</span><span class="sh_symbol">;</span></li><li><span class="sh_cbracket">}</span></li></ol></code></pre><p>运行结果：</p><p>max: 20</p><p>str[0]: <a href="http://c.biancheng.net" rel="nofollow">http://c.biancheng.net</a></p><p>str[1]: C语言中文网</p><p>str[2]: C-Language</p><p><span style="color: rgb(178, 34, 34);">需要强调的是，typedef 是赋予现有类型一个新的名字，而不是创建新的类型。为了“见名知意”，请尽量使用含义明确的标识符，并且尽量大写。</span></p><h2>	typedef 和 #define 的区别</h2><p>typedef 在表现上有时候类似于 #define，但它和宏替换之间存在一个关键性的区别。正确思考这个问题的方法就是把 typedef 看成一种彻底的“封装”类型，声明之后不能再往里面增加别的东西。</p><p>1) 可以使用其他类型说明符对宏类型名进行扩展，但对 typedef 所定义的类型名却不能这样做。如下所示：</p><p>	#define INTERGE int<br>	unsigned INTERGE n; &nbsp;//没问题<br>	<br>	typedef int INTERGE;<br>	unsigned INTERGE n; &nbsp;//错误，不能在 INTERGE 前面添加 unsigned</p><p>2) 在连续定义几个变量的时候，typedef 能够保证定义的所有变量均为同一类型，而 #define 则无法保证。例如：</p><p>	#define PTR_INT int *<br>	PTR_INT p1, p2;</p><p>经过宏替换以后，第二行变为：</p><p>	int *p1, p2;</p><p>这使得 p1、p2 成为不同的类型：p1 是指向 int 类型的指针，p2 是 int 类型。</p><p>相反，在下面的代码中：</p><p>	typedef int *&nbsp;PTR_INT<br>	PTR_INT p1, p2;</p><p>p1、p2 类型相同，它们都是指向 int 类型的指针。</p>'),
  (28, 234, '<pre><code><span class="hljs-preprocessor">#include &lt;stdio.h&gt;</span>\r\n<span class="hljs-preprocessor">#include &lt;malloc.h&gt;</span>\r\n<span class="hljs-preprocessor">#include &lt;stdlib.h&gt;</span>\r\n<span class="hljs-preprocessor">#include &lt;stdbool.h&gt;</span>\r\n<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> Arr{\r\n<span class="hljs-keyword">int</span> len;\r\n<span class="hljs-keyword">int</span> num;\r\n<span class="hljs-keyword">int</span> *head;\r\n}A;\r\n<span class="hljs-keyword">void</span> initArr(A *arr,<span class="hljs-keyword">int</span> len){\r\n       arr-&gt;head=(<span class="hljs-keyword">int</span> *)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>)*len);\r\n       <span class="hljs-keyword">if</span>(NULL==arr){\r\n              <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Dynamic storage fail to distribute!"</span>);\r\n              <span class="hljs-built_in">exit</span>(-<span class="hljs-number">1</span>);\r\n       }\r\n       arr-&gt;len=len;\r\n       arr-&gt;num=<span class="hljs-number">0</span>;\r\n       <span class="hljs-keyword">return</span>;\r\n}\r\n<span class="hljs-keyword">bool</span> isFull(A *arr){\r\n       <span class="hljs-keyword">if</span>(arr-&gt;num&gt;=arr-&gt;len){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n       }\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n}\r\n<span class="hljs-keyword">bool</span> isEmpty(A *arr){\r\n       <span class="hljs-keyword">if</span>(arr-&gt;num==<span class="hljs-number">0</span>){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n       }\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n\r\n\r\n}\r\n<span class="hljs-keyword">bool</span> insert(A *arr,<span class="hljs-keyword">int</span> index,<span class="hljs-keyword">int</span> val){\r\n     <span class="hljs-keyword">if</span>(isFull(arr)){\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n     }\r\n     <span class="hljs-keyword">if</span>(index&lt;<span class="hljs-number">0</span>&amp;&amp;index&gt;arr-&gt;len-<span class="hljs-number">1</span>){\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n     }\r\n\r\n       <span class="hljs-keyword">int</span> temp=arr-&gt;len;\r\n       <span class="hljs-keyword">while</span>(temp&gt;index){\r\n              arr-&gt;head[temp]=arr-&gt;head[temp-<span class="hljs-number">1</span>];\r\n              --temp;\r\n       }\r\n       arr-&gt;head[index]=val;\r\n       arr-&gt;num++;\r\n       <span class="hljs-keyword">return</span>  <span class="hljs-keyword">true</span>;\r\n}\r\n<span class="hljs-keyword">bool</span> append(A *arr,<span class="hljs-keyword">int</span> val){\r\n       <span class="hljs-keyword">if</span>(isFull(arr)){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n       }<span class="hljs-keyword">else</span>{\r\n       arr-&gt;head[arr-&gt;num]=val;\r\n       (arr-&gt;num)++;\r\n       }\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n}\r\n<span class="hljs-keyword">bool</span> remove_arr(A *arr,<span class="hljs-keyword">int</span> index){\r\n       <span class="hljs-keyword">if</span>(arr-&gt;num&lt;=<span class="hljs-number">0</span>){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n       }\r\n       <span class="hljs-keyword">if</span>(index&lt;<span class="hljs-number">0</span>&amp;&amp;index&gt;arr-&gt;num-<span class="hljs-number">1</span>){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n       }\r\n       <span class="hljs-keyword">int</span> temp=index;\r\n       <span class="hljs-keyword">while</span>(temp&lt;arr-&gt;num-<span class="hljs-number">1</span>){\r\n              arr-&gt;head[temp]=arr-&gt;head[temp+<span class="hljs-number">1</span>];\r\n              temp++;\r\n       }\r\n       --arr-&gt;num;\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n}\r\n<span class="hljs-keyword">void</span> show_arr(A *arr){\r\n           <span class="hljs-keyword">int</span> i;\r\n       <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>;i&lt;arr-&gt;num;i++){\r\n              <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%d "</span>,arr-&gt;head[i]);\r\n       }\r\n        <span class="hljs-built_in">printf</span>(<span class="hljs-string">"\\n"</span>);\r\n\r\n}\r\n<span class="hljs-keyword">bool</span> inverse(A *arr){\r\n       <span class="hljs-keyword">if</span>(arr-&gt;num&lt;=<span class="hljs-number">0</span>){\r\n              <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n       }\r\n       <span class="hljs-keyword">int</span> temp=<span class="hljs-number">0</span>;\r\n       <span class="hljs-keyword">int</span> temp2=arr-&gt;num;\r\n       <span class="hljs-keyword">while</span>(temp!=temp2){\r\n              <span class="hljs-keyword">int</span> x=arr-&gt;head[temp];\r\n              arr-&gt;head[temp]=arr-&gt;head[temp2-<span class="hljs-number">1</span>];\r\n              arr-&gt;head[temp2-<span class="hljs-number">1</span>]=x;\r\n              temp++;\r\n              temp2--;\r\n       }\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n}\r\n<span class="hljs-keyword">bool</span> replace(A * arr,<span class="hljs-keyword">int</span> index,<span class="hljs-keyword">int</span> val){\r\n       <span class="hljs-keyword">if</span>(arr-&gt;num&lt;=<span class="hljs-number">0</span> || index&lt;<span class="hljs-number">0</span> ||index &gt;arr-&gt;num-<span class="hljs-number">1</span>){\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;\r\n       }\r\n       arr-&gt;head[index]=val;\r\n       <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;\r\n}\r\n<span class="hljs-keyword">int</span> main(<span class="hljs-keyword">void</span>){\r\n       A arr;\r\n       initArr(&amp;arr,<span class="hljs-number">6</span>);\r\n       append(&amp;arr,<span class="hljs-number">4</span>);\r\n       append(&amp;arr,<span class="hljs-number">2</span>);\r\n       append(&amp;arr,<span class="hljs-number">3</span>);\r\n       append(&amp;arr,<span class="hljs-number">1</span>);\r\n       append(&amp;arr,<span class="hljs-number">1</span>);\r\n       insert(&amp;arr,<span class="hljs-number">0</span>,<span class="hljs-number">5</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       remove_arr(&amp;arr,<span class="hljs-number">0</span>);\r\n       append(&amp;arr,<span class="hljs-number">0</span>);\r\n       append(&amp;arr,<span class="hljs-number">2</span>);\r\n       append(&amp;arr,<span class="hljs-number">30</span>);\r\n       append(&amp;arr,<span class="hljs-number">23</span>);\r\n       inverse(&amp;arr);\r\n       replace(&amp;arr,<span class="hljs-number">3</span>,<span class="hljs-number">8</span>);\r\n\r\n    show_arr(&amp;arr);\r\n\r\n}</code></pre>'),
  (29, 235, '<p>修改php配置文件中的session.gc_maxlifetime。如果想了解更多session回收机制，继续阅读。（本文环境php5.2）</p><p>概述：每一次php请求，会有1/100的概率（默认值）触发“session回收”。如果“session回收”发生，那就会检查/tmp/sess_*的文件，如果最后的修改时间到现在超过了1440秒（gc_maxlifetime的值），就将其删除，意味着这些session过期失效。</p><p>1. session在server端（一般是Apache with PHP module）如何存在的？</p><p>默认的，php会将session保存在/tmp目录下，文件名为这个样子：sess_01aab840166fd1dc253e3b4a3f0b8381。每一个文件对应了一个session（会话）。</p><p>more /tmp/sess_01aab840166fd1dc253e3b4a3f0b8381</p><p>username|s:9:”jiangfeng”;admin|s:1:”0″;</p><p>#变量名|类型:长度:值</p><p>删除这里的session文件，就表示对应的session失效了。</p><p>2. session在client端（一般是浏览器）如何存在的？</p><p>session在浏览器端，只需要保存session ID（由server端生成的唯一ID）就可以了。有两种保存方式：在cookie中、在url里面。如果cookie中保存session ID，就可以看到浏览器的cookie中有一个PHPSESID变量。如果是URL传递的，就可以看到形如:</p><p>index.php?PHPSESID=01aab840166fd1dc253e3b4a3f0b8381的URL。（在server端通过session.use_cookies来控制使用哪一种方式）</p><p>3. 在server端，php如何判断session文件是否过期？</p><p>如果”最后的修改时间”到”现在”超过了gc_maxlifetime（默认是1440）秒，这个session文件就被认为是过期了，在下一次session回收的时候，如果这个文件仍然没有被更改过，这个session文件就会被删除（session就过期了）。</p><p>简单的说，如果我登录到某网站，如果在1440秒（默认值）内没有操作过，那么对应的session就认为是过期了。</p><p>所以，修改php.ini文件中的gc_maxlifetime变量就可以延长session的过期时间了：（例如，我们把过期时间修改为86400秒）</p><p>session.gc_maxlifetime = 86400</p><p>然后，重启你的web服务（一般是apache）就可以了。</p><p>注意：php5里面session过期使用了回收机制。这里设置时间为86400秒，如果session在86400秒内没有被修改过，那么在下一次“回收”时才真的被删除。</p><p>3. session“回收”何时发生？</p><p>默认情况下，每一次php请求，就会有1/100的概率发生回收，所以可能简单的理解为“每100次php请求就有一次回收发生”。这个概率是通过以下参数控制的</p><p>#概率是gc_probability/gc_divisor</p><p>session.gc_probability = 1</p><p>session.gc_divisor = 100</p><p>注意1：假设这种情况gc_maxlifetime=120，如果某个session文件最后修改时间是120秒之前，那么在下一次回收（1/100的概率）发生前，这个session仍然是有效的。</p><p>注意2：如果你的session使用session.save_path中使用别的地方保存session，session回收机制有可能不会自动处理过期session文件。这时需要定时手动（或者crontab）的删除过期的session：cd /path/to/sessions; find -cmin +24 | xargs rm</p>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (30, 236, '<p>本文介绍了PHP会话控制，主要阐述以下几点内容：</p><p>• 会话控制的产生背景/概念<br>• cookie的维护与生命周期(有效时间)<br>• session的维护与生命周期(回收机制)<br>• cookie与session之间的区别与联系<br>• 问题1：禁用cookie后session为什么会失效？<br>• 问题2：IE浏览器下丢失session，每次刷新页面，都会生成新的sessionID（Firefox浏览器正常）<br>• session、cookie简单实例</p><p><strong>理解会话控制的概念</strong></p><p>理解一个概念就需要理解他的背景及产生的原因，这里引入WEB环境及其HTTP协议。会话控制产生的背景：<br>阅读过HTTP协议相关资料的同学都会知道HTTP协议是WEB服务器与客户端(浏览器)相互通信的协议，它是一种无状态协议，所谓无状态，指的是不会维护http请求数据，http请求是独立的，不持久的。也就是说HTTP协议没有一个内建的机制来维护两个事务之间的状态或者说是关系吧。当一个用户在请求一个页面后再去请求另外一个页面时，HTTP将无法告诉我们这两个请求是否来自同一个用户。</p><p>由此我们就会觉得很奇怪了，平时我们在论坛逛帖子或电商网站购物时，只要我们在这个站点内，不论我们怎么跳转，从一个页面跑到另一个页面，网站总会记得我是谁，比如告诉你购买了哪些东西。这是怎么做到的呢，估计大家猜到了，这就是运用了HTTP会话控制。在网站中跟踪一个变量，通过对变量的跟踪，使多个请求事物之间建立联系，根据授权和用户身份显示不同的内容、不同页面。</p><p><strong>PHP Session会话控制：</strong></p><p>PHP的session会话是通过唯一的会话ID来驱动的，会话ID是一个加密的随机数字，由PHP生成，在会话的生命周期中都会保存在客户端。我们知道客户端（也就是浏览器）保存数据的地方只有cookie，所以PHP的会话ID一般保存在用户机器的cookie中。了解cookie后我们知道，浏览器是可以禁用cookie的，这样会话就会失效。所以PHP会话控制还有一种模式，就是在URL中传递会话ID。如果在浏览网站时我们稍加留心的话，有些URL中有一串看起来像随机数字的字符串，那么其实很有可能就是URL形式的会话控制。</p><p>讲到这里，有些人可能会有疑问了，客户端只是保存一个会话ID，那么会话控制中保存的会话变量比如你购物时买的物品列表等，它们是存放在哪个地方的呢？很显然，会话变量是在服务器端使用的，那么这些会话变量必定存放在服务器端。默认情况下，会话变量保存在服务器的普通文件中（也可以自己配置使用数据库来保存，可以Google一下），会话ID的作用就像是一把钥匙，在服务器端保存会话的文件中找到该会话ID对应的会话变量，比如购买物品的列表。</p><p>那么会话控制的整个过程可能就像这个样子，用户登录或者第一次浏览某个站点的页面时，该站点会生成一个PHP的会话ID并通过cookie发送到客户端（浏览器）。当用户点击该站点的另一个页面时，浏览器开始连接这个URL。在连接之前，浏览器会先搜索本地保存的cookie，如果在cookie中有任何与正在连接的URL相关的cookie，就将它提交到服务器。而刚好在登陆或第一次连接时，已经产生了一个与该网站URL相关的cookie（保存的会话ID），所以当用户再次连接这个站点时，站点就可以通过这个会话ID识别出用户，从服务器的会话文件中取出与这个会话ID相关的会话变量，从而保持事务之间的连续。</p><p>接下来我们了解下两个重要的概念：cookie和session</p><p><strong>关于cookie的维护与生命周期</strong></p><p>cookie是在服务器端被创建并写回到客户端浏览器，浏览器接到响应头中关于写cookie的指令则在本地临时文件夹中。</p><p>创建了一个cookie文件，其中保存了你的cookie内容，cookie内容的存储是键值对的方式，键和值都只能是字符串。例如：<br>文件：Cookie:administrator@localhost/<br>内容格式：voteID100101localhost/15361167667230343893360385046430343691*</p><p>cookie的创建：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>setcookie()函数设置cookie,函数原型如下</p><p>setcookie(name, value, expire, path, domain);</p><p>注释：cookie标题头必须在发送其他标题头之前发送，否则就无效（这是cookie的限制，而不是PHP的限制）。在发送 cookie 时，cookie 的值会自动进行 URL 编码，在取回时进行自动解码（为防止 URL 编码，请使用 setrawcookie() 取而代之）。</p><p>cookie的维护：</p><p>cooke有四个标识符：cookie的name，domain，path，secure标记。要想在将来改变这个cookie的值，需要发送另一个具有相同cookie name,domain,path的Set-Cookie消息头，这将以一个新</p><p>的值来覆盖原来cookie的值。然而，如果仅仅只是改变这些选项的某一个也会创建一个完全不同的cookie，如只是更改了name值。</p><p>cookie失效时间：</p><p>可以设置过期时间，如果不设置则是会话级别的，即关闭浏览器就会消失。当cookie创建时包含了失效日期，这个失效日期则关联了以name-domain-path-secure为标识的cookie。要改变一个cookie的失效日期，你必须指定同样的组合。当改变一个cookie的值时，你不必每次都设置失效日期，因为它不是cookie标识信息的组成部分。例如：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>setcookie(vote ,$id+1,time()+3600*24);</p><p>setcookie(vote,$id);</p><p>在cookie上的失效日期并没有改变，因为cookie的标识符是相同的。实际上，只有你手工的改变cookie的失效日期，否则其失效日期不会改变。这意味着在同一个会话中，一个会话cookie可以变成一个持久化cookie（一个可以在多个会话中存在的），反之则不可。为了要将一个持久化cookie变为一个会话cookie，你必须删除这个持久化cookie，这只要设置它的失效日期为过去某个时间之后再创建一个同名的会话cookie就可以实现。</p><p>需要记得的是失效日期是以浏览器运行的电脑上的系统时间为基准进行核实的。没有任何办法来来验证这个系统时间是否和服务器的时间同步，所以当服务器时间和浏览器所处系统时间存在差异时这样的设置会出现错误。</p><p>cookie自动删除：</p><p>cookie会被浏览器自动删除，通常存在以下几种原因：<br>会话cooke(Session cookie)在会话结束时（浏览器关闭）会被删除<br>持久化cookie（Persistent cookie）在到达失效日期时会被删除，如：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>setcookie("vote", "", time()-3600);</p><p>如果浏览器中的cookie限制到达，那么cookies会被删除以为新建cookies创建空间。</p><p><strong>关于session的维护与生命周期</strong></p><p>Session是由应用服务器维持的一个服务器端的存储空间，用户在连接服务器时，会由服务器创建生成一个唯一的sessionID，用该sessionID为标识符来存取服务器端的Session存储空间，在会话期间，分配给客户端的唯一sessionID,用来标识当前用户，与其他用户进行区分。通过SessionID接受每一次访问的请求,从而识别当前用户,跟踪和保持用户的具体资料,以及session变量，可在session中存储数字或文字资料.比如session_name.这些信息都保存在服务器端。当然，sessionID也可以作为会话信息保存到数据库中，进行session持久化。这样可以跟踪用户的登陆次数、在线与否、在线时间等从而维护HTTP无状态事物之间的关系。session的内容存储是键值对的列表，键是字符串类型，session的存储更方便，值可以是对象。</p><p>在session会话期间，session会分别保存在客户端和服务器端两个文件，客户端可以是cookie方式保存的sessionID(默认的保存方式)或通过url字符串形式传递。服务器端一般以文本的形式保存在指定的session目录中。在服务器端我们可以通过session.use_cookies来控制客户端使用哪一种保存方式。如果定义为cookie保存方式，我们可以通过session.cookie_lifetime(默认值0，闭浏览器就清除)来控制被保存在client上的cookie的有效期。而如果客户端用cookie方式保存的sessionID，则使用“临时”的cookie保存(cookie的名称为PHPSESSID，通过Firebug你可以了解到详细的信息，该名称你可以通过php.ini session.name进行更改)，用户提交页面时，会将这一SessionID提交到服务器端，来存取session数据。这一过程，是不用开发人员干预的。</p><p>Session的创建：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>session_start()&nbsp; //开始一个会话及返回已经存在会话</p><p>功能：初始化Session，也标识着session生命周期的开始。要使用session，必须初始化一个session环境，有点类似于OOP概念中调用构造函数构创建对象实例一样。session初始化操作，声明一个全局数组$_SESSION，映射寄存在内存的session数据。如果session文件已经存在，并且保存有session数据，session_start()则会读取session数据，填入$_SESSION中，开始一个新的session生命周期。</p><p>说明：这个函数没有参数,且返回值为true，如果使用基于cookie的sessin，那么在session_satrt()之前不能有任何的输出，包括空白<br>如果在php.ini中session.auto_start=1开启,则在每个页面执行session_start()，不需要手工设置，该选项默认为关闭状态，开启后不能将对象放入session中。</p><p>Session ID：</p><p>用户session唯一标识符，随机生成的一串字符串，具有唯一性，随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候，php的session初始化函数调用会分配给当前来访用户一个唯一的ID，也称之为session_id。</p><p>获得session_id()：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>echo $_COOKIE[''PHPSESSID''].''&lt;br/&gt;'';</p><p>echo $_COOKIE[session_name()].''&lt;br/&gt;'';</p><p>echo session_id().''&lt;br/&gt;'';</p><p>session数据：</p><p>我们把需要通过session保存的用户状态信息，称为用户session数据，也称为session data。一般是在当前session生命周期内，相应的$_SESSION数据。一旦调用了session_start()初始化session，就意味着开始了一个session生命周期。也就是宣布了，可以使用相关函数操作$_SESSION来管理session数据。这个session生命周期产生的数据并没有实时地写入session文件，而是通过$_SESSION变量寄存在内存中。$_SESSION是一个全局变量，类型是Array，映射了session生命周期的session数据，寄存在内存中。在session初始化的时候，从session文件中读取数据，填入该变量中。在session(生命周期)结束时，将$_SESSION数据写回session文件。</p><p>注册一个会话变量：</p><p>从PHP4.1以后，会话变量保存在超级全局数组$_SESSION中。要创建一会话变量，只需要在数组中设置一个元素，如：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>$_SESSION[''domain''] = blog.jb51.net;</p><p>$_SESSION[''poll'']=$_SESSION[poll] + 1;</p><p>使用一个会话变量:</p><p><a><u>复制代码</u></a> 代码如下:</p><p>echo $_SESSION[''blogdomain''];&nbsp;&nbsp; //打印出blog.jb51.net，使用会话前必须先使用session_start()函数启动一个会话</p><p>注销Session变量/销毁会话：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>unset($_SESSION);&nbsp; //销毁单个会话变量</p><p>如：unset($_SESSION[''blogdomain'']);</p><p>#unset($_SESSION)这个函数会将全局变量$_SESSION销毁，而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量，所以此函数千万不可使用。</p><p>session_unset(); //多项释放。将所有登陆在session文件里的变量释放出来<br>#在session生命周期，从当前session中注销全部session数据，让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量，释放内存资源;另一个区别在于，session_unset()仅在session生命周期能够操作$_SESSION数组，而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作，只影响$_SESSION数组。</p><p>$_SESSION=array();&nbsp; //多项释放，释放所有登录在$_SESSION参数里的变量</p><p>session_destroy(); <br>#当使用完一个会话后，首先应该注销所有的变量，然后再调用该函数结束当前的会话,并清空会话中的所有资源，删除服务器上的session文件.该函数不会unset(释放)和当前session相关的全局变量,也不会删除客户端的session cookie<br>#如果说session_start()初始化一个session的话，而它则注销一个session。意味着session生命周期结束了。在session生命周期结整后， session_unset, $_SESSION[''domain''] 都将不能操作$_SESSION数组，而$_SESSION数组依然可以被unset()等函数操作。这时，session意味着是未定义的，而$_SESSION依然是一个全局变量，他们脱离了关映射关系。<br>通过session_destroy()注销session,除了结束session生命周期外，它还会删除sesion文件，但不会影响当前$_SESSION变量。即它会产生一个IO操作。<br></p><p>备注：</p><p>1、php默认的session是基于cookie的,如果要删除cookie的话，必须借助setcookie()函数<br>2、session_unset()和unset()函数区别：</p><p>在session生命周期，session_unset()从当前session中注销全部session数据，让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于：unset直接删除$_SESSION变量，释放内存资源；另一个区别在于，session_unset()仅在session生命周期能够操作$_SESSION数组，而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作，只影响$_SESSION数组。</p><p>Session生命周期(session lifetime)：Session失效时间与过期回收机制<br>我们把初始化session开始，直到注销session这段期间，称为session生命周期<br>默认的，php会将session保存在php.ini配置中session.save_path设定的目录下，文件名为这个样子：sess_ves0d7uvdsab9k6sig73mnn592。每一个文件对应了一个session（会话）。session文件格式大致如下：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>poll_200|i:1;poll_100|i:3;&nbsp;&nbsp; //#变量名|类型:长度:值</p><p>设置SESSION的生命周期：</p><p>php session是基于cookie的，所以要设置session的生命周期，首先要设置cookie的失效时间。因为在客户端（如浏览器）登录网站时，SESSION 是否有用，首先找客户端是否有 COOKIE，通过COOKIE 中的 SESSION ID 去找服务器上的文件。<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>session_start(); </p><p>$lifeTime = 24 * 3600; // 保存一天 </p><p>setcookie(session_name(), session_id(), time() + $lifeTime, "/"); </p><p>其实PHP5 Session还提供了一个函数 session_set_cookie_params(); 来设置PHP5 Session的生存期的，该函数必须在 session_start() 函数调用之前调用：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>$lifeTime = 24 * 3600; // 保存一天 </p><p>session_set_cookie_params($lifeTime); </p><p>session_start(); </p><p>在服务器端，php如何判断session文件是否过期？<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>session.gc_maxlifetime = 1440 （初始值）</p><p>#设置session存活时间，单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。</p><p>如果"最后的修改时间"到"现在"超过了session.gc_maxlifetime（默认是1440）秒，也就是说在这里设置的时间内，该文件没有被修改过，这个session文件就被认为是过期了，由于php5的session采用被动的回收机制，过期的session文件不会自己消失，而是通过触发“回收”来处理过期的session，那么在下一次session回收的时候，如果这个文件仍然没有被更改过，这个session文件就会被删除（session就过期了）。</p><p>session回收何时发生？</p><p>默认情况下，每一次php请求，就会有1%的概率发生回收，所以可能简单的理解为“每100次php请求就可能有一次回收概率发生”。这个概率是通过以下参数控制的：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>session.gc_probability = 1 （初始值）</p><p>session.gc_divisor = 100 （初始值）</p><p>#由这二个函数决定了启用GC的概率，默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。过于频繁访问的网站，并发量大的网站，可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。</p><p>这两个合起来就是启动Gabadge Collection(gc)进程管理概率的，在session初使化时(session_start())。Gabadge Collection启动后跟踪session信息文件。其启动概率为session.gc_probability/session.gc_divisor。也就是说不是每个session信息文件都有100%的被系统当作垃圾来处理的。如果直接关闭浏览器的话，session信息文件很多情况下都是留在了服务器上，如果把概率改成了100%，虽然Gabadge Collection百分之百被启动了，但是这会对服务器添加负荷，也就失去了GC本身的意义了。</p><p>补充说明：</p><p>1、假设这种情况session.gc_maxlifetime=1440，如果某个session文件最后修改时间是1440秒之前，那么在下一次回收（1/100的概率）发生前，这个session仍然是有效的；</p><p>2、如果你的session使用session.save_path中使用别的地方保存session，session回收机制有可能不会自动处理过期session文件。这时需要定时手动（或者crontab）的删除过期的session：cd /path/to/sessions; find -cmin +24 | xargs rm；</p><p>3、注意，当服务器端session文件数量没有得到有效的回收，逐渐增长到GB或更大级别时可能你的站点在存取session时就会越来越缓慢，多见于站点登入登出会受到影响；</p><p>4、写日志、周报、月报等时候我们最后提交的关头，有时会出现”无效的操作，请登陆后重试”等消息，其原因也不言而喻，可能就是session失效，gc清除那些已经“超时”的session文件。</p><p>一些特殊情况：</p><p>因为回收机制会检查文件的“最后修改时间”，所以如果某个会话是活跃的，但是session的内容没有改变过，那么对应的session文件也就没有改变过，回收机制会认为这是一个长时间没有活跃的session而将其删除。这是我们不愿看到的，可以通过增加如下的简单代码解决这个问题：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>&lt;?php</p><p>if(!isset($_SESSION[''last_access''])||(time()-$_SESSION[''last_access''])&gt;120)</p><p>&nbsp;&nbsp;$_SESSION[''last_access''] = time(); </p><p>?&gt;&nbsp;&nbsp; //代码会每隔120秒，尝试修改修改一次session</p><p><strong>了解cookie与session之间的区别与联系</strong></p><p>相同点：都可以在解决HTTP无状态的问题,使同一个客户端在访问网站的多次请求中,可以保存,设置信息,并且在请求事物之间建立联系。</p><p>不同点：简单的说cookie的信息保存在客户端，session的信息保存在服务器端。</p><p>Session采用键值对,也就是说ID存放客户端,而值放在服务器端,是通过用户的ID去找服务器上对应的值,这种方式值放置在服务器端,有个时间限制,时间到则服务器自动回收/释放。</p><p>Cookies则有两种方法,一种方法是把值保存在浏览器的变量中,当浏览器关闭时结束,另一种方法是保存在硬盘中,只要时间不过期,下次还可使用。</p><p>联系：当客户端使用基于Cookie方式保存的SessionID时,SessionID一般保存在cookie中。</p><p>备注：cookie在相同内核的浏览器之间是共享的，不同内核浏览器是不共享的例如火狐和IE（存放位置都不同，当然不共享）。不同内核浏览器不能共享cookie，也会产生不同sessionid。</p><p><strong>问题1：禁用cookie后session为什么会失效？</strong></p><p>首先说明一点：session不一定必须依赖cookie，只是php默认客户端sessionid基于cookie方式保存。</p><p>到此，我想你也应该了解了php默认的session客户端保存方式是基于cookie的，所以一旦客户端禁用Cookie，那么session跨页将会失效，不知道这么描述是否合适，通俗的说无状态的东西要变的有状态，只能两边都进行比对，如果用cookie方式保存的SessionID，客户端这边的比对条件就放到cookie里，所以客户端禁用cookie，session便也会随之失效。php的session客户端ID一般有两种保存方式：cookie和url方式。如果是cookie中保存session ID，就可以看到浏览器的cookie中有一个PHPSESID变量(可以通过firefox查看)。如果是URL传递的(建议使用隐藏表单传递)，就可以看到形如:index.php?PHPSESID=ves0d7uvdsab9k6sig73mnn592的URL。例如：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>demo1.php</p><p>&lt;?php</p><p>session_start();</p><p>$_SESSION[''blog'']=''<a href="http://blog.jb51.net" rel="nofollow">http://blog.jb51.net</a>'';</p><p>echo "&lt;a href=''demo2.php''&gt;test2&lt;/a&gt;";</p><p>?&gt;</p><p>demo2.php<br>&lt;?php<br>session_start();<br>echo ''session值为''.$_SESSION[''blog''];<br>?&gt;<br></p><p>运行上面的代码，在客户端cookie正常情况下，我么可以在demo2.php中打印出$_SESSION[''blog'']的值为：<a href="http://blog.jb51.net" rel="nofollow">http://blog.jb51.net</a>。但是，现在如果你手动禁用客户端的cookie，再运行该实例，可能就得不到结果了。因为默认的客户端sessionid保存方式在跨页后，读取不到前一页的sessionid，当执行session_start();将又会产生一个session文件，与之对应产生相应的session id，用这个session id是取不出前面提到的第一个session文件中的变量的，因为这个session id不是打开它的“钥匙”。如果在session_start();之前加代码session_id($sessionid);将不产生新的session文件，直接读取与这个id对应的session文件。简单的说就是在前一页取得session id，然后想办法传递到下一页，在下一页的session_start();代码之前加代码session_id(传过来的sessionid); 例如：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>demo.php</p><p>&lt;?php</p><p>$sid = $_GET[''sid''];</p><p>if(!empty($sid)){</p><p>&nbsp;&nbsp;session_id($sid);</p><p>&nbsp;&nbsp;session_start();</p><p>}else{</p><p>&nbsp;&nbsp;session_start();</p><p>&nbsp;&nbsp;$sid = session_id();</p><p>}</p><p>?&gt;</p><p>&lt;form action="demo2.php?sid=&lt;?php echo $sid ?&gt;" method="post"&gt;</p><p>&lt;input type="text" name="id" value="100" /&gt;</p><p>&lt;input type="submit" value="提交"/&gt;</p><p>&lt;/form&gt;</p><p>demo2.php<br>&lt;?php<br>$sid = $_GET[''sid''];<br>if(!empty($sid)){<br>&nbsp;&nbsp;session_id($sid);<br>&nbsp;&nbsp;session_start();<br>}else{<br>&nbsp;&nbsp;session_start();<br>&nbsp;&nbsp;$sid = session_id();<br>}<br>$id = $_POST[''id''];<br>$key = ''poll_''.$id;<br>if($id!=''''){<br>&nbsp;&nbsp;echo $key = ''poll''.$id;<br>&nbsp;&nbsp;if(!empty($_SESSION[$key])){<br>&nbsp;&nbsp;&nbsp;&nbsp;$_SESSION[$key]=$_SESSION[$key] + 1;<br>&nbsp;&nbsp;}else{<br>&nbsp;&nbsp;&nbsp;&nbsp;$_SESSION[$key]=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;setcookie($key ,$id+1,time()+3600*24);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;echo ''&lt;script&gt;alert("success");javascript:location.href="demo.php?sid=''.$sid.''";&lt;/script&gt;'';<br>}else{<br>&nbsp;&nbsp;echo ''&lt;script&gt;alert("failed！ID Null");javascript:history.back(-1);&lt;/script&gt;'';<br>}<br>?&gt;<br></p><p>除此之外，我们还可以将客户端PHPSESID存放到文件中，如：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>demo.php</p><p>session_start();</p><p>$_SESSION[''blogdomain'']= ''<a href="http://blog.jb51.net" rel="nofollow">http://blog.jb51.net</a>'';</p><p>$sid=session_id();</p><p>$fp=fopen("D:\\tmp\\websid.txt","w+");</p><p>fwrite($fp,$sid);</p><p>fclose($fp);</p><p>echo ''&lt;a href="demo2.php"&gt;demo2&lt;/a&gt;'';</p><p>demo2.php<br>$fp=fopen("D:\\tmp\\websid.txt","r");<br>$sid=fread($fp,1024);<br>fclose($fp);<br>session_id($sid);<br>session_start();<br>print_r($_SESSION);<br></p><p>当客户端禁用cookie，可以通过以下几种方式改变session对客户端cookie的依赖，使session抛开客户端cookie：</p><p>1、设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项，让PHP自动跨页传递session id。当session.use_trans_sid为有效时，ession.use_only_cookies一定要设置为无效0。</p><p>2、手动通过URL传值、隐藏表单传递session id。</p><p>3、用文件、数据库等形式保存session_id,在跨页过程中手动调用。</p><p>PHP也提供一个函数：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>output_add_rewrite_var&nbsp; ( string $name , string $value ) # 变量名 变量值</p><p>说明：此函数给URL重写机制添加名/值对。 这种名值对将被添加到URL（以GET参数的形式）和表单（以input隐藏域的形式），当透明URL重写用 session.use_trans_sid 开启时同样可以添加到session ID。 要注意，绝对URL(<a href="http://jb51.net/.." rel="nofollow">http://jb51.net/..</a>)不能被重写。此函数的行为由url_rewriter.tags php.ini 参数控制。</p><p><a><u>复制代码</u></a> 代码如下:</p><p>&lt;?</p><p>session_start();</p><p>output_add_rewrite_var(''PHPSESSID'',session_id ());</p><p>echo ''&lt;a href="demo2.php"&gt;demo&lt;/a&gt;'';</p><p>?&gt;</p><p>这样sessionID会跟在URL后面而且from中会出现sessionID的hidden值。</p><p>改变session客户端ID保存方式：</p><p>session.use_cookies //控制客户端保存SessionID时使用哪一种方式，当它为“1”时，就说明启动了session cookie（初始值为1）<br>可以使用上面我们提到的函数来查询得到目前的session id：echo $_COOKIE["PHPSESSID"];<br>但是，如果client的浏览器不支持cookie的话，即使session.use_cookies这个参数的值等于“1”，用上述的查询也只会得到null。</p><p>php.ini中两个和该选项相关的配置参数：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>session.use_cookies = 1&nbsp; //是否使用cookies(默认值为1)</p><p>session.use_only_cookies=1&nbsp; //为1时只使用cookie；为0时可使用cookie和其它方式，这时如果客户端cookie可用，则session还是默认用cookie(默认值为1)</p><p>注意：如果客户的浏览器是支持cookie的，强烈推荐“session.use_only_cookies = 1”，当session.use_only_cookies为有效时，即使想通过URL来传递session id也会被认为无效，这样可以减少通过sessionid被攻击的可能性。上面两个配置，在php代码页面中设置方式：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>ini_set(''session.use_cookies'',''1'');</p><p>ini_set(''session.use_only_cookies'',''1'');</p><p>IE下丢失session，每次刷新页面，都会生成新的sessionID（Firefox浏览器都正常）</p><p>如果你的服务器或站点出现这种问题，请正确配置session.cookie_path网站域，如果配置错误可能会引起以下常见故障：</p><p>（1）客户端的每个PHPSESSID在服务器端都会一对一的对应生成一个独立的session记录存储在服务器端，故服务器端session文件冗余将会增多（GC回收机制异常时、站点访问量较大时）</p><p>（2）使用session记录相关信息的站点可能在除Firefox(Chrome未测试)之外的浏览器下访问出现问题，例如：购物车无法记录选购项目、站点登录失败等</p><p><a><u>复制代码</u></a> 代码如下:</p><p>session.cookie_path 是指 session 生效的网站域;</p><p>session.save_path 是指存储 session 临时文件的路径。</p><p>例如：session.cookie_path= /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //cookie的有效路径</p><p>补充：如果所有浏览器访问刷新产生新sessionID，请检查客户端是否禁用了cookie。</p><p><strong>session简单实例</strong></p><p>使用session防止表单重复提交：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>&lt;?php</p><p>session_start();</p><p>$_SESSION["num"] = 0;</p><p>if(isset($_POST["action"] &amp;&amp; $_POST["action"]=="post")){</p><p>if($_SESSION["num"] == 0){</p><p>&nbsp;&nbsp;&nbsp;&nbsp;echo "提交成功！";</p><p>&nbsp;&nbsp; $_SESSION["num"] = 1;</p><p>}else{</p><p>&nbsp;&nbsp; echo "请勿重复提交！";</p><p>}</p><p>}</p><p>?&gt;</p><p>使用session方式的登录验证实例代码：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>&lt;?php</p><p>session_start();//启动session，必须放在第一句，否则会出错。</p><p>if($_GET[''out'']){</p><p>unset($_SESSION[''id'']);</p><p>unset($_SESSION[''pass'']);</p><p>}</p><p>if($_POST[''name'']&amp;&amp;$_POST[''password'']){</p><p>&lt;span style="font-family: 微软雅黑;"&gt;&lt;span style="font-size: 16px;line-height:2.5em;"&gt;//用于设置session&lt;/span&gt;&lt;/span&gt;</p><p>$_SESSION[''id'']=$_POST[''name''];</p><p>$_SESSION[''pass'']=$_POST[''password''];</p><p>}</p><p>if($_SESSION[''id'']&amp;&amp;$_SESSION[''pass'']){</p><p>echo "登录成功！</p><p>用户ID：".$_SESSION[''id'']."&lt;br /&gt;用户密码：".$_SESSION[''pass''];</p><p>echo "&lt;br /&gt;";</p><p>echo "&lt;a href=''login.php?out=out''&gt;注销session&lt;/a&gt;";</p><p>}</p><p>&nbsp;</p><p>?&gt;</p><p>&lt;form action="login.php" method="post"&gt;</p><p>用户ID：&lt;input type="text" name="name" /&gt;</p><p>密码：&lt;input type="password" name="password" /&gt;</p><p>&lt;br /&gt;</p><p>&lt;input type="submit" name="submit"&gt;</p><p>&lt;/form&gt;</p><p>使用cookie方式的登录验证实例代码：<br></p><p><a><u>复制代码</u></a> 代码如下:</p><p>if($_GET[''out'']){ //用于注销cookies</p><p>setcookie(''id'',"");</p><p>setcookie(''pass'',"");</p><p>echo "&lt;script&gt;location.href=''login.php''&lt;/script&gt;"; //因为cookies不是及时生效的，只有你再次刷新时才生效，所以，注销后让页面自动刷新。</p><p>}</p><p>if($_POST[''name'']&amp;&amp;$_POST[''password'']) //如果变量用户名和密码存在时，在下面设置cookies</p><p>{ //用于设置cookies</p><p>setcookie(''id'',$_POST[''name''],time()+3600);</p><p>setcookie(''pass'',$_POST[''password''],time()+3600);</p><p>echo "&lt;script&gt;location.href=''login.php''&lt;/script&gt;"; //让cookies及时生效</p><p>}</p><p>if($_COOKIE[''id'']&amp;&amp;$_COOKIE[''pass'']){ //cookies设置成功后，用于显示cookies</p><p>echo "登录成功！&lt;br /&gt;用户名：".$_COOKIE[''id'']."</p><p>密码：".$_COOKIE[''pass''];</p><p>echo "&lt;br /&gt;";</p><p>echo "&lt;a href=''login.php?out=out''&gt;注销cookies&lt;/a&gt;"; </p><p>}</p><p>?&gt;</p><p>&lt;form action="" method="post"&gt;</p><p>用户ID：&lt;input type="text" name="name" /&gt;</p><p>密 码：&lt;input type="password" name="password" /&gt;</p><p>&lt;br /&gt;</p><p>&lt;input type="submit" name="submit"&gt;</p><p>&lt;/form&gt;</p><p>使用session随机码验证投票合法性：</p><p><a><u>复制代码</u></a> 代码如下:</p><p>list.php 选项页面</p><p>session_start();</p><p>$tokenKey = md5(rand(1,100));</p><p>$_SESSION[''tokenKey''] = $tokenKey;</p><p>注意：在传值时同时传入随机码$tokenKeyvote.php&nbsp;&nbsp;投票动作执行页面</p><p>$tokenKey = $_SESSION[''tokenKey''];</p><p>if($_POST[''tokenKey''] !=&nbsp;&nbsp;$tokenKey){&nbsp;&nbsp;&nbsp;&nbsp; //判断随机码是否和上一页相同</p><p>&nbsp;&nbsp;echo "&lt;script&gt;alert(''请重新投票！'');location.href=''list.php'';&lt;/script&gt;";&nbsp;&nbsp; //随机码无效</p><p>&nbsp;&nbsp;exit;</p><p>}else{</p><p>&nbsp;&nbsp;执行投票操作;</p><p>&nbsp;&nbsp;清空session存储的随机码</p><p>}</p><h1><br></h1>'),
  (31, 237, '<p>这几个宏是为了进行条件编译。一般情况下，源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译，也就是对一部分内容指定编译的条件，这就是“条件编译”。有时，希望当满足某条件时对一组语句进行编译，而当条件不满足时则编译另一组语句。 </p><p>&nbsp;&nbsp;&nbsp; 条件编译命令最常见的形式为： </p><p>&nbsp;&nbsp;&nbsp; #ifdef 标识符 </p><p>&nbsp;&nbsp;&nbsp; 程序段1 </p><p>&nbsp;&nbsp;&nbsp; #else </p><p>&nbsp;&nbsp;&nbsp; 程序段2 </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 它的作用是：当标识符已经被定义过(一般是用#define命令定义)，则对程序段1进行编译，否则编译程序段2。 </p><p>&nbsp;&nbsp;&nbsp; 其中#else部分也可以没有，即： </p><p>&nbsp;&nbsp;&nbsp; #ifdef </p><p>&nbsp;&nbsp;&nbsp; 程序段1 </p><p>&nbsp;&nbsp;&nbsp; #denif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 这里的“程序段”可以是语句组，也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上系统上运行，而不同的计算机又有一定的差异。例如，我们有一个数据类型，在Windows平台中，应该使用long类型表示，而在其他平台应该使用float表示，这样往往需要对源程序作必要的修改，这就降低了程序的通用性。可以用以下的条件编译： </p><p>&nbsp;&nbsp;&nbsp; #ifdef WINDOWS </p><p>&nbsp;&nbsp;&nbsp; #define MYTYPE long </p><p>&nbsp;&nbsp;&nbsp; #else </p><p>&nbsp;&nbsp;&nbsp; #define MYTYPE float </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 如果在Windows上编译程序，则可以在程序的开始加上 </p><p>&nbsp;&nbsp;&nbsp; #define WINDOWS </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 这样则编译下面的命令行： </p><p>&nbsp;&nbsp;&nbsp; #define MYTYPE long </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 如果在这组条件编译命令之前曾出现以下命令行： </p><p>&nbsp;&nbsp;&nbsp; #define WINDOWS 0 </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 则预编译后程序中的MYTYPE都用float代替。这样，源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况，可以根据此思路设计出其它的条件编译。 </p><p>&nbsp;&nbsp;&nbsp; 例如，在调试程序时，常常希望输出一些所需的信息，而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段： </p><p>&nbsp;&nbsp;&nbsp; #ifdef DEBUG </p><p>&nbsp;&nbsp;&nbsp; print ("device_open(%p)/n", file); </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 如果在它的前面有以下命令行： </p><p>&nbsp;&nbsp;&nbsp; #define DEBUG </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 则在程序运行时输出file指针的值，以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的，即在调试时加一批printf语句，调试后一一将printf语句删除去。的确，这是可以的。但是，当调试时加的printf语句比较多时，修改的工作量是很大的。用条件编译，则不必一一删改printf语句，只需删除前面的一条“#define DEBUG”命令即可，这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用，即起统一控制的作用，如同一个“开关”一样。 </p><p>&nbsp;&nbsp;&nbsp; 有时也采用下面的形式： </p><p>&nbsp;&nbsp;&nbsp; #ifndef 标识符 </p><p>&nbsp;&nbsp;&nbsp; 程序段1 </p><p>&nbsp;&nbsp;&nbsp; #else </p><p>&nbsp;&nbsp;&nbsp; 程序段2 </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 只是第一行与第一种形式不同：将“ifdef”改为“ifndef”。它的作用是：若标识符未被定义则编译程序段1，否则编译程序段2。这种形式与第一种形式的作用相反。 </p><p>&nbsp;&nbsp;&nbsp; 以上两种形式用法差不多，根据需要任选一种，视方便而定。 </p><p>&nbsp;&nbsp;&nbsp; 还有一种形式，就是#if后面的是一个表达式，而不是一个简单的标识符： </p><p>&nbsp;&nbsp;&nbsp; #if 表达式 </p><p>&nbsp;&nbsp;&nbsp; 程序段1 </p><p>&nbsp;&nbsp;&nbsp; #else </p><p>&nbsp;&nbsp;&nbsp; 程序段2 </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 它的作用是：当指定的表达式值为真（非零）时就编译程序段1，否则编译程序段2。可以事先给定一定条件，使程序在不同的条件下执行不同的功能。 </p><p>&nbsp;&nbsp;&nbsp; 例如：输入一行字母字符，根据需要设置条件编译，使之能将字母全改为大写输出，或全改为小写字母输出。 </p><p>&nbsp;&nbsp;&nbsp; #define LETTER 1 </p><p>&nbsp;&nbsp;&nbsp; main() </p><p>&nbsp;&nbsp;&nbsp; { </p><p>&nbsp;&nbsp;&nbsp; char str[20]="C Language",c; </p><p>&nbsp;&nbsp;&nbsp; int i="0"; </p><p>&nbsp;&nbsp;&nbsp; while((c=str[i])!=''/0''){ </p><p>&nbsp;&nbsp;&nbsp; i++; </p><p>&nbsp;&nbsp;&nbsp; #if LETTER </p><p>&nbsp;&nbsp;&nbsp; if(c&gt;=''a''&amp;&amp;c&lt;=''z'') c="c-32"; </p><p>&nbsp;&nbsp;&nbsp; #else </p><p>&nbsp;&nbsp;&nbsp; if(c&gt;=''A''&amp;&amp;c&lt;=''Z'') c="c"+32; </p><p>&nbsp;&nbsp;&nbsp; #endif </p><p>&nbsp;&nbsp;&nbsp; printf("%c",c); </p><p>&nbsp;&nbsp;&nbsp; } </p><p>&nbsp;&nbsp;&nbsp; } </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 运行结果为：C LANGUAGE </p><p>&nbsp;&nbsp;&nbsp; 现在先定义LETTER为1，这样在预处理条件编译命令时，由于LETTER为真（非零），则对第一个if语句进行编译，运行时使小写字母变大写。如果将程序第一行改为： </p><p>&nbsp;&nbsp;&nbsp; #define LETTER 0 </p><p>&nbsp;&nbsp;&nbsp;&nbsp; </p><p>&nbsp;&nbsp;&nbsp; 则在预处理时，对第二个if语句进行编译处理，使大写字母变成小写字母（大写字母与相应的小写字母的ASCII代码差32）。此时运行情况为： </p><p>&nbsp;&nbsp;&nbsp; c language </p><p>&nbsp;&nbsp;&nbsp; 有人会问：不用条件编译命令而直接用if语句也能达到要求，用条件编译命令有什么好处呢？的确，此问题完全可以不用条件编译处理，但那样做目标程序长（因为所有语句都编译），而采用条件编译，可以减少被编译的语句，从而减少目标的长度。当条件编译段比较多时，目标程序长度可以大大减少。</p><p><br><strong><span style="color: rgb(0, 0, 128);">浅谈＃ifdef在软件开发中的妙用</span></strong></p><p>　　笔者从事UNIX环境下某应用软件的开发与维护工作，用户分布于全国各地，各用户需要的基本功能都是一样的，但在某些功能上要随着需求变化，不断加以升级，要想实现全国各地用户的升级工作是很困难的，而我们则只是利用E-mail发送补丁程序给用户，这些补丁程序都是在一套软件的基础上不断地修改与扩充而编写的，并由不同的标志文件转入到不同的模块，虽然程序体积在不断扩大，但丝毫不影响老用户的功能，这主要是得益于C程序的 #ifdef/#else/#endif的作用。</p><p>&nbsp;<br>　　我们主要使用以下几种方法,假设我们已在程序首部定义＃ifdef DEBUG与＃ifdef TEST：</p><p>　　1.利用#ifdef/#endif将某程序功能模块包括进去，以向某用户提供该功能。</p><p>　　在程序首部定义#ifdef HNLD：</p><p>　　#ifdef HNLD</p><p>　　include"n166_hn.c"</p><p>　　#endif</p><p>　　如果不许向别的用户提供该功能，则在编译之前将首部的HNLD加一下划线即可。</p><p>　　2.在每一个子程序前加上标记，以便追踪程序的运行。</p><p>　　#ifdef DEBUG</p><p>　　printf(" Now is in hunan !");</p><p>　　#endif</p><p>　　3.避开硬件的限制。有时一些具体应用环境的硬件不一样，但限于条件，本地缺乏这种设备，于是绕过硬件，直接写出预期结果。具体做法是:</p><p>　　#ifndef TEST</p><p>　　i=dial(); </p><p>　　//程序调试运行时绕过此语句</p><p>　　#else </p><p>　　i=0;</p><p>　　#endif</p><p>　　调试通过后，再屏蔽TEST的定义并重新编译，即可发给用户使用了。 </p><p><strong><span style="color: rgb(0, 0, 128);"># ifdef&nbsp; #ifndef 等用法（转）</span></strong></p><p>　　头件的中的#ifndef，这是一个很关键的东西。比如你有两个C文件，这两个C文件都include了同一个头文件。而编译时，这两个C文件要一同编译成一个可运行文件，于是问题来了，大量的声明冲突。 </p><p>还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用，你都要加上这个。一般格式是这样的： </p><p>#ifndef &lt;标识&gt; <br>#define &lt;标识&gt; </p><p>...... <br>...... </p><p>#endif </p><p>&lt;标识&gt;在理论上来说可以是自由命名的，但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写，前后加下划线，并把文件名中的“.”也变成下划线，如：stdio.h </p><p>#ifndef _STDIO_H_ <br>#define _STDIO_H_ </p><p>...... </p><p>#endif </p><p>2.在#ifndef中定义变量出现的问题（一般不定义在#ifndef中）。</p><p>#ifndef AAA<br>#define AAA<br>...<br>int i;<br>...<br>#endif<br>里面有一个变量定义<br>在vc中链接时就出现了i重复定义的错误，而在c中成功编译。</p><p>结论：</p><p>(1).当你第一个使用这个头的.cpp文件生成.obj的时候，int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候，int i 又被定义然后两个obj被另外一个.cpp也include 这个头的，连接在一起，就会出现重复定义.</p><p>(2).把源程序文件扩展名改成.c后，VC按照C语言的语法对源程序进行编译，而不是C++。在C语言中，若是遇到多个int i，则自动认为其中一个是定义，其他的是声明。</p><p>(3).C语言和C++语言连接结果不同，可能（猜测）时在进行编译的时候，C++语言将全局<br>变量默认为强符号，所以连接出错。C语言则依照是否初始化进行强弱的判断的。（参考）</p><p>解决方法：</p><p>(1).把源程序文件扩展名改成.c。</p><p>(2).推荐解决方案：<br>.h中只声明 extern int i;在.cpp中定义</p><p>&lt;x.h&gt;<br>#ifndef __X_H__<br>#define __X_H__<br>extern int i;<br>#endif //__X_H__<br>&lt;x.c&gt;<br>int i;</p><p>注意问题：</p><p>(1).变量一般不要定义在.h文件中。</p>'),
  (32, 238, '<p>MySQL服务器的连接数并不是要达到最大的100%为好，还是要具体问题具体分析，下面就对<a href="http://database.51cto.com/art/201010/229528.htm">MySQL</a>服务器最大连接数的合理设置进行了详尽的分析，供您参考。</p><p>我们经常会遇见“MySQL: ERROR 1040: Too many connections”的情况，一种是访问量确实很高，MySQL服务器抗不住，这个时候就要考虑增加从服务器分散读压力，另外一种情况是MySQL配置文件中max_connections值过小：</p><p>mysql&gt; show variables like ''max_connections'';<br>+-----------------+-------+<br>| Variable_name | Value |<br>+-----------------+-------+<br>| max_connections | 256 |<br>+-----------------+-------+</p><p>这台MySQL服务器最大连接数是256，然后查询一下服务器响应的最大连接数：</p><p>mysql&gt; show global status like ''Max_used_connections'';</p><p>MySQL服务器过去的最大连接数是245，没有达到服务器连接数上限256，应该没有出现1040错误，比较理想的设置是：</p><p>Max_used_connections / max_connections * 100% ≈ 85%</p><p>最大连接数占上限连接数的85%左右，如果发现比例在10%以下，MySQL服务器连接上线就设置得过高了。</p><p><br></p><p><br></p><pre><code>mysql中查看最大连接数max方法：<br>命令： show status;<br>命令：show status like ''%下面变量%'';<br>其中：Max_used_connections 同时使用的连接的最大数目。 <br><br>其它状态说明：<br>Aborted_clients 由于客户没有正确关闭连接已经死掉，已经放弃的连接数量。 <br>Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。 <br>Connections 试图连接MySQL服务器的次数。 <br>Created_tmp_tables 当执行语句时，已经被创造了的隐含临时表的数量。 <br>Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。 <br>Delayed_writes 用INSERT DELAYED写入的行数。 <br>Delayed_errors 用INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。 <br>Flush_commands 执行FLUSH命令的次数。 <br>Handler_delete 请求从一张表中删除行的次数。 <br>Handler_read_first 请求读入表中第一行的次数。 <br>Handler_read_key 请求数字基于键读行。 <br>Handler_read_next 请求读入基于一个键的一行的次数。 <br>Handler_read_rnd 请求读入基于一个固定位置的一行的次数。 <br>Handler_update 请求更新表中一行的次数。 <br>Handler_write 请求向表中插入一行的次数。 <br>Key_blocks_used 用于关键字缓存的块的数量。 <br>Key_read_requests 请求从缓存读入一个键值的次数。 <br>Key_reads 从磁盘物理读入一个键值的次数。 <br>Key_write_requests 请求将一个关键字块写入缓存次数。 <br>Key_writes 将一个键值块物理写入磁盘的次数。 <br>Max_used_connections 同时使用的连接的最大数目。 <br>Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。 <br>Not_flushed_delayed_rows 在INSERT DELAY队列中等待写入的行的数量。 <br>Open_tables 打开表的数量。 <br>Open_files 打开文件的数量。 <br>Open_streams 打开流的数量(主要用于日志记载） <br>Opened_tables 已经打开的表的数量。 <br>Questions 发往服务器的查询的数量。 <br>Slow_queries 要花超过long_query_time时间的查询数量。 <br>Threads_connected 当前打开的连接的数量。 <br>Threads_running 不在睡眠的线程数量。 <br>Uptime 服务器工作了多少秒。</code></pre>'),
  (33, 239, '<p><a href="http://www.example.com" target="_blank">http://blog.csdn.net/e421083458/article/details/38342051</a></p>'),
  (34, 240, '<p><a href="http://www.example.com" target="_blank">http://www.cnblogs.com/Bozh/archive/2013/01/22/2871545.html</a></p><p>安装MySQL后，配置文件my.cnf在 /MySQL安装目录/share/mysql目录中，该目录中还包含多个配置文件可供参考，有my-large.cnf ，my-huge.cnf， &nbsp;my-medium.cnf，my-small.cnf，分别对应大中小型数据库应用的配置。win环境下即存在于MySQL安装目录中的.ini文件。</p><p>&nbsp;</p><p>下面列出了对性能优化影响较大的主要变量，主要分为连接请求的变量和缓冲区变量。</p><p><strong>1.&nbsp;&nbsp;&nbsp;</strong><strong>连接请求的变量：</strong></p><h2>1)&nbsp;&nbsp;&nbsp;&nbsp; max_connections</h2><p>MySQL的最大连接数，增加该值增加mysqld 要求的文件描述符的数量。如果服务器的并发连接请求量比较大，建议调高此值，以增加并行连接数量，当然这建立在机器能支撑的情况下，因为如果连接数越多，介于MySQL会为每个连接提供连接缓冲区，就会开销越多的内存，所以要适当调整该值，不能盲目提高设值。</p><p>数值过小会经常出现ERROR 1040: Too many connections错误，可以过’conn%’通配符查看当前状态的连接数量，以定夺该值的大小。</p><p>show variables like ‘max_connections’ 最大连接数</p><p>show&nbsp; status like ‘max_used_connections’响应的连接数</p><p>如下：</p><p>mysql&gt; show variables like ‘max_connections‘;</p><p>+———————–+——-+</p><p>| Variable_name　| Value |</p><p>+———————–+——-+</p><p>| max_connections | 256　　|</p><p>+———————–+——-+</p><p>mysql&gt; show status like ‘max%connections‘;</p><p>+———————–+——-+</p><p>| Variable_name　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Value |</p><p>+—————————-+——-+</p><p>| max_used_connections | 256|</p><p>+—————————-+——-+</p><p>max_used_connections / max_connections * 100% （理想值≈ 85%）&nbsp;</p><p>如果max_used_connections跟max_connections相同 那么就是max_connections设置过低或者超过服务器负载上限了，低于10%则设置过大。</p><h2>2)&nbsp;&nbsp;&nbsp;&nbsp; back_log</h2><p>MySQL能暂存的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求，这就起作用。如果MySQL的连接数据达到max_connections时，新来的请求将会被存在堆栈中，以等待某一连接释放资源，该堆栈的数量即back_log，如果等待连接的数量超过back_log，将不被授予连接资源。</p><p>back_log值指出在MySQL暂时停止回答新请求之前的短时间内有多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接，你需要增加它，换句话说，这值对到来的TCP/IP连接的侦听队列的大小。</p><p>当观察你主机进程列表（mysql&gt; show full processlist），发现大量264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时，就要加大back_log 的值了。</p><p>默认数值是50，可调优为128，对于<a href="http://www.2cto.com/os/linux/" target="_blank">Linux</a>系统设置范围为小于512的整数。&nbsp;</p><h2>3)&nbsp;&nbsp;&nbsp;&nbsp; interactive_timeout</h2><p>一个交互连接在被服务器在关闭前等待行动的秒数。一个交互的客户被定义为对mysql_real_connect()使用CLIENT_INTERACTIVE 选项的客户。&nbsp;</p><p>默认数值是28800，可调优为7200。&nbsp;</p><p><strong>2.&nbsp;&nbsp;&nbsp;</strong><strong>缓冲区变量</strong></p><p><strong>全局缓冲：</strong></p><h2>4)&nbsp;&nbsp;&nbsp;&nbsp; key_buffer_size</h2><p>key_buffer_size指定索引缓冲区的大小，它决定索引处理的速度，尤其是索引读的速度。通过检查状态值Key_read_requests和Key_reads，可以知道key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低，至少是1:100，1:1000更好（上述状态值可以使用SHOW STATUS LIKE ‘key_read%’获得）。</p><p>key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表，但是内部的临时磁盘表是MyISAM表，也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。</p><p>举例如下：</p><p>mysql&gt; show variables like ‘key_buffer_size‘;</p><p>+——————-+————+</p><p>| Variable_name | Value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>+———————+————+</p><p>| key_buffer_size | 536870912 |</p><p>+———— ———-+————+</p><p>key_buffer_size为512MB，我们再看一下key_buffer_size的使用情况：</p><p>mysql&gt; show global status like ‘key_read%‘;</p><p>+————————+————-+</p><p>| Variable_name　&nbsp; | Value&nbsp;&nbsp; &nbsp;|</p><p>+————————+————-+</p><p>| Key_read_requests| 27813678764 |</p><p>| Key_reads　　　| &nbsp;6798830 &nbsp; &nbsp;&nbsp;&nbsp;|</p><p>+————————+————-+</p><p>一共有27813678764个索引读取请求，有6798830个请求在内存中没有找到直接从硬盘读取索引，计算索引未命中缓存的概率：</p><p>key_cache_miss_rate ＝Key_reads / Key_read_requests * 100%，设置在1/1000左右较好</p><p>默认配置数值是8388600(8M)，主机有4GB内存，可以调优值为268435456(256MB)。</p><h2>5)&nbsp;&nbsp;&nbsp;&nbsp; query_cache_size</h2><p>使用查询缓冲，MySQL将查询结果存放在缓冲区中，今后对于同样的SELECT语句（区分大小写），将直接从缓冲区中读取结果。</p><p>通过检查状态值Qcache_*，可以知道query_cache_size设置是否合理（上述状态值可以使用SHOW STATUS LIKE ‘Qcache%’获得）。如果Qcache_lowmem_prunes的值非常大，则表明经常出现缓冲不够的情况，如果Qcache_hits的值也非常大，则表明查询缓冲使用非常频繁，此时需要增加缓冲大小；如果Qcache_hits的值不大，则表明你的查询重复率很低，这种情况下使用查询缓冲反而会影响效率，那么可以考虑不用查询缓冲。此外，在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲。</p><p>&nbsp;</p><p>与查询缓冲有关的参数还有query_cache_type、query_cache_limit、query_cache_min_res_unit。</p><p>&nbsp;</p><p>query_cache_type指定是否使用查询缓冲，可以设置为0、1、2，该变量是SESSION级的变量。</p><p>query_cache_limit指定单个查询能够使用的缓冲区大小，缺省为1M。</p><p>query_cache_min_res_unit是在4.1版本以后引入的，它指定分配缓冲区空间的最小单位，缺省为4K。检查状态值Qcache_free_blocks，如果该值非常大，则表明缓冲区中碎片很多，这就表明查询结果都比较小，此时需要减小query_cache_min_res_unit。</p><p>举例如下：</p><p>mysql&gt; show global status like ‘qcache%‘;</p><p>+——————————-+—————–+</p><p>| Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Value　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>+——————————-+—————–+</p><p>| Qcache_free_blocks　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 22756　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>| Qcache_free_memory　&nbsp;&nbsp;&nbsp; | 76764704&nbsp;&nbsp;&nbsp; |</p><p>| Qcache_hits　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 213028692 |</p><p>| Qcache_inserts　　　　&nbsp;&nbsp;&nbsp;&nbsp; | 208894227&nbsp;&nbsp; |</p><p>| Qcache_lowmem_prunes&nbsp;&nbsp; | 4010916&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>| Qcache_not_cached　| 13385031&nbsp;&nbsp;&nbsp; |</p><p>| Qcache_queries_in_cache | 43560　|</p><p>| Qcache_total_blocks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 111212　&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>+——————————-+—————–+</p><p>mysql&gt; show variables like ‘query_cache%‘;</p><p>+————————————–+————–+</p><p>| Variable_name　　　　　&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; | Value　&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>+————————————–+———–+</p><p>| query_cache_limit　　　　　&nbsp;&nbsp;&nbsp; | 2097152 &nbsp;&nbsp;&nbsp; |</p><p>| query_cache_min_res_unit　&nbsp;&nbsp;&nbsp;&nbsp; | 4096　　&nbsp; |</p><p>| query_cache_size　　　　　&nbsp;&nbsp;&nbsp; | 203423744 |</p><p>| query_cache_type　　　　　&nbsp;&nbsp; | ON　&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</p><p>| query_cache_wlock_invalidate | OFF　&nbsp; |</p><p>+————————————–+—————+</p><p>查询缓存碎片率= Qcache_free_blocks / Qcache_total_blocks * 100%</p><p>如果查询缓存碎片率超过20%，可以用FLUSH QUERY CACHE整理缓存碎片，或者试试减小query_cache_min_res_unit，如果你的查询都是小数据量的话。</p><p>查询缓存利用率= (query_cache_size – Qcache_free_memory) / query_cache_size * 100%</p><p>查询缓存利用率在25%以下的话说明query_cache_size设置的过大，可适当减小；查询缓存利用率在80％以上而且Qcache_lowmem_prunes &gt; 50的话说明query_cache_size可能有点小，要不就是碎片太多。</p><p>查询缓存命中率= (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%</p><p>示例服务器查询缓存碎片率＝20.46％，查询缓存利用率＝62.26％，查询缓存命中率＝1.94％，命中率很差，可能写操作比较频繁吧，而且可能有些碎片。</p><p><strong>每个连接的缓冲</strong></p><h2>6)&nbsp;&nbsp;&nbsp;&nbsp;record_buffer_size</h2><p>每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描，你可能想要增加该值。</p><p>默认数值是131072(128K)，可改为16773120 (16M)</p><h2>7)&nbsp;&nbsp;&nbsp;&nbsp; read_rnd_buffer_size</h2><p>随机读缓冲区大小。当按任意顺序读取行时(例如，按照排序顺序)，将分配一个随机读缓存区。进行排序查询时，MySQL会首先扫描一遍该缓冲，以避免磁盘搜索，提高查询速度，如果需要排序大量数据，可适当调高该值。但MySQL会为每个客户连接发放该缓冲空间，所以应尽量适当设置该值，以避免内存开销过大。</p><p>一般可设置为16M&nbsp;</p><h2>8)&nbsp;&nbsp;&nbsp;&nbsp; sort_buffer_size</h2><p>每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速ORDER BY或GROUP BY操作。</p><p>默认数值是2097144(2M)，可改为16777208 (16M)。</p><h2>9)&nbsp;&nbsp;&nbsp;&nbsp; join_buffer_size</h2><p>联合查询操作所能使用的缓冲区大小</p><p><strong>record_buffer_size</strong><strong>，read_rnd_buffer_size，sort_buffer_size，join_buffer_size为每个线程独占，也就是说，如果有100个线程连接，则占用为16M*100</strong></p><h2>10)&nbsp; table_cache</h2><p>表高速缓存的大小。每当MySQL访问一个表时，如果在表缓冲区中还有空间，该表就被打开并放入其中，这样可以更快地访问表内容。<strong>通过检查峰值时间的状态值</strong>Open_tables<strong>和</strong>Opened_tables<strong>，可以决定是否需要增加</strong>table_cache<strong>的值。</strong>如果你发现open_tables等于table_cache，并且opened_tables在不断增长，那么你就需要增加table_cache的值了（上述状态值可以使用SHOW STATUS LIKE ‘Open%tables’获得）。注意，不能盲目地把table_cache设置成很大的值。如果设置得太高，可能会造成文件描述符不足，从而造成性能不稳定或者连接失败。</p><p>1G内存机器，推荐值是128－256。内存在4GB左右的服务器该参数可设置为256M或384M。</p><h2>11)&nbsp; max_heap_table_size</h2><p>用户可以创建的内存表(memory table)的大小。这个值用来计算内存表的最大行数值。这个变量支持动态改变，即set @max_heap_table_size=#</p><p>这个变量和tmp_table_size一起限制了内部内存表的大小。如果某个内部heap（堆积）表大小超过tmp_table_size，MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。</p><h2>12)&nbsp; tmp_table_size</h2><p>通过设置tmp_table_size选项来增加一张临时表的大小，例如做高级GROUP BY操作生成的临时表。如果调高该值，MySQL同时将增加heap表的大小，可达到提高联接查询速度的效果，<strong>建议尽量优化查询，要确保查询过程中生成的临时表在内存中，避免临时表过大导致生成基于硬盘的MyISAM表</strong>。</p><p>mysql&gt; show global status like ‘created_tmp%‘;</p><p>+——————————–+———+</p><p>| Variable_name　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Value　|</p><p>+———————————-+———+</p><p>| Created_tmp_disk_tables | 21197&nbsp; |</p><p>| Created_tmp_files　　　| 58　　|</p><p>| Created_tmp_tables　　| 1771587 |</p><p>+——————————–+———–+</p><p>每次创建临时表，Created_tmp_tables增加，如果临时表大小超过tmp_table_size，则是在磁盘上创建临时表，Created_tmp_disk_tables也增加,Created_tmp_files表示MySQL服务创建的临时文件文件数，比较理想的配置是：</p><p>Created_tmp_disk_tables / Created_tmp_tables * 100% &lt;= 25%比如上面的服务器Created_tmp_disk_tables / Created_tmp_tables * 100% ＝1.20%，应该相当好了</p><p>默认为16M，可调到64-256最佳，线程独占，太大可能内存不够I/O堵塞</p><h2>13)&nbsp;&nbsp;thread_cache_size</h2><p>可以复用的保存在中的线程的数量。如果有，新的线程从缓存中取得，当断开连接的时候如果有空间，客户的线置在缓存中。如果有很多新的线程，为了提高性能可以这个变量值。</p><p>通过比较 Connections和Threads_created状态的变量，可以看到这个变量的作用。</p><p>默认值为110，可调优为80。&nbsp;</p><h2>14)&nbsp; thread_concurrency</h2><p>推荐设置为服务器&nbsp;CPU核数的2倍，例如双核的CPU, 那么thread_concurrency的应该为4；2个双核的cpu,&nbsp;thread_concurrency的值应为8。默认为8</p><h2>15)&nbsp; wait_timeout</h2><p>指定一个请求的最大连接时间，对于4GB左右内存的服务器可以设置为5-10。</p><p>&nbsp;</p><p>3.&nbsp;&nbsp;&nbsp;&nbsp;配置InnoDB的几个变量</p><p><strong>innodb_buffer_pool_size</strong></p><p>对于InnoDB表来说，innodb_buffer_pool_size的作用就相当于key_buffer_size对于MyISAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引。对于单独的MySQL<a href="http://www.2cto.com/database/" target="_blank">数据库</a>服务器，最大可以把该值设置成物理内存的80%。</p><p>根据MySQL手册，对于2G内存的机器，推荐值是1G（50%）。</p><p>&nbsp;</p><p><strong>innodb_flush_log_at_trx_commit</strong></p><p>主要控制了innodb将log buffer中的数据写入日志文件并flush磁盘的时间点，取值分别为0、1、2三个。0，表示当事务提交时，不做日志写入操作，而是每秒钟将log buffer中的数据写入日志文件并flush磁盘一次；1，则在每秒钟或是每次事物的提交都会引起日志文件写入、flush磁盘的操作，确保了事务的ACID；设置为2，每次事务提交引起写入日志文件的动作，但每秒钟完成一次flush磁盘操作。</p><p>实际测试发现，该值对插入数据的速度影响非常大，设置为2时插入10000条记录只需要2秒，设置为0时只需要1秒，而设置为1时则需要229秒。因此，MySQL手册也建议尽量将插入操作合并成一个事务，这样可以大幅提高速度。</p><p>根据MySQL手册，在允许丢失最近部分事务的危险的前提下，可以把该值设为0或2。</p><p>&nbsp;</p><p><strong>innodb_log_buffer_size</strong></p><p>log缓存大小，一般为1-8M，默认为1M，对于较大的事务，可以增大缓存大小。</p><p>可设置为4M或8M。</p><p>&nbsp;</p><p><strong>innodb_additional_mem_pool_size</strong></p><p>该参数指定InnoDB用来存储数据字典和其他内部数据结构的内存池大小。缺省值是1M。通常不用太大，只要够用就行，应该与表结构的复杂度有关系。如果不够用，MySQL会在错误日志中写入一条警告信息。</p><p>根据MySQL手册，对于2G内存的机器，推荐值是20M，可适当增加。</p><p>&nbsp;</p><p><strong>innodb_thread_concurrency=8</strong></p><p>推荐设置为&nbsp;2*(NumCPUs+NumDisks)，默认一般为8</p><p><a href="http://www.example.com" target="_blank"><br></a></p>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (35, 241, '<h2><span style="color: rgb(0, 0, 0);"><strong>一般模式： 移动光标的方法</strong></span></h2><p><br></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">h <span style="color: rgb(0, 0, 0);">或 向左方向键<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">←<span style="color: rgb(0, 0, 0);">) <span style="color: rgb(0, 0, 0);">光标向左移动一个字符<br><span style="color: rgb(0, 0, 0);">j <span style="color: rgb(0, 0, 0);">或 向下方向键<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">↓<span style="color: rgb(0, 0, 0);">) <span style="color: rgb(0, 0, 0);">光标向下移动一个字符<br><span style="color: rgb(0, 0, 0);">k <span style="color: rgb(0, 0, 0);">或 向上方向键<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">↑<span style="color: rgb(0, 0, 0);">) <span style="color: rgb(0, 0, 0);">光标向上移动一个字符<br><span style="color: rgb(0, 0, 0);">l <span style="color: rgb(0, 0, 0);">或 向右方向键<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">→<span style="color: rgb(0, 0, 0);">) <span style="color: rgb(0, 0, 0);">光标向右移动一个字符</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">0<span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">：移动到这一行的最前面字符处 <span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">常用<span style="color: rgb(0, 0, 0);">)<br><span style="color: rgb(0, 0, 0);">$ <span style="color: rgb(0, 0, 0);">移动到这一行的最后面字符处<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">常用<span style="color: rgb(0, 0, 0);">)<br><span style="color: rgb(0, 0, 0);">H <span style="color: rgb(0, 0, 0);">光标移动到这个屏幕的最上方那一行<br><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">L <span style="color: rgb(0, 0, 0);">光标移动到这个屏幕的最下方那一行<br><span style="color: rgb(0, 0, 0);">G <span style="color: rgb(0, 0, 0);">移动到这个档案的最后一行<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">常用<span style="color: rgb(0, 0, 0);">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>n&lt;space&gt;</strong><br><span style="color: rgb(0, 0, 0);">那个 <span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">表示『数字』，例如 <span style="color: rgb(0, 0, 0);">20 <span style="color: rgb(0, 0, 0);">。按下数字后再按空格键，光标<span style="color: rgb(0, 0, 0);">会向右移动这一行的 <span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">个字符。例如 <span style="color: rgb(0, 0, 0);">20&lt;space&gt; <span style="color: rgb(0, 0, 0);">则光标会向后面<span style="color: rgb(0, 0, 0);">移动 <span style="color: rgb(0, 0, 0);">20 <span style="color: rgb(0, 0, 0);">个字符距离。</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>n&lt;Enter&gt;</strong></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">为数字。光标向下移动 <span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">行<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">常用<span style="color: rgb(0, 0, 0);">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>nG</strong><br><span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">为数字。移动到这个档案的第 <span style="color: rgb(0, 0, 0);">n <span style="color: rgb(0, 0, 0);">行。例如 <span style="color: rgb(0, 0, 0);">20G <span style="color: rgb(0, 0, 0);">则会移动到这个<span style="color: rgb(0, 0, 0);">档案的第 <span style="color: rgb(0, 0, 0);">20 <span style="color: rgb(0, 0, 0);">行<span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">可配合 <span style="color: rgb(0, 0, 0);">:set nu)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>/word</strong><br><span style="color: rgb(0, 0, 0);">向光标之下寻找一个字符串名称为 <span style="color: rgb(0, 0, 0);">word <span style="color: rgb(0, 0, 0);">的字符串。</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>?word</strong></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">&nbsp;<span style="color: rgb(0, 0, 0);">向光标之上寻找一个字符串名称为 <span style="color: rgb(0, 0, 0);">word <span style="color: rgb(0, 0, 0);">的字符串。</span></span></span></span></span></span></span></span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"></span></span></span></span></span></span><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><strong>:n1,n2s/word1/word2/g</strong><br><span style="color: rgb(0, 0, 0);">n1 <span style="color: rgb(0, 0, 0);">与 <span style="color: rgb(0, 0, 0);">n2 <span style="color: rgb(0, 0, 0);">为数字。在第 <span style="color: rgb(0, 0, 0);">n1 <span style="color: rgb(0, 0, 0);">与 <span style="color: rgb(0, 0, 0);">n2 <span style="color: rgb(0, 0, 0);">行之间寻找 <span style="color: rgb(0, 0, 0);">word1 <span style="color: rgb(0, 0, 0);">这个字符<span style="color: rgb(0, 0, 0);">串，并将该字符串取代为 <span style="color: rgb(0, 0, 0);">word2 <span style="color: rgb(0, 0, 0);">！举例来说，在 <span style="color: rgb(0, 0, 0);">100 <span style="color: rgb(0, 0, 0);">到 <span style="color: rgb(0, 0, 0);">200 <span style="color: rgb(0, 0, 0);">行<span style="color: rgb(0, 0, 0);">之间搜寻 <span style="color: rgb(0, 0, 0);">vbird <span style="color: rgb(0, 0, 0);">并取代为 <span style="color: rgb(0, 0, 0);">VBIRD <span style="color: rgb(0, 0, 0);">则：<span style="color: rgb(0, 0, 0);">『 <span style="color: rgb(0, 0, 0);">:100,200s/vbird/VBIRD/g<span style="color: rgb(0, 0, 0);">』。 <span style="color: rgb(0, 0, 0);">(<span style="color: rgb(0, 0, 0);">常用<span style="color: rgb(0, 0, 0);">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p><p><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><br></p><p><strong>&nbsp;:1,$s/word1/word2/g</strong></p><p>从第一行到最后一行寻找 word1 字符串，并将该字符串取代为word2 ！ (常用)</p><p><br></p><p><strong>x, X</strong></p><p>在一行字当中， x 为向后删除一个字符 (相当于 [del] 按键)， X为向前删除一个字符(相当于 [backspace] 亦即是退格键) (常用)</p><p><br></p><p><strong>nx</strong></p><p>n 为数字，连续向后删除 n 个字符。举例来说，我要连续删除 10个字符， 『 10x』。</p><p><br></p><p><strong>dd</strong> </p><p>删除游标所在的那一整行(常用)</p><p><br></p><p><strong>ndd</strong></p><p>n 为数字。删除光标所在的向下 n 列，例如 20dd 则是删除 行(常用)</p><p><br></p><p><strong>p, P</strong></p><p>p 为将已复制的数据在光标下一行贴上， P 则为贴在游标上一行！举例来说，我目前光标在第 20 行，且已经复制了 10 行数据。则按下 p 后， 那 10 行数据会贴在原本的 20 行之后，亦即由 21行开始贴。但如果是按下 P 呢？ 那么原本的第 20 行会被推到变成 30 行。 (常用)</p><p><br></p><p><strong>u</strong> </p><p>复原前一个动作。 (常用)</p><p><br></p><p><strong>[Ctrl]+r</strong></p><p>&nbsp;重做上一个动作。 (常用)</p><p><br></p><h2><strong>编辑模式</strong></h2><p><br></p><p><strong>a, A</strong></p><p>a 为『从目前光标所在的下一个字符处开始插入』， A 为『从光标所在行的最后一个字符处开始插入』。 (常用)</p><p><br></p><p><strong>o, O</strong></p><p>这是英文字母 o 的大小写。 o 为『在目前光标所在的下一行处插入新的一行』； O 为在目前光标所在处的上一行插入新的一行！(常用)</p><p><br></p><h2><strong>指令模式</strong></h2><p><br></p><p><span style="color: rgb(0, 0, 0);"></span><p><strong>:e!</strong> </p><p>将档案还原到最原始的状态！</p><p><br></p><p><strong>:w [filename]</strong> </p><p>将编辑的数据储存成另一个档案（类似另存新档）</p><p><br></p><p><strong>:set nu</strong></p><p>&nbsp;显示行号，设定之后，会在每一行的前缀显示该行的行号</p><p><br></p><p><strong>:set nonu</strong> </p><p>与 set nu 相反，为取消行号！</p>'),
  (36, 242, '<p>1. 如同前面 bash command 提到的，指令与参数间的多个空白会被忽略掉；</p><p>2. 而空白行也将被忽略掉！，并且 [tab] 也是不会被理会的！</p><p>3. 如果读取到一个 Enter 符号 ( CR )），就尝试开始执行该行命令；</p><p>4. 至于如果一行的内容太多，则可以使用 \\[Enter] 来延伸至下一行；</p><p>5. 此外，使用最多的 # 可做为批注！任何加在 # 后面的字，将全部被视为批注文字而被忽略！</p><p>来源：鸟哥私房菜</p>'),
  (37, 243, '<pre><code class="lang-bash">#!/bin/sh\r\n\r\nPATH=$PATH:/home/dmtsai/bin\r\nPATH="$PATH":/home/dmtsai/bin<br></code></pre>'),
  (60, 266, '<pre><code>#include &lt;stdio.h&gt;\r\n#include &lt;malloc.h&gt;\r\n#include &lt;stdbool.h&gt;\r\n\r\n//定义一个链表节点\r\ntypedef struct Node {\r\n    int data;\r\n    struct Node * pNext;\r\n} NODE, * PNODE;\r\n\r\n//定义一个栈\r\ntypedef struct stack {\r\n    PNODE pTop;\r\n    PNODE pBottom;\r\n} STACK, * PSTACK;\r\n\r\n//初始化栈\r\nvoid init(PSTACK);\r\n//入栈\r\nvoid push(PSTACK,int);\r\n//出栈\r\nvoid pop(PSTACK,int *);\r\n//遍历栈\r\nvoid traverse(PSTACK);\r\n//栈是否为空\r\nbool isEmpty(PSTACK);\r\n//清空栈\r\nvoid clear(PSTACK);\r\n\r\n\r\nmain()\r\n{\r\n    //定义栈\r\n    STACK stack;\r\n\r\n    //初始化栈\r\n    init(&amp;stack);\r\n\r\n    //入栈\r\n    push(&amp;stack,45);\r\n    push(&amp;stack,56);\r\n    push(&amp;stack,77);\r\n\r\n    //遍历栈\r\n    printf("栈内容为：");\r\n    traverse(&amp;stack);\r\n    printf("\\n");\r\n\r\n    //出栈\r\n	int val;\r\n    pop(&amp;stack,&amp;val);\r\n    printf("\\n");\r\n\r\n	//清空栈\r\n	//clear(&amp;stack);\r\n\r\n    //遍历栈\r\n    printf("出栈后内容为：");\r\n    traverse(&amp;stack);\r\n    printf("\\n");\r\n}\r\n\r\n//初始化栈\r\nvoid init(PSTACK pStack)\r\n{\r\n    pStack-&gt;pTop=(PNODE)malloc(sizeof(NODE));\r\n    if (pStack-&gt;pTop == NULL) {\r\n        printf("创建内存失败！\\n");\r\n        exit(-1);\r\n    }\r\n\r\n	pStack-&gt;pBottom=pStack-&gt;pTop;\r\n	pStack-&gt;pBottom-&gt;pNext = NULL;\r\n}\r\n\r\n//入栈\r\nvoid push(PSTACK pStack, int val)\r\n{\r\n	PNODE pNew;\r\n	pNew=(PNODE)malloc(sizeof(NODE));\r\n	pNew-&gt;data=val;\r\n	pNew-&gt;pNext=pStack-&gt;pTop;\r\n	pStack-&gt;pTop=pNew;\r\n}\r\n\r\n//栈是否为空\r\nbool isEmpty(PSTACK pStack)\r\n{\r\n	return pStack-&gt;pTop == pStack-&gt;pBottom ? true : false;\r\n}\r\n\r\n//遍历栈\r\nvoid traverse(PSTACK pStack)\r\n{\r\n	if (isEmpty(pStack))\r\n	{\r\n		printf("当前栈为空！\\b");\r\n		exit(-1);\r\n	}\r\n\r\n	PNODE p;\r\n	p = pStack-&gt;pTop;\r\n	while(p != pStack-&gt;pBottom)\r\n	{\r\n		printf("%d ",p-&gt;data);\r\n		p=p-&gt;pNext;\r\n	}\r\n	printf("\\n");\r\n}\r\n\r\n//出栈\r\nvoid pop(PSTACK pStack,int * val)\r\n{\r\n	if (isEmpty(pStack))\r\n	{\r\n		printf("当前栈为空！\\n");\r\n		exit(-1);\r\n	}\r\n\r\n	PNODE p;\r\n	p = pStack-&gt;pTop;\r\n	val = p-&gt;data;\r\n	pStack-&gt;pTop=p-&gt;pNext;\r\n	free(p);\r\n	printf("出栈的元素为：%d\\n",val);\r\n}\r\n\r\n//清空栈\r\nvoid clear(PSTACK pStack)\r\n{\r\n	PNODE pNew = NULL;\r\n	while (pStack-&gt;pTop != pStack-&gt;pBottom) {\r\n		pNew = pStack-&gt;pTop;\r\n		pStack-&gt;pTop = pStack-&gt;pTop-&gt;pNext;\r\n		free(pNew);\r\n	}\r\n}\r\n<br></code></pre>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (38, 244, '<p>mongodb设置后台运行</p><p>我们要在mongodb下面创建data目录和logs目录，用于存放data和logs。</p><p>设置好了之后，我们通常通过</p><pre style=""><code><span class="pln">mongod </span><span class="pun">--</span><span class="pln">dbpath </span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">db/</span><span class="pln">data</span></code></pre><p>让mongodb启动。</p><p>但是我们关闭shell，mongodb就停止运行了。<strong>如果想在后台运行，启动时只需添加 --fork函数即可。可以在日志路径后面添加--logappend，防止日志被删除。</strong></p><p>代码如下：</p><p>   mongod  --fork --dbpath=/usr/local/mongodb/data  --logpath=/usr/local/mongodb/logs/mongodb2.log  --logappend</p><p>这样，你关闭shell，在打开shell，照常可以允许mongo了！</p><h2>mongodb设置开机启动。</h2><p>当我们把服务器关闭，重启之后，发现mongodb又停止了，有没有开机就启动的方法呢？我们把上面代码放到/etc/rc.local，中，就可以了。</p><p>具体操作步骤：</p><pre style=""><code><span class="pln">vim  </span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">rc</span><span class="pun">.</span><span class="kwd">local</span></code></pre><p>添加上面启动代码：</p><pre style=""><code><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">mongod  </span><span class="pun">--</span><span class="pln">fork </span><span class="pun">--</span><span class="pln">dbpath</span><span class="pun">=</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">data  </span><span class="pun">--</span><span class="pln">logpath</span><span class="pun">=</span><span class="str">/usr/</span><span class="kwd">local</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">logs</span><span class="pun">/</span><span class="pln">mongodb2</span><span class="pun">.</span><span class="pln">log  </span><span class="pun">--</span><span class="pln">logappend</span></code></pre><p>下次重启就可以直接运行mongodb了！</p><p>关于linux的rc.local也是一个重点，我下节课给大家讲讲！具体可以看<a href="http://www.haorooms.com/post/linux_path_commond" target="_blank">http://www.haorooms.com/post/linux_path_commond</a></p><h2>关闭mongodb</h2><p>有开启就有关闭，上面方法会永久开启mongodb，那么如何关闭其运行呢？</p><p>1、普通命令</p><pre style=""><code><span class="pln">$ </span><span class="pun">./</span><span class="pln">mongod\r\n</span><span class="pun">&gt;</span><span class="pln"> </span><span class="kwd">use</span><span class="pln"> admin\r\n</span><span class="pun">&gt;</span><span class="pln"> db</span><span class="pun">.</span><span class="pln">shutdownServer</span><span class="pun">()</span></code></pre><p>2、如果没有up-to-date 从Mongodb且你想强制关闭服务，可以通过添加force:true;命令如下</p><pre style=""><code><span class="pun">&gt;</span><span class="pln"> db</span><span class="pun">.</span><span class="pln">adminCommand</span><span class="pun">({</span><span class="pln">shutdown </span><span class="pun">:</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> force </span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">})</span><span class="pln">\r\n</span><span class="pun">&gt;</span><span class="pln"> </span><span class="com">//or</span><span class="pln">\r\n</span><span class="pun">&gt;</span><span class="pln"> db</span><span class="pun">.</span><span class="pln">shutdownServer</span><span class="pun">({</span><span class="pln">force </span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">})</span></code></pre><p>3、指定特定超时时间的关闭服务器，命令同上，另外加上一个timeoutsec:参数</p><pre style=""><code><span class="pun">&gt;</span><span class="pln"> db</span><span class="pun">.</span><span class="pln">adminCommand</span><span class="pun">(</span><span class="pln">shutdown </span><span class="pun">:</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> force </span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">,</span><span class="pln"> timeoutsec </span><span class="pun">:</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">\r\n</span><span class="pun">&gt;</span><span class="pln"> </span><span class="com">//or</span><span class="pln">\r\n</span><span class="pun">&gt;</span><span class="pln"> db</span><span class="pun">.</span><span class="pln">shutdownServer</span><span class="pun">({</span><span class="pln">force </span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">,</span><span class="pln"> timeoutsec </span><span class="pun">:</span><span class="pln"> </span><span class="lit">5</span><span class="pun">})</span></code></pre><p><br></p><p><br></p><p><a href="http://www.haorooms.com/post/linux_mongo_backupgo">http://www.haorooms.com/post/linux_mongo_backupgo</a><br></p>'),
  (39, 245, '<p><strong>grep -v ''^$'' /etc/filename.conf | grep -v ''^#''&nbsp; </strong></p><p>过滤空白行与开头为 #的文本</p><p>&nbsp;</p><p><strong>cat filename</strong> </p><p>一次显示整个文件</p><p><strong>cat &gt; filename</strong></p><p>创建文件</p><p><strong>cat file1 file2 &gt; file</strong></p><p>将几个文件合并为一个文件</p><p><strong>cat /etc/passwd |&nbsp; sed -e ''4d'' -e ''6c no six line'' &gt; /tmp/test/passwd</strong></p><p>将 /etc/passwd 的内容，将第四行删除， 第六行则取代成为『 no six line』，新的档案放置到 /tmp/test 里面</p><p>&nbsp;</p><p><strong>nl /etc/passwd | sed ''2,5d'' </strong></p><p>将 /etc/passwd 的内容列出，并且我需要打印行号，同时，请将第 2~5 行删除！</p><p><strong>&nbsp;nl /etc/passwd | sed -n ''5,7p''</strong></p><p>仅列出第 5-7 行</p><p><strong>ifconfig eth0 | grep ''inet '' | sed ''s/^.*addr://g'' |&nbsp; sed ''s/Bcast.*$//g''</strong></p><p>我们可以使用 ifconfig 来列出 IP ，仅要 eth0 的 IP </p><p><strong>nl /etc/passwd | sed ''2,5c No 2-5 number''</strong></p><p>将第 2-5 行的内容取代成为『No 2-5 number』</p><p>&nbsp;</p><p><strong>&nbsp;last | awk ''{print $1 "\\t" $3}''</strong></p><p>取出账号与登入者的 IP ，且账号与 IP 之间以 [tab] 隔开</p><p><strong>cat /etc/passwd | awk ''{FS=":"} $3&lt;10 {print $1 "\\t" $3}''</strong></p><p> /etc/passwd 当中是以冒号 ":" 来作为字段的分隔，那假设我要查阅，第三栏小于 10 以下的数据，并且仅列出账号与第三栏</p><p><strong>awk运算</strong></p><p>&nbsp;cat pay.txt |&nbsp; awk ''NR==1{printf "%10s %10s %10s %10s %10s\\n",$1,$2,$3,$4,"Total" } NR&gt;=2 {total = $2 + $3 + $4 printf &nbsp;"%10s %10d %10d %10d %10.2f\\n", $1, $2, $3, $4, total}''</p><p>&nbsp;PS: awk的三个内建变量 NF 每一行 ($0) 拥有的字段总数, NR 目前 awk 所处理的是『第几行』数 ,  FS 目前的分隔字符，预设是空格键</p><p>&nbsp;</p><p><strong>mkdir -m 777 -p dirname</strong></p><p>创建目录</p>'),
  (40, 246, '<p> PHP中两个小于号“&lt;&lt;”表示的php中的位运算符，&lt;&lt;表示的是向左移动，&gt;&gt;表示的是向右移动，这个我们可以通过一个例子更加容易的来理解位运算： </p><p> </p><pre><code><span class="php"><span class="hljs-meta"><span class="php"><span class="hljs-meta">&lt;?php</span></span></span><span class="php">&nbsp;&nbsp;\r\n</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//定义权限&nbsp;&nbsp;</span></span></span><span class="php">\r\ndefine(</span><span class="hljs-string"><span class="php"><span class="hljs-string">''READ''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-number"><span class="php"><span class="hljs-number">1</span></span></span><span class="php">&lt;&lt;&nbsp;</span><span class="hljs-number"><span class="php"><span class="hljs-number">0</span></span></span><span class="php">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//&nbsp;把可读权限放在最右边&nbsp;&nbsp;</span></span></span><span class="php">\r\ndefine(</span><span class="hljs-string"><span class="php"><span class="hljs-string">''WRITE''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-number"><span class="php"><span class="hljs-number">1</span></span></span><span class="php">&lt;&lt;</span><span class="hljs-number"><span class="php"><span class="hljs-number">1</span></span></span><span class="php">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//&nbsp;可读权限向左移一位&nbsp;&nbsp;</span></span></span><span class="php">\r\ndefine(</span><span class="hljs-string"><span class="php"><span class="hljs-string">''EXCUTE''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-number"><span class="php"><span class="hljs-number">1</span></span></span><span class="php">&lt;&lt;</span><span class="hljs-number"><span class="php"><span class="hljs-number">2</span></span></span><span class="php">);&nbsp;&nbsp;&nbsp;</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//&nbsp;可执行权限向左移两位&nbsp;&nbsp;</span></span></span><span class="php">\r\n&nbsp;&nbsp;\r\n</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//赋予权限&nbsp;&nbsp;</span></span></span><span class="php">\r\n$user_permission&nbsp;=&nbsp;READ&nbsp;|&nbsp;WRITE;&nbsp;&nbsp;\r\n&nbsp;&nbsp;\r\n</span><span class="hljs-comment"><span class="php"><span class="hljs-comment">//验证权限&nbsp;&nbsp;</span></span></span><span class="php">\r\n</span><span class="hljs-keyword"><span class="php"><span class="hljs-keyword">echo</span></span></span><span class="php">&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''可读：''</span></span></span><span class="php">,&nbsp;($user_permission&nbsp;&amp;&nbsp;READ)&nbsp;?&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''Yes''</span></span></span><span class="php">&nbsp;:&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''No''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">"\\n"</span></span></span><span class="php">;&nbsp;&nbsp;\r\n</span><span class="hljs-keyword"><span class="php"><span class="hljs-keyword">echo</span></span></span><span class="php">&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''可写：''</span></span></span><span class="php">,&nbsp;($user_permission&nbsp;&amp;&nbsp;WRITE)&nbsp;?&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''Yes''</span></span></span><span class="php">&nbsp;:&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''No''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">"\\n"</span></span></span><span class="php">;&nbsp;&nbsp;\r\n</span><span class="hljs-keyword"><span class="php"><span class="hljs-keyword">echo</span></span></span><span class="php">&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''可执行：''</span></span></span><span class="php">,&nbsp;($user_permission&nbsp;&amp;&nbsp;EXCUTE)&nbsp;?&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''Yes''</span></span></span><span class="php">&nbsp;:&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">''No''</span></span></span><span class="php">,&nbsp;</span><span class="hljs-string"><span class="php"><span class="hljs-string">"\\n"</span></span></span><span class="php">;&nbsp;&nbsp;\r\n</span><span class="hljs-meta"><span class="php"><span class="hljs-meta">?&gt;</span></span></span></span></code></pre><p> </p><p> 通过位运算，我们能更加方便的控制权限。 </p><p> </p><p> <br> </p><p> </p><pre><code><pre class="best-text mb-10"><code><span class="hljs-string"><span class="hljs-string">"&amp;"</span></span> 按位与运算\r\n    按位与运算符<span class="hljs-string"><span class="hljs-string">"&amp;"</span></span>是<a href="https://www.baidu.com/s?wd=%E5%8F%8C%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6&amp;tn=44039180_cpr&amp;fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3rHKhnvN9njR4PHfsnHPW0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtznj03nWcvrjf" target="_blank" rel="nofollow">双目运算符</a>。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为<span class="hljs-number"><span class="hljs-number">1</span></span>时，结果\r\n位才为<span class="hljs-number"><span class="hljs-number">1</span></span>，否则为<span class="hljs-number"><span class="hljs-number">0</span></span>。参与运算的数以补码方式出现。\r\n\r\n例如：<span class="hljs-number"><span class="hljs-number">9</span></span>&amp;<span class="hljs-number"><span class="hljs-number">5</span></span>可写算式如下：\r\n\r\n      <span class="hljs-number"><span class="hljs-number">00001001</span></span>        (<span class="hljs-number"><span class="hljs-number">9</span></span>的二进制补码)\r\n\r\n     &amp;<span class="hljs-number"><span class="hljs-number">00000101</span></span>        (<span class="hljs-number"><span class="hljs-number">5</span></span>的二进制补码)\r\n\r\n      <span class="hljs-number"><span class="hljs-number">00000001</span></span>        (<span class="hljs-number"><span class="hljs-number">1</span></span>的二进制补码)\r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">9</span></span>;\r\n$b = <span class="hljs-number"><span class="hljs-number">5</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%b"</span></span>, $a&amp;$b);\r\n<span class="hljs-meta"><span class="hljs-meta">?&gt;</span></span>\r\n\r\n<span class="hljs-string"><span class="hljs-string">"|"</span></span> 按位或运算\r\n按位或运算符“|”是<a href="https://www.baidu.com/s?wd=%E5%8F%8C%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6&amp;tn=44039180_cpr&amp;fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3rHKhnvN9njR4PHfsnHPW0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtznj03nWcvrjf" target="_blank" rel="nofollow">双目运算符</a>。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为<span class="hljs-number"><span class="hljs-number">1</span></span>时，结果位\r\n就为<span class="hljs-number"><span class="hljs-number">1</span></span>。参与运算的两个数均以补码出现。\r\n\r\n例如：<span class="hljs-number"><span class="hljs-number">9</span></span>|<span class="hljs-number"><span class="hljs-number">5</span></span>可写算式如下：\r\n\r\n    <span class="hljs-number"><span class="hljs-number">00001001</span></span>\r\n\r\n   |<span class="hljs-number"><span class="hljs-number">00000101</span></span>\r\n\r\n    <span class="hljs-number"><span class="hljs-number">00001101</span></span>        (十进制为<span class="hljs-number"><span class="hljs-number">13</span></span>)可见<span class="hljs-number"><span class="hljs-number">9</span></span>|<span class="hljs-number"><span class="hljs-number">5</span></span>=<span class="hljs-number"><span class="hljs-number">13</span></span>\r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">9</span></span>;\r\n$b = <span class="hljs-number"><span class="hljs-number">5</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%b"</span></span>, $a|$b).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//二进制</span></span>\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%d"</span></span>, $a|$b).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//十进制</span></span>\r\n\r\n<span class="hljs-string"><span class="hljs-string">"^"</span></span> 按位异或运算\r\n   按位异或运算符“^”是<a href="https://www.baidu.com/s?wd=%E5%8F%8C%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6&amp;tn=44039180_cpr&amp;fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3rHKhnvN9njR4PHfsnHPW0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtznj03nWcvrjf" target="_blank" rel="nofollow">双目运算符</a>。其功能是参与运算的两数各对应的二进位相异或，当两对应的二进位相异时，结果为<span class="hljs-number"><span class="hljs-number">1</span></span>。\r\n参与运算数仍以补码出现，例如<span class="hljs-number"><span class="hljs-number">9</span></span>^<span class="hljs-number"><span class="hljs-number">5</span></span>可写成算式如下：\r\n\r\n     <span class="hljs-number"><span class="hljs-number">00001001</span></span>\r\n\r\n    ^<span class="hljs-number"><span class="hljs-number">00000101</span></span>  \r\n\r\n     <span class="hljs-number"><span class="hljs-number">00001100</span></span>       (十进制为<span class="hljs-number"><span class="hljs-number">12</span></span>)\r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">9</span></span>;\r\n$b = <span class="hljs-number"><span class="hljs-number">5</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%b"</span></span>, $a^$b).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//二进制</span></span>\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%d"</span></span>, $a^$b).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//十进制</span></span>\r\n\r\n<span class="hljs-string"><span class="hljs-string">"~"</span></span> 求反运算\r\n求反运算符～为单目运算符，具有右结合性。其功能是对参与运算的数的各二进位按位求反。\r\n\r\n例如～<span class="hljs-number"><span class="hljs-number">9</span></span>的运算为：\r\n\r\n    ~(<span class="hljs-number"><span class="hljs-number">0000000000001001</span></span>)结果为：<span class="hljs-number"><span class="hljs-number">1111111111110110</span></span>\r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">9</span></span>;\r\n$b = <span class="hljs-number"><span class="hljs-number">5</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%b"</span></span>, ~$a).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//二进制</span></span>\r\n\r\n<span class="hljs-string"><span class="hljs-string">"〈〈"</span></span> 左移运算\r\n左移运算符“&lt;&lt;”是双目运算符。其功能把“&lt;&lt; ”左边的运算数的各二进位全部左移若干位，由“&lt;&lt;”右边的数指定移动的位数，\r\n高位丢弃，低位补<span class="hljs-number"><span class="hljs-number">0</span></span>。\r\n\r\n例如：\r\n\r\n    a&lt;&lt;<span class="hljs-number"><span class="hljs-number">4</span></span>\r\n\r\n指把a的各二进位向左移动<span class="hljs-number"><span class="hljs-number">4</span></span>位。如a=<span class="hljs-number"><span class="hljs-number">00000011</span></span>(十进制<span class="hljs-number"><span class="hljs-number">3</span></span>)，左移<span class="hljs-number"><span class="hljs-number">4</span></span>位后为<span class="hljs-number"><span class="hljs-number">00110000</span></span>(十进制<span class="hljs-number"><span class="hljs-number">48</span></span>)。 \r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">3</span></span>;\r\n$temp = $a&lt;&lt;<span class="hljs-number"><span class="hljs-number">4</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%d"</span></span>, $temp).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//十进制</span></span>\r\n\r\n“&gt;&gt;” 右移运算 <a href="https://www.baidu.com/s?wd=%E5%8F%B3%E7%A7%BB%E8%BF%90%E7%AE%97%E7%AC%A6&amp;tn=44039180_cpr&amp;fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3rHKhnvN9njR4PHfsnHPW0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtznj03nWcvrjf" target="_blank" rel="nofollow">右移运算符</a>“&gt;&gt;”是双目运算符。其功能是把“&gt;&gt; ”左边的运算数的各二进位全部右移若干位，“&gt;&gt;”右边的数\r\n指定移动的位数。\r\n\r\n例如：\r\n\r\n设  a=<span class="hljs-number"><span class="hljs-number">48</span></span>，\r\n\r\na&gt;&gt;<span class="hljs-number"><span class="hljs-number">4</span></span>\r\n\r\n表示把<span class="hljs-number"><span class="hljs-number">00110000</span></span>右移为<span class="hljs-number"><span class="hljs-number">00000011</span></span>(十进制<span class="hljs-number"><span class="hljs-number">3</span></span>)。\r\n\r\n应该说明的是，对于有符号数，在右移时，符号位将随同移动。当为正数时，最高位补<span class="hljs-number"><span class="hljs-number">0</span></span>，而为负数时，符号位为<span class="hljs-number"><span class="hljs-number">1</span></span>，最高位是 补<span class="hljs-number"><span class="hljs-number">0</span></span>或是补<span class="hljs-number"><span class="hljs-number">1</span></span> 取决于编译系统的规定\r\n\r\n<span class="hljs-meta"><span class="hljs-meta">&lt;?php</span></span>\r\n$a = <span class="hljs-number"><span class="hljs-number">48</span></span>;\r\n$temp = $a&gt;&gt;<span class="hljs-number"><span class="hljs-number">4</span></span>;\r\n<span class="hljs-keyword"><span class="hljs-keyword">echo</span></span> sprintf(<span class="hljs-string"><span class="hljs-string">"%d"</span></span>, $temp).<span class="hljs-string"><span class="hljs-string">"\\n"</span></span>; <span class="hljs-comment"><span class="hljs-comment">//十进制</span></span></code></pre></code></pre>'),
  (41, 247, '<p>0&nbsp; &lt;&lt; 1 = 0</p><p>1 &lt;&lt; 1 = 2</p><p>1 &lt;&lt; 0 = 1</p><p>可用于条件判断</p><p><br></p><p>n &gt;&gt; 1 相当于 floor(n/2)<br></p>'),
  (42, 248, '<p><span style="line-height: 25.2px;">flush()函数实时把程序的所有输出发送到用户的游览器，但实际上不会这样</span></p><p><span style="line-height: 25.2px;">例如：</span></p><pre style="max-width: 100%;"><code class="php hljs" codemark="1"><span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>;$i&lt;<span class="hljs-number">10</span>;$i++) {\r\n	flush();\r\n	<span class="hljs-keyword">echo</span> $i;\r\n	sleep(<span class="hljs-number">1</span>);\r\n}\r\n</code></pre><p><span style="line-height: 25.2px;">这段代码按道理应该是每一秒会输出一个数，但是可能要等10秒后所有输出才同时呈现出来</span></p><p><span style="line-height: 25.2px;">这个原因是因为php会把程序的输出给缓存起来，查看php.ini，output_buffering就是用来</span></p><p><span style="line-height: 25.2px;">设置输出缓存，如果想要实时输出数据就必须释放缓存，或者把output_buffering设置足够小的值，</span></p><p><span style="line-height: 25.2px;">否则程序没达到output_buffering的值或者脚本结束，输出是不会被发送出去</span></p><p><span style="line-height: 25.2px;"><br></span></p><p><span style="line-height: 25.2px;">ob_flush() : 冲刷出（送出）输出缓冲区中的内容</span></p><p><span style="line-height: 25.2px;">ob_end_clean() : 清空（擦除）缓冲区并关闭输出缓冲</span></p><p><span style="line-height: 25.2px;">ob_end_flush() : 冲刷出（送出）输出缓冲区内容并关闭缓冲</span></p><p><span style="line-height: 25.2px;">ob_implicit_flush() : 打开/关闭绝对刷送,每次输出调用后有一次刷送操作，以便不再需要对 flush() 的显式调用</span></p><p><br></p><pre style="max-width: 100%;"><code class="php hljs" codemark="1">改进后的程序：\r\n\r\n第一种：\r\nob_implicit_flush(<span class="hljs-keyword">true</span>) <span class="hljs-comment">/* 每一次有输出都会把输出发送到游览器 */</span>\r\n<span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>;$i&lt;<span class="hljs-number">10</span>;$i++) {\r\n	<span class="hljs-keyword">echo</span> $i;\r\n	ob_flush(); <span class="hljs-comment">/* 释放缓存内容 */</span>\r\n	sleep(<span class="hljs-number">1</span>);\r\n}\r\n\r\n第二种：\r\n<span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>;$i&lt;<span class="hljs-number">10</span>;$i++) {\r\n	<span class="hljs-keyword">echo</span> $i;\r\n	ob_flush(); <span class="hljs-comment">/* 释放缓存内容 */</span>\r\n	flush(); <span class="hljs-comment">/* 把输出内容发送到游览器 */</span>\r\n	sleep(<span class="hljs-number">1</span>);\r\n}\r\n\r\n第三种：\r\nob_end_clean(); <span class="hljs-comment">/* 清空缓存区，并且关闭输出缓存 */</span>\r\n<span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>;$i&lt;<span class="hljs-number">10</span>;$i++) {\r\n	<span class="hljs-keyword">echo</span> $i;\r\n	flush();\r\n	sleep(<span class="hljs-number">1</span>);\r\n}\r\n\r\n第四种：\r\nob_end_clean(); <span class="hljs-comment">/* 清空缓存区，并且关闭输出缓存 */</span>\r\nob_implicit_flush(<span class="hljs-keyword">true</span>); <span class="hljs-comment">/* 每一次有输出都会把输出发送到游览器 */</span>\r\n<span class="hljs-keyword">for</span> ($i=<span class="hljs-number">0</span>;$i&lt;<span class="hljs-number">10</span>;$i++) {\r\n	<span class="hljs-keyword">echo</span> $i;\r\n	sleep(<span class="hljs-number">1</span>);\r\n}</code></pre><p><br></p>'),
  (43, 249, '<h4><strong>grep全称是Global Regular Expression Print</strong>&nbsp;</h4><p> </p><p><br>－c：只输出匹配行的计数。<br>－i：不区分大 小写(只适用于单字符)。<br>－h：查询多文件时不显示文件名。<br>－l：查询多文件时只输出包含匹配字符的文件名。<br>－n：显示匹配行及 行号。（常用）<br>－s：不显示不存在或无匹配文本的错误信息。<br>－v：显示不包含匹配文本的所有行。（常用）</p><p><br></p><p><strong>例如：</strong></p><p>grep -i pattern files ：不区分大小写地搜索。默认情况区分大小写，</p><p>grep -l pattern files ：只列出匹配的文件名，</p><p>grep -L pattern files ：列出不匹配的文件名，</p><p>grep -w pattern files ：只匹配整个单词，而不是字符串的一部分(如匹配’magic’，而不是’magical’)，</p><p>grep -C number pattern files ：匹配的上下文分别显示[number]行，</p><p>grep pattern1 | pattern2 files ：显示匹配 pattern1 或 pattern2 的行，</p><p>grep pattern1 files | grep pattern2 ：显示既匹配 pattern1 又匹配 pattern2 的行。</p><p>grep -n pattern files&nbsp; 即可显示行号信息</p><p>grep -c pattern files&nbsp; 即可查找总行数</p><p><br></p><p> </p><p><strong>简单实例：</strong></p><p><span style="color: rgb(0, 0, 0);">$ grep -A1 -B3 --color=auto&nbsp; ''<span style="color: rgb(0, 0, 0);">word<span style="color: rgb(0, 0, 0);">'' filename</span></span></span></p><p>从filename显示包含word的行，并显示前三行和后一行，高亮显示</p><p><strong></strong><br>$ grep ''test'' d*<br>显示所有以d开头的文件中包含 test的行。</p><p><br>$ grep ''test'' aa bb cc<br>显示在aa，bb，cc文件中匹配test的行。</p><p><br>$ grep ''[a-z]\\{5\\}'' aa （注意{}需要逃逸字符）<br>显示所有包含每个字符串至少有5个连续小写字符的字符串的行。</p><p><br>$ grep ‘w\\(es\\)t.*\\1′ aa<br>如果west被匹配，则es就被存储到内存中，并标记为1，然后搜索任意个字符(.*)，这些字符后面紧跟着 另外一个es(\\1)，找到就显示该行。如果用egrep或grep -E，就不用”\\”号进行转义，直接写成’w(es)t.*\\1′就可以了。</p><p><br></p><p> </p><p>用于搜索的特殊符号：<br>\\&lt; 和 \\&gt; 分别标注单词的开始与结尾。<br>例如：<br>grep man * 会匹配 ‘Batman’、’manic’、’man’等，<br>grep ‘\\&lt;man’ * 匹配’manic’和’man’，但不是’Batman’，<br>grep ‘\\&lt;man\\&gt;’ 只匹配’man’，而不是’Batman’或’manic’等其他的字符串。</p><p><br></p><p><strong>特殊字符：<br></strong>[[:upper:]]&nbsp; &nbsp;[A-Z]<br> [[:lower:]]&nbsp; &nbsp;[a-z]<br> [[:digit:]]&nbsp; &nbsp;[0-9]<br> [[:alnum:]]&nbsp; &nbsp;[0-9a-zA-Z]<br> [[:space:]]&nbsp; &nbsp;空格或tab<br> [[:alpha:]]&nbsp; &nbsp;[a-zA-Z]<br><strong>&nbsp;<br></strong></p>'),
  (73, 279, '<p>nl test1.txt | sed ''15,$d'' 显示test1.txt文本并删除15到最后一行</p><p>nl test1.txt&nbsp; | sed ''2,5c hello word'' test1.txt文本2到5行替换成hello word</p><p>nl test1.txt | sed ''3a hello word'' test1.txt文本第三行后增加hello world,增加多行用 “ \\ ”隔开</p><p>nl test1.txt | sed -n ''5,7p'' 只显示5到7行数据</p>'),
  (74, 280, '<pre><code class="lang-sql">SELECT name\r\n  FROM random AS r1 JOIN\r\n       (SELECT CEIL(RAND() *\r\n                     (SELECT MAX(id)\r\n                        FROM random)) AS id)\r\n        AS r2\r\n WHERE r1.id &gt;= r2.id\r\n ORDER BY r1.id ASC\r\n LIMIT 1<br></code></pre><p><br></p><p><br></p><p><a href="http://stackoverflow.com/questions/4329396/mysql-select-10-random-rows-from-600k-rows-fast" rel="nofollow">http://stackoverflow.com/questions/4329396/mysql-select-10-random-rows-from-600k-rows-fast</a><br></p>'),
  (75, 281, '<h2 style="font-size: 21px; line-height: 1.5; color: rgb(0, 0, 0); font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5; font-size: 14pt;">awk内置变量</span></h2><pre style="max-width: 100%;"><code class="apache hljs" codemark="1"><span class="hljs-attribute">ARGC</span>               命令行参数个数\r\n<span class="hljs-attribute">ARGV</span>               命令行参数排列\r\n<span class="hljs-attribute">ENVIRON</span>            支持队列中系统环境变量的使用\r\n<span class="hljs-attribute">FILENAME</span>           awk浏览的文件名\r\n<span class="hljs-attribute">FNR</span>                浏览文件的记录数\r\n<span class="hljs-attribute">FS</span>                 设置输入域分隔符，等价于命令行 -F选项\r\n<span class="hljs-attribute">NF</span>                 浏览记录的域的个数\r\n<span class="hljs-attribute">NR</span>                 已读的记录数\r\n<span class="hljs-attribute">OFS</span>                输出域分隔符\r\n<span class="hljs-attribute">ORS</span>                输出记录分隔符\r\n<span class="hljs-attribute">RS</span>                 控制记录分隔符</code></pre><p>&nbsp;\r\n\r\n</p><pre style="max-width:100%;overflow-x:auto;"><code codemark="1" class="bash hljs">cat /etc/passwd | awk <span class="hljs-string">''BEGIN {FS=":"} $3 &lt; 10 {print $1 "\\t" $3}''</span> #显示第三栏小于10 以下的数据\r\n\r\nlast -n 5 | awk <span class="hljs-string">''{print $1 "\\t lines: " NR "\\t columns: " NF}''</span> #最后五行登录信息\r\n\r\n\r\ncat pay.txt | awk <span class="hljs-string">''NR==1{printf "%10s %10s %10s %10s\\n",$1,$2,$3,"total"} \\\r\n\r\nNR&gt;=2{total = $2+$3\r\n\r\nprintf "%10s %10s %10s %10s\\n",$1,$2,$3,total}''</span></code></pre><p><br></p><p></p><p>参考：<a href="http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html" target="_blank">http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html</a></p><p></p><p><br></p>'),
  (76, 282, '<p>                                                                                    </p><p>作者： <a href="http://www.ruanyifeng.com">阮一峰</a></p><p>                                    </p><p>日期： <a href="http://www.ruanyifeng.com/blog/2011/08/">2011年8月16日</a></p><p>                                    </p><p>                                                                                                                                            </p><p><a href="http://jquery.com/" target="_blank">jQuery</a>的开发速度很快，几乎每半年一个大版本，每两个月一个小版本。</p><p>                                                                                                                </p><p>每个版本都会引入一些新功能。今天我想介绍的，就是从jQuery 1.5.0版本开始引入的一个新功能----<a href="http://api.jquery.com/category/deferred-object/" target="_blank">deferred对象</a>。</p><p>这个功能很重要，未来将成为jQuery的核心方法，它彻底改变了如何在jQuery中使用ajax。为了实现它，jQuery的全部ajax代码都被改写了。但是，它比较抽象，初学者很难掌握，网上的教程也不多。所以，我把自己的学习笔记整理出来了，希望对大家有用。</p><p>本文不是初级教程，针对的读者是那些已经具备jQuery使用经验的开发者。如果你想了解jQuery的基本用法，请阅读我编写的<a href="http://www.ruanyifeng.com/blog/2011/07/jquery_fundamentals.html" target="_blank">《jQuery设计思想》</a>和<a href="http://www.ruanyifeng.com/blog/2011/08/jquery_best_practices.html" target="_blank">《jQuery最佳实践》</a>。</p><p>======================================</p><p><strong>jQuery的deferred对象详解</strong></p><p>作者：阮一峰</p><p><img src="http://image.beekka.com/blog/201108/bg2011081601.jpg"></p><p><strong>一、什么是deferred对象？</strong></p><p>开发网站的过程中，我们经常遇到某些耗时很长的javascript操作。其中，既有异步的操作（比如ajax读取服务器数据），也有同步的操作（比如遍历一个大型数组），它们都不是立即能得到结果的。</p><p>通常的做法是，为它们指定回调函数（callback）。即事先规定，一旦它们运行结束，应该调用哪些函数。</p><p>但是，在回调函数方面，jQuery的功能非常弱。为了改变这一点，jQuery开发团队就设计了<a href="http://api.jquery.com/category/deferred-object/" target="_blank">deferred对象</a>。</p><p><strong>简单说，deferred对象就是jQuery的回调函数解决方案。</strong>在英语中，defer的意思是"延迟"，所以deferred对象的含义就是"延迟"到未来某个点再执行。</p><p>它解决了如何处理耗时操作的问题，对那些操作提供了更好的控制，以及统一的编程接口。它的主要功能，可以归结为四点。下面我们通过示例代码，一步步来学习。</p><p><strong>二、ajax操作的链式写法</strong></p><p>首先，回顾一下jQuery的ajax操作的传统写法：</p><blockquote><p>　　$.ajax({</p><p>　　　　url: "test.html",</p><p>　　　　success: function(){<br>　　　　　　alert("哈哈，成功了！");<br>　　　　},</p><p>　　　　error:function(){<br>　　　　　　alert("出错啦！");<br>　　　　}</p><p>　　});</p><p>（运行<a href="http://jsfiddle.net/ruanyf/pdQYH/" target="_blank">代码示例1</a>）</p></blockquote><p>在上面的代码中，$.ajax()接受一个对象参数，这个对象包含两个方法：success方法指定操作成功后的回调函数，error方法指定操作失败后的回调函数。</p><p>$.ajax()操作完成后，如果使用的是低于1.5.0版本的jQuery，返回的是XHR对象，你没法进行链式操作；如果高于1.5.0版本，返回的是deferred对象，可以进行链式操作。</p><p>现在，新的写法是这样的：</p><blockquote><p>　　$.ajax("test.html")</p><p>　　<strong>.done(function(){ alert("哈哈，成功了！"); })</strong></p><p>　　<strong>.fail(function(){ alert("出错啦！"); });</strong></p><p>（运行<a href="http://jsfiddle.net/ruanyf/dYKLJ/" target="_blank">代码示例2</a>）</p></blockquote><p>可以看到，<a href="http://api.jquery.com/deferred.done/" target="_blank">done()</a>相当于success方法，<a href="http://api.jquery.com/deferred.fail/" target="_blank">fail()</a>相当于error方法。采用链式写法以后，代码的可读性大大提高。</p><p><strong>三、指定同一操作的多个回调函数</strong></p><p>deferred对象的一大好处，就是它允许你自由添加多个回调函数。</p><p>还是以上面的代码为例，如果ajax操作成功后，除了原来的回调函数，我还想再运行一个回调函数，怎么办？</p><p>很简单，直接把它加在后面就行了。</p><blockquote><p>　　$.ajax("test.html")</p><p>　　.done(function(){ alert("哈哈，成功了！");} )</p><p>　　.fail(function(){ alert("出错啦！"); } )</p><p>　　<strong>.done(function(){ alert("第二个回调函数！");} );</strong></p><p>（运行<a href="http://jsfiddle.net/ruanyf/sQYjs/" target="_blank">代码示例3</a>）</p></blockquote><p>回调函数可以添加任意多个，它们按照添加顺序执行。</p><p><strong>四、为多个操作指定回调函数</strong></p><p>deferred对象的另一大好处，就是它允许你为多个事件指定一个回调函数，这是传统写法做不到的。</p><p>请看下面的代码，它用到了一个新的方法<a href="http://api.jquery.com/jQuery.when/" target="_blank">$.when()</a>：</p><blockquote><p>　　<strong>$.when($.ajax("test1.html"), $.ajax("test2.html"))</strong></p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/ruanyf/CdKjn/" target="_blank">代码示例4</a>）</p></blockquote><p>这段代码的意思是，先执行两个操作$.ajax("test1.html")和$.ajax("test2.html")，如果都成功了，就运行done()指定的回调函数；如果有一个失败或都失败了，就执行fail()指定的回调函数。</p><p><strong>五、普通操作的回调函数接口（上）</strong></p><p>deferred对象的最大优点，就是它把这一套回调函数接口，从ajax操作扩展到了所有操作。也就是说，任何一个操作----不管是ajax操作还是本地操作，也不管是异步操作还是同步操作----都可以使用deferred对象的各种方法，指定回调函数。</p><p>我们来看一个具体的例子。假定有一个很耗时的操作wait：</p><blockquote><p>　　var wait = function(){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　};</p><p>　　　　setTimeout(tasks,5000);</p><p>　　};</p></blockquote><p>我们为它指定回调函数，应该怎么做呢？</p><p>很自然的，你会想到，可以使用$.when()：</p><blockquote><p>　　$.when(wait())</p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/5wzrt/" target="_blank">代码示例5</a>）</p></blockquote><p>但是，这样写的话，done()方法会立即执行，起不到回调函数的作用。原因在于$.when()的参数只能是deferred对象，所以必须对wait()进行改写：</p><blockquote><p>　　var dtd = $.Deferred(); // 新建一个deferred对象</p><p>　　var wait = function(dtd){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　<strong>dtd.resolve();</strong> // 改变deferred对象的执行状态</p><p>　　　　};</p><p>　　　　setTimeout(tasks,5000);</p><p>　　　　<strong>return dtd;</strong></p><p>　　};</p></blockquote><p>现在，wait()函数返回的是deferred对象，这就可以加上链式操作了。</p><blockquote><p>　　$.when(wait(dtd))</p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/gfFPj/" target="_blank">代码示例6</a>）</p></blockquote><p>wait()函数运行完，就会自动运行done()方法指定的回调函数。</p><p><strong>六、deferred.resolve()方法和deferred.reject()方法</strong></p><p>如果仔细看，你会发现在上面的wait()函数中，还有一个地方我没讲解。那就是<a href="http://api.jquery.com/deferred.resolve" target="_blank">dtd.resolve()</a>的作用是什么？</p><p>要说清楚这个问题，就要引入一个新概念"执行状态"。jQuery规定，deferred对象有三种执行状态----未完成，已完成和已失败。如果执行状态是"已完成"（resolved）,deferred对象立刻调用done()方法指定的回调函数；如果执行状态是"已失败"，调用fail()方法指定的回调函数；如果执行状态是"未完成"，则继续等待，或者调用<a href="http://api.jquery.com/deferred.progress/" target="_blank">progress()</a>方法指定的回调函数（jQuery1.7版本添加）。</p><p>前面部分的ajax操作时，deferred对象会根据返回结果，自动改变自身的执行状态；但是，在wait()函数中，这个执行状态必须由程序员手动指定。dtd.resolve()的意思是，将dtd对象的执行状态从"未完成"改为"已完成"，从而触发done()方法。</p><p>类似的，还存在一个<a href="http://api.jquery.com/deferred.reject" target="_blank">deferred.reject()</a>方法，作用是将dtd对象的执行状态从"未完成"改为"已失败"，从而触发fail()方法。</p><blockquote><p>　　var dtd = $.Deferred(); // 新建一个Deferred对象</p><p>　　var wait = function(dtd){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　<strong>dtd.reject(); // 改变Deferred对象的执行状态</strong></p><p>　　　　};</p><p>　　　　setTimeout(tasks,5000);</p><p>　　　　return dtd;</p><p>　　};</p><p>　　$.when(wait(dtd))</p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/bhDjd/" target="_blank">代码示例7</a>）</p></blockquote><p><strong>七、deferred.promise()方法</strong></p><p>上面这种写法，还是有问题。那就是dtd是一个全局对象，所以它的执行状态可以从外部改变。</p><p>请看下面的代码：</p><blockquote><p>　　var dtd = $.Deferred(); // 新建一个Deferred对象</p><p>　　var wait = function(dtd){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　dtd.resolve(); // 改变Deferred对象的执行状态</p><p>　　　　};</p><p>　　　　setTimeout(tasks,5000);</p><p>　　　　return dtd;</p><p>　　};</p><p>　　$.when(wait(dtd))</p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>　　<strong>dtd.resolve(); </strong></p><p>（运行<a href="http://jsfiddle.net/nBFse/" target="_blank">代码示例8</a>）</p></blockquote><p>我在代码的尾部加了一行dtd.resolve()，这就改变了dtd对象的执行状态，因此导致done()方法立刻执行，跳出"哈哈，成功了！"的提示框，等5秒之后再跳出"执行完毕！"的提示框。</p><p>为了避免这种情况，jQuery提供了<a href="http://api.jquery.com/deferred.promise/" target="_blank">deferred.promise()</a>方法。它的作用是，在原来的deferred对象上返回另一个deferred对象，后者只开放与改变执行状态无关的方法（比如done()方法和fail()方法），屏蔽与改变执行状态有关的方法（比如resolve()方法和reject()方法），从而使得执行状态不能被改变。</p><p>请看下面的代码：</p><blockquote><p>　　var dtd = $.Deferred(); // 新建一个Deferred对象</p><p>　　var wait = function(dtd){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　dtd.resolve(); // 改变Deferred对象的执行状态</p><p>　　　　};<br> <br>　　　　setTimeout(tasks,5000);</p><p>　　　　<strong>return dtd.promise(); // 返回promise对象</strong></p><p>　　};</p><p>　　<strong>var d = wait(dtd); // 新建一个d对象，改为对这个对象进行操作</strong></p><p>　　$.when(d)</p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>　　<strong>d.resolve(); // 此时，这个语句是无效的</strong></p><p>（运行<a href="http://jsfiddle.net/Yur4R/" target="_blank">代码示例9</a>）</p></blockquote><p>在上面的这段代码中，wait()函数返回的是promise对象。然后，我们把回调函数绑定在这个对象上面，而不是原来的deferred对象上面。这样的好处是，无法改变这个对象的执行状态，要想改变执行状态，只能操作原来的deferred对象。</p><p>不过，更好的写法是<a href="http://blog.allenm.me/2012/01/jquery_deferred_promise_method/" target="_blank">allenm</a>所指出的，将dtd对象变成wait(）函数的内部对象。</p><blockquote><p>　　var wait = function(dtd){</p><p>　　　　<strong>var dtd = $.Deferred(); //在函数内部，新建一个Deferred对象</strong></p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　dtd.resolve(); // 改变Deferred对象的执行状态</p><p>　　　　};<br> <br>　　　　setTimeout(tasks,5000);</p><p>　　　　return dtd.promise(); // 返回promise对象</p><p>　　};</p><p>　　<strong>$.when(wait())</strong></p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/q9TvT/" target="_blank">代码示例10</a>）</p></blockquote><p><strong>八、普通操作的回调函数接口（中）</strong></p><p>另一种防止执行状态被外部改变的方法，是使用deferred对象的建构函数$.Deferred()。</p><p>这时，wait函数还是保持不变，我们直接把它传入$.Deferred()：</p><blockquote><p>　　<strong>$.Deferred(wait)</strong></p><p>　　.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>（运行<a href="http://jsfiddle.net/ruanyf/CucGp/" target="_blank">代码示例11</a>）</p></blockquote><p>jQuery规定，$.Deferred()可以接受一个函数名（注意，是函数名）作为参数，$.Deferred()所生成的deferred对象将作为这个函数的默认参数。</p><p><strong>九、普通操作的回调函数接口（下）</strong></p><p>除了上面两种方法以外，我们还可以直接在wait对象上部署deferred接口。</p><blockquote><p>　　var dtd = $.Deferred(); // 生成Deferred对象</p><p>　　var wait = function(dtd){</p><p>　　　　var tasks = function(){</p><p>　　　　　　alert("执行完毕！");</p><p>　　　　　　dtd.resolve(); // 改变Deferred对象的执行状态</p><p>　　　　};</p><p>　　　　setTimeout(tasks,5000);</p><p>　　};</p><p>　　<strong>dtd.promise(wait);</strong></p><p>　　wait.done(function(){ alert("哈哈，成功了！"); })</p><p>　　.fail(function(){ alert("出错啦！"); });</p><p>　　wait(dtd);</p><p>（运行<a href="http://jsfiddle.net/ruanyf/PF7Xf/" target="_blank">代码示例12</a>）</p></blockquote><p>这里的关键是dtd.promise(wait)这一行，它的作用就是在wait对象上部署Deferred接口。正是因为有了这一行，后面才能直接在wait上面调用done()和fail()。</p><p><strong>十、小结：deferred对象的方法</strong></p><p>前面已经讲到了deferred对象的多种方法，下面做一个总结：</p><p>　　（1） <a href="http://api.jquery.com/category/deferred-object/" target="_blank">$.Deferred()</a> 生成一个deferred对象。</p><p>　　（2） <a href="http://api.jquery.com/deferred.done/" target="_blank">deferred.done()</a> 指定操作成功时的回调函数</p><p>　　（3） <a href="http://api.jquery.com/deferred.fail/" target="_blank">deferred.fail()</a> 指定操作失败时的回调函数</p><p>　　（4） <a href="http://api.jquery.com/deferred.promise/" target="_blank">deferred.promise()</a> 没有参数时，返回一个新的deferred对象，该对象的运行状态无法被改变；接受参数时，作用为在参数对象上部署deferred接口。</p><p>　　（5） <a href="http://api.jquery.com/deferred.resolve/" target="_blank">deferred.resolve()</a> 手动改变deferred对象的运行状态为"已完成"，从而立即触发done()方法。</p><p>　　（6）<a href="http://api.jquery.com/deferred.reject/" target="_blank">deferred.reject()</a> 这个方法与deferred.resolve()正好相反，调用后将deferred对象的运行状态变为"已失败"，从而立即触发fail()方法。</p><p>　　（7） <a href="http://api.jquery.com/jQuery.when/" target="_blank">$.when()</a> 为多个操作指定回调函数。</p><p>除了这些方法以外，deferred对象还有二个重要方法，上面的教程中没有涉及到。</p><p>　　（8）<a href="http://api.jquery.com/deferred.then/" target="_blank">deferred.then()</a></p><p>有时为了省事，可以把done()和fail()合在一起写，这就是then()方法。</p><blockquote><p>　　$.when($.ajax( "/main.php" ))</p><p>　　<strong>.then(successFunc, failureFunc );</strong></p></blockquote><p>如果then()有两个参数，那么第一个参数是done()方法的回调函数，第二个参数是fail()方法的回调方法。如果then()只有一个参数，那么等同于done()。</p><p>　　（9）<a href="http://api.jquery.com/deferred.always/" target="_blank">deferred.always()</a></p><p>这个方法也是用来指定回调函数的，它的作用是，不管调用的是deferred.resolve()还是deferred.reject()，最后总是执行。</p><blockquote><p>　　$.ajax( "test.html" )</p><p>　　.always( function() { alert("已执行！");} );</p></blockquote><p>（致谢：本文第一稿发表后，<a href="http://blog.allenm.me/" target="_blank">allenm</a>来信指出原文对promise()的理解是错的。现在的第二稿是根据<a href="http://blog.allenm.me/2012/01/jquery_deferred_promise_method/" target="_blank">他的文章</a>修改的，在此我表示衷心感谢。）</p><p>（完）</p><p><br></p><pre style="max-width:100%;overflow-x:auto;"><code class="javascript hljs" codemark="1"><span class="hljs-keyword">var</span> ajaxRequest = <span class="hljs-literal">null</span>;\r\n        $(<span class="hljs-string">"#username"</span>).blur(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{\r\n        ajaxRequest = $.ajax({\r\n                url: <span class="hljs-string">"&lt;?= \\yii\\helpers\\Url::to([''test/defer'']);?&gt;"</span>,\r\n                type: <span class="hljs-string">"POST"</span>,\r\n                beforeSend:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{\r\n\r\n                },\r\n                success:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{\r\n                    alert(data);\r\n                },\r\n                error:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{\r\n\r\n                }\r\n            });\r\n        });\r\n\r\n        $(<span class="hljs-string">"#submit"</span>).click(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{\r\n            $.when(ajaxRequest) <span class="hljs-comment">/* if ajaxRequest is not a deferred object, the function done will perform immediately  */</span>\r\n                .done(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ alert(<span class="hljs-string">"哈哈，成功了！"</span>); })\r\n                .fail(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ alert(<span class="hljs-string">"出错啦！"</span>); });\r\n        });</code></pre><p><br></p><p><a href="http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html" rel="nofollow">http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html</a><br></p><p><br></p>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (44, 250, '<p>php的引用（就是在变量或者函数、对象等前面加上&amp;符号）<br><br>在PHP 中引用的意思是：不同的名字访问同一个变量内容。<br>与Ｃ语言中的指针是有差别的．Ｃ语言中的指针里面存储的是变量的内容，在内存中存放的地址。<br><br><strong>1.变量的引用</strong><br><br>PHP 的引用允许你用两个变量来指向同一个内容<br></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ABC</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出:ABC</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出:ABC</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">EFG</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里$a的值变为EFG&nbsp;所以输出EFG</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出EFG</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>&nbsp;</p><p><br><strong>2.函数的引用传递（传址调用</strong>）<br></p><p>&nbsp;</p><p>传址调用我就不多说了 下面直接给出代码<br></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;test(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">输出１</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;test(</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">);&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里$b传递给函数的其实是$b的变量内容所处的内存地址，通过在函数里改变$a的值　就可以改变$b的值了</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;br&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">输出101</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><br>要注意的是，在这里test(１);的话就会出错，原因自己去想。</p><p>&nbsp;</p><p><strong>注意：</strong></p><p>&nbsp;&nbsp;&nbsp; 上面的“&nbsp;test(<span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">);&nbsp;”&nbsp;中的<span style="color: rgb(128, 0, 128);">$b</span>前面不要加</span> <span style="color: red;">&amp;</span> 符号，但是在函数“<span style="color: rgb(0, 0, 255);"><strong>call_user_func_array</strong></span>”中，若要引用传参，就得需要&nbsp;<span style="color: red;">&amp;</span> 符号，如下代码所示：</p><p>&nbsp;</p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br><br></span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;a(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">;<br>}<br></span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br><br></span><span style="color: rgb(0, 128, 128);">call_user_func_array</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 255);">array</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">));<br><br></span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">;<br><br></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">输出&nbsp;1</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><br><br><strong>3.函数的引用返回</strong><br></p><p>&nbsp;</p><p>先看代码<br></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br></span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">test()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">申明一个静态变量</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;<br>}<br><br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">test();</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这条语句会输出　$b的值　为１</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">test();</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这条语句会输出　$b的值　为2</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">test();</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这条语句会输出　$b的值　为3</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">test();</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这条语句会输出　$b的值　为6</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><br>下面解释下：　<br>通过这种方式$a=test();得到的其实不是函数的引用返回，这跟普通的函数调用没有区别　至于原因：　这是ＰＨＰ的规定<br>ＰＨＰ规定通过$a=&amp;test(); 方式得到的才是函数的引用返回<br>至于什么是引用返回呢（ＰＨＰ手册上说：引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话　害我半天没看懂<br><br>用上面的例子来解释就是<br>$a=test()方式调用函数，只是将函数的值赋给$a而已，　而$a做任何改变　都不会影响到函数中的$b<br>而通过$a=&amp;test()方式调用函数呢, 他的作用是　将return $b中的　$b变量的内存地址与$a变量的内存地址　指向了同一个地方<br>即产生了相当于这样的效果($a=&amp;$b;) 所以改变$a的值　也同时改变了$b的值　所以在执行了<br>$a=&amp;test();<br>$a=5;<br>以后，$b的值变为了5<br><br>这里是为了让大家理解函数的引用返回才使用静态变量的，其实函数的引用返回多用在对象中<br><br></p><p>另附一个php官方例子： <br></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">This&nbsp;is&nbsp;the&nbsp;way&nbsp;how&nbsp;we&nbsp;</span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);">&nbsp;pointer&nbsp;to&nbsp;access&nbsp;variable&nbsp;inside&nbsp;the&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;talker{<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">Hi</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;get(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">data;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;out(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">data;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br><br>}<br><br></span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;talker();<br></span><span style="color: rgb(128, 0, 128);">$d</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">get();<br><br></span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">out();<br></span><span style="color: rgb(128, 0, 128);">$d</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">How</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">out();<br></span><span style="color: rgb(128, 0, 128);">$d</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">Are</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">out();<br></span><span style="color: rgb(128, 0, 128);">$d</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">You</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$aa</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">out();<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span><span style="color: rgb(0, 0, 0);"><br><br>the&nbsp;output&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">HiHowAreYou</span><span style="color: rgb(0, 0, 0);">"</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>&nbsp;</p><p>&nbsp;</p><p><strong>4.对象的引用</strong><br></p><p>&nbsp;</p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;a{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$abc</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ABC</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;a;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">abc;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出ABC</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">abc;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出ABC</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">abc</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DEF</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$c</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">abc;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">这里输出DEF</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>以上代码是在PHP5中的运行效果</p><p>&nbsp;</p><p>在PHP5中 对象的赋值是个引用的过程。上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&amp;$b;<br>PHP5中默认就是通过引用来调用对象， 但有时你可能想建立一个对象的副本，并希望原来的对象的改变不影响到副本 . 为了这样的目的，PHP5定义了一个特殊的方法，称为__clone。</p><p>自 PHP 5 起，new 自动返回引用，因此在此使用 =&amp; 已经过时了并且会产生 E_STRICT 级别的消息。</p><p>&nbsp;</p><p>&nbsp;</p><p>在php4中，对象的赋值是个拷贝过程，</p><p>如：$b=new a，其中new a产生的是一个匿名的a对象实例，而此时的$b是对这个匿名对象的拷贝。同理$c=$b，也是对$b内容的一个拷贝。所以在php4中，为了节省内存空间，$b=new a 一般会改成引用的模式，即 $b=&amp; new a。<br></p><p>&nbsp;</p><p>下面再来个 官方 提供的例子：</p><p>&nbsp;在php5中，你不需要额外添加什么东西就可到达“对象引用”的功能：</p><p>&nbsp; <br></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;foo{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$name</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__construct(</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">name&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__toString(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">my&nbsp;name&nbsp;is&nbsp;"</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">name&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">"&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;"</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 255);">__CLASS__</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">".</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;setName(</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">name&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterOne{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$foo</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__construct(</span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__toString(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">Master:&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 255);">__CLASS__</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;|&nbsp;foo:&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;setFooName(</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">setName(&nbsp;</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterTwo{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$foo</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__construct(</span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;__toString(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">Master:&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(255, 0, 255);">__CLASS__</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;|&nbsp;foo:&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo&nbsp;</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;setFooName(</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">setName(&nbsp;</span><span style="color: rgb(128, 0, 128);">$str</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br></span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;foo(</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Only&nbsp;Created&nbsp;\\$bar&nbsp;and&nbsp;printing&nbsp;\\$bar\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Now&nbsp;\\$baz&nbsp;is&nbsp;referenced&nbsp;to&nbsp;\\$bar&nbsp;and&nbsp;printing&nbsp;\\$bar&nbsp;and&nbsp;\\$baz\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Now&nbsp;Creating&nbsp;MasterOne&nbsp;and&nbsp;Two&nbsp;and&nbsp;passing&nbsp;\\$bar&nbsp;to&nbsp;both&nbsp;constructors\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$m1</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterOne(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterTwo(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m1</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Now&nbsp;changing&nbsp;value&nbsp;of&nbsp;\\$bar&nbsp;and&nbsp;printing&nbsp;\\$bar&nbsp;and&nbsp;\\$baz\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">setName(</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">baz</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Now&nbsp;printing&nbsp;again&nbsp;MasterOne&nbsp;and&nbsp;Two\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m1</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Now&nbsp;changing&nbsp;MasterTwo''s&nbsp;foo&nbsp;name&nbsp;and&nbsp;printing&nbsp;again&nbsp;MasterOne&nbsp;and&nbsp;Two\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">setFooName(&nbsp;</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">MasterTwo\\''s&nbsp;Foo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m1</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br><br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Also&nbsp;printing&nbsp;\\$bar&nbsp;and&nbsp;\\$baz\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);">(&nbsp;</span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>&nbsp;</p><p>输出：</p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">Only&nbsp;Created&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;printing&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);"><br>my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br>Now&nbsp;</span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);">&nbsp;is&nbsp;referenced&nbsp;to&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;printing&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;</span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);"><br>my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br>Now&nbsp;Creating&nbsp;MasterOne&nbsp;and&nbsp;Two&nbsp;and&nbsp;passing&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;to&nbsp;both&nbsp;constructors<br>Master</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterOne&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;foo</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br>Master</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterTwo&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;foo</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br><br>Now&nbsp;changing&nbsp;value&nbsp;of&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;printing&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;</span><span style="color: rgb(128, 0, 128);">$baz</span><span style="color: rgb(0, 0, 0);"><br>my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">baz</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br>my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">baz</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br>Now&nbsp;printing&nbsp;again&nbsp;MasterOne&nbsp;and&nbsp;Two<br>Master</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterOne&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;foo</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">baz</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br>Master</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterTwo&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;foo</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">&nbsp;my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">baz</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br><br><br>Now&nbsp;changing&nbsp;MasterTwo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">s&nbsp;foo&nbsp;name&nbsp;and&nbsp;printing&nbsp;again&nbsp;MasterOne&nbsp;and&nbsp;Two<br>Master:&nbsp;MasterOne&nbsp;|&nbsp;foo:&nbsp;my&nbsp;name&nbsp;is&nbsp;"MasterTwo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">s&nbsp;Foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.<br><br>Master:&nbsp;MasterTwo&nbsp;|&nbsp;foo:&nbsp;my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">MasterTwo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">s&nbsp;Foo"&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;"foo".<br><br>Also&nbsp;printing&nbsp;$bar&nbsp;and&nbsp;$baz<br>my&nbsp;name&nbsp;is&nbsp;"MasterTwo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">s&nbsp;Foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.<br>my&nbsp;name&nbsp;is&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">MasterTwo</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">s&nbsp;Foo"&nbsp;and&nbsp;I&nbsp;live&nbsp;in&nbsp;"foo".</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>&nbsp;</p><p>上个例子解析：</p><p><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;foo(</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">bar</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$m1</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterOne(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);<br></span><span style="color: rgb(128, 0, 128);">$m2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;MasterTwo(&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">&nbsp;);</span></p><p>实例对象$m1与$m2中的$bar是对实例$bar的引用，而非拷贝，这是php5中，对象引用的特点，也就是说</p><p>1.$m1或$m2内部，任何对$bar的操作都会影响外部对象实例$bar的相关值。</p><p>2.外部对象实例$bar的改变也会影响$m1和$m2内部的$bar的引用相关值。</p><p>&nbsp;</p><p>在php4中，要实现如上述的 用一个对象实例去当着另外一个对象的属性时，其等价代码（即引用调用）类似如下：</p><p><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;foo{<br>&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$bar</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;setBar(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(128, 0, 128);">$newBar</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$this</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">bar&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;newBar;<br>&nbsp;&nbsp;&nbsp;}<br>}</span></p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><strong>5.引用的作用</strong><br>&nbsp;&nbsp;&nbsp;&nbsp; 如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 "&amp;" 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 "&amp;" 方式, 毕竟节省内存空间使用。<br><br><br><strong>6.取消引用</strong><br><span style="color: rgb(0, 0, 255);">当你 unset 一个引用，只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了</span>。例如： <br><br></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">unset</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp; <br></span></p><p><br><br>不会 unset $b，只是 $a。 <br><br><br><strong>7.global 引用</strong><br>当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的： <br></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$var</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$GLOBALS</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">var</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">];<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp; <br></span></p><p><br>这意味着，例如，unset $var 不会 unset 全局变量。 <br><br></p><p>&nbsp;</p><p>&nbsp;</p><p>如果在一个函数内部给一个声明为 global 的变量赋于一个引用，该引用只在函数内部可见。可以通过使用 <a href="http://www.php.net/manual/zh/reserved.variables.globals.php">$GLOBALS</a> 数组避免这一点。 </p><p><strong>Example&nbsp; 在函数内引用全局变量</strong></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br></span><span style="color: rgb(128, 0, 128);">$var1</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Example&nbsp;variable</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(128, 0, 128);">$var2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">;<br><br></span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;global_references(</span><span style="color: rgb(128, 0, 128);">$use_globals</span><span style="color: rgb(0, 0, 0);">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">global</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$var1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$var2</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(128, 0, 128);">$use_globals</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$var2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$var1</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;visible&nbsp;only&nbsp;inside&nbsp;the&nbsp;function</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$GLOBALS</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">var2</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$var1</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;visible&nbsp;also&nbsp;in&nbsp;global&nbsp;context</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br>global_references(</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">var2&nbsp;is&nbsp;set&nbsp;to&nbsp;''</span><span style="color: rgb(128, 0, 128);">$var2</span><span style="color: rgb(0, 0, 0);">''\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;var2&nbsp;is&nbsp;set&nbsp;to&nbsp;''''</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">global_references(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">var2&nbsp;is&nbsp;set&nbsp;to&nbsp;''</span><span style="color: rgb(128, 0, 128);">$var2</span><span style="color: rgb(0, 0, 0);">''\\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;var2&nbsp;is&nbsp;set&nbsp;to&nbsp;''Example&nbsp;variable''</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></p><p>把 global $var; 当成是 $var =&amp; $GLOBALS[''var'']; 的简写。从而将其它引用赋给 $var 只改变了本地变量的引用。 </p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><strong>8.$this</strong><br>在一个对象的方法中，$this 永远是调用它的对象的引用。<br><br><br>//下面再来个小插曲<br>php中对于地址的指向（类似指针）功能不是由用户自己来实现的，是由Zend核心实现的，php中引用采用的是“写时拷贝”的原理，就是除非发生写操作，指向同一个地址的变量或者对象是不会被拷贝的。<br><br>通俗的讲<br>1:如果有下面的代码<br></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ABC</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><br>其实此时　$a与$b都是指向同一内存地址　而并不是$a与$b占用不同的内存<br><br>２:如果在上面的代码基础上再加上如下代码<br></p><p><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br>&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">EFG</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br></span><span style="color: rgb(0, 0, 0);">?&gt;</span></p><p><br>由于$a与$b所指向的内存的数据要重新写一次了，此时Zend核心会自动判断　自动为$b生产一个$a的数据拷贝，重新申请一块内存进行存储<br><br></p><p>php的引用（就是在变量或者函数、对象等前面加上&amp;符号）是个高级话题，新手多注意，正确的理解php的引用很重要，对性能有较大影响，而且理解错误可能导致程序错误！</p><p>很 多人误解php中的引用跟C当中的指针一样，事实上并非如此，而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外，其他都需要使用*进行定 义，而php中对于地址的指向（类似指针）功能不是由用户自己来实现的，是由Zend核心实现的，php中引用采用的是“写时拷贝”的原理，就是除非发生 写操作，指向同一个地址的变量或者对象是不会被拷贝的，比如下面的代码：</p><p>&nbsp;</p><p><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">array</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">c</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">...</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">n</span><span style="color: rgb(0, 0, 0);">''</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(128, 0, 128);">$b</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$a</span><span style="color: rgb(0, 0, 0);">;</span></p><p>如 果程序仅执行到这里，$a和$b是相同的，但是并没有像C那样，$a和$b占用不同的内存空间，而是指向了同一块内存，这就是php和c的差别，并不需要 写成$b=&amp;$a才表示$b指向$a的内存，zend就已经帮你实现了引用，并且zend会非常智能的帮你去判断什么时候该这样处理，什么时候不 该这样处理。</p><p>');
  INSERT INTO `article_content` (`id`, `content_id`, `content`) VALUES
  (45, 251, '<p><b>$(selector).after(content)</b></p><p>after() 方法在selector后插入指定的content</p><p><br></p><p><b>$(selector).append(content)</b></p><p>append() 方法在selector的结尾插入指定内容（插入的内容是在selector的标签内结尾）。</p>'),
  (46, 252, '<p>设计模式就是解决问题的方案或者说是模板<br></p>'),
  (47, 253, '<p>查看远程库信息：git remote -v（Note:参数v表示详细信息）</p><p>推送分支：git push &lt;remote&gt; &lt;name&gt;</p><p>查看分支：git branch</p><p>创建分支：git branch &lt;name&gt;</p><p>切换分支：git checkout &lt;name&gt;</p><p>创建+切换分支：git checkout -b &lt;name&gt; （Note:命令加上-b参数表示创建并切换）</p><p>创建远程分支：git checkout -b &lt;name&gt;             git push origin &lt;name&gt;</p><p>本地合并某分支到当前分支：git merge &lt;name&gt;</p><p>删除分支：git branch -d &lt;name&gt;</p><p>删除远程分支：git push origin :&lt;name&gt;</p><p>查看远程分支：git branch -r</p><p>查看所有分支：git branch -a</p><p>查看日志（单行显示）：git log --pretty=oneline </p><p>查看日志（分支合并图显示）：git log --graph --pretty=oneline --abbrev-commit</p><p>撤销暂存区文件：git reset HEAD -- file</p><p>撤销工作区文件：git checkout -- file</p><p>从远程获取最新版本到本地：git fetch（Note:不会自动merge,后续git merge origin/master）</p><p>从远程获取最新版本到本地：git pull（Note:从远程获取最新版本并merge到本地）</p><p>从远程库checkout文件：git checkout origin/master file（如果本地仓库文件被删除，可以使用该命令重新获取远程库最新文件）</p><p>回退版本到上一个版本：git reset --hard HEAD^</p><p>回退到指定版本：git reset --hard &lt;commit_id&gt;</p>'),
  (48, 254, '<pre style="max-width:100%;overflow-x:auto;"><code class="php hljs" codemark="1"><span class="hljs-meta">&lt;?php</span>\r\n\r\n<span class="hljs-comment">/**\r\n\r\n * 所有观察者必须实现的接口\r\n\r\n * Interface Observer\r\n\r\n */</span>\r\n\r\n<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Observer</span> </span>{\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span><span class="hljs-params">()</span></span>;\r\n\r\n}\r\n\r\n<span class="hljs-comment">/**\r\n\r\n * 观察者1\r\n\r\n * Class sendEmail\r\n\r\n */</span>\r\n\r\n<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SendEmail</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Observer</span> </span>{\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span><span class="hljs-params">()</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">echo</span> <span class="hljs-string">''the email has been send &lt;br&gt;''</span>;\r\n\r\n    }\r\n\r\n}\r\n\r\n<span class="hljs-comment">/**\r\n\r\n * 观察者2\r\n\r\n * Class SaveName\r\n\r\n */</span>\r\n\r\n<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SaveName</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Observer</span> </span>{\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">update</span><span class="hljs-params">()</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">echo</span> <span class="hljs-string">''the name has been save &lt;br&gt;''</span>;\r\n\r\n    }\r\n\r\n}\r\n\r\n<span class="hljs-comment">/**\r\n\r\n * 被观察者接口\r\n\r\n * Interface Observered\r\n\r\n */</span>\r\n\r\n<span class="hljs-class"><span class="hljs-keyword">interface</span>  <span class="hljs-title">Observered</span> </span>{\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">attach</span><span class="hljs-params">($object)</span></span>;\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">delete</span><span class="hljs-params">($object)</span></span>;\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span></span>;\r\n\r\n}\r\n\r\n<span class="hljs-comment">/**\r\n\r\n * 被观察者\r\n\r\n * Class User\r\n\r\n */</span>\r\n\r\n<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Observered</span> </span>{\r\n\r\n    <span class="hljs-keyword">public</span> $observers = <span class="hljs-keyword">array</span>();\r\n\r\n    <span class="hljs-comment">/**\r\n\r\n     * 注册观察者\r\n\r\n     * <span class="hljs-doctag">@param</span> $object\r\n\r\n     */</span>\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">attach</span><span class="hljs-params">($object)</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">if</span> (!is_object($object)) {\r\n\r\n            <span class="hljs-keyword">exit</span>(<span class="hljs-string">''it is not an object''</span>);\r\n\r\n        }\r\n\r\n        <span class="hljs-keyword">if</span> ($object <span class="hljs-keyword">instanceof</span> Observer) {\r\n\r\n            <span class="hljs-keyword">if</span> (!in_array($object,$this-&gt;observers)) {\r\n\r\n                $this-&gt;observers[] = $object;\r\n\r\n            }\r\n\r\n        } <span class="hljs-keyword">else</span> {\r\n\r\n            <span class="hljs-keyword">echo</span> get_class($object) . <span class="hljs-string">'' is disable &lt;br&gt;''</span>;\r\n\r\n        }\r\n\r\n    }\r\n\r\n    <span class="hljs-comment">/**\r\n\r\n     * 删除观察者\r\n\r\n     * <span class="hljs-doctag">@param</span> $object\r\n\r\n     */</span>\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">delete</span><span class="hljs-params">($object)</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">if</span> (in_array($object,$this-&gt;observers)) {\r\n\r\n            $index = array_search($object,$this-&gt;observers);\r\n\r\n            <span class="hljs-keyword">unset</span>($this-&gt;observers[$index]);\r\n\r\n        }\r\n\r\n    }\r\n\r\n    <span class="hljs-comment">/**\r\n\r\n     * 通知所有观察者\r\n\r\n     */</span>\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">foreach</span> ($this-&gt;observers <span class="hljs-keyword">as</span> $val) {\r\n\r\n            $val-&gt;update();\r\n\r\n        }\r\n\r\n    }\r\n\r\n    <span class="hljs-comment">/**\r\n\r\n     * 被观察者自己的业务\r\n\r\n     */</span>\r\n\r\n    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printName</span><span class="hljs-params">()</span>\r\n\r\n    </span>{\r\n\r\n        <span class="hljs-keyword">echo</span> <span class="hljs-string">''I have been observing &lt;br&gt;''</span>;\r\n\r\n    }\r\n\r\n}\r\n\r\n    $object = <span class="hljs-keyword">new</span> User();\r\n\r\n    $object-&gt;attach(<span class="hljs-keyword">new</span> SendEmail()); <span class="hljs-comment">//注册观察者1</span>\r\n\r\n    $object-&gt;attach(<span class="hljs-keyword">new</span> SaveName());  <span class="hljs-comment">//注册观察者2</span>\r\n\r\n    $object-&gt;printName();             <span class="hljs-comment">//被观察者自己的业务</span>\r\n\r\n    $object-&gt;notify();                <span class="hljs-comment">//通知所有的观察者</span></code></pre><p><br></p>'),
  (50, 256, '<h2>引入 highlight.js 文件</h2><p>我们需要在页面中同时引入一个 js 文件和一个 css 文件（&nbsp;<a href="http://open.bootcss.com/">CDN</a>&nbsp;链接，既简单又提升加载速度）：</p><pre><code class="lang-css"><font size="3">&lt;link href="http://cdn.bootcss.com/highlight.js/8.0/styles/monokai_sublime.min.css" rel="stylesheet"&gt;  \r\n&lt;script src="http://cdn.bootcss.com/highlight.js/8.0/highlight.min.js"&gt;&lt;/script&gt;  \r\n</font></code></pre><p>第一个文件是样式文件，我们采用 sublime 编辑器类似的样式；第二个文件是 highlight.js 的核心文件，就是它解析代码的。</p><pre><code class="lang-js"><font size="3">&lt;script &gt;hljs.initHighlightingOnLoad();&lt;/script&gt;  </font></code></pre><p>初始化加载，OK</p><p><br></p><p>另外，也可以自己的网站引入js和css</p><p><a href="http://pan.baidu.com/s/1mgIQjH2"><font color="#333333">下载地址：</font>http://pan.baidu.com/s/1mgIQjH2</a><br></p>'),
  (51, 257, '<p><strong>单例模式的要点有三个：<br></strong><font>一、只能有一个实例；<br>二、自行创建这个实例；<br>三、向整个系统提供这个实例。</font></p><p><br></p><p><strong><font color="#ff0000">优点：</font></strong></p><ol><li>单例模式可以避免大量的new操作，因为每一次new操作都会消耗内存资源和系统资源（例如所有的应用情景只应有一个数据库句柄资源）</li><li>使用类来全局控制系统的配置信息，例如Yii中的Yii::app()</li></ol><p><br></p><p><strong><font>缺点：</font></strong></p><p>众所周知，PHP语言是一种解释型的脚本语言，这种运行机制使得每个PHP页面被解释执行后，所有的相关资源都会被回收。也就是说，PHP在语言级别上没有办法让某个对象常驻内存，这和asp.net、Java等编译型是不同的，比如在Java中单例会一直存在于整个应用程序的生命周期里，变量是跨页面级的，真正可以做到这个实例在应用程序生命周期中的唯一性。然而在PHP中，所有的变量无论是全局变量还是类的静态成员，都是页面级的，每次页面被执行时，都会重新建立新的对象，都会在页面执行完毕后被清空，这样似乎PHP单例模式就没有什么意义了，所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的。</p><pre style="-ms-overflow-x: auto; max-width: 100%;"><code class="php hljs" codemark="1"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Singleton</span></span>{ \r\n\r\n <span class="hljs-comment">//保存类的实例 </span>\r\n <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> $_instance; \r\n\r\n <span class="hljs-comment">//设置为private,防止外部实例化对象</span>\r\n <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span><span class="hljs-params">()</span></span>{ \r\n  <span class="hljs-keyword">echo</span> <span class="hljs-string">"This is a Constructed method;"</span>; \r\n } \r\n\r\n <span class="hljs-comment">//防止对象被克隆 </span>\r\n <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__clone</span><span class="hljs-params">()</span></span>{ \r\n  trigger_error(<span class="hljs-string">''Clone is not allow !''</span>,E_USER_ERROR); \r\n } \r\n\r\n <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getInstance</span><span class="hljs-params">()</span></span>{ \r\n  <span class="hljs-keyword">if</span>(!(<span class="hljs-keyword">self</span>::$_instance <span class="hljs-keyword">instanceof</span> <span class="hljs-keyword">self</span>)){ \r\n   <span class="hljs-keyword">self</span>::$_instance = <span class="hljs-keyword">new</span> <span class="hljs-keyword">self</span>; \r\n  } \r\n  <span class="hljs-keyword">return</span> <span class="hljs-keyword">self</span>::$_instance; \r\n } \r\n \r\n <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span><span class="hljs-params">()</span></span>{ \r\n  <span class="hljs-keyword">echo</span> <span class="hljs-string">''调用方法成功''</span>; \r\n } \r\n} \r\n\r\n<span class="hljs-comment">//正确的调用方法 </span>\r\n$singleton = Singleton::getInstance(); \r\n$singleton-&gt;test(); \r\n\r\n$singleton_clone = <span class="hljs-keyword">clone</span> $singleton; \r\n\r\n</code></pre><p><br></p><p><a href="https://www.douban.com/group/topic/47722220/?author=1" rel="nofollow">https://www.douban.com/group/topic/47722220/?author=1</a><br></p><p><br></p>'),
  (52, 258, '<p>require文件不存在时，程序中断，并报致命错误</p><p>include文件不存在时，程序不中断，但会抛出警告<br></p>'),
  (53, 259, '<p><b>ls&nbsp; &gt;&nbsp; filelist.txt</b></p><p>"&gt;" 是输出到文件中, 如果文件存在, 则原来的内容被清空, 不存在则创建文件</p><p><br></p><p><b>ls&nbsp; &gt;&gt;&nbsp; filelist.txt</b></p><p>"&gt;&gt;"是把输出追加到文件中, 如果文件存在, 追加到末尾, 不存在则创建文件<br></p><p><br></p><p><b>ps -ef |grep abc </b><br></p><p>查看含有"abc"的活动进程</p><p><br></p><p><b>ps -ef |grep -v abc </b><br></p><p>查看不含abc的活动进程</p><p><br></p><p><b>清空整个文档</b><br></p><p>&nbsp;gg 这里是跳至文件首行 再执行：dG 这样就清空了整个文件<br></p>'),
  (54, 260, '<p>cat命令主要用来查看文件内容，创建文件，文件合并，追加文件内容等功能。</p><p>&nbsp;</p><p>A:查看文件内容主要用法：</p><p>1、cat f1.txt，查看f1.txt文件的内容。</p><p>2、cat -n f1.txt，查看f1.txt文件的内容，并且由1开始对所有输出行进行编号。</p><p>3、cat -b f1.txt，查看f1.txt文件的内容，用法与-n相似，只不过对于空白行不编号。</p><p>4、cat -s&nbsp;f1.txt，当遇到有连续两行或两行以上的空白行，就代换为一行的空白行。</p><p>5、cat -e&nbsp;f1.txt，在输出内容的每一行后面加一个$符号。</p><p>6、cat&nbsp;f1.txt&nbsp;f2.txt，同时显示f1.txt和f2.txt文件内容，注意文件名之间以空格分隔，而不是逗号。</p><p>7、cat -n f1.txt&gt;f2.txt，对f1.txt文件中每一行加上行号后然后写入到f2.txt中，会覆盖原来的内容，文件不存在则创建它。</p><p>8、cat -n f1.txt&gt;&gt;f2.txt，对f1.txt文件中每一行加上行号后然后追加到f2.txt中去，不会覆盖原来的内容，文件不存在则创建它。</p><p>&nbsp;</p><p>B:创建文件以及写入文件内容的用法：</p><p><img src="file:///C:/Users/L/AppData/Local/YNote/data/549241301@qq.com/ed7bcfe9e5b94a53a37faa6c39883b1d/20130608203711.jpg" alt=""></p><p>注意：创建文件的时候要设置文件结束标志，也就是&lt;&lt;EOF，可以把EOF换成别的字符，注意是大小写敏感的，当文件内容写完之后要输入结束标志EOF，这时命令会正确结束，表示成功创建文件并且写进内容。</p><p>&nbsp;<img src="http://images.cnitblog.com/blog/352319/201411/061948276112586.jpg" alt=""></p><p>&nbsp;</p><p>&nbsp;C:追加文件内容的用法：</p><p><img src="file:///C:/Users/L/AppData/Local/YNote/data/549241301@qq.com/6b2e8b1a65f24a2b8bb48851eaa22a90/20130608204344.jpg" alt=""></p><p>注意：与创建文件内容不同的是符号单边号&gt;变成了双边号&gt;&gt;。</p><p><img src="http://images.cnitblog.com/blog/352319/201411/061949161747450.jpg" alt=""></p><p>&nbsp;</p><p>D:文件合并的用法</p><p><img src="http://images.cnitblog.com/blog/352319/201411/061949574247848.jpg" alt=""></p><p><img src="file:///C:/Users/L/AppData/Local/YNote/data/549241301@qq.com/1d824936f69a4dd3aec00d3876ced303/20130608205024.jpg" alt=""></p><p>把文件f2.txt,f3.txt,f4.txt的文件内容写入到f1.txt中，如果f1.txt文件以前有内容，则先会清除它们然后再写入合并后的内容。</p><p>如果不想清除文件内容，则可以把单边号&gt;变成了双边号&gt;&gt;，如下图所示：</p><p><img src="http://images.cnitblog.com/blog/352319/201411/061950394083388.jpg" alt=""></p><p>&nbsp;</p><p><span style="color: rgb(255, 0, 0);">附：</span></p><p><span style="color: rgb(255, 0, 0);">cat命令的全称：</span></p><p><span style="color: rgb(255, 0, 0);">concatenate files and print on the standard output</span></p><p><br></p><p><br></p><p><a href="http://www.cnblogs.com/fabulousyoung/p/4079759.html" rel="nofollow">http://www.cnblogs.com/fabulousyoung/p/4079759.html</a><br></p>'),
  (55, 261, '<p>管道符号，是unix一个很强大的功能,符号为一条竖线:"|"。</p><p>用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command2的输入传给command </p>'),
  (56, 262, '<p><b>$$&nbsp;</b></p><p>Shell本身的PID（ProcessID）&nbsp;</p><p><b>$!&nbsp;</b></p><p>Shell最后运行的后台Process的PID&nbsp;</p><p><b>$?&nbsp;</b></p><p>最后运行的命令的结束代码（返回值）&nbsp;</p><p><b>$-&nbsp;</b></p><p>使用Set命令设定的Flag一览&nbsp;</p><p><b>$*&nbsp;</b></p><p>所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。&nbsp;</p><p><b>$@</b>&nbsp;</p><p>所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。&nbsp;</p><p><b>$#&nbsp;</b></p><p>添加到Shell的参数个数&nbsp;</p><p><b>$0&nbsp;</b></p><p>Shell本身的文件名&nbsp;</p><p><b>$1～$n&nbsp;</b></p><p>添加到Shell的各参数值。$1是第1参数、$2是第2参数…。 </p><p><br></p><p><br></p><p><a href="http://www.cnblogs.com/fhefh/archive/2011/04/15/2017613.html" rel="nofollow">http://www.cnblogs.com/fhefh/archive/2011/04/15/2017613.html</a><br></p>'),
  (57, 263, '<p>     <b>command&nbsp; &gt; out.file &nbsp; 2&gt;&amp;1 &amp;</b></p><p><b><br></b></p><p>2&gt;&amp;前面的2表示错误输出，如果是1&gt;表示表示标准输出，这个1可以省略掉</p><p><br></p><p>&gt;out.file&nbsp; 是将command的输出重定向到out.file文件，即输出内容不打印到屏幕上，而是输出到out.file文件中。</p><p><br></p><p>2&gt;&amp;1&nbsp;&nbsp; 是将标准出错重定向到标准输出，这里的标准输出已经重定向到了out.file文件，即将标准出错也输出到out.file文件中<br></p><p><br></p><p>最后一个&amp;， 是让该命令在后台执行。</p><p><br></p><p><br></p><p>测试例子</p><pre><code class="lang-bash">#!/bin/sh\r\n \r\nls 2&gt;1测试一下，不会报没有2文件的错误，但会输出一个空的文件1；\r\n\r\nls xxx 2&gt;1测试，没有xxx这个文件的错误输出到了1中；\r\n\r\nls xxx 2&gt;&amp;1测试，不会生成1这个文件了，不过错误跑到标准输出了；\r\n\r\nls xxx &gt;out.txt 2&gt;&amp;1, 实际上可换成 ls xxx 1&gt;out.txt 2&gt;&amp;1；重定向符号&gt;默认是1,错误和输出都传到out.txt了。<br><br></code></pre>'),
  (58, 264, '<p>把/dev/null看作"黑洞". 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而,/dev/null对命令行和脚本都非常的有用.</p><p>禁止标准输出.</p><table><colgroup></colgroup><tbody><tr><td><pre><code>1 cat $filename &gt;/dev/null\r\n   2 # 文件内容丢失，而不会输出到标准输出.</code></pre></td></tr></tbody></table><p>禁止标准错误 </p><table><colgroup></colgroup><tbody><tr><td><pre><code>1 rm $badname 2&gt;/dev/null\r\n2 #           这样错误信息[标准错误]就被丢到太平洋去了.</code></pre></td></tr></tbody></table><p>禁止标准输出和标准错误的输出.</p><table><colgroup></colgroup><tbody><tr><td><pre><code>1 cat $filename 2&gt;/dev/null &gt;/dev/null\r\n2 # 如果"$filename"不存在，将不会有任何错误信息提示.\r\n3 # 如果"$filename"存在, 文件的内容不会打印到标准输出.\r\n4 # 因此Therefore, 上面的代码根本不会输出任何信息.\r\n5 # 当只想测试命令的退出码而不想有任何输出时非常有用。\r\n6 #-----------测试命令的退出 begin ----------------------#\r\n7 # ls dddd 2&gt;/dev/null 8 \r\n8 # echo $?    //输出命令退出代码：0为命令正常执行，1-255为有出错。  \r\n9 #-----------测试命令的退出 end-----------#  \r\n10# cat $filename &amp;&gt;/dev/null \r\n11 #   也可以, 由 Baris Cicek 指出.</code></pre></td></tr></tbody></table><p>清除日志文件内容</p><table><colgroup></colgroup><tbody><tr><td><pre><code>1 cat /dev/null &gt; /var/log/messages\r\n2 #  : &gt; /var/log/messages   有同样的效果, 但不会产生新的进程.（因为:是内建的）\r\n3 \r\n4 cat /dev/null &gt; /var/log/wtmp</code></pre></td></tr></tbody></table><p><strong>例子 28-1. 隐藏cookie而不再使用</strong></p><table><colgroup></colgroup><tbody><tr><td><pre><code>1 if [ -f ~/.netscape/cookies ]  # 如果存在则删除.\r\n2 then\r\n3   rm -f ~/.netscape/cookies\r\n4 fi\r\n5 \r\n6 ln -s /dev/null ~/.netscape/cookies\r\n7 # 现在所有的cookies都会丢入黑洞而不会保存在磁盘上了.</code></pre></td></tr></tbody></table><p><br></p><pre><code class="lang-bash">&gt; /dev/null表示把标准输出重定向到/dev/null，也就是不在屏幕上输出标准输出\r\n\r\n&gt;&amp; /dev/null表示把标准输出和错误输出重定向到/dev/null，程序不在屏幕上输出<br></code></pre><p><br></p><p><br></p><p><a href="http://blog.csdn.net/kaiwii/article/details/7308729">http://blog.csdn.net/kaiwii/article/details/7308729</a><br></p>'),
  (59, 265, '<p>mysql查询缓存保存查询返回的完整结果，一旦命中该缓存，mysql会跳过解析，优化，执行阶段直接返回结果</p><p><br></p><p>缓存是放在一个引用表，通过一个哈希值引用（包括查询本身，数据库，版本等等）来匹配缓存，如果sql语句存在不确定的数据（例如NOW()）则不会被缓存，所以，写代码时最好是把计算结果传到到sql语句，而不是在sql语句使用数据库内置函数</p><p><br></p><p>问题：</p><p>查询缓存对读和写有额外的开销</p><p>查询缓存是一个加锁排他操作</p><p><br></p><p>查询缓存完全存储在内存中</p><p><br></p><p>判断查询缓存是否有效的直接数据是命中率，就是查询缓存的时间占总查询比率（命中率 = Qcache_hits/(Qcache_hits+Com_select)）</p><p>可以用过show status like ''qcache_hits'' 和 show status like ''Com_select'' 查看数值</p><p><br></p><p><b><span style="color: rgb(0, 0, 0);">mysql<span style="color: rgb(0, 0, 204);">&gt;</span> <span style="color: rgb(255, 0, 0);">SHOW</span> STATUS <span style="color: rgb(0, 0, 255);">LIKE</span> <span style="color: rgb(255, 0, 255);">''qcache%''</span><span style="color: rgb(0, 0, 204);">;</span></span><br></b></p><p><b>MySQL&nbsp;<font>查询缓存变量 说明</font></b><br></p><p></p><p>Qcache_free_blocks</p><p>缓存中相邻内存块的个数。数目大说明可能有碎片。<font>FLUSH&nbsp;QUERY&nbsp;CACHE&nbsp;</font><font>会对缓存中的碎片进行整理，从而得到一个空闲块。</font></p><p>Qcache_free_memory</p><p>缓存中的空闲内存。</p><p>Qcache_hits</p><p>每次查询在缓存中命中时就增大。</p><p>Qcache_inserts</p><p>每次插入一个查询时就增大。</p><p>Qcache_lowmem_prunes</p><p>缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看；如果这个数字在不断增长，就表示可能碎片非常严重，或者内存很少。</p><p>Qcache_not_cached</p><p>不适合进行缓存的查询的数量，通常是由于这些查询不是&nbsp;<font>SELECT&nbsp;</font><font>语句。</font></p><p>Qcache_queries_in_cache &nbsp; <br></p><p>&nbsp;当前缓存的查询（和响应）的数量。</p><p><br></p><p><span style="color: rgb(0, 0, 0);">mysql<span style="color: rgb(0, 0, 204);">&gt;</span>  <span style="color: rgb(255, 0, 0);">SHOW</span> VARIABLES <span style="color: rgb(0, 0, 255);">LIKE</span> <span style="color: rgb(255, 0, 255);">''%query_cache%''</span><span style="color: rgb(0, 0, 204);">;</span></span><br></p>'),
  (61, 267, '<pre><code class="lang-c++">#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;malloc.h&gt;\r\n#include &lt;stdbool.h&gt;\r\n\r\n/*节点结构体*/\r\ntypedef struct Node {\r\n    int data;\r\n    struct Node * pNext;\r\n}NODE, * PNODE;\r\n\r\n//创建联表\r\nPNODE create_list();\r\n//显示链表\r\nvoid traverse_list(PNODE pHead);\r\n//链表是否为空\r\nbool is_empty(PNODE pHead);\r\n//链表长度\r\nint list_length(PNODE pHead);\r\n//删除指定位置的节点\r\nint delete_node(PNODE pHead, int pos);\r\n//插入新节点\r\nbool insert_node(PNODE pHead, int pos, int val);\r\n//链表向前移动一位\r\nvoid left_shift_one(PNODE pHead);\r\n//链表向前移动pos位\r\nvoid left_rotate_string(PNODE pHead, int pos);\r\n//翻转链表\r\nvoid reverse_string(PNODE pHead, int from, int to);\r\n//在某个位置翻转链表\r\nvoid rotate_string(PNODE pHead, int pos);\r\n//根据位置获取节点\r\nPNODE get_node_by_pos(PNODE pHead, int pos);\r\n//是否为回文链表\r\nbool is_palindrome(PNODE pHead);\r\n\r\n\r\nmain()\r\n{\r\n    PNODE pHead;\r\n\r\n    //创建链表\r\n    pHead = create_list();\r\n\r\n    //打印链表\r\n    traverse_list(pHead);\r\n\r\n    //判断链表长度\r\n    printf("链表创建成功，长度为：%d\\n", list_length(pHead));\r\n\r\n    //回文链表判断\r\n	if (is_palindrome(pHead)) {\r\n        printf("这是一个回文链表\\n\\n");\r\n	} else {\r\n        printf("这不是一个回文链表\\n\\n");\r\n	}\r\n\r\n    //翻转链表（暴力翻转）\r\n    int start;\r\n    printf("请输入从第几位开始翻转链表:");\r\n    scanf("%d", &amp;start);\r\n    printf("------------------从第%d位置开始翻转链表后的变化-----------------\\n", start);\r\n	rotate_string(pHead, start);\r\n    traverse_list(pHead);\r\n	printf("当前链表的长度：%d\\n", list_length(pHead));\r\n\r\n	//插入新节点\r\n	int pos,val;\r\n	printf("请输入新插入节点位置：");\r\n	scanf("%d", &amp;pos);\r\n	printf("请输入新节点数值：");\r\n	scanf("%d", &amp;val);\r\n	printf("------------------新插入节点后的变化-----------------\\n");\r\n	insert_node(pHead, pos, val);\r\n	printf("新插入的节点是%d，位置是%d\\n", val, pos);\r\n	traverse_list(pHead);\r\n	printf("当前链表的长度：%d\\n\\n", list_length(pHead));\r\n\r\n	//删除链表节点\r\n	int delPos;\r\n	printf("请输入删除节点的位置：");\r\n	scanf("%d", &amp;delPos);\r\n	int hasDel = delete_node(pHead, delPos);\r\n	printf("------------------删除节点后的变化-----------------\\n");\r\n	printf("删除的节点是%d，位置是%d\\n", hasDel, delPos);\r\n	traverse_list(pHead);\r\n	printf("当前链表的长度：%d\\n\\n", list_length(pHead));\r\n\r\n}\r\n\r\n//创建联表\r\nPNODE create_list()\r\n{\r\n    int i;int len;int val;\r\n    PNODE pHead; //链表首地址\r\n    PNODE pNew;  //新增加的节点\r\n    PNODE pLast; //链表最后一个节点\r\n\r\n    //先分配表头\r\n    pHead = (PNODE)malloc(sizeof(NODE));\r\n    if (NULL == pHead) {\r\n        printf("创建表头失败！\\n");\r\n        exit(-1);\r\n    }\r\n\r\n    //创建一个节点的指针变量，用来保存链表的最后一个节点\r\n    pLast = pHead;\r\n    pLast-&gt;pNext = NULL;\r\n\r\n    printf("请输入链表个数：");\r\n    scanf("%d", &amp;len);\r\n\r\n    for(i=0;i&lt;len;i++) {\r\n        printf("请输入第%d个值：", i+1);\r\n        scanf("%d", &amp;val);\r\n\r\n        pNew = (PNODE)malloc(sizeof(NODE));\r\n        if (NULL == pNew) {\r\n            printf("链表分配内存失败！\\n");\r\n            exit(-1);\r\n        }\r\n        pNew-&gt;data = val;\r\n        pLast-&gt;pNext = pNew;\r\n        pNew-&gt;pNext = NULL;\r\n        pLast = pNew;         //将新节点作为最后一个节点\r\n    }\r\n\r\n    return pHead;\r\n}\r\n\r\n//打印链表\r\nvoid traverse_list(PNODE pHead)\r\n{\r\n    PNODE p = pHead-&gt;pNext; //首节点（第一个有效节点）\r\n    while (p != NULL) {\r\n        printf("%d\\n",p-&gt;data);\r\n        p = p-&gt;pNext;\r\n    }\r\n}\r\n\r\n//链表是否为空\r\nbool is_empty(PNODE pHead)\r\n{\r\n    return pHead-&gt;pNext == NULL;\r\n}\r\n\r\n//链表长度\r\nint list_length(PNODE pHead)\r\n{\r\n    int len = 0;\r\n    PNODE p = pHead-&gt;pNext; //首节点（第一个有效节点）\r\n    while (p != NULL) {\r\n        ++len;\r\n        p = p-&gt;pNext;\r\n    }\r\n    return len;\r\n}\r\n\r\n//插入新节点\r\nbool insert_node(PNODE pHead, int pos, int val)\r\n{\r\n	int i = 0;\r\n	PNODE p = pHead;\r\n	while (i&lt;pos-1 &amp;&amp; p != NULL) {\r\n		p = p-&gt;pNext;\r\n		i++;\r\n	}\r\n\r\n	int len = list_length(pHead);\r\n	if (pos&lt;i || pos&gt;len+1) {\r\n        return false;\r\n	}\r\n\r\n	PNODE pNew = (PNODE)malloc(sizeof(NODE));\r\n	if (NULL == pNew) {\r\n		printf("分配内存失败！\\n");\r\n		exit(-1);\r\n	}\r\n	pNew-&gt;data = val;\r\n	pNew-&gt;pNext = p-&gt;pNext;\r\n	p-&gt;pNext = pNew;\r\n}\r\n\r\n//删除节点\r\nint delete_node(PNODE pHead, int pos)\r\n{\r\n    int i = 0;\r\n	PNODE p = pHead;\r\n	while (i&lt;pos-1 &amp;&amp; p != NULL) {\r\n		p = p-&gt;pNext;\r\n		i++;\r\n	}\r\n\r\n	if (pos&lt;i || pos&gt;list_length(pHead)) {\r\n        return 0;\r\n	}\r\n\r\n	PNODE nextNode = p-&gt;pNext;\r\n	int val = nextNode-&gt;data;\r\n	p-&gt;pNext = nextNode-&gt;pNext;\r\n	free(nextNode);\r\n	return val;\r\n}\r\n\r\n//翻转链表\r\nvoid reverse_string(PNODE pHead, int from, int to)\r\n{\r\n    int t;\r\n    PNODE pFrom,pTo;\r\n    pFrom = get_node_by_pos(pHead, from);\r\n    pTo = get_node_by_pos(pHead, to);\r\n\r\n    while(from&lt;to){\r\n        t=pFrom-&gt;data;\r\n        pFrom-&gt;data=pTo-&gt;data;\r\n        pTo-&gt;data = t;\r\n        pFrom = pFrom-&gt;pNext;\r\n        pTo = get_node_by_pos(pHead, to-1); //单向拿不到上一个节点,只能通过循环找出来\r\n        from++;\r\n        to--;\r\n    }\r\n}\r\n\r\n//是否为回文链表\r\nbool is_palindrome(PNODE pHead)\r\n{\r\n    int front = 0;\r\n    int back = list_length(pHead) - 1;\r\n    PNODE pFront, pBack;\r\n\r\n    pFront = get_node_by_pos(pHead, front);\r\n    pBack = get_node_by_pos(pHead, back);\r\n\r\n    while(front&lt;back)\r\n    {\r\n        if (pFront-&gt;data != pBack-&gt;data) {\r\n            return false;\r\n        }\r\n\r\n        pFront = pFront-&gt;pNext;\r\n        pBack = get_node_by_pos(pHead, back - 1); //单向拿不到上一个节点,只能通过循环找出来\r\n        front++;\r\n        back--;\r\n    }\r\n    return true;\r\n}\r\n\r\n//根据位置找出节点\r\nPNODE get_node_by_pos(PNODE pHead, int pos)\r\n{\r\n    int i = 0;\r\n    PNODE p = pHead-&gt;pNext;\r\n\r\n    while(p!=NULL &amp;&amp; i&lt;pos){\r\n        p = p-&gt;pNext;\r\n        ++i;\r\n    }\r\n    return p;\r\n}\r\n\r\n//链表翻转。给出一个链表和一个数k，比如，链表为1→2→3→4→5→6，k=2，则翻转后2→1→6→5→4→3\r\nvoid rotate_string(PNODE pHead, int pos)\r\n{\r\n    int n;\r\n    int len = list_length(pHead);\r\n\r\n    pos %= len;\r\n    reverse_string(pHead, 0, pos-1);\r\n\r\n    //traverse_list(pHead);exit(-1);\r\n    if(pos&lt;len){\r\n        reverse_string(pHead,pos,len-1);\r\n    }\r\n\r\n}\r\n<br></code></pre>'),
  (62, 268, '<p>php-mongo扩展下载地址：<br></p><p><a href="https://pecl.php.net/package/mongodb/1.1.9/windows">https://pecl.php.net/package/mongodb/1.1.9/windows</a></p><p><br></p><p>Yii2.0-mongodb地址：<br></p><p><a href="https://github.com/yiisoft/yii2-mongodb/tree/38590d631d121051646c123459e9345bd4eba406/docs/guide">https://github.com/yiisoft/yii2-mongodb/tree/38590d631d121051646c123459e9345bd4eba406/docs/guide</a></p><p><br></p><p>注意问题：<br></p><p>	（1）yii2-mongodb 2.1.x 不再支持 mongo 扩展,需要改用 mongodb 1.0 以上版本.</p><p>（2）php -m 查看的是CLI下的扩展,如果和php-fpm分开使用配置文件是不会生效的.具体看phpinfo()是否开启.</p><p>（3）如果是wamp环境下，注意有两个php.ini文件，一个在php目录下，一个在apache目录下，这两个文件都需要开启扩展：extension=php_mongodb.dll <br></p>'),
  (63, 269, '<pre><code class="lang-bash"><span class="hljs-comment"># 下载composer.phar </span>\r\n<span class="hljs-title">curl</span> -sS <span class="hljs-url">https://getcomposer.org/installer</span> | php\r\n\r\n<span class="hljs-comment"># 把composer.phar移动到环境下让其变成可执行 </span>\r\nmv composer.phar /usr/local/bin/composer\r\n\r\n<span class="hljs-comment"># 测试</span>\r\ncomposer -V \r\n<span class="hljs-comment"># 输出：Composer version 1.0-dev (e64470c987fdd6bff03b85eed823eb4b865a4152) 2015-05-28 14:52:12</span></code></pre><p><br></p><p><br></p><p><a href="https://segmentfault.com/a/1190000004627398">https://segmentfault.com/a/1190000004627398</a><br></p>'),
  (64, 270, '<p>网站下载coreseek-4.1-beta.tar.gz安装包，并上传到服