<?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>程默的博客 &#187; web性能</title>
	<atom:link href="http://blog.chacuo.net/category/web-tech/web-optimize/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.chacuo.net</link>
	<description>web原理、web架构、web安全、web性能、服务器性能、服务器架构、服务器安全;你不能预知明天，但你可以利用今天。你不能样样顺利，但你可以事事尽力!</description>
	<lastBuildDate>Mon, 31 Aug 2020 15:33:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>正则表达式性能优化（高效正则表达式书写）</title>
		<link>http://blog.chacuo.net/329.html</link>
		<comments>http://blog.chacuo.net/329.html#comments</comments>
		<pubDate>Thu, 04 Jul 2013 09:25:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web性能]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=329</guid>
		<description><![CDATA[这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：正则表达式匹配解析过程探讨分析 [...]]]></description>
				<content:encoded><![CDATA[<p>这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：<a href="http://blog.chacuo.net/255.html">正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</a>。从上面例子，我们可以推断出，影响NFA类正则表达式（常见语言：GNU Emacs,Java,ergp,less,more,.NET语言,     <br />PCRE library,Perl,PHP,Python,Ruby,sed,vi )其实主要是它的“回溯”，<u>减少“回溯”次数（减少循环查找同一个字符次数），是提高性能的主要方法。 </u>我们来看个例子：</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">源字符串：&lt;script type=&quot;text/javascript&quot;&gt;adsfadfsdasfsdafdsfsadfsa&lt;/script&gt;</font></p>
<p><font style="background-color: #ffffff" face="Arial">匹配要求，匹配&lt;script….&gt;….&lt;/script&gt;标签里面所有内容，包括改标签</font></p>
<p><font style="background-color: #ffffff" face="Arial"><strong>常见写法(1)</strong>，因为&lt;script后面可能出现字符、空白、特殊符号等，还有标签里面也可能出现各种js代码。我们简单方法是：</font></p>
<p>正则表达式：&lt;script.*?&gt;.*?&lt;/script&gt; (测试工具使用了：<a title="regexBuddy介绍" href="http://blog.chacuo.net/238.html" rel="regexBuddy介绍" target="_blank">regexBuddy</a>)</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb.png" width="821" height="699" /></a> </pre>
<pre><font color="#0000ff"><u>总共花费115步，回溯了：48次。 </u>因为我们使用”.”字符，匹配默认情况下除了\n之外所有字符。</font></pre>
<p><strong>方法（2）</strong>，我们分析特点发现，&lt;script…&gt;后面，应该是除了”&gt;”之外都可以字符，然后一对&lt;script&gt;标签里面js内容。可以定义为除了”&lt;”之外。（<font color="#0000ff">这里面我只是举例说明优化方法，实际网页中script标签里面，常见都会出现有”&lt;”字符了</font>）</p>
<p>正则表达式：&lt;script[^?&gt;]+&gt;[^&lt;]+&lt;/script&gt;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb1.png" width="808" height="581" /></a> </pre>
<pre><font color="#0000ff"><u>19步，0次回溯！ </u>，步骤只有原先的15%左右，性能几倍的提升了！</font></pre>
</blockquote>
<p>从上面我们看到，不同正则表达式，对通用字符配平，性能相差会很大。减少“回溯”是最好的方法，减少回溯其中最主要的方法是：”用最小范围的元字符，尽量避免用过大的元字符！”。一般规律如下：</p>
<p>1、使用正确的边界匹配器（^、$、\b、\B等），限定搜索字符串位置</p>
<p>2、使用具体的元字符、字符类（\d、\w、\s等） ，少用”.”字符</p>
<p>3、使用正确的量词（+、*、?、{n,m}），如果能够限定长度，匹配最佳</p>
<p>4、使用非捕获组、原子组，减少没有必要的字匹配捕获用(?:) </p>
<p>如：我想匹配一些英文字母，它后面接的是数字。如：abc1234,我可以写 “\w+\d+”，也可以写”[a-zA-Z]+\d+” ，其中第一个\w+会先匹配所有abc1234，然后回溯，匹配满足\d+格式。一共4步，而后面这个只需要2步，步骤减少一半了！好了，今天就先到这里，欢迎大家讨论、交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/329.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式性能测试工具推荐、优化工具推荐(regexbuddy推荐)</title>
		<link>http://blog.chacuo.net/238.html</link>
		<comments>http://blog.chacuo.net/238.html#comments</comments>
		<pubDate>Thu, 13 Jun 2013 14:59:17 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web性能]]></category>
		<category><![CDATA[学习工具]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=238</guid>
		<description><![CDATA[前不久，我们推荐了个正则表达式入门学习工具。正则表达式工具推荐（学习工具、测试工具） ，今天我们看下，正则表达 [...]]]></description>
				<content:encoded><![CDATA[<p>前不久，我们推荐了个正则表达式入门学习工具。<a href="http://blog.chacuo.net/198.html">正则表达式工具推荐（学习工具、测试工具）</a> ，今天我们看下，正则表达式的性能测试工具。这里我们先说下，为什么需要这样的工具，这个工具有什么作用呢？</p>
<ul>
<li>
<h3><span style="font-weight: bold">为什么需要性能测试工具</span></h3>
</li>
</ul>
<h3></h3>
<p>我们都知道，正则表达式使用进行搜索查找，没有字符串直接查找快！而且性能是几何倍数下降。那么，为什么正则表达式速度会比字符串搜索慢呢。我们来看看，正则表达式查找字符串的匹配过程吧。正则表达式由一些元字符，普通字符，量词字符组合成。默认情况下，这些量词元字符（*,+,?)都是贪婪模式，会最大长度匹配字符串。我们知道，正则表达式往往搜索路径会有多个，我们看看，下面匹配过程。就知道，主要影响正则表达式执行性能有哪些了。</p>
<p>正则表达式匹配过程如：\d+abc，元字符是：”12345bdc”，查找会从左向右进行，\d+，贪婪模式，一下子匹配到12345，然后bdc与\d+不能匹配，”abc”中,”a”字符，开始匹配”bdc”，发现匹配失败。正则表达式开始回溯匹配（贪婪模式量词开始逐一减少匹配字符长度)，\d+只匹配”1234”，”5bdc”与”abc”匹配，任然失败。\d+继续减少匹配长度为：”123”，”45bdc”与”abc”匹配，任然失败。继续回退，直到\d+匹配”1”，用”2345bdc”与”bdc”匹配，任然失败。整个匹配就失败了。</p>
<p>从上面过程中，我们发现，每次回溯，要重新操作匹配因此匹配搜索次数，直接影响正则表达式的性能。做正则表达式性能优化，一般就是优化查询的次数。这个是我们分析过程，如果有个工具能够实实在在看到每一步匹配过程，对于我们优化正则表达式将带来太多方便了。这里介绍工具是：<strong>regexbuddy软件</strong>，它就是一个实实在在看到匹配过程工具。</p>
<ul>
<li>
<h3><span style="font-weight: bold">regexbuddy工具怎么样使用，使用介绍</span></h3>
</li>
</ul>
<blockquote><pre>1、安装完<strong>regexbuddy</strong></pre>
<p></p>
<pre><strong></strong></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image23.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy介绍" border="0" alt="regexbuddy介绍" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb23.png" width="863" height="523"></a></pre>
<p>该工具支持多种程序语言正则表达式，如：perl,pcre,javascript,python,ruby,c#,java等等，还能自动生成程序代码，并且内部带有大量的常用正则表达式。</p>
<pre>2、一般切换到side by side：</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image24.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy使用" border="0" alt="regexbuddy使用" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb24.png" width="865" height="549"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre>3、匹配过程</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image25.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb25.png" width="867" height="524"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image26.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb26.png" width="866" height="524"></a></pre>
<p>从上面一个匹配看，这个简单一个匹配，搜索了8次，进行了不断查找。如果我们已经准确知道自己要匹配什么样字符，我们可以对源正则表达式修改下，减少匹配次数。就达到优化正则表达式目的，提高匹配效率！</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image27.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy优化正则表达式" border="0" alt="regexbuddy优化正则表达式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb27.png" width="869" height="526"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
</blockquote>
<p><strong>后记：</strong>这个工具是不是很强大呢，你知道在baidu搜索，该关键字：<strong>regexbuddy，</strong>就可以方便下载到。通过该工具，对我们写出好的高性能正则表达式确实能带来很大帮助。有时候可能一个小小修改，自己程序正则表达式匹配速度可能几个数量级的提升。好了，欢迎大家交流，你有好的工具、方法，欢迎留言，可以给更多朋友分享！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/238.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php session阻塞页面分析及优化 （session_write_close session_commit使用）</title>
		<link>http://blog.chacuo.net/168.html</link>
		<comments>http://blog.chacuo.net/168.html#comments</comments>
		<pubDate>Thu, 06 Jun 2013 11:17:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web性能]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=168</guid>
		<description><![CDATA[这个问题很多做php开发朋友应该都有遇到过，一个启用了session_start 页面，由于执行时间过长。导致 [...]]]></description>
				<content:encoded><![CDATA[<p>这个问题很多做php开发朋友应该都有遇到过，一个启用了session_start 页面，由于执行时间过长。导致通一个用户访问，另外一个很简单的启用session_start页面一直阻塞着。 直到第一个页面执行完了。第二个页面就可以读取。这个就是，我们常说的，session阻塞机制。</p>
<ul>
<li>
<h3><strong>我用file 存放用户session</strong></h3>
</li>
</ul>
<p>session默认以文件保存，当一个用户访问session_start页面后，这个时候，就会默认创建一个包含session_id文件名，并且这个时候，会对文件进行锁定。如果这个用户点击链接，又访问一个该站session_start网页。这是，由于session_id一样，这个页面也有读取锁定该用户存放session文件。 由于，第一个页面没有执行完，它一直锁定了该文件。 第2个页面就不能获取锁，一直处于等待状态。</p>
<p>这样一个看似小的问题，实际上，如果网站上面有大量用户访问，会导致session读取文件一直阻塞等待着。用户浏览器一直跟服务器保持连接，会消耗很多服务器资源。web服务器活跃连接数也会增大，可能很快就会耗费完连接资源，出现拒绝服务器。</p>
<ul>
<li>
<h3><strong>我用memcache 存放用户session</strong></h3>
</li>
</ul>
<p>用memcache保存用户session，相比读取文件有很大速度提升。而且可以做到多服务器共享session。确实很方便，这个时候，我们发现不会出现用文件保存session锁定清理。memcached读取时候，是共享的，不会出现等待。但是，我们会发现，memcached连接数，还是会保持着。并且，连接数会增加，如果这个时候，你设置的memcached连接数过小，你会发现，很快memcached就挂死了。 这也是，做memcache接管session时候，经常遇到问题。 有时候，web服务器很多，session(memcache)很少。发现memcache莫名其妙死掉，可能跟这个有关系。太多反映很慢的页面(启动session)，会导致占用了大量memcached连接数。</p>
<ul>
<li>
<h3><strong>改变session使用习惯、优化调用方法</strong></h3>
</li>
</ul>
<p>其实，通过file或者session，如果处理耗时页面，都会带来服务器资源很大消耗。其实我们一般写入session或者读取时候，如果自己能够控制。用完了，就关闭掉文件锁，或者mem连接。就会自动释放资源，其实，php里面的：session_write_close，session_commit 函数就能做到改功能。我们看下下面代码执行过程：</p>
<blockquote><pre style="text-indent: 0px" lang="php">&lt;?php
ini_set('session.save_path','/tmp/');

function open($save_path, $session_name)
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
	return(true);
}
function close()
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
	return(true);
}
function read($id)
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
}
function write($id, $sess_data)
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
	return(true);
}
function destroy($id)
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
	return(true);
}
function gc($maxlifetime)
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
	return true;
}
session_set_save_handler(&quot;open&quot;, &quot;close&quot;, &quot;read&quot;, &quot;write&quot;, &quot;destroy&quot;, &quot;gc&quot;);
register_shutdown_function('test');

