<?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; PHP</title>
	<atom:link href="http://x1989.com/category/webdev/php/feed" rel="self" type="application/rss+xml" />
	<link>http://x1989.com</link>
	<description>小谢的Blog — 认真生活 快乐工作 专注Web前后端开发&#124;移动平台</description>
	<lastBuildDate>Mon, 30 Apr 2012 11:29:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>PHP模拟BigPipe</title>
		<link>http://x1989.com/a/469.html</link>
		<comments>http://x1989.com/a/469.html#comments</comments>
		<pubDate>Sat, 08 Oct 2011 08:20:58 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web开发]]></category>
		<category><![CDATA[BigPipe]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[前端]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=469</guid>
		<description><![CDATA[前不久新浪微博改版，前端引入了BigPipe（最早是Facebook提出的），页面载入速度嗖嗖嗖地上去了。。那末为神马BigPipe能这么快呢？

与AJAX相似，BigPipe使页面可以按区块渲染。但与AJAX不同的是，BigPipe不需要在页面载入后再通过XMLHttpRequest向服务器发起异步请求，而是（通过使用缓冲区）在页面载入过程中先输出页面布局，并在HTML中预留各个页面区块（Facebook称为Pagelet），在页面底部才输出Javascript代码，DOM操作，从而对区块进行内容填充，也就是把内容赋给innerHTML。

<span class="readmore"><a href="http://x1989.com/a/469.html" title="PHP模拟BigPipe">阅读全文——共1439字</a></span>]]></description>
			<content:encoded><![CDATA[<p>前不久新浪微博改版，前端引入了BigPipe（最早是Facebook提出的），页面载入速度嗖嗖嗖地上去了。。那末为神马BigPipe能这么快呢？<br />
与AJAX相似，BigPipe使页面可以按区块渲染。但与AJAX不同的是，BigPipe不需要在页面载入后再通过XMLHttpRequest向服务器发起异步请求，而是（通过使用缓冲区）在页面载入过程中先输出页面布局，并在HTML中预留各个页面区块（Facebook称为Pagelet），在页面底部才输出Javascript代码，DOM操作，从而对区块进行内容填充，也就是把内容赋给innerHTML。<br />
这么做的好处是，在页面加载的过程中，把一些响应时间相对较长的输出放到了页面底部，而页面整体轮廓先显示出来，减少用户的等待时间；此外，与Ajax相比，BigPipe不需要进行多次请求就能完全显示内容，降低了服务器的负担。<br />
下面用PHP模拟一下BigPipe，代码里用sleep(1)模拟一些运算的时间损耗（要先关闭Apache的GZip）：</p>
<pre>
&lt;!doctype&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot; /&gt;
	&lt;title&gt;PHP模拟BigPipe&lt;/title&gt;
&lt;/head&gt;
&lt;style&gt;
.section{height:200px;}
#con1{background:#ef8090;}
#con2{background:#fef000;}
#con3{background:#19c000;}
&lt;/style&gt;
&lt;body&gt;
	&lt;div class=&quot;wrapper&quot;&gt;
		&lt;div class=&quot;section&quot; id=&quot;con1&quot;&gt;页头内容，正在加载……&lt;/div&gt;
		&lt;div class=&quot;section&quot; id=&quot;con2&quot;&gt;正文内容，正在加载……&lt;/div&gt;
		&lt;div class=&quot;section&quot; id=&quot;con3&quot;&gt;页尾内容，正在加载……&lt;/div&gt;
	&lt;/div&gt;
	&lt;?php
	/*
	 * 输出缓存区
	 */
	function flush_now(){
		ob_flush();
		flush();
	}
	flush_now();
	?&gt;

	&lt;?php sleep(1);?&gt;
	&lt;script&gt;
		document.getElementById(&quot;con1&quot;).innerHTML = &quot;&lt;?php echo str_repeat(\'内容1\', 200) ?&gt;&quot;;
	&lt;/script&gt;
	&lt;?php flush_now()?&gt;

	&lt;?php sleep(1);?&gt;
	&lt;script&gt;
		document.getElementById(&quot;con2&quot;).innerHTML = &quot;&lt;?php echo str_repeat(\'内容2\', 200) ?&gt;&quot;;
	&lt;/script&gt;
	&lt;?php flush_now()?&gt;

	&lt;?php sleep(1);?&gt;
	&lt;script&gt;
		document.getElementById(&quot;con3&quot;).innerHTML = &quot;&lt;?php echo str_repeat(\'内容3\', 200) ?&gt;&quot;;
	&lt;/script&gt;
	&lt;?php flush_now()?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>这样，打开页面后，页头、正文和页尾的内容一开始显示的是“正在加载……”，但随后内容会逐一显示出来，肿么样，很神奇吧。<br />
<strong>但话说回来，这只是模拟的BigPipe，因为每个区块的内容输出之间是阻塞的，需要等待前一个区块处理完了，才能接着处理后一个。而要真正实现BigPipe就得使用多线程，可以通过CURL的异步模式或者pctnl。</strong> </p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/469.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于一些编程语言的运算符“优先级”</title>
		<link>http://x1989.com/a/436.html</link>
		<comments>http://x1989.com/a/436.html#comments</comments>
		<pubDate>Tue, 12 Jul 2011 11:35:06 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web开发]]></category>
		<category><![CDATA[其他文章]]></category>
		<category><![CDATA[前端开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[运算符优先级]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=436</guid>
		<description><![CDATA[Tips:这个问题是铁军师兄发现并提出的，我写篇博客梳理一下。

当我们在学习一门编程语言的时候，我们经常会看到类似这样的一句话：运算符优先级是一套规则。该规则在计算表达式时控制运算符执行的顺序。具有较高优先级的运算符先于较低优先级的运算符执行。

那么事实是不是果真如此呢，下面让我们用Javascript等几门语言为例来验证一下。

<span class="readmore"><a href="http://x1989.com/a/436.html" title="关于一些编程语言的运算符“优先级”">阅读全文——共1627字</a></span>]]></description>
			<content:encoded><![CDATA[<p>Tips:这个问题是<a href="http://www.yigle.net/" title="铁军" target="_blank">铁军</a>师兄发现并提出的，我写篇博客梳理一下。<br />
当我们在学习一门编程语言的时候，我们经常会看到类似这样的一句话：运算符优先级是一套规则。该规则在计算表达式时控制运算符执行的顺序。具有较高优先级的运算符先于较低优先级的运算符执行。<br />
那么事实是不是果真如此呢，下面让我们用Javascript等几门语言为例来验证一下。<br />
首先，在官方的ECMA-262/Core JavaScript手册以及权威的MDN Docs中，分别是这样介绍Javascript运算符优先级的：</p>
<blockquote><p>
All operators have a pre-defined execution priority or precedence. Within a given complex expression, operations will be performed in order of priority.
</p></blockquote>
<blockquote><p>
Operator precedence determines the order in which operators are evaluated. Operators with higher precedence are evaluated first.
</p></blockquote>
<p>两段介绍的意思大致是一样的，都是说运算符优先级决定了运算符执行的先后顺序。运算符优先级高的运算符会被先执行（计算）。我们以往的编程经验似乎也在告诉我们这是真理，然而请先看下面一段代码：</p>
<pre>
var a=1;
function fn(){
    console.log(a);
}
var b = a++ + fn();
</pre>
<p>按照Javascript官方手册上对运算符优先级的定义以及的运算符优先级表（如图所示或参考http://rx4ajax-jscore.com/ecmacore/operator/predence.html），我们可以推算运行结果：在最后一行代码中，由于函数调用的括号运算符“()”优先级比自增运算符“++”和算术运算符“+”都要高，所以会先被执行。所以在控制台中被log的a的值应该是1。而事实上，结果是2。这说明了什么？——虽然“()”运算符的优先级比“++”要来得高，但a++却先于fn()被执行。<br />
<a href="http://x1989.com/wp-content/uploads/2011/07/javascriptPrecedence.png" target="_blank"><img src="http://x1989.com/wp-content/uploads/2011/07/javascriptPrecedence-300x98.png" alt="javascript优先级" title="javascriptPrecedence" width="300" height="98" class="alignnone size-medium wp-image-441" /></a><br />
图节选自Javascript运算符优先级表（http://rx4ajax-jscore.com/ecmacore/operator/predence.html）<br />
那么在Javascript中是这种状况，在其他语言中又会是什么情况呢？随后，我们分别测试了PHP、C/C++、Java以及C#版本的代码（Python和Ruby中没有自增运算符）。猜猜结果各是什么？<br />
PHP版：</p>
<pre>
$a=1;
function fn($a1){
    echo $a1;
}
$b = $a++ + fn($a);
</pre>
<p>C++版：</p>
<pre>
#include "stdafx.h"
#include &lt;iostream&gt;
using namespace std;
int fn(int a1)
{
	cout&lt;&lt;a1;
	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int a = 1;
	int b = a++ + fn(a);
	int i;
	cin&gt;&gt;i;
	return 0;
}
</pre>
<p>揭晓答案：<br />
只有C/C++输出了1，其他语言都输出了2。<br />
这样看来似乎最传统的编译型语言C/C++能得出与其运算符优先级定义相符合的结果。而事实上关于运算符优先级，PHP手册是这样定义的：</p>
<blockquote><p>
The precedence of an operator specifies how “tightly” it binds two expressions together.
</p></blockquote>
<p>意思是运算符优先级决定了两个表达式之间“紧密程度”——也就是说代码的组合方式。这么一来PHP为什么输出2就能解释了。而C#和Java的代码，如果这么解释也能解释得清楚。不过在Java的运算符中，并没有函数调用的“()”运算符。C#当中却是有的。更有趣的是，在C/C++中，前自增/减运算符“++/&#8211;”的优先级居然排在了函数调用运算符“()”的前面，仅次于“::”运算符。<br />
结论：混乱啊。。</p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/436.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Fatal Error重定向跳转</title>
		<link>http://x1989.com/a/362.html</link>
		<comments>http://x1989.com/a/362.html#comments</comments>
		<pubDate>Sat, 26 Mar 2011 06:57:51 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web开发]]></category>
		<category><![CDATA[fatal error]]></category>
		<category><![CDATA[handler]]></category>
		<category><![CDATA[重定向]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=362</guid>
		<description><![CDATA[在前端生产环境下，我们需要error_reporting(0)来禁止对用户输出任何错误信息；与此同时，如果能在不可预见地发生Fatal errors和Parse errors的时候跳转到其他页面，而不出现空白，那就能在一定程度上保证用户体验。

我们发现，PHP的error_handlers不能用来处理Fatal errors和Parse errors，于是就有了下面这个方法。

在php.ini文件中可以找到：

<span class="readmore"><a href="http://x1989.com/a/362.html" title="PHP Fatal Error重定向跳转">阅读全文——共525字</a></span>]]></description>
			<content:encoded><![CDATA[<p>在前端生产环境下，我们需要error_reporting(0)来禁止对用户输出任何错误信息；与此同时，如果能在不可预见地发生Fatal errors和Parse errors的时候跳转到其他页面，而不出现空白，那就能在一定程度上保证用户体验。<br />
我们发现，PHP的error_handlers不能用来处理Fatal errors和Parse errors，于是就有了下面这个方法。<br />
在php.ini文件中可以找到：</p>
<pre>
; String to output before an error message.
;error_prepend_string = "html code"
; String to output after an error message.
;error_append_string = "html code"
</pre>
<p>那么我们可以把error_prepend_string或者error_append_string前面的分号去掉，把它的值设置为”&lt;script&gt;window.location.href=&#8217;another_page.php&#8217;;&lt;/script&gt;”，在出错的时候使用javascript的redirect到另一个页面。<br />
但是这种做法似乎不太优雅…正在寻找通过服务器302临时重定向的方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/362.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP SPL File Browser</title>
		<link>http://x1989.com/a/359.html</link>
		<comments>http://x1989.com/a/359.html#comments</comments>
		<pubDate>Thu, 24 Mar 2011 12:44:11 +0000</pubDate>
		<dc:creator>xhowhy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web开发]]></category>
		<category><![CDATA[创新工厂]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Directory]]></category>
		<category><![CDATA[File]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://x1989.com/?p=359</guid>
		<description><![CDATA[俗话说不想偷懒的程序员不是好程序员。

所以为了向“好程序员”靠拢，我们要自觉地在工作中偷懒…当然不是要你偷工减料，而是要用程序员应该有的方式来“偷懒”，提高工作效率。

我所在的公司使用的PHP demo环境，出于安全方面的考虑，设置了禁止访问网站目录（列出目录文件列表），造成了我没有办法通过浏览器直接访问目录，查看到目录下的文件列表。上传了个php探针到demo服务器上，发现PHP的系列文件操作函数都被禁用了。这样我也没有办法写一段php脚本通过opendir、chdir、scandir等函数来遍历目录下的文件，输出文件列表到浏览器。

<span class="readmore"><a href="http://x1989.com/a/359.html" title="PHP SPL File Browser">阅读全文——共469字</a></span>]]></description>
			<content:encoded><![CDATA[<p>俗话说不想偷懒的程序员不是好程序员。<br />
所以为了向“好程序员”靠拢，我们要自觉地在工作中偷懒…当然不是要你偷工减料，而是要用程序员应该有的方式来“偷懒”，提高工作效率。<br />
我所在的公司使用的PHP demo环境，出于安全方面的考虑，设置了禁止访问网站目录（列出目录文件列表），造成了我没有办法通过浏览器直接访问目录，查看到目录下的文件列表。上传了个php探针到demo服务器上，发现PHP的系列文件操作函数都被禁用了。这样我也没有办法写一段php脚本通过opendir、chdir、scandir等函数来遍历目录下的文件，输出文件列表到浏览器。<br />
好在经过测试，发现并没有禁用PHP的SPL(SPL是Standard PHP Library的缩写)。这样我们就可以通过SPL中的DirectoryIterator来遍历目录了。<br />
于是就有了下面这个小工具，我想可以把它叫做PHP SPL File Browser或者PHP SPL Directory Browser。它强大得放在任意子目录下都可以浏览整站目录。代码写得很乱，就不献丑了，有需要的童鞋可以发Email给我。<br />
<a href="http://x1989.com/wp-content/uploads/2011/03/phpspldirectorybrowser.png"><img src="http://x1989.com/wp-content/uploads/2011/03/phpspldirectorybrowser-300x226.png" alt="" title="phpspldirectorybrowser" width="300" height="226" class="alignnone size-medium wp-image-382" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://x1989.com/a/359.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

