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

<channel>
	<title>少侠的博客--Enjoy PHP</title>
	<atom:link href="http://www.enjoyphp.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.enjoyphp.com</link>
	<description>享受每日进步的乐趣</description>
	<lastBuildDate>Wed, 07 Dec 2011 10:13:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PHP分割汉字为数组</title>
		<link>http://www.enjoyphp.com/2011/development/php/php-split-chinese/</link>
		<comments>http://www.enjoyphp.com/2011/development/php/php-split-chinese/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 10:13:30 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[汉字]]></category>
		<category><![CDATA[编码]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1388</guid>
		<description><![CDATA[&#60;?php $string =&#34;帅朱好cc变c态啊，2！&#34;; $arr1 = str_split_utf8($string,&#039;gbk&#039;); var_dump($arr1); /**  * 将汉字字符串分割为数组  *  * @param string $str  * @param string $charset 字符编码 默认gbk  * @return Array  */ function str_split_utf8($str,$charset=&#039;gbk&#039;) {     $str...]]></description>
			<content:encoded><![CDATA[<pre class="brush: php; ">

&lt;?php
$string =&quot;帅朱好cc变c态啊，2！&quot;;
$arr1 = str_split_utf8($string,&#039;gbk&#039;);
var_dump($arr1);

/**
 * 将汉字字符串分割为数组
 *
 * @param string $str
 * @param string $charset 字符编码 默认gbk
 * @return Array
 */
function str_split_utf8($str,$charset=&#039;gbk&#039;) {
    $str = iconv($charset,&#039;utf-8&#039;,$str);
    $split=1;
    $array = array();
    for ( $i=0; $i &lt; strlen( $str ); ){
        $value = ord($str[$i]);
        if($value &gt; 127){
            if($value &gt;= 192 &amp;&amp; $value &lt;= 223)
            $split=2;
            elseif($value &gt;= 224 &amp;&amp; $value &lt;= 239)
            $split=3;
            elseif($value &gt;= 240 &amp;&amp; $value &lt;= 247)
            $split=4;
        }else{
            $split=1;
        }
        $key = NULL;
        for ( $j = 0; $j &lt; $split; $j++, $i++ ) {
            $key .= $str[$i];
        }
        array_push( $array, $key );
    }

    foreach($array as $key=&gt;$value)
    {
        $array[$key] = iconv(&#039;utf-8&#039;,$charset,$value);
    }
    return $array;
}
</pre>
<p>&nbsp;</p>
<p>结果：<br />
<a href="http://www.enjoyphp.com/wp-content/uploads/2011/12/QQ截图20111207180245.jpg"><img class="alignnone size-full wp-image-1389" title="QQ截图20111207180245" src="http://www.enjoyphp.com/wp-content/uploads/2011/12/QQ截图20111207180245.jpg" alt="" width="229" height="392" /></a></p>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2009/development/php/php-utf8-json/" title="PHP中非UTF-8编码下的JSON处理">PHP中非UTF-8编码下的JSON处理</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/development/php/php-split-chinese/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]mysql_pconnect的水挺深,apache下的数据库长连接</title>
		<link>http://www.enjoyphp.com/2011/development/php/mysql_pconnect/</link>
		<comments>http://www.enjoyphp.com/2011/development/php/mysql_pconnect/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 15:13:14 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1383</guid>
		<description><![CDATA[服务器上一直用着mysql_pconnect，之前听说它会出现各种各样的问题，但服务器一直没事，也就没去管。今天看这篇文章，才知道原来mysql_pconnect有这么多的道道。 原文地址：http://www.cnblogs.com/funlake/archive/2011/09/08/2171822.html 　　php的mysql持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是为啥么。近距离观察后发现，这家伙也不容易啊，要看apache的脸色，还得听mysql指挥。 　　对于做为apache模块运行的php来说，要实现mysql持久化连接，首先得取决于apache这个web服务器是否支持Keep-Alive。 　　Keep-Alive 　　Keep-Alive是什么东西？它是http协议的一部分，让我们复习一下没有Keep-Alive的http请求，从客户在浏览器输入一个有效url地址开始，浏览器就会利用socket向url对应的web服务器发送一条tcp请求，这个请求成功一次就得需要来回握三次手才能确定，成功以后，浏览器利用socket tcp连接资源向web服务器请求http协议，发送以后就等着web服务器把http返回头和body发送回来，发回来后浏览器关闭socket连接，然后做http返回头和body的解析工作，最后呈现在浏览器上的就是漂亮的页面了。这里面有什么问题呢？tcp连接需要三次握手，也就是来回请求三次方能确定一个tcp请求是否成功，然后tcp关闭呢？来回需要4次请求才能完成!每次http请求就3次握手，4次拜拜，这来来回回的不嫌累啊，多少时间和资源都被浪费在socket连接关闭上了，能不能一次socket tcp连接发送多次http请求呢？于是Keep-Alive就应运而生,http/1.0里需要客户端自己在请求头加入Connection:Keep-alive方能实现，在这里我们只考虑http1.1了，只需要设置一下apache，让它默认就是Keep-Alive持久连接模式(apache必须1.2+才能支持Keep-Alive).在httpd.conf里找到KeepAive配置项，果断设置为On,MaxKeepAliveRequests果断为0(一个持久tcp最多允许的请求数，如果过小，很容易在tcp未过期的情况下，达到最大连接，那下次连接就又是新的tcp连接了,这里设置0表示不限制)，然后对于mysql_pconnect最重要的选项KeepAliveTimeout设置为15(表示15秒). 　　好了，重启apache,测试一下，赶紧写行东西 &#60;?php echo "Apache进程号:".getmypid(); ?&#62; 很简单，获取当前php执行者(apache)的进程号，用浏览器浏览这个页面，看到什么？对,有看到一串进程号数字,15秒内,连续刷新页面,看看进程号有无变化?木有吧？现在把手拿开，交叉在胸前，度好时间，1秒，2秒，3,&#8230;15,16。好，过了15秒了，再去刷新页面,进程号有没有变化？变了！又是一个新的apache进程了，为什么15秒后就变成新的进程了?记得我们在apache里设置的KeepAliveTimeout吗？它的值就是15秒.现在我们应该大致清楚了,在web服务器默认打开KeepAlive的情况下，客户端第一次http成功请求后，apache不会立刻断开socket,而是一直监听来自这一客户端的请求，监听多久?根据KeepAliveTimeout选项配置的时间决定，一旦超过这一时间,apache就会断开socket了，那么下次同一客户端再次请求，apache就会新开一个进程来相应。所以我们之前15内不停的刷新页面，看到的进程号都是一致的，表明是浏览器请求给了同一个apache进程。 　　浏览器是怎么知道不需要重新进行tcp连接就可以直接发送http请求呢？因为http返回头里就会带上Connection:keep-alive,Keep-alive:15两行，意思就是让客户端浏览器明白，这次socket连接我这边还没关闭呢，你可以在15内继续使用这个连接，并发送http请求，于是乎浏览器就知道应该怎么做了. 　　php怎么做 　　那么，php的mysql连接资源是怎么被hold住的呢，这需要查看php的mysql_pconnect的函数代码，我看了下，大概的做法就是根据当前apache进程号，生成hash key,找hash表内有无对应的连接资源，没有则推入hash表，有则直接使用。有些代码片段可以说明(具体可查看php5.3.8源码ext/mysql/php_mysql.c文件690行php_mysql_do_connect函数) #1.生成hash key user=php_get_current_user();//获取当前php执行者(apache)的进程唯一标识号 hashed_details_length = spprintf(&#38;hashed_details, 0, "mysql__%s_", user);//hashed_details就是hash key #2.如果未找到已有资源，就推入hash表，名字叫persistent_list，如果找到就直接使用 /*...]]></description>
			<content:encoded><![CDATA[<p>服务器上一直用着mysql_pconnect，之前听说它会出现各种各样的问题，但服务器一直没事，也就没去管。今天看这篇文章，才知道原来mysql_pconnect有这么多的道道。</p>
<p>原文地址：<a href="http://www.cnblogs.com/funlake/archive/2011/09/08/2171822.html">http://www.cnblogs.com/funlake/archive/2011/09/08/2171822.html</a></p>
<p>　　php的mysql持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是为啥么。近距离观察后发现，这家伙也不容易啊，要看apache的脸色，还得听mysql指挥。</p>
<p>　　对于做为apache模块运行的php来说，要实现mysql持久化连接，首先得取决于apache这个web服务器是否支持Keep-Alive。</p>
<p>　　<strong>Keep-Alive</strong></p>
<p>　　Keep-Alive是什么东西？它是http协议的一部分，让我们复习一下没有Keep-Alive的http请求，从客户在浏览器输入一个有效url地址开始，浏览器就会利用socket向url对应的web服务器发送一条tcp请求，这个请求成功一次就得需要来回握三次手才能确定，成功以后，浏览器利用socket tcp连接资源向web服务器请求http协议，发送以后就等着web服务器把http返回头和body发送回来，发回来后浏览器关闭socket连接，然后做http返回头和body的解析工作，最后呈现在浏览器上的就是漂亮的页面了。这里面有什么问题呢？tcp连接需要三次握手，也就是来回请求三次方能确定一个tcp请求是否成功，然后tcp关闭呢？来回需要4次请求才能完成!每次http请求就3次握手，4次拜拜，这来来回回的不嫌累啊，多少时间和资源都被浪费在socket连接关闭上了，能不能一次socket tcp连接发送多次http请求呢？于是Keep-Alive就应运而生,http/1.0里需要客户端自己在请求头加入Connection:Keep-alive方能实现，在这里我们只考虑http1.1了，只需要设置一下apache，让它默认就是Keep-Alive持久连接模式(apache必须1.2+才能支持Keep-Alive).在httpd.conf里找到KeepAive配置项，果断设置为On,MaxKeepAliveRequests果断为0(一个持久tcp最多允许的请求数，如果过小，很容易在tcp未过期的情况下，达到最大连接，那下次连接就又是新的tcp连接了,这里设置0表示不限制)，然后对于mysql_pconnect最重要的选项KeepAliveTimeout设置为15(表示15秒).</p>
<p>　　好了，重启apache,测试一下，赶紧写行东西</p>
<div>
<pre>&lt;?php
    echo "Apache进程号:".getmypid();
?&gt;</pre>
</div>
<p>很简单，获取当前php执行者(apache)的进程号，用浏览器浏览这个页面，看到什么？对,有看到一串进程号数字,15秒内,连续刷新页面,看看进程号有无变化?木有吧？现在把手拿开，交叉在胸前，度好时间，1秒，2秒，3,&#8230;15,16。好，过了15秒了，再去刷新页面,进程号有没有变化？变了！又是一个新的apache进程了，为什么15秒后就变成新的进程了?记得我们在apache里设置的KeepAliveTimeout吗？它的值就是15秒.现在我们应该大致清楚了,在web服务器默认打开KeepAlive的情况下，客户端第一次http成功请求后，apache不会立刻断开socket,而是一直监听来自这一客户端的请求，监听多久?根据KeepAliveTimeout选项配置的时间决定，一旦超过这一时间,apache就会断开socket了，那么下次同一客户端再次请求，apache就会新开一个进程来相应。所以我们之前15内不停的刷新页面，看到的进程号都是一致的，表明是浏览器请求给了同一个apache进程。</p>
<p>　　浏览器是怎么知道不需要重新进行tcp连接就可以直接发送http请求呢？因为http返回头里就会带上Connection:keep-alive,Keep-alive:15两行，意思就是让客户端浏览器明白，这次socket连接我这边还没关闭呢，你可以在15内继续使用这个连接，并发送http请求，于是乎浏览器就知道应该怎么做了.</p>
<p>　　<strong>php怎么做</strong></p>
<p>　　那么，php的mysql连接资源是怎么被hold住的呢，这需要查看php的mysql_pconnect的函数代码，我看了下，大概的做法就是根据当前apache进程号，生成hash key,找hash表内有无对应的连接资源，没有则推入hash表，有则直接使用。有些代码片段可以说明(具体可查看php5.3.8源码ext/mysql/php_mysql.c文件690行php_mysql_do_connect函数)</p>
<div>
<pre>    #1.生成hash key
        user=php_get_current_user();//获取当前php执行者(apache)的进程唯一标识号
        hashed_details_length = spprintf(&amp;hashed_details, 0, "mysql__%s_", user);//hashed_details就是hash key
    #2.如果未找到已有资源，就推入hash表，名字叫persistent_list，如果找到就直接使用
         /* try to find if we already have this link in our persistent list */
         if (zend_hash_find(&amp;EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &amp;le)==FAILURE) {  /* we don't */
            ...
            ...
            /* hash it up(推入hash表) */
            Z_TYPE(new_le) = le_plink;
            new_le.ptr = mysql;
            if (zend_hash_update(&amp;EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &amp;new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
                ...
                ...
            }

         }else{/* The link is in our list of persistent connections(连接已在hash表里)*/
            ...
            ...
            mysql = (php_mysql_conn *) le-&gt;ptr;//直接使用对应的sql连接资源
            ...
            ...

         }</pre>
</div>
<p>zend_hash_find比较容易看明白,原型是zend_hash_find(hash表，key名,key长,value);如果找到，value就有值了。</p>
<p>     <strong> mysql的wait_timeout和interactive_timeout</strong></p>
<p>　　说完Keep-Alive，该到mysql家串串门了，说的是mysql_pconnect，怎么能绕开mysql的设置。</p>
<p>　　影响mysql_pconnect最重要的两个参数就是wait_timeout和interactive_timeout,它们是什么东西？先撇一边，首先让我们把上面的代码改动一下php代码</p>
<div>
<pre>&lt;?php
    $conn = mysql_pconnect("localhost","root","123456") or die("Can not connect to mysql");
    echo "Mysql线程号:".mysql_thread_id($conn)."&lt;br/&gt;";
    echo "Apache进程号".getmypid();
?&gt;</pre>
</div>
<p>以上的代码没啥好解释的，让我们用浏览器浏览这个页面，看到什么？看到两个显眼的数字。一个是mysql线程号，一个是apache进程号,好了，15秒后再刷新这个页面,发现这两个id都变了,因为已经是新的apache进程了,进程id是新的,hash key就变了,php只好重新连接mysql,连接资源推入persistent list。如果15内刷新呢？apache进程肯定不变，mysql线程号会变吗？答案得问mysql了。首先这个mysql_thread_id是什么东西？shell方式登录mysql后执行命令&#8217;show processlist&#8217;，看到了什么？</p>
<div>
<pre>mysql&gt; show processlist;
+-----+------+-----------+------+---------+------+-------+------------------+
| Id  | User | Host      | db   | Command | Time | State | Info             |
+-----+------+-----------+------+---------+------+-------+------------------+
| 348 | root | localhost | NULL | Query   |    0 | NULL  | show processlist |
| 349 | root | localhost | NULL | Sleep   |    2 |       | NULL             |
+-----+------+-----------+------+---------+------+-------+------------------+</pre>
</div>
<p>,发现了很重要的信息，这个processlist列表就是记录了正在跑的线程，忽略Info列为show processlist那行,那行是你当前shell登录mysql的线程。php连接mysql的线程就是Id为349那行，如果读者自己做测试，应该知道这个Id=349在你的测试环境里是另外一个值，我们把这个值和网页里输出的mysql_thread_id($conn)做做比较，对！他们是一样的。接下来最重要的是观察Command列和Time列，Command = Sleep，表明什么？表明我们mysql_pconnect连接后就一直在sleep，Time字段就告诉我们，这个线程Sleep了多久,那么Sleep了多久这个线程才能作废呢？那就是wait_timeout或者interactive_timeout要做的工作了,他们默认的值都是8小时,天啊,太久了,所以如果说web服务器关掉KeepAlive支持,那个这个processlist很容易就被撑爆,就爆出那个Too many connections的错误了,max_connectiosns配置得再多也没用。为了观察这两个参数,我们可以在mysql配置文件my.cnf里设置这两个值,找到[mysqld]节点，在里面设置多两行</p>
<div>
<pre>interactive_timeout = 60
wait_timeout        = 30</pre>
</div>
<p>配置完后，重启mysql,shell登录mysql,这时候show processlist可以发现只有当前线程。然后运行那个带有mysql_pconnect的php页面,再回来mysql端show processlist可发现，多了一个Commond为Sleep的线程,不停的show processlist(方向键上+enter键)观察Time列的变化2,5,10..14!，突然那个Sleep线程程被kill掉了,咋回事,还没到30秒呢,噢!忘了修改一下apache keepalive的参数了,把KeepAliveTimeOut从15改成120(只为观察,才这么改),重启apache.刷新那个页面,好,开始不停的show processlist,2..5..10..14,15,..20&#8230;26&#8230;.28,29!线程被kill,这次是因为wait_timeout起了作用,浏览器那边停了30秒,30秒内如果浏览器刷新,那这个Time又会从0开始计时。这种连接不属于interactive connection(mysql shell登录那种连接就属于interactive connection)，所以采用了wait_timeout的值。如果mysql_pconnect的第4个参数改改呢</p>
<div>
<pre>&lt;?php
$conn = mysql_pconnect('localhost','root','123456',MYSQL_CLIENT_INTERACTIVE);
echo "Mysql线程号:".mysql_thread_id($conn)."&lt;br/&gt;";
echo "Apache进程号:".getmypid();
?&gt;</pre>
</div>
<p>刷新下页面,mysql那边开始刷show processlist，这回Time &gt; 30也不会被kill，&gt;60才被kill了,说明设置了MYSQL_CLIENT_INTERACTIVE,就会被mysql视为interactive connection,那么这次php的mysql连接在120秒内未刷新页面的情况下,何时作废将取决于mysql的interactive_timeout的配置值。</p>
<p>　　<strong>总结</strong></p>
<p>　　<strong>#1</strong>.php的mysql_pconnect要达到功效,首先必须保证apache是支持keep alive的,然后KeepAliveTimeOut应该设置多久呢,要根据自身站点的访问情况做调整,时间太短,keep alive没啥意义,时间太长,就很可能为一个闲客户端连接牺牲很多服务器资源,毕竟hold住socket监听进程是要消耗cpu内存的.</p>
<p>　　<strong>#2</strong>.apache的KeepAliveTimeOut配置得和mysql的time out配置要有个平衡点,联系以上的观察,假设mysql_pconnect未带上第4个参数,如果apache的KeepAliveTimeOut设置的秒数比wait_timeout小,那真正对mysql_pconnect起作用的是apache而不是mysql的配置.这时如果mysql的wait_timeout偏大,并发量大的情况下,很可能就一堆废弃的connection了,mysql这边如果不及时回收,那就很可能Too many connections了.可是如果KeepAliveTimeOut太大呢，又回到之前的问题，所以貌似Apache.KeepAliveTimeOu不要太大,但比Mysql.wait_timeout 稍大，或者相等是比较好的方案,这样可以保证keep alive过期后,废弃的mysql连接可以及时被回收. </p>
<p>　　<strong>后记</strong></p>
<p>　　Pdo数据库的长连接机制是否和mysql_pconnect一样?经过试验观察和源码探究，发现也是一样的处理方式。</p>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2010/front/javascript/jquery/6-jquery-documentation-alternatives-for-quick-implementationjquery/" title="6 jQuery documentation alternatives for quick implementation(jquery六个便于快速开发的文档)">6 jQuery documentation alternatives for quick implementation(jquery六个便于快速开发的文档)</a></li><li><a href="http://www.enjoyphp.com/2008/uncategorized/apmserv520-rewrite/" title="APMServ5.2.0开启Rewrite（伪静态）的方法（经验总结）">APMServ5.2.0开启Rewrite（伪静态）的方法（经验总结）</a></li><li><a href="http://www.enjoyphp.com/2010/%e6%9e%b6%e6%9e%84/taobao-image-cdn/" title="淘宝海量图片存储与CDN系统">淘宝海量图片存储与CDN系统</a></li><li><a href="http://www.enjoyphp.com/2011/front/min-web/" title="[转]网站优化 更小的静态资源">[转]网站优化 更小的静态资源</a></li><li><a href="http://www.enjoyphp.com/2009/front/javascript/javascript-chinese-chess/" title="JS版中国象棋">JS版中国象棋</a></li><li><a href="http://www.enjoyphp.com/2010/front/design/uedsky-htmlcompressor-v1-0/" title="Uedsky HtmlCompressor v1.0发布(前端性能优化之Html压缩)">Uedsky HtmlCompressor v1.0发布(前端性能优化之Html压缩)</a></li><li><a href="http://www.enjoyphp.com/2008/storeage/mysql-lamp/mysql-function-list/" title="整理了下MySQL内置函数表,包括字符串函数、数学函数和日期时间函数 ">整理了下MySQL内置函数表,包括字符串函数、数学函数和日期时间函数 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/development/php/mysql_pconnect/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GODADDY .net续费优惠码</title>
		<link>http://www.enjoyphp.com/2011/news/hot/godaddy-net/</link>
		<comments>http://www.enjoyphp.com/2011/news/hot/godaddy-net/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 15:25:34 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[时文热点]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1381</guid>
		<description><![CDATA[SCAM14 相关文章学习一种新的编程语言所要做的15个练习推荐软件：Navicat 9（附中文版/英文版注册机）Javascript动态添加CSSPHP-API类大全(Amazon,Bing&#8230;&#8230;N多)ECSHOP更改后台管理地址的方法（ECSHOP 2.6.0）MySQL中SQL优化中文编码基础知识介绍]]></description>
			<content:encoded><![CDATA[<p>SCAM14</p>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2009/front/javascript/js-safe-transfer/" title="JS实现HTTP安全传输密码">JS实现HTTP安全传输密码</a></li><li><a href="http://www.enjoyphp.com/2010/news/uncategorized/furen/" title="富人的28个理财习惯 思维导图">富人的28个理财习惯 思维导图</a></li><li><a href="http://www.enjoyphp.com/2009/server/linux/ubuntu-9-04-mouse-keyboard-cant-work/" title="ubuntu 9.04 键盘鼠标失效的问题">ubuntu 9.04 键盘鼠标失效的问题</a></li><li><a href="http://www.enjoyphp.com/2009/front/w3c/css-sprites/" title="解密CSS Sprites：技巧、工具和教程">解密CSS Sprites：技巧、工具和教程</a></li><li><a href="http://www.enjoyphp.com/2009/front/javascript/jquery/jquery-speed-up-1/" title="jQuery性能优化指南（1）">jQuery性能优化指南（1）</a></li><li><a href="http://www.enjoyphp.com/2009/news/uncategorized/ten-necessary-skills/" title="未来5年开发人员必需的10项技能">未来5年开发人员必需的10项技能</a></li><li><a href="http://www.enjoyphp.com/2011/development/php/search-result-highlight/" title="用于搜索结果的关键字高亮显示（不区分大小写）">用于搜索结果的关键字高亮显示（不区分大小写）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/news/hot/godaddy-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]网站优化 更小的静态资源</title>
		<link>http://www.enjoyphp.com/2011/front/min-web/</link>
		<comments>http://www.enjoyphp.com/2011/front/min-web/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 03:25:44 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[前端技术]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1378</guid>
		<description><![CDATA[更小的静态资源(js、css、png、gif)，意味着更少的网络传送时间。构建的时候，可以把这些静态资源进行压缩优化(不像gzip/deflate压缩)，使之更小化。有很多相应的开源工具帮助你完成这项工作。 javascript Google Closure Compiler UglifyJS YUI Compressor ShrinkSafe 其它,比如JSMIN Node.js、jQuery1.5开始使用UglifyJS，UglifyJS压缩比YUI Compressor更小、比Google Closure Compiler更安全。尽管如此，但UglifyJS需要部署NodeJS环境，所以我们还是选择使用Google Closure Compiler style(css) CSSTidy YUI Compressor Yslow/Google Page Speed CSSTidy和YUI Compressor都很棒，我们还是选择老牌的YUI Compressor，因为我们更熟悉它，它也能够满足我们的需求。 png8/gif图片 Optipng AdvanceCOMP(advpng、advdef) ImageMagic(mogrify、identify、convert)...]]></description>
			<content:encoded><![CDATA[<p>更小的静态资源(js、css、png、gif)，意味着更少的网络传送时间。构建的时候，可以把这些静态资源进行压缩优化(不像gzip/deflate压缩)，使之更小化。有很多相应的开源工具帮助你完成这项工作。</p>
<h3>javascript</h3>
<ul>
<li>Google Closure Compiler</li>
<li>UglifyJS</li>
<li>YUI Compressor</li>
<li>ShrinkSafe</li>
<li>其它,比如JSMIN</li>
</ul>
<p>Node.js、jQuery1.5开始使用UglifyJS，UglifyJS压缩比YUI Compressor更小、比Google Closure Compiler更安全。尽管如此，但UglifyJS需要部署NodeJS环境，所以我们还是选择使用Google Closure Compiler</p>
<h3>style(css)</h3>
<ul>
<li>CSSTidy</li>
<li>YUI Compressor</li>
<li>Yslow/Google Page Speed</li>
</ul>
<p>CSSTidy和YUI Compressor都很棒，我们还是选择老牌的YUI Compressor，因为我们更熟悉它，它也能够满足我们的需求。</p>
<h3>png8/gif图片</h3>
<ul>
<li>Optipng</li>
<li>AdvanceCOMP(advpng、advdef)</li>
<li>ImageMagic(mogrify、identify、convert)</li>
<li>Pngcrush</li>
<li>Pngout</li>
<li>gifsicle</li>
<li>jpegtran</li>
</ul>
<p>任何大一点的网站页面都会使用到不少图片，压缩优化图片很有必要。选择什么样的图片格式，决定了怎么去压缩图片。一般而言，只要是非动画图片，我们 推荐png8，即便是颜色很少的小图片(尽管这样的图片gif有更高压缩性，但应该使用css sprites)。Pngout没有开放源码，仅能在Window NT平台使用，所以我们并不考滤使它。Pngcrush虽然很好用，但是optipng、advpng以及advdef结合使用能把图片压缩得更小，所以 我们选择optipng、advpng以及advdef压缩优化PNG图片。 Optipng压缩优化图片、而advdef则优化压缩算法。</p>
<h3>构建脚本</h3>
<p>发布产品的时候，我们希望构建前端资源，包括压缩优化、合并等等。构建应该尽量满足:<br />
1.整个过程是自动的，不需要人工介入<br />
2.所有的操作都是安全的<br />
3.免费的命令行工具</p>
<p>我们这里应用bash写了一个简版的部署脚本，能够简单地应付中小型网站静态资源发布。</p>
<div>
<pre>#!/bin/sh
#filename:build.sh
IN_FILE="/var/www.imgwell.com/themes/ocean/misc"
OUT_FILE="/var/www.imgwell.com/misc"
EXCLUDE_FILES="jquery.min.js LAB.min.js"
GOOGLE_COMPILER="/opt/build/bin/compiler.jar"
YUI_COMPRESSOR="/opt/build/bin/yuicompressor-2.4.6.jar"
OPTIPNG="/usr/local/bin/optipng -quiet -o3 "
ADVPNG="/usr/local/bin/advpng -q -z -4 "
ADVDEF="/usr/local/bin/advdef -q -z -4 "

function mt_ver_code() {
    local MATRIX="23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz"
    local LENGTH=12
    while [ "${n:=1}" -le "$LENGTH" ]; do
        local PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
        let n+=1
    done
    echo -n ${PASS}
}

function mt_file_ext() {
    local FILE=`basename -- "$1"`
    echo -n "${FILE##*.}"
}

function mt_file_size() {
    if [ -f "$1" ]; then
        echo -n `ls -l -- "$1" |awk '{print $5}'`
    else
        echo -n 0
    fi
}

function mt_has_exclude() {
    if [ -z "$EXCLUDE_FILES" ]; then
        echo -n 0
        return 0
    fi
    echo "$EXCLUDE_FILES" |grep -q -w -- "${1}"
    if [ $? -eq 0 ]; then
        echo -n "1"
    else
        echo -n "0"
    fi
}

function mt_google_compile() {
    java -jar "$GOOGLE_COMPILER" --js $1 --js_output_file $2
}

function mt_yui_compressor() {
    java -jar "$YUI_COMPRESSOR" $1 -o $2 --charset utf-8
}

function mt_png_opti() {
    [ -f "`echo ${OPTIPNG} |awk '{print $1}'`" ] &amp;&amp; ${OPTIPNG} "${1}"
    [ -f "`echo ${ADVPNG} |awk '{print $1}'`" ] &amp;&amp; ${ADVPNG} "${1}"
    [ -f "`echo ${ADVDEF} |awk '{print $1}'`" ] &amp;&amp; ${ADVDEF} "${1}"
}

function __main__() {
    [ -d "$IN_FILE" ] || exit 1
    local VER_CODE=`mt_ver_code`
    local FILE_STATUS="!"
    mkdir -p "${OUT_FILE}/${VER_CODE}"

    for f in `ls -1 "$IN_FILE"`; do
        if [ -d "${IN_FILE}/${f}" ] ; then
            continue
        fi

        local HAS_EXCLUDE=`mt_has_exclude "${f}"`
        local FILE_SRC_SIZE=`mt_file_size "${IN_FILE}/${f}"`

        if [ "`mt_file_ext "${f}"`" = "js" -a "$HAS_EXCLUDE" = "0" ]; then
            mt_google_compile "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}/${f}"
            FILE_STATUS="G"
        elif [ "`mt_file_ext "${f}"`" = "css" -a "$HAS_EXCLUDE" = "0"  ]; then
            mt_yui_compressor "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}/${f}"
            FILE_STATUS="Y"
        elif [ "`mt_file_ext "${f}"`" = "png" -a "$HAS_EXCLUDE" = "0" ]; then
            cp "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}"
            [ -f "${OUT_FILE}/${VER_CODE}/${f}" ] &amp;&amp; {
                mt_png_opti "${OUT_FILE}/${VER_CODE}/${f}"
                FILE_STATUS='O'
            }
        else
            cp "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}"
            if [ $? -eq 0 ]; then
                FILE_STATUS="-"
            else
                FILE_STATUS="D"
            fi
        fi

        local FILE_DST_SIZE=`mt_file_size "${OUT_FILE}/${VER_CODE}/${f}"`
        echo "${FILE_STATUS} ${HAS_EXCLUDE} ${f} ${FILE_SRC_SIZE}/${FILE_DST_SIZE}"
    done
    echo "===========/" $VER_CODE "\=========="
}

__main__</pre>
</div>
<p>执行结果如下</p>
<div>[root@www-avatar misc]# ./build.sh<br />
O 0 6N9FQPpTHCy.png 820/258<br />
Y 0 base.css 40171/35530<br />
O 0 FSEB6oLTK3I.png 10362/10362<br />
- 0 GsNJNwuI-UM.gif 522/522<br />
O 0 heart.png 921/807<br />
O 0 IJYgcESal33.png 5771/5771<br />
O 0 _IKHHfAgFQe.png 2635/2302<br />
G 0 jquery.elastic.js 4988/1665<br />
- 1 jquery.min.js 85260/85260<br />
G 0 jquery.ui.dialog.js 10074/5274<br />
G 0 jquery.ui.pview.js 4565/2878<br />
- 1 LAB.min.js 5537/5537<br />
O 0 lFahQXTaTNO.png 90/90<br />
G 0 mutfa.js 36958/21777<br />
O 0 nCItFQafRu8.png 452/288<br />
O 0 p13yZ069LVL.png 792/219<br />
- 0 plupload.flash.swf 18537/18537<br />
G 0 plupload.full.js 48277/46682<br />
Y 0 position.css 7737/7440<br />
O 0 star.png 3292/283<br />
G 0 stars.js 6333/2622<br />
Y 0 ui_plugin.css 12794/12079<br />
G 0 up.js 6230/3991<br />
- 0 uVR6w3wRHEJ.gif 54/54<br />
O 0 WSQ2wnhSG-F.png 245/229<br />
- 0 _ZWZupdaAgS.gif 827/827<br />
===========/ LruQcmx4Zi84 \==========</div>
<h3>总结</h3>
<p>1.UglifyJS压缩比YUI Compressor更小，比Google Closure Compiler更安全。不想冒险，还是应该选择UglifyJS。若想最小化，可以选择Google Closure Compiler<br />
2.YUI Compressor压缩css文件。但CSSTidy也很不错<br />
3.optipng -o3 *.png |advpng -z -4 *.png |advdef -z -4 *.png 将最大化压缩优化png图片<br />
4.网页尽量使用png格式图片，并且压缩优化它，使之最优</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>原文地址：http://www.perfgeeks.com/?p=660</p>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2009/news/uncategorized/update-wp/" title="花了一下午，把博客升级改版了">花了一下午，把博客升级改版了</a></li><li><a href="http://www.enjoyphp.com/2009/front/w3c/css-standard-and-best-cases/" title="CSS标准和最佳示例">CSS标准和最佳示例</a></li><li><a href="http://www.enjoyphp.com/2009/front/javascript/get-user-selection-text/" title="获取页面中被选中的内容">获取页面中被选中的内容</a></li><li><a href="http://www.enjoyphp.com/2009/news/uncategorized/facebook-photos/" title="Facebook 如何管理150亿张照片">Facebook 如何管理150亿张照片</a></li><li><a href="http://www.enjoyphp.com/2010/server/linux/centos-5-5/" title="CentOS 5.5 发布">CentOS 5.5 发布</a></li><li><a href="http://www.enjoyphp.com/2009/development/php/php-html/" title="PHP生成静态页面详解 ">PHP生成静态页面详解 </a></li><li><a href="http://www.enjoyphp.com/2009/front/design/starting-design/" title="设计项目开始前，9件需要了解客户的事情">设计项目开始前，9件需要了解客户的事情</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/front/min-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一键启用firebug-lite调试程序</title>
		<link>http://www.enjoyphp.com/2011/front/javascript/firebug-lite/</link>
		<comments>http://www.enjoyphp.com/2011/front/javascript/firebug-lite/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 14:18:59 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1360</guid>
		<description><![CDATA[习惯在firebox下用firebug调试程序，用IE的开发者工具有点不习惯。还好firebug提供lite版本，可以直接在页面中嵌入 &#60;script type=&#34;text/javascript&#34; src=&#34;https://getfirebug.com/firebug-lite-debug.js&#34;&#62;&#60;/script&#62; 进行调试。 但是但是但是，每次调试都要往页面中嵌入这样一段JS，然后保存，然后刷新，然后XXXX，毕竟很麻烦。 介绍一种简单的方法： 在浏览器（包括IE或其它任何的浏览器）中，收藏下面的网址 javascript:void((function(){var%20e=document.createElement(&#34;script&#34;);e.onload=e.onreadystatechange=function(){};document.body.appendChild(e);e.setAttribute(&#34;src&#34;,&#34;https://getfirebug.com/firebug-lite-debug.js&#34;);})()) (注意把里面的全角引号改成半角，万恶的wordpress编辑器，我治不了了，老是自动把半角引号改为全角) 在你需要调试的页面，直接点击收藏夹中的该链接，就可以启动firebug-lite。so easy&#8230;&#8230; 上面firebug官方提供的JS地址（https://getfirebug.com/firebug-lite.js）有点慢，点击后需要十几秒才能加载完，所以点一下后要耐心等待。也可以自行下载JS到本地，然后把路径改为自己的地址即可。 &#160; 相关文章Firebug-WEB开发调试利器-全介绍PHP获取当前网址/替换网址query中的值jquery suggest修改版(支持中文)，类似google suggest的下拉提示避免AJAX缓存用PHP向MSN发送信息的工具PhpMSN ClassECSHOP更改后台管理地址的方法（ECSHOP 2.6.0）Google推出apache加速模块mod_pagespeed]]></description>
			<content:encoded><![CDATA[<p>习惯在firebox下用firebug调试程序，用IE的开发者工具有点不习惯。还好firebug提供lite版本，可以直接在页面中嵌入</p>
<p><span style="color: #ff0000;">
<pre class="brush: js; ">
&lt;script type=&quot;text/javascript&quot; src=&quot;https://getfirebug.com/firebug-lite-debug.js&quot;&gt;&lt;/script&gt;
</pre>
<p></span>进行调试。</p>
<p>但是但是但是，每次调试都要往页面中嵌入这样一段JS，然后保存，然后刷新，然后XXXX，毕竟很麻烦。</p>
<p>介绍一种简单的方法：</p>
<p>在浏览器（包括IE或其它任何的浏览器）中，收藏下面的网址</p>
<pre class="brush: js; ">
javascript:void((function(){var%20e=document.createElement(&quot;script&quot;);e.onload=e.onreadystatechange=function(){};document.body.appendChild(e);e.setAttribute(&quot;src&quot;,&quot;https://getfirebug.com/firebug-lite-debug.js&quot;);})())
</pre>
<p>(注意把里面的全角引号改成半角，万恶的wordpress编辑器，我治不了了，老是自动把半角引号改为全角)</p>
<p><a href="http://www.enjoyphp.com/wp-content/uploads/2011/08/QQ截图20110822221144.png"><img class="alignnone size-full wp-image-1361" title="QQ截图20110822221144" src="http://www.enjoyphp.com/wp-content/uploads/2011/08/QQ截图20110822221144.png" alt="" width="487" height="403" /></a></p>
<p>在你需要调试的页面，直接点击收藏夹中的该链接，就可以启动firebug-lite。so easy&#8230;&#8230;</p>
<p><a href="http://www.enjoyphp.com/wp-content/uploads/2011/08/QQ截图20110822221559.png"><img class="alignnone size-full wp-image-1362" title="QQ截图20110822221559" src="http://www.enjoyphp.com/wp-content/uploads/2011/08/QQ截图20110822221559.png" alt="" width="433" height="309" /></a></p>
<p>上面firebug官方提供的JS地址（<a href="https://getfirebug.com/firebug-lite.js">https://getfirebug.com/firebug-lite.js</a>）有点慢，点击后需要十几秒才能加载完，所以点一下后要耐心等待。也可以自行下载JS到本地，然后把路径改为自己的地址即可。</p>
<p>&nbsp;</p>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2009/development/php/php-chinese-calendar/" title="[转]PHP农历日历">[转]PHP农历日历</a></li><li><a href="http://www.enjoyphp.com/2011/front/javascript/jslinux/" title="惊现牛人：JS版高仿LINUX">惊现牛人：JS版高仿LINUX</a></li><li><a href="http://www.enjoyphp.com/2010/news/dianzishangwu/10-steps-to-a-more-usable-ecommerce-website/" title="电子商务网站的 10 个易用性规则">电子商务网站的 10 个易用性规则</a></li><li><a href="http://www.enjoyphp.com/2009/front/javascript/jquery-sizzle/" title="jquery sizzle完全解析">jquery sizzle完全解析</a></li><li><a href="http://www.enjoyphp.com/2008/development/php/ttplayer-lyric/" title="从千千静听歌词服务器下载歌词的代码">从千千静听歌词服务器下载歌词的代码</a></li><li><a href="http://www.enjoyphp.com/2009/front/javascript/jquery-sizzle-2/" title="jQuery的新选择器引擎&#8211;Sizzle">jQuery的新选择器引擎&#8211;Sizzle</a></li><li><a href="http://www.enjoyphp.com/2011/front/javascript/jquery/jquery-has-element/" title="jQuery判断网页元素是否存在">jQuery判断网页元素是否存在</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/front/javascript/firebug-lite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>用于搜索结果的关键字高亮显示（不区分大小写）</title>
		<link>http://www.enjoyphp.com/2011/development/php/search-result-highlight/</link>
		<comments>http://www.enjoyphp.com/2011/development/php/search-result-highlight/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 03:25:01 +0000</pubDate>
		<dc:creator>虫少侠</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[关键字]]></category>
		<category><![CDATA[搜索]]></category>
		<category><![CDATA[高亮]]></category>

		<guid isPermaLink="false">http://www.enjoyphp.com/?p=1356</guid>
		<description><![CDATA[在搜索结果的显示中，我们通常要把关键字高亮，对于中文，直接用strtr把关键字替换成加&#60;font color=red&#62;&#60;b&#62;关键字&#60;/b&#62;&#60;/font&#62;就可以了。 但对于英文，存在大小写的问题，比如用户搜iphone，我们需要把结果中的iPhone/IPHONE之类的单词都要高亮；简单的用strtr直接替换就不行了。 下面是自己写的一个函数： &#60;?php //搜索结果，要高亮替换的文字，如文章标题等（为演示效果，选的字符串比较乱） $str = &#34;sdfdiphoneabIPHoNEipHONE&#34;; //搜索关键字 $key_arr = array(&#34;fd&#34;,&#34;iphone&#34;); //返回高亮结果 echo highlight($str,$key_arr); function highlight($str,$key_arr) { $param_temp = array(); preg_match_all(&#039;/&#039;.join(&#039;&#124;&#039;,$key_arr).&#039;/i&#039;,$str,$matches); foreach($matches[0] as $value) { $param_temp[$value] = &#34;&#60;font...]]></description>
			<content:encoded><![CDATA[<p>在搜索结果的显示中，我们通常要把关键字高亮，对于中文，直接用strtr把关键字替换成加&lt;font color=red&gt;&lt;b&gt;关键字&lt;/b&gt;&lt;/font&gt;就可以了。</p>
<p>但对于英文，存在大小写的问题，比如用户搜iphone，我们需要把结果中的iPhone/IPHONE之类的单词都要高亮；简单的用strtr直接替换就不行了。</p>
<p>下面是自己写的一个函数：</p>
<pre class="brush: php; ">

&lt;?php
//搜索结果，要高亮替换的文字，如文章标题等（为演示效果，选的字符串比较乱）
$str = &quot;sdfdiphoneabIPHoNEipHONE&quot;;
//搜索关键字
$key_arr = array(&quot;fd&quot;,&quot;iphone&quot;);
//返回高亮结果
echo highlight($str,$key_arr);

function highlight($str,$key_arr)
{
$param_temp = array();
preg_match_all(&#039;/&#039;.join(&#039;|&#039;,$key_arr).&#039;/i&#039;,$str,$matches);

foreach($matches[0] as $value)
{
$param_temp[$value] = &quot;&lt;font color=red&gt;&lt;b&gt;&quot;.$value .&quot;&lt;/b&gt;&lt;/font&gt;&quot;;
}

$str2 = strtr($str,$param_temp);
return $str2;
}
</pre>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li><a href="http://www.enjoyphp.com/2008/storeage/mysql-lamp/mysql-function-list/" title="整理了下MySQL内置函数表,包括字符串函数、数学函数和日期时间函数 ">整理了下MySQL内置函数表,包括字符串函数、数学函数和日期时间函数 </a></li><li><a href="http://www.enjoyphp.com/2009/front/design/ue-ad-last/" title="增强用户体验之&#8211;广告后加载">增强用户体验之&#8211;广告后加载</a></li><li><a href="http://www.enjoyphp.com/2010/news/software/connectify/" title="Connectify-将Win7笔记本变成无线路由器">Connectify-将Win7笔记本变成无线路由器</a></li><li><a href="http://www.enjoyphp.com/2009/development/php/php-chinese-calendar/" title="[转]PHP农历日历">[转]PHP农历日历</a></li><li><a href="http://www.enjoyphp.com/2009/development/php/close-magic-quote/" title="关闭PHP魔术引号（Magic Quote）">关闭PHP魔术引号（Magic Quote）</a></li><li><a href="http://www.enjoyphp.com/2009/server/linux/ubuntu-9-10-linux-qq-bug/" title="Ubuntu 9.10下linux QQ自动退出问题的解决">Ubuntu 9.10下linux QQ自动退出问题的解决</a></li><li><a href="http://www.enjoyphp.com/2010/front/javascript/js-get-content-of-div/" title="关于js中获取div中的数据">关于js中获取div中的数据</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.enjoyphp.com/2011/development/php/search-result-highlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: enjoyphp.com @ 2012-02-09 10:20:23 -->