function test()
{
	echo __FUNCTION__,&quot;&lt;br /&gt;&quot;;
}
session_start();
echo 'aaaaa',&quot;&lt;br /&gt;&quot;;</pre>
</blockquote>
<p>&#160;</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image3.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb3.png" width="760" height="486" /></a> </p>
<p>启动”session_start” 会自动执行,open,read函数，然后页面执行完，会执行shutdown函数，最后会把session写入进去，然后执行close关闭文件。从session_start 到页面结束，会一直锁定文件或者保持连接的。</p>
<p>我们如果 执行完session_start后，执行”session_commit();” 看看结果</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb4.png" width="495" height="202" /></a><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image5.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb5.png" width="395" height="271" /></a>&#160; </p>
<p><strong>执行过程：</strong>执行commit后，直接会调用，wirte,close操作。直接关闭文件或者关闭连接(memcache)了。 </p>
<p><strong></strong></p>
<ul>
<li>
<h3><strong>我们的问题</strong></h3>
</li>
</ul>
<h3>1.我们页面有多次写入，怎么样操作？</h3>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb6.png" width="472" height="228" /></a> <a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image7.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb7.png" width="414" height="170" /></a> </p>
<p>&#160;</p>
</p>
</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image8.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb8.png" width="474" height="310" /></a> </p>
<p>第一次写入后，然后提交，再次打开写入，然后再次提交。我们发现，2次数据都保存到用户session中了。</p>
<p>&#160;</p>
<ul>
<li>
<h3><strong>我们来总结下吧</strong></h3>
</li>
</ul>
<p>1.只读取session页面，建议打开后，就直接commit，这是$_SESSION变量已经生成了。</p>
<p>2.有对session进行写入页面，建议修改完$_SESSION后，直接调用commit</p>
<p>3.多次打开并且写入，这个不建议使用，比较打开文件，写入都是耗费时间的。如果能一次搞定的，就不要做多次了。 除非，中间执行很耗时的业务。 </p>
<p>后记：其实，使用完session，随手commit也不是坏事，养成习惯后。可以节省性能，减少服务器开销。是个不错选择！欢迎大家交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/168.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 站点相对包含，路径的问题解决方法（include,require)</title>
		<link>http://blog.chacuo.net/134.html</link>
		<comments>http://blog.chacuo.net/134.html#comments</comments>
		<pubDate>Sat, 01 Jun 2013 09:53:18 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web性能]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[相对路径]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=134</guid>
		<description><![CDATA[以前看了，很多框架，基本上很少使用相对路径包含。而一般很多做php web站点，喜欢用相对路径。 认为这样，无 [...]]]></description>
				<content:encoded><![CDATA[<p>以前看了，很多框架，基本上很少使用相对路径包含。而一般很多做php web站点，喜欢用相对路径。 认为这样，无论目录放到那里。 只要跟另外目录关系一致。那么就不会出现问题。如果一个站点，一般都认为，如果用根目录，经常会改变网站地址，觉得很不方便。其实，我们从各大常见框架里面会发现，基本上都是采用是绝对路径方法。</p>
<ul>
<li>
<h3><font style="font-weight: bold">相对路径带来问题</font></h3>
</li>
</ul>
<p>我们有如下结构的目录。</p>
<blockquote><pre style="text-indent: 0px">&lt;web&gt;(网站根目录)
├&lt;a&gt;文件夹
│ │
│ └a.php
├&lt;b&gt;文件夹
│ │
│ └b.php
└test.php</pre>
</blockquote>
<p></p>
<p>&#160;</p>
<p>如果b.php 包含a.php (include(“../a/a.php”)) ，然后test.php 包含b.php (include(“b/b.php”)) ，我们发现很奇怪问题。</p>
<p>首先访问：b.php 可以正常访问， 然后访问test.php</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb.png" width="769" height="103" /></a></p>
<p>发现，找不到 a.php了。 这里注意一个问题是：<strong><u>php 默认相对路径都是以，被访问页面所在路径为准的。无论一个入口页面，里面包含多少文件，相对路径，都是以这个页面为准</u></strong>。</p>
<p>如果访问test.php 根路径是：test.php，如果访问b.php 相对路径都以b.php 所在路径为准。刚刚页面test.php 包含了b.php,b.php包含了a.php. 所有包含都以test.php 为准的。</p>
<p>估计刚刚开始php学习朋友，经常遇到这个问题，而且发现经常出现一大堆警告影响大家学习的兴趣。</p>
<ul>
<li>
<h3><font style="font-weight: bold">使用绝对路径方法</font></h3>
</li>
</ul>
<p>各大开源框架基本上采用绝对路径方法，这样可以避免相对路径因为包含访问文件变了。基准路径变化，让包含出现错误了。 所以，我们看看常见方法。</p>
<p>首先将网站基准订到一个固定文件。一般可以用下面方法实现。如：根目录下面有个config.php文件。</p>
<blockquote>
<p><font style="background-color: #ffffff" face="Arial">&lt;?php </font></p>
<p><font style="background-color: #ffffff" face="Arial">define(‘Root_Path’,<b>dirname(__FILE__));</b></font></p>
</blockquote>
<p>__FILE__ 至的是当前脚本路径，在那个脚步php里面调用该变量，它的值就是该脚步的绝对路径。</p>
<p>然后，任何其它页面，在做包含时候，只需要包含了该config.php后。</p>
<blockquote>
<p><font style="background-color: #ffffff" face="Arial">&lt;?php</font></p>
<p><font style="background-color: #ffffff" face="Arial">包含config.php…..</font></p>
<p><font style="background-color: #ffffff" face="Arial">include(Root_Path.”/文件路径”);即可</font></p>
</blockquote>
<p>&#160;</p>
<h3></h3>
<ul>
<li>
<h3><strong>使用绝对路径好处</strong></h3>
</li>
</ul>
<p>使用解决路径好处除了可以在大型项目中，包含时候更准确定位到文件，不易产生错误外。还有另外一个好处，包含文件，性能会得到很大提升。</p>
<p>如果给一个相对位置包含，php查找该文件，一般会在set_include_path 函数，设置的所有路径里面去搜索。 我们知道，要一个一个去尝试，列举目录，然后查找文件。这直接会消耗大的IO。 也会消耗很多性能。 如果我们用绝对包含，直接就可以准确判断出，文件是否存在。不会去set_include_path设置目录去查找了。 </p>
<p>以上问题，对于刚刚接触到php大型项目开发，可能会很容易遇到。欢迎讨论！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/134.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《我的博客》之从技术眼中分析wordpress结构优缺点</title>
		<link>http://blog.chacuo.net/67.html</link>
		<comments>http://blog.chacuo.net/67.html#comments</comments>
		<pubDate>Sat, 25 May 2013 15:33:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web性能]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=67</guid>
		<description><![CDATA[我还是觉得自己开辟搭建一个独立blog平台，我常用linux服务器，因此选择php环境。 这样，我可以选择的开 [...]]]></description>
				<content:encoded><![CDATA[<p>我还是觉得自己开辟搭建一个独立blog平台，我常用linux服务器，因此选择php环境。 这样，我可以选择的开源博客系统会有很多。这里不对博客系统进行纵向对比。我说下，对wordpress认识过程，一些自己的体会。纯属代表个人意见，欢迎讨论！</p>
<p>&#160;</p>
<p>刚开始，下载一套wordpress 3.5，然后一路安装下来，比较简单，跟常见其它一些开源平台查不到。 只要配置好数据库连接，然后一路下一步，分把钟就可以做好。 也是由于，对wordpress 早已经有所耳闻，而且感觉它名气很大，这类系统中佼佼者。</p>
<ul>
<li>
<h3><strong>首先看看它数据库结构吧</strong></h3>
</li>
</ul>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image9.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb9.png" width="423" height="350" /></a></p>
<p>&#160;</p>
<p>11张表，实现了强大的博客功能，首先表示不简单。现在很多cms 基本上都是40-50个表。其中很有几张表，设计为窄表，基本上类似，类型，键值名，键值。类似近年的NoSql类型数据库。都是键值对。读取灵活，扩展方便。 可能就是，开发时候复杂些。这类基本设计是：posts,postmeta表，所有文章都具备的通用字段，就放到posts表，而针对文章进行属性设置，如：访问数，tag，权限等。都放到postmeta表。如：</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image10.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb10.png" width="434" height="144" /></a></p>
<p>窄表，可以任意对一篇文章新增键值，扩展新的属性。 这也是wordpress 插件几乎可以做到无所能一个原因。 这类表可以非常灵活。新增一个属性，只需要在这个表里面，对posts ID 增加这类属性的一条记录。而且这类窄表，字段少，读取速度也很快。</p>
<p><u><em><font color="#ff0000">感觉到表设计不足之处(个人认为，欢迎交流）</font></em></u></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image11.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb11.png" width="606" height="382" /></a></p>
<p>Posts表里面字段，<u><font color="#ff0000">一张表里面，居然有6个text 字段</font></u>。如果读取时候，不小心select *,该会有多少磁盘IO,一条记录，该会占多少的数据块。记得刚刚，分析wordpress时候，当时一下子就看到这样情况。我毅然选择放弃该系统。也因此让我忽略了，他窄表设计优点。 个人认为，一些字段可以设置为varchar,另外text 可以移到单独posts_data表。里面只存放text字段,PostID 信息。欢迎高人指点。</p>
<p>&#160;</p>
<ul>
<li>
<h3><font style="font-weight: bold">再看看它的代码吧</font></h3>
</li>
</ul>
<h3><strong>&#160;</strong></h3>
<p>现在wordpress插件有成百上千个，它基本上可以做各种系统。除了blog外，它还被改成了新闻网站，企业网站，电影网站，甚至是商城系统。这些足以说明，他前端程序一定有过人的设计架构，有它足够灵活性。</p>
<ol>
<li><strong>看下他的目录结构吧</strong></li>
</ol>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image12.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb12.png" width="535" height="617" /></a></p>
<p>&#160;</p>
<p>从这些目录，真的还没有发现它比较独特优越性。现在网上常见的MVC 结构，有独立模版目录。 这个wordpress,实际只能算，MC，而没有V，它实际上前端是通过php 直接调用include 目录里面函数而已。如：</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image13.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb13.png" width="715" height="90" /></a></p>
<p>这个也是它的一个独特特点了，国内很多模版，都会开辟自己的标签，如smarty的是：{$smarty.config.aa} 等。 而wordpress里面没有自己标签，要读取，通过函数去读。它省去了标签省去了大家学习标签成本，但大家也需要掌握N多的函数。 可以把它的函数，理解为其其它系统中定义标签。</p>
<p>无论是函数，还是标签，只要你在前端页面都使用这些方法，去读取你要的数据，实际上都对后端数据库做了隔离。从而让使用者不关系数据库数据了。 数据库结构修改，只要调用函数做相应跳转。前端页面还可以照样那样用。而不需要任何修改。从而保证它的稳定性。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image14.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb14.png" width="635" height="312" /></a></p>
<p>它函数封装，不光做到从DB读取数据，通过函数，读模版，读公共包含文件，等等都做到了，函数封装。几乎做到了，所有读取数据封装（DB,file,request中），这样封装，在目前国内系统中很少见，因为为每个功能去写一堆函数，切实很多工作量。国内框架，基本上喜欢封个方法，做到很通用，然后自己去调去吧。 这个方法，可能可以读取用户表，也可以读评论，也可以读文章。 其实，看起来很通用，实际用起来就会很复杂，也会增加上手难度。我们看看wordpress 设计方法。</p>
<p>&#160;</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image15.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb15.png" width="577" height="520" /></a></p>
<p>这只是其中的很少一部分函数，真正差不多1000把个函数呢。 因为，<strong><u><font color="#ff0000">wordpress 函数几乎封装了所有数据调用，因此前端开发只用调用函数，就可以完成。简单容易，这也是灵活性，及得到广泛使用一个原因。</font></u></strong></p>
<p><strong><font color="#000000">2.&#160; 看看它代码实现优点</font></strong></p>
<p><strong></strong>如果说，wordpress 光只有，强大的含数据库，做到前端页面与数据直接分离。现在很多标签调用也能做到分离。 真正wordpress灵活性，以及能够扩展出各类插件，完成独特开发功能，与它独立系统分不开。 </p>
<p>它有一个 消息机制，还有一个队列过滤模块，任务队列处理模块。这2个模块，都建立在它的一个消息机制上，普通开发方式如下：</p>
<p>消息机制，可以做到，前端跟实现地方解耦。这里打个比方，如一个用户完成注册，我要给用户发一个邮件，然后给管理员发一个站内信。我们以前做法是：</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image16.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb16.png" width="482" height="480" /></a></p>
<p>如果发完站内信后，还有发一个手机短信，我们必须修改注册逻辑，在接下来再增加一个发送手机短信功能。 这时，你发现任何前端修改，都需要在原先逻辑里面修改一通。 如果我们采用消息机制，程序将变为:</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image17.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb17.png" width="593" height="465" /></a></p>
<p>&#160;</p>
<p>这个图，是改用消息模式结果，用户注册功能模块，跟接收到消息处理各个任务直接，代码没有直接关联。如果需要增加一个接收注册消息，给其它人通知一下，只需要新增一个模块，订制注册消息，然后处理一个新流程即可。</p>
<p>目前各类开源项目里面，消息机制已经变得非常常见了。 但在wordpress这个blog框架，它的消息主题非常完善。几乎任何动作都有消息主题发送消息。 这样让开发者，只要订制相关主题，就可以，增加自己额外处理功能。 例如： 用户发一个帖子后。检测下用户是不是有广告信息，只要订制：发帖消息，然后，增加新功能，检测内容。发现不满足，直接屏蔽帖子。</p>
<p>有人估计要说，这类功能，现在很多框架有类似东西，例如，页面开始有个start事件，结束有个end事件。 确实，消息概念在很多框架里面确实有用。 但是，没有这么完毕的消息主题抛出。 <strong><u>几乎做到整个系统任何操作，都能有消息，这样没有什么功能不能进行扩展了</u></strong>。</p>
<p>有兴趣可以去研究下，wordpress add_filter,apply_filters ，还有add_action，apply_action ，只是收到消息后，一个按顺序进行一系列元内容过滤，一个是接收元内容，进行一系列任务。</p>
<p><strong>wordpress 2大优点，一个是函数封装数据操作，一个是它完善消息功能。</strong>那它有何种确定呢？</p>
<ul>
<li>
<h3>wordpress源码不足</h3>
</li>
</ul>
<p>&#160;</p>
<p>任何一个系统，有优点，一定有不尽人意的地方。</p>
<p>首先，因为它要做到自己很多函数，可以直接读取一些循环数据。或者直接读取数据库配置项。它启动时候，<strong>采用了大量的全局变量</strong>。一个大的blog,可能启动后全局变量有几百个。 有的是数据记录，有的是字符串，有的是对象。你可能会发现，这些数据可能有1，2M；无论有没有使用，这些都会先创建。可想而知，他将带来大量内存浪费。另外一个就是，可能会影响调用速度。 很多网友使用wordpress就明显有这个感觉了。 </p>
<p>另外一个问题，其实正式来自它的消息处理模块。 它跟我们网上看到的不一样，<strong>它的消息模块是同步模块</strong>。以上面打的比方来说，尽管做到发送消息，跟处理模块代码分离。 但实际上执行过程没有多大变化，也是要先注册用户完，然后完成一些列处理功能。最好这个php页面才算处理完了。 需要时间还是那么些。 如果真的，能把这类跟功能无关接收消息，处理模块异步到后端。 那么估计再没有人抱怨wordpress打开一个要4，5秒了。 </p>
<p>&#160;</p>
<ul>
<li>
<h3>后记：</h3>
</li>
</ul>
<h3>&#160;</h3>
<p>就说这么些了，估计很多同人告诉我说。居然它性能不好，又慢。 你干什么还要用它呢？ 这个就看你主要关注的是什么了，如果你需要快的开发模版，而且非常容易开发各种扩展。那么它是你最好选择了。 况且，性能问题，一但静态化后，几乎解决了。 </p>
<p>估计还有人说，你既然提到它性能这么些不足，那么你有什么好的调优方法没有。 呵呵，这里欢迎大家交流意见，我也有一些想法，就先不详说，还不成熟。欢迎交流！！！祝朋友们，周末愉快！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/67.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
