<?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>Some reminiscences, some memories &#187; PHP</title>
	<atom:link href="http://www.mikespook.com/index.php/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mikespook.com</link>
	<description>Just another boring day</description>
	<lastBuildDate>Thu, 05 Aug 2010 14:36:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Web编程异步模型的 Gearman 实现（残）</title>
		<link>http://www.mikespook.com/index.php/archives/597</link>
		<comments>http://www.mikespook.com/index.php/archives/597#comments</comments>
		<pubDate>Tue, 08 Jun 2010 02:34:35 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[Gearman]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[异步]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=597</guid>
		<description><![CDATA[写了 PHP 原生的二段式异步模型的实现，我就想着用 Gearman 实现一个 callback 方式的异步。还没准备好怎么去写，就看到了靓文一篇《Gearman 心得》。 看过之后，甚感压力：好文！！于是，弃笔不写，洗洗睡罢了…… 补充一下，在“心得”文中仅仅说明了不阻塞的后台作业。对于异步获取数据并未说明。所以我这里罗嗦一下…… worker 如果用 php 来实现，并且不用《Web编程异步模型的PHP 原生实现》中的异步方式，是无法实现 php 的 client 的异步的。比较好的实现方式是 worker 不使用 php，用 python、perl 或者 c，实现一个线程池来执行 job。当然，私下觉得用 stackless python 可能是更好的选择。 2010年07月18日补充： 好吧，终于有人撰文，正好可以补充完整这个异步思路： 淺談coroutine與gevent 就他了，太棒了！]]></description>
			<content:encoded><![CDATA[<p>写了 PHP 原生的二段式异步模型的实现，我就想着用 Gearman 实现一个 callback 方式的异步。还没准备好怎么去写，就看到了靓文一篇<a href="http://www.jaceju.net/blog/?p=1211" target="_blank">《Gearman 心得》</a>。</p>
<p>看过之后，甚感压力：<strong>好文！！</strong>于是，弃笔不写，洗洗睡罢了……</p>
<p>补充一下，在“心得”文中仅仅说明了不阻塞的后台作业。对于异步获取数据并未说明。所以我这里罗嗦一下……</p>
<p>worker 如果用 php 来实现，并且不用<a href="http://www.mikespook.com/index.php/archives/587" target="_blank">《Web编程异步模型的PHP 原生实现》</a>中的异步方式，是无法实现 php 的 client 的异步的。比较好的实现方式是 worker 不使用 php，用 python、perl 或者 c，实现一个线程池来执行 job。当然，私下觉得用 stackless python 可能是更好的选择。</p>
<p>2010年07月18日补充：<br />
好吧，终于有人撰文，正好可以补充完整这个异步思路：<br />
<a href="http://blog.ez2learn.com/2010/07/17/talk-about-coroutine-and-gevent/" target="_blank">淺談coroutine與gevent</a><br />
就他了，太棒了！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/597/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web编程异步模型的PHP原生实现</title>
		<link>http://www.mikespook.com/index.php/archives/587</link>
		<comments>http://www.mikespook.com/index.php/archives/587#comments</comments>
		<pubDate>Sat, 05 Jun 2010 03:01:31 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[异步]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=587</guid>
		<description><![CDATA[这是基于上一篇随笔：关于Web编程异步模型的白日梦的实现。这一思路我记得在 05 年还是 07 年的时候就在 ChinaUnix 上有高人所讨论，只是自己当时愚钝未能明晰本质，纠结于 PHP 的多线程之中…… 这个实现写好有段时间了，最近琐碎的事情很多，一直没有整理出来。今日得闲记录下来。 利用PHP自带的 stream_select 函数实现异步，利用这个函数使得 PHP 原生支持的异步调用实现，无须第三方服务或库。不过只能实现二段式异步调用，就是说会有明显的 Begin 和 End 两个阶段。 代码比较容易理解，大家自己看吧。 先看看，封装好的方法，如何异步调用： /** * DEMO */ /** * 请求集合 */ $requestSet = array( 'foobar' =&#62; array( 'stream' =&#62; '127.0.0.1:80', 'path' =&#62; '/api.php', 'params' =&#62; array('a'=&#62;1), 'callback' =&#62; 'echoArray', ), 'foo-bar' =&#62; array( 'stream' =&#62; '127.0.0.1:80', 'path' [...]]]></description>
			<content:encoded><![CDATA[<p>这是基于上一篇随笔：<a href="http://www.mikespook.com/index.php/archives/580" target="_blank">关于Web编程异步模型的白日梦</a>的实现。这一思路我记得在 05 年还是 07 年的时候就在 ChinaUnix 上有高人所讨论，只是自己当时愚钝未能明晰本质，纠结于 PHP 的多线程之中……</p>
<p>这个实现写好有段时间了，最近琐碎的事情很多，一直没有整理出来。今日得闲记录下来。</p>
<p>利用PHP自带的 stream_select 函数实现异步，利用这个函数使得 PHP 原生支持的异步调用实现，无须第三方服务或库。不过只能实现二段式异步调用，就是说会有明显的 Begin 和 End 两个阶段。<br />
<span id="more-587"></span><br />
代码比较容易理解，大家自己看吧。</p>
<p>先看看，封装好的方法，如何异步调用：</p>
<pre class="brush: php;">
/**
 * DEMO
 */

/**
 * 请求集合
 */
$requestSet = array(
    'foobar' =&gt; array(
        'stream'    =&gt;  '127.0.0.1:80',
        'path'      =&gt;  '/api.php',
        'params'    =&gt;  array('a'=&gt;1),
        'callback'  =&gt;  'echoArray',
    ),
    'foo-bar' =&gt; array(
        'stream'    =&gt;  '127.0.0.1:80',
        'path'      =&gt;  '/api.php',
        'params'    =&gt;  array('method'=&gt;'get', 'table'=&gt;'user', 'id'=&gt;1),
        'callback'  =&gt;  'echoArray',
    ),
    'another' =&gt; array(
        'stream'    =&gt;  '127.0.0.1:80',
        'path'      =&gt;  '/api.php',
        'params'    =&gt;  array(),
        'callback'  =&gt;  'echoArray',
    ),
);

/**
 * 演示处理函数，这里只作打印
 * @param $a array 输入数组
 */
function echoArray($a) {
    var_dump($a);
}

/**
 * 二段异步调用
 */

/**
 * 第一阶段，发起请求
 */
$fps = beginRequest($requestSet);
/**
 * 第二阶段，处理返回
 */
endReponse($requestSet, $fps);
</pre>
<p>封装的异步函数：</p>
<pre class="brush: php;">
/**
 * 发起一个请求
 * @param $stream string 主机、端口
 * @param $path string api路径
 * @param $params array 参数
 * @return resource 文件描述符
 */
function request($stream, $path, $params) {
    $fp = stream_socket_client(&quot;tcp://{$stream}&quot;, $errno, $errstr, 30);
    if (!$fp) {
        throw new Exception($errstr, $errno);
    } else {
        $params = http_build_query($params);
        $host = explode(':', $stream);
        $str = &quot;GET {$path}?{$params} HTTP/1.0\r\nHost: {$host[0]}\r\nAccept: */*\r\n\r\n&quot;;
        fwrite($fp, $str);
    }
    return $fp;
}

/**
 * 获取请求的返回
 * @param $fp resource 文件描述符
 * @return array 取得的返回值
 */
function response($fp) {
    $r = stream_get_contents($fp);
    // 简陋的 HTTP 协议解析
    $r = explode(&quot;\n&quot;, $r);
    return json_decode($r[count($r) - 1]);
}

/**
 * 发起请求
 * @param $requestSet array 请求队列数组
 * @return array 文件描述符数组
 */
function beginRequest($requestSet) {
    $fps = array();
    foreach($requestSet as $key =&gt; $request) {
        try {
            $fps[$key] = request($request['stream'], $request['path'], $request['params']);
        } catch (Exception $e) {
            echo $e;
        }
    }
    return $fps;
}

/**
 * 处理返回
 * @param $requestSet array 请求队列数组
 * @param $fps array 文件描述符数组
 */
function endReponse($requestSet, $fps) {
    $r = $fps;

    while(count($fps) &gt; 0) {
        // 这里是重点，stream_select 保证了先返回的先处理。
        $n = stream_select($r, $w, $e, 0);
        if ($n === false) {
            echo $e;
    	    continue;
        }
        if ($n &gt; 0) {
            foreach($r as $socket) {
                // 读取返回值，并调用回调
                $r = response($socket);
                $key = array_search($socket, $fps);
                $callback = $requestSet[$key]['callback'];
                $callback($r);
                fclose($socket);
	        unset($fps[$key]);
	    }
        }
        $r = $fps;
    }
}
</pre>
<p>api.php 接口：</p>
<pre class="brush: php;">
&lt;?php
$a = array(
    'hello' =&gt; 'world',
    'foobar' =&gt; array(0,1,2,3,4),
    'GET'   =&gt;  $_GET,
    );
echo json_encode($a);
</pre>
<p>为了演示的需要剔除了面向对象、异常处理的一些内容。同时硬性规定 api 接口使用 json 通过 http 协议传递数据。<br />
实际上，由于 php 的 stream 的功能可以处理包括 udp 协议在内的I/O。可利用其他协议和开销更小的报文格式，以便能获得更好的性能。</p>
<p>由于模型的限制，callback 异步无法直接实现，可将存在数据读取依赖关系的数据读取过程拆解为若干个二段异步调用。</p>
<p>PS：这里只是一个实现方法的演示，并不涉及该方法是否在真实环境可用。也就是说，虽然实现了PHP的异步调用，但是实际运行可能并不比顺序阻塞读取的性能高。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/587/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>关于Web编程异步模型的白日梦</title>
		<link>http://www.mikespook.com/index.php/archives/580</link>
		<comments>http://www.mikespook.com/index.php/archives/580#comments</comments>
		<pubDate>Thu, 27 May 2010 03:04:26 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[golang]]></category>
		<category><![CDATA[异步]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=580</guid>
		<description><![CDATA[早上刷牙，处于半睡状态。突然想起昨天晚上看到的那个 go-lang 的 MVC 框架，若使用 go func() 方式异步获取数据，应当是不错的。窃喜……梦醒…… 在地铁上被前前后后那些特种男女逼到车角，无奈。又想起早上那个白日梦，遂上网搜索了一番。得老赵的佳作一篇《F# 与ASP.NET（1）：基于事件的异步模式与异步Action》。之前看过，由于对微软无爱，未能细品。今日一读，如醍醐灌顶，豁然开朗。 遂整理思路如下，以待后用。 在说异步模型之前，先说说最常见的同步模型吧。例如下面的 PHP 代码： // 获取数据 $userInfo = getUserInfo(); $newsList = getNewsList(); $topRateNewsList = getNewsList('DESC `rate`'); // 创建模板，绑定变量 $tmp = CreateTemplate(); $tmp-&#62;bind('userInfo', $userInfo); $tmp-&#62;bind('newsList', $newsList); $tmp-&#62;bind('topRateNewsList', $topRateNewsList); // 渲染模板，输出 $tmp-&#62;render(); echo $tmp; 在这段代码中，所有调用都是顺序的。也就是说，如果 getUserInfo($userId) 没有返回用户信息的话，getNewsList(5) 永远都不会被调用。实际情况，可能是用户信息是从用户库取数据，新闻是从新闻库取数据。假设新闻库运行良好，而由于某种原因用户库宕机了，那么这次请求也就废掉了。故障也从一个库的宕机扩散到整个站点。 现在，我白日做梦的创建一种新语言 go-php，引入 go-lang 的关键字 go 到 php 中： // [...]]]></description>
			<content:encoded><![CDATA[<p>早上刷牙，处于半睡状态。突然想起昨天晚上看到的那个 go-lang 的 MVC 框架，若使用 go func() 方式异步获取数据，应当是不错的。窃喜……梦醒……</p>
<p>在地铁上被前前后后那些特种男女逼到车角，无奈。又想起早上那个白日梦，遂上网搜索了一番。得老赵的佳作一篇<a href="http://blog.zhaojie.me/2010/04/fsharp-for-asp-net-1-event-based-asynchronous-pattern-and-async-action.html" target="_blank">《F# 与ASP.NET（1）：基于事件的异步模式与异步Action》</a>。之前看过，由于对微软无爱，未能细品。今日一读，如醍醐灌顶，豁然开朗。</p>
<p>遂整理思路如下，以待后用。<br />
<span id="more-580"></span></p>
<p>在说异步模型之前，先说说最常见的同步模型吧。例如下面的 PHP 代码：</p>
<pre class="brush: php;">
// 获取数据
$userInfo = getUserInfo();
$newsList = getNewsList();
$topRateNewsList = getNewsList('DESC `rate`');
// 创建模板，绑定变量
$tmp = CreateTemplate();
$tmp-&gt;bind('userInfo', $userInfo);
$tmp-&gt;bind('newsList', $newsList);
$tmp-&gt;bind('topRateNewsList', $topRateNewsList);
// 渲染模板，输出
$tmp-&gt;render();
echo $tmp;
</pre>
<p>在这段代码中，所有调用都是顺序的。也就是说，如果 getUserInfo($userId) 没有返回用户信息的话，getNewsList(5) 永远都不会被调用。实际情况，可能是用户信息是从用户库取数据，新闻是从新闻库取数据。假设新闻库运行良好，而由于某种原因用户库宕机了，那么这次请求也就废掉了。故障也从一个库的宕机扩散到整个站点。</p>
<p>现在，我白日做梦的创建一种新语言 go-php，引入 go-lang 的关键字 go 到 php 中：</p>
<pre class="brush: php;">
// 创建一个数据通道
$chan = CreateChan();
// 获取数据，并放到数据通道上去
go getUserInfo($chan);
go getNewsList($chan);
$params = array('DESC `rate`');
go getNewsList($chan, $params);
// 创建模板
$tmp = CreateTemplate();
// 从通道上取数据
while($d = $chan-&gt;read()) {
    if ($d['error']) {
        // 数据有错误 ……处理一下吧
    } else {
        $tmp-&gt;bind($d['key'], $d['data']);
    }
}
// 渲染模板，输出
$tmp-&gt;render();
echo $tmp;
</pre>
<p>好了，这其实不是什么新奇创造，这只是一个<strong>二段式异步调用（Begin/End）</strong>。这有点像大宗采购，采购商并不一件一件的商品进行采购，而是拿着清单说：“好了，兄弟，这是我要的货，你们帮我找齐，放到码头406号仓库去……”，然后他就在 406 号仓库等着点货了。这段代码还可以改进，就像采购清单一样，将这个清单推到数据层，数据层把数据返回到数据通道上去。恩，应该不少人在自己的应用中使用 MQ，Memcache 甚至 pipe 实现了这种异步了吧。</p>
<p>再来看另外一段 go-php 代码：</p>
<pre class="brush: php;">
/**
 * 回调函数
 * @param $tmp 模板
 * @param $d 返回的数据
 */
function callbackBind($tmp, $d) {
    if ($d['error']) {
        // 数据有错误 ……处理一下吧
    } else {
        $tmp-&gt;bind($d['key'], $d['data']);
    }
}
// 创建模板
$tmp = CreateTemplate();
// 获取数据，并设置数据回调
go getUserInfo(callbackBind, $tmp);
go getNewsList(callbackBind, $tmp);
$params = array('DESC `rate`');
go getNewsList(callbackBind, $tmp, $params);
// 如果不是所有数据都回调了，则阻塞
$tmp-&gt;wait();
// 渲染模板，输出
$tmp-&gt;render();
echo $tmp;
</pre>
<p>这就是老赵的<strong>事件回调</strong>的异步处理的 go-php 版本。这有点像渠道商订货（或者淘宝上的无货代理？）：“我需要XXXX，你帮我送到XXXX去”。然后坐等，所有的内容都送到了，就收钱走人。</p>
<p>对于数据读取的错误，只要处理得当也不是致命的。最多在渲染页面的时候，少某块数据，用户只会奇怪：“这次怎么打开没有新闻那部分的内容了呢……刷新一下看看……”。而不会说：“烂网站，又打不开了……”用户体验直线上升啊！</p>
<p>好了，梦就做到这里。相信这两种方式其实已经有实际案例了。我比较孤陋寡闻一些，了解的不多。而且有的东西，未经许可也不好多说……大家私下打听吧。</p>
<p>总之呢，两种异步模型各自有各自的好处。并行的数据存取，提高 I/O 利用率是其本质。王道啊……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/580/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>关于昨日爆出的 Nginx + PHP CGI 漏洞的一点点补充</title>
		<link>http://www.mikespook.com/index.php/archives/575</link>
		<comments>http://www.mikespook.com/index.php/archives/575#comments</comments>
		<pubDate>Fri, 21 May 2010 06:14:52 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[漏洞]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=575</guid>
		<description><![CDATA[我第一次看到这个漏洞是在 Laruence 的博客。看完之后，我赶紧评估了一下我们正在开发的产品出现这个漏洞的可能性。还不错，在我们当前架构下，这个漏洞被成功利用的可能性为 0 …… 结果，今天在大嘴巴 cnbeta 看到了这篇很标题党的新闻《80后发现nginx 0day漏洞，上传图片可入侵100万服务器》。然后引用的出处是这里。 好了，我认为我提供的背景资料足够详细了。现在说说为什么我们的产品不会出现这个被利用的可能吧。 其实很简单，将资源文件和 php 脚本文件放在不同的域名下面。然后将资源文件（含产品自身的和用户贡献的）的访问限于只作文件传输，不作任何的脚本解析。 例如 PHP 脚本执行的主机名是 www.mikespook.com。而上传文件和图像、js、css 等放在 static.mikespook.com 主机名下。 其实，就是这么简单的一个隔离措施，就避免了出现这种上传并解析的漏洞。 即使想用同一个域名，通过对 nginx 的配置禁止资源文件目录下的文件被当作脚本解析也是很容易的。 这个故事教育我们：细节是基石，架构是王道！！！ 另，根据来自高春辉的可靠消息，手机之家也不存在此问题……]]></description>
			<content:encoded><![CDATA[<p>我第一次看到这个漏洞是在 <a href="http://www.laruence.com/2010/05/20/1495.html" target="_blank">Laruence 的博客</a>。看完之后，我赶紧评估了一下我们正在开发的产品出现这个漏洞的可能性。还不错，在我们当前架构下，这个漏洞被成功利用的可能性为 0 ……</p>
<p>结果，今天在大嘴巴 cnbeta 看到了这篇很标题党的新闻<a href="http://www.cnbeta.com/articles/111711.htm" target="_blank">《80后发现nginx 0day漏洞，上传图片可入侵100万服务器》</a>。然后引用的出处是<a href="http://www.80sec.com/nginx-securit.html" target="_blank">这里</a>。</p>
<p>好了，我认为我提供的背景资料足够详细了。现在说说为什么我们的产品不会出现这个被利用的可能吧。</p>
<p>其实很简单，将资源文件和 php 脚本文件放在不同的域名下面。然后将资源文件（含产品自身的和用户贡献的）的访问限于只作文件传输，不作任何的脚本解析。</p>
<p>例如 PHP 脚本执行的主机名是 www.mikespook.com。而上传文件和图像、js、css 等放在 static.mikespook.com 主机名下。</p>
<p>其实，就是这么简单的一个隔离措施，就避免了出现这种上传并解析的漏洞。</p>
<p>即使想用同一个域名，通过对 nginx 的配置禁止资源文件目录下的文件被当作脚本解析也是很容易的。</p>
<p>这个故事教育我们：细节是基石，架构是王道！！！</p>
<p>另，根据来自高春辉的可靠消息，手机之家也不存在此问题……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/575/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]MongoDB：PHP开发者应该知道的关于 MongoDB 的 5 件事儿</title>
		<link>http://www.mikespook.com/index.php/archives/524</link>
		<comments>http://www.mikespook.com/index.php/archives/524#comments</comments>
		<pubDate>Tue, 23 Mar 2010 04:04:52 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=524</guid>
		<description><![CDATA[原文：http://technosophos.com/content/mongodb-5-things-every-php-developer-should-know-about-mongodb 感觉这篇文章说了一些 MongoDB 的要点，适合 MongoDB 扫盲使用。所以翻译出来，造福于民。虽然文章是针对 PHP 开发者写的，但实际上 python、ruby 或者其他 web 开发人员也可借鉴。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-这里是译文分隔线&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; 2010年将被记住，因为这一年 SQL 死了；这一年关系数据库从一线退下；这一年开发人员发现他们没必要为了持久化数据，将每个对象转化为表格结构。 2010年是文档数据库的一年。尽管一直在稳步发展势头，通过过去七年多的发展，现在有各种稳定的文档数据库——从基于亚马逊和谷歌的云，到各种开放源码工具，尤其是 CouchDB 和 MongoDB。 那么，MongoDB 是什么？这里的五件事是每个 PHP 开发人员应该知道的： 1、MongoDB 是一个独立的服务器 2、它是基于文档的，而不是基于表格的 3、它是非结构化的 4、不必去学习另一种查询语言 5、它具有强大的 PHP 支持 阅读下文，可以了解关于这些的详细内容。 1、MongoDB 是一个独立的服务器 如 MySQL 或 PostgreSQL 一样，MongoDB 侦听端口以便接入。它提供了用于查询，创建，更新和删除的工具。从理论上讲，你使用它的工作方式与你使用 MySQL 或 PostgreSQL 的工作方式相同：连接，执行任务，并关闭连接。 2、跟行和表格说再见，向文档和集合说你好 MongoDB 存储整个文档，代替了存储在表的行数据中。如果有一个含有标题、多位作者、内容和标签的“文章”数据，该数据基本上看起来像这样： &#60;? php array( 'title' =&#62; 'Hello World', [...]]]></description>
			<content:encoded><![CDATA[<p>原文：<a href="http://technosophos.com/content/mongodb-5-things-every-php-developer-should-know-about-mongodb" target="_blank">http://technosophos.com/content/mongodb-5-things-every-php-developer-should-know-about-mongodb</a></p>
<p>感觉这篇文章说了一些 MongoDB 的要点，适合 MongoDB 扫盲使用。所以翻译出来，造福于民。虽然文章是针对 PHP 开发者写的，但实际上 python、ruby 或者其他 web 开发人员也可借鉴。<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-这里是译文分隔线&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
<span id="more-524"></span></p>
<p>2010年将被记住，因为这一年 SQL 死了；这一年关系数据库从一线退下；这一年开发人员发现他们没必要为了持久化数据，将每个对象转化为表格结构。</p>
<p>2010年是文档数据库的一年。尽管一直在稳步发展势头，通过过去七年多的发展，现在有各种稳定的文档数据库——从基于亚马逊和谷歌的云，到各种开放源码工具，尤其是 <a href="http://couchdb.apache.org/" target="_blank">CouchDB</a> 和 <a href="http://www.mongodb.org/display/DOCS/Home" target="_blank">MongoDB</a>。</p>
<p>那么，MongoDB 是什么？这里的五件事是每个 PHP 开发人员应该知道的：</p>
<p><strong>1、MongoDB 是一个独立的服务器<br />
2、它是基于文档的，而不是基于表格的<br />
3、它是非结构化的<br />
4、不必去学习另一种查询语言<br />
5、它具有强大的 PHP 支持</strong></p>
<p>阅读下文，可以了解关于这些的详细内容。</p>
<p><strong>1、MongoDB 是一个独立的服务器</strong></p>
<p>如 MySQL 或 PostgreSQL 一样，MongoDB 侦听端口以便接入。它提供了用于查询，创建，更新和删除的工具。从理论上讲，你使用它的工作方式与你使用 MySQL 或 PostgreSQL 的工作方式相同：连接，执行任务，并关闭连接。<br />
<strong><br />
2、跟行和表格说再见，向文档和集合说你好</strong></p>
<p>MongoDB 存储整个文档，代替了存储在表的行数据中。如果有一个含有标题、多位作者、内容和标签的“文章”数据，该数据基本上看起来像这样：</p>
<pre class="brush: php;">
&lt;? php
array(
    'title' =&gt; 'Hello World',
    'authors' =&gt; array('John', 'Sally', 'Jim'),
    'body' =&gt; 'Hello world',
    'tags' =&gt; array('tag1', 'tag2', 'tag3')
);
?&gt;
</pre>
<p>要注意的关键，上面的例子是一个记录——一个文档——实际上是像文档一样存储，并支持同一字段有多个值的情况。没有必要将数据转化为通常意义上的表中，因为，根本没有表。</p>
<p>现在，作为将文档存储在表中的替代方案，它们存储在一个集合里，这可以认为是一个大的文档列表。</p>
<p><strong>3、MongoDB 是非结构化的</strong></p>
<p>MongoDB 没有结构化语言。如果你想创建一个新的文档类型，你不用做任何事来告诉数据库关于这些数据的结构，而仅仅是存到数据库中即可。</p>
<p>在第 2 点中，我虚构了一个文档。现在，如果我想在这些字段上定义文章类型，我所要做的仅仅是存储对象到数据库如果我想定义它与这些领域的文章类型，首先，我需要做的就是写入数据库中的对象。日后，如果我决定增加一些什么，例如，一个日期？我只是从数据库中获得文章，添加日期字段，并保存它。</p>
<p>相关的数据类型是什么？简单的说，MongoDB 使用类似 JavaScript 或 PHP 的类型处理方式。也就是说，数据库是灵活的弱类型。</p>
<p>虽然有一些数据是有限制条件的（大块的数据可能需要一些明确的处理），但在大多数情况下，你可以像写 PHP 代码一样编写你的 MongoDB 代码。</p>
<p><strong>4、不必去学习另一种查询语言！</strong></p>
<p>还记得这些你写的数据库抽象层吗？还记得那些你处理过的 ORM 层吗？现在，你可以将它们全部丢弃。在 Mongo 中你不需要他们。</p>
<p>MongoDB（当使用 PHP 驱动）没有很多查询语句。在大多数情况下，只需给它一个数组指定你想要的信息，然后它会给你返回文档的数组。</p>
<p>如果你想运行一些非常复杂的查询（如Map-Reduce操作），可以向MongoDB 传递 JavaScript，其内部的 JavaScript 引擎可以解析这个脚本。</p>
<p><strong>5、PHP 和 MongoDB 是上天注定的一对搭档</strong></p>
<p>PHP 已经有很好的 MongoDB 支持。Mongo 驱动可以通过 PECL 扩展安装到 PHP，这意味着运行 pecl 安装 mongo 非常简单。（早些时候我写了一篇短文，详细介绍了<a href="http://technosophos.com/content/os-x-installing-mongodb-and-php-mongo-driver" target="_blank">安装过程</a>）</p>
<p>然后，你可以立即使用<a href="http://us2.php.net/manual/en/book.mongo.php" target="_blank"> Mongo 的 API</a> 开始工作。复杂性，站在 PDO 的阵营中。它不够简单，<del datetime="2010-03-24T01:00:36+00:00">but there should be nothing foreign about it for anyone who has done database development before.（注：不知道怎么翻译，不是关键，大家自悟吧）</del>但是这对于之前做过数据库开发的人来说，不会很陌生。</p>
<p>API 文档（上面有连接）包括了指引和许多例子，所以你应该能够在一个很短的时间里学会。这里有一些你需要注意的：</p>
<p>* MongoDB 是神速的<br />
* 开发时间也短，因为没有结构需要管理，和很少（如果有的话）的数据映射。<br />
* 学习曲线很平滑，因为没有新的查询语言学习。<br />
* 代码是简洁的。毕竟，无须任何其他 ORM，封装可以非常简单。<br />
* 你的代码是未来的保证。向你的对象增加更多的字段是很轻松的——甚至复杂的字段。因此，需求变化了，你可以很快修改代码以便适应。</p>
<p>我用 MongoDB 开发只有一段时间，但这足以让我意识到它有改变游戏规则的潜力。这也是让我主张使用新一代的文档数据库代替基于 SQL 的关系数据库的原因。将关系数据库留在尘土里——或者，更可能的是让它们做它们能做好的事情：存数属于行和表的数据。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/524/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>脚本语言的配置文件</title>
		<link>http://www.mikespook.com/index.php/archives/405</link>
		<comments>http://www.mikespook.com/index.php/archives/405#comments</comments>
		<pubDate>Mon, 21 Sep 2009 02:30:26 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[配置文件]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=405</guid>
		<description><![CDATA[关于配置文件，在 PHP 的 Zend Framework 中我做过一些简单的关于性能的测试：http://www.mikespook.com/index.php/archives/36。将 ninnypro 的配置文件从 ini 修改为 xml ，并且声称能提高传说中的性能。 最近被调到另外一个在用 python 的组帮忙，阅读了他们的实现服务器端的 python 代码之，配置文件近二十余个，全是 xml 文件。为了使用着些配置文件，从 XMLFile 继承，实现了二十余个 Config 类。 这看起来似乎没什么问题。 是的，一点问题也没有。 XML是高度结构化的描述方式。 XML有大量丰富的包、库支持。 XML的跨语言能力也是相当优异。你可以轻松的用市面上常见的所有语言轻松的掌控 XML。 这些都决定了 XML 作为配置文件，肯定是比 ini 或者自定义结构的配置文件更加优异的结构。同时，大量的实践也证明 XML 的优异性。例如 j2ee 的实践、SOA的实现、Jabber 的应用都说明 XML: is the lord of the configuration。 但是真得一点问题都没有么？ 首先，来看一下 Zend Framework 的 Zend_Config。由于 PHP 自身的数据结构特点，Zend_Config_Xml 和 [...]]]></description>
			<content:encoded><![CDATA[<p>关于配置文件，在 PHP 的 Zend Framework 中我做过一些简单的关于性能的测试：<a href="http://www.mikespook.com/index.php/archives/36" target="_blank">http://www.mikespook.com/index.php/archives/36</a>。将 ninnypro 的配置文件从 ini 修改为 xml ，并且声称能提高传说中的性能。</p>
<p>最近被调到另外一个在用 python 的组帮忙，阅读了他们的实现服务器端的 python 代码之，配置文件近二十余个，全是 xml 文件。为了使用着些配置文件，从 XMLFile 继承，实现了二十余个 Config 类。</p>
<p><strong>这看起来似乎没什么问题。<span id="more-405"></span></strong></p>
<p>是的，一点问题也没有。</p>
<ol>
<li>XML是高度结构化的描述方式。</li>
<li>XML有大量丰富的包、库支持。</li>
<li>XML的跨语言能力也是相当优异。你可以轻松的用市面上常见的所有语言轻松的掌控 XML。</li>
</ol>
<p>这些都决定了 XML 作为配置文件，肯定是比 ini 或者自定义结构的配置文件更加优异的结构。同时，大量的实践也证明 XML 的优异性。例如 j2ee 的实践、SOA的实现、Jabber 的应用都说明 XML: is the lord of the configuration。</p>
<p><strong>但是真得一点问题都没有么？</strong></p>
<p>首先，来看一下 Zend Framework 的 Zend_Config。由于 PHP 自身的数据结构特点，Zend_Config_Xml 和 Zend_Config_Ini 两个类都会加载相应的配置文件，解析后作为数组传递到 Zend_Config 类中。也就是说，最终殊途同归，所有的配置都变成了 PHP 的数组。</p>
<p>然后，再来看一下那个项目中的配置文件。结构化的 XML 被 XMLFile 读取，然后转化为 XMLFile 对象。再统一放入 ConfigManagement 中，经过转换，将部分结构转为 dict 使用。</p>
<p>使用配置文件的原因，我猜测是因为以前，编译语言开发的程序经过编译后，不具有动态改变参数的能力。虽然可以从命令行通过传参来在每次运行时修改配置，但是无论是谁需要通过命令行传递成百上千的参数，都会疯掉。而且，命令行传参，不具有结构化的特征。在一些场景下，需要快速修改部分配置，就变得极为困难。</p>
<p>于是聪明的程序员发明了对人友好的、结构化的配置文件，通过读取配置文件来改变程序内部参数的使用。</p>
<p>这一习惯一直沿用至今。伴随 XML 的问世，配置文件的地位再次上升。更有甚者，在开发中不做编码，只写配置。</p>
<p><strong>看出问题了么？</strong></p>
<p>如果还是没有想法的话，那就再来看看脚本语言：</p>
<ol>
<li>脚本语言具有动态性。</li>
<li>脚本语言自身就是结构化的。</li>
<li>脚本语言可以增强编译语言的动态能力。</li>
</ol>
<p>在各个脚本语言应用 XML 作为配置文件的实践中，不论是 PHP 的 array，还是 Python 的 dict，无一例外的将配置文件转换为了脚本语言内部的一种数据结构。在多数情况下，这也是 XML 作为脚本语言配置文件唯一的解决方案。</p>
<p>再来看一个问题：在项目中使用 XML 作为配置文件的时候，是否有使用 DTD 作为 XML 的效验工具？</p>
<p>如果答案是否定的，那么 XML作为脚本语言就没有任何优势。没有应用 DTD 的 XML 就如同 PHP 的 array，Python 的 dict 一样。</p>
<p>那又何必要苦苦的追随 XML，不用脚本语言的数据结构来直接编写配置文件呢？</p>
<p>本来，早就像对这个话题写点什么。星期六（2009-09-19）的时候参加了广州技术沙龙，听了朱童鞋的 nginx 代码剖析后，突然有所顿悟：<strong></strong></p>
<p><strong>成功在于细节，性能在于细节。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/405/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>［翻译］PHP的命名空间真这么糟糕么？</title>
		<link>http://www.mikespook.com/index.php/archives/394</link>
		<comments>http://www.mikespook.com/index.php/archives/394#comments</comments>
		<pubDate>Wed, 02 Sep 2009 02:27:11 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[命名空间]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=394</guid>
		<description><![CDATA[几年前（大约应该在02-03年之间，也就是php5刚出来那会）曾经跟朋友讨论过一次关于php的命名空间的问题。当时觉得，php要是能有命名空间，那是多完美的事情啊。 如今，php5.3已经包含了命名空间。但是似乎并没有当年的那种感慨了。大约是旧的系统要迁移，新的系统要重新设计，这个名字空间都有点鸡肋的感觉。看来还要习惯一下才好。 看到这篇文章，觉得说得是有点对的。也不长，就随手翻译出来。翻译后的感觉：作者 超级喜欢使用“However”。 能说明两个问题： php本身为什么是这样 php的名字空间为什么是这样 作者：Craig Buckler 原文：http://www.sitepoint.com/blogs/2009/08/13/are-php-namespaces-bad/ PHP开发者对于PHP中命名空间的实现，已经变得异常的渴望。当PHP应用开始变得巨大，并且更加复杂的时候，命名空间是解决代码冲突的必要手段。 我最近的一些指南收到了大量关于PHP的命名空间实现的评论。问题主要集中在语法和反斜杠上面。在解决这些问题之前，让我们先来快速回顾一下PHP的历史。 混乱的PHP 像C#和Java这些语言，是被设计和遵循严格的语法标准的。PHP是演化的。最早的版本发布于1995年，版本号3，是面向过程的语言。版本4包含了最基本的面向对象，而版本5提供了合适的标准OOP模型。命名空间在版本5.3被加入其中。 PHP批评者声明说这个语言是混乱的。函数名不一致（例如strpos，str_split，substr），对象处理是无用的，还有一些语法同其他语言相比，不是极其怪诞，就是异乎寻常。 然而，PHP仍然保持着使用最广泛的服务器端开发语言的头把交椅。它的才华主要在下面的长处： 初学者可以从简单的面向过程编程开始。他们无须触及OOP技术仍然可以有所见数。 10年前为PHP 3编写的代码仍然可以运行在PHP 5.3下。可能需要一些微小的调整，但是很少需要大量重写。 PHP代码可能并不总是可爱的、有逻辑的或者优雅的，但是相比其他选择它的开发总是快捷和容易被理解的。 PHP命名空间的实现 不像C#和Java，PHP不得不保持没有名字空间代码的兼容性。这个已经被实现，你可以选择使用或者不使用命名空间。然而，如果你使用PHP 5.3或更高版本，我推荐使用命名空间，即使你在项目中只使用相同的名字。 使用namespace和use作为命名空间操作符看起来很有逻辑。一些开发者可能不同意，但是在这种情况下它们如何命名其实并不重要。 最后，回到反斜杠的问题上。多数批评者人为这是丑陋的，难以阅读，并且在Mac上难以输入。即便如此，我仍然认为它比曾经提议过的两个冒号要好。例如下面的静态方法调用： // PHP 5.3 beta版静态方法调用 echo ::App::Lib1::MyClass::WhoAmI&#40;&#41;; // PHP 5.3正式版静态方法调用 echo \App\Lib1\MyClass::WhoAmI&#40;&#41;; 第二行可以被快速录入，更少的错误可能，容易阅读，并且容易理解。如果你在字符串之外看到反斜杠，你就知道那一定存在命名空间。 当然，如果PHP使用“.”作为公共方法、静态方法和命名空间会更好。这样可以同Java、C#、JavaScript、Python和许多其他语言一致起来。不幸的是PHP的历史和向下兼容让这一切难以实现。 没有语言是完美的，而PHP更加不会是完美语言中的一员。无论如何，命名空间已经被很好的实现，特别是考虑到它可能产生的限制和问题。我相信你一定会学习并且着迷那个反斜杠的。 相关阅读： How to Use PHP Namespaces, Part 1: The Basics How to Use PHP Namespaces, Part 2: Importing, Aliases, and [...]]]></description>
			<content:encoded><![CDATA[<p>几年前（大约应该在02-03年之间，也就是php5刚出来那会）曾经跟朋友讨论过一次关于php的命名空间的问题。当时觉得，php要是能有命名空间，那是多完美的事情啊。<br />
如今，php5.3已经包含了命名空间。但是似乎并没有当年的那种感慨了。大约是旧的系统要迁移，新的系统要重新设计，这个名字空间都有点鸡肋的感觉。看来还要习惯一下才好。<br />
看到这篇文章，觉得说得是有点对的。也不长，就随手翻译出来。翻译后的感觉：作者 超级喜欢使用“However”。<br />
能说明两个问题：</p>
<ol>
<li> php本身为什么是这样</li>
<li> php的名字空间为什么是这样</li>
</ol>
<p>作者：<a title="Craig Buckler's Author Bio" rel="nofollow" href="http://www.sitepoint.com/articlelist/560">Craig Buckler</a><br />
原文：<a href="http://www.sitepoint.com/blogs/2009/08/13/are-php-namespaces-bad/" target="_blank">http://www.sitepoint.com/blogs/2009/08/13/are-php-namespaces-bad/</a><span id="more-394"></span><br />
<img class="alignright" title="PHP namespaces" src="http://www.mikespook.com/wp-content/uploads/2009/12/0414_php-namespaces1.png" alt="PHP namespaces" width="240" height="240" /></p>
<p>PHP开发者对于PHP中命名空间的实现，已经变得异常的<a href="http://www.petitiononline.com/phpns/petition.html">渴望</a>。当PHP应用开始变得巨大，并且更加复杂的时候，命名空间是解决代码冲突的必要手段。<br />
我最近的一些<a href="http://www.sitepoint.com/blogs/2009/07/13/php-53-namespaces-basics/">指南</a>收到了大量关于PHP的命名空间实现的评论。问题主要集中在语法和反斜杠上面。在解决这些问题之前，让我们先来快速回顾一下PHP的历史。</p>
<h2>混乱的PHP</h2>
<p>像C#和Java这些语言，是被设计和遵循严格的语法标准的。PHP是<em>演化</em>的。最早的版本发布于1995年，版本号3，是面向过程的语言。版本4包含了最基本的面向对象，而版本5提供了合适的标准OOP模型。命名空间在版本5.3被加入其中。</p>
<p>PHP批评者声明说这个语言是混乱的。函数名不一致（例如strpos，str_split，substr），对象处理是无用的，还有一些语法同其他语言相比，不是极其怪诞，就是异乎寻常。</p>
<p>然而，PHP仍然保持着使用最广泛的服务器端开发语言的头把交椅。它的才华主要在下面的长处：</p>
<ul>
<li>初学者可以从简单的面向过程编程开始。他们无须触及OOP技术仍然可以有所见数。</li>
<li>10年前为PHP 3编写的代码仍然可以运行在PHP 5.3下。可能需要一些微小的调整，但是很少需要大量重写。</li>
</ul>
<p>PHP代码可能并不总是可爱的、有逻辑的或者优雅的，但是相比其他选择它的开发总是快捷和容易被理解的。</p>
<h2>PHP命名空间的实现</h2>
<p>不像C#和Java，PHP不得不保持没有名字空间代码的兼容性。这个已经被实现，你可以选择使用或者不使用命名空间。然而，如果你使用PHP 5.3或更高版本，我推荐使用命名空间，即使你在项目中只使用相同的名字。</p>
<p>使用<code>namespace</code>和<code>use</code>作为命名空间操作符看起来很有逻辑。一些开发者可能不同意，但是在这种情况下它们如何命名其实并不重要。</p>
<p>最后，回到反斜杠的问题上。多数批评者人为这是丑陋的，难以阅读，并且在Mac上难以输入。即便如此，我仍然认为它比曾经提议过的两个冒号要好。例如下面的静态方法调用：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// PHP 5.3 beta版静态方法调用</span>
<span style="color: #b1b100;">echo</span> <span style="color: #339933;">::</span><span style="color: #004000;">App</span><span style="color: #339933;">::</span><span style="color: #004000;">Lib1</span><span style="color: #339933;">::</span><span style="color: #004000;">MyClass</span><span style="color: #339933;">::</span><span style="color: #004000;">WhoAmI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// PHP 5.3正式版静态方法调用</span>
<span style="color: #b1b100;">echo</span> \App\Lib1\MyClass<span style="color: #339933;">::</span><span style="color: #004000;">WhoAmI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>第二行可以被快速录入，更少的错误可能，容易阅读，并且容易理解。如果你在字符串之外看到反斜杠，你就知道那一定存在命名空间。</p>
<p>当然，如果PHP使用“.”作为公共方法、静态方法和命名空间会更好。这样可以同Java、C#、JavaScript、Python和许多其他语言一致起来。不幸的是PHP的历史和向下兼容让这一切难以实现。</p>
<p>没有语言是完美的，而PHP更加不会是完美语言中的一员。无论如何，命名空间已经被很好的实现，特别是考虑到它可能产生的限制和问题。我相信你一定会学习并且着迷那个反斜杠的。</p>
<p>相关阅读：</p>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2009/07/13/php-53-namespaces-basics/">How to Use PHP Namespaces, Part 1: The Basics</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/14/php-namespaces-import-alias-resolution/">How to Use PHP Namespaces, Part 2: Importing, Aliases, and Name Resolution</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/15/how-to-use-php-namespaces-part-3-keywords-and-autoloading/">How to Use PHP Namespaces, Part 3: Keywords and Autoloading</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/394/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>mb_ereg(i)_replace() 执行任意代码的漏洞</title>
		<link>http://www.mikespook.com/index.php/archives/309</link>
		<comments>http://www.mikespook.com/index.php/archives/309#comments</comments>
		<pubDate>Fri, 08 May 2009 14:24:13 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[漏洞]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=309</guid>
		<description><![CDATA[这个漏洞说大也大，说小也小。大是因为真得可以通过注入的方式让漏洞代码执行任意代码。小是因为产生漏洞的环境还是比较苛刻的。 来源于此：http://milw0rm.com/exploits/8641 当最后一个参数设置为“e”，也就是将替换的内容作为 PHP 代码执行的时候，漏洞就产生了。 例如： function hi80vul&#40;&#41; &#123;&#125; &#160; $str = '\', phpinfo(), \''; mb_ereg_replace&#40;'^(.*)$', 'hi80vul(\'\1\')', $str, 'e'&#41;; 又例如： function hi80vul&#40;&#41; &#123;&#125; &#160; $str = '\', var_dump(get_loaded_extensions()), \''; mb_ereg_replace&#40;'^(.*)$', 'hi80vul(\'\1\')', $str, 'e'&#41;; 如果有在代码中使用过 mb_ereg_replace 和 mb_eregi_replace，以及参数“e”，那就赶紧检查一下是否有这样的安全隐患吧。]]></description>
			<content:encoded><![CDATA[<p>这个漏洞说大也大，说小也小。大是因为真得可以通过注入的方式让漏洞代码执行任意代码。小是因为产生漏洞的环境还是比较苛刻的。</p>
<p>来源于此：<a href="http://milw0rm.com/exploits/8641" target="_blank">http://milw0rm.com/exploits/8641</a></p>
<p>当最后一个参数设置为“e”，也就是将替换的内容作为 PHP 代码执行的时候，漏洞就产生了。<br />
例如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> hi80vul<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'\', phpinfo(), \''</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mb_ereg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'^(.*)$'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hi80vul(\'\1\')'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$str</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'e'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>又例如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> hi80vul<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'\', var_dump(get_loaded_extensions()), \''</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mb_ereg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'^(.*)$'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hi80vul(\'\1\')'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$str</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'e'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>如果有在代码中使用过 mb_ereg_replace 和 mb_eregi_replace，以及参数“e”，那就赶紧检查一下是否有这样的安全隐患吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/309/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>广州PHP培训和我的一些想法</title>
		<link>http://www.mikespook.com/index.php/archives/301</link>
		<comments>http://www.mikespook.com/index.php/archives/301#comments</comments>
		<pubDate>Thu, 07 May 2009 15:00:57 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dodi]]></category>
		<category><![CDATA[培训]]></category>
		<category><![CDATA[多迪]]></category>
		<category><![CDATA[广州]]></category>
		<category><![CDATA[慧的]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=301</guid>
		<description><![CDATA[首先，在 google 做一个搜索，关键词“广州 PHP 培训”。大约有 1,230,000 项符合的结果。在百度上搜索相同的关键字，大约有 38,500 项符合的结果。 其中呢，“多迪”培训是占了大多数的，然后就是“慧的”培训。其实这两家都是老熟人了。 广州PNP （群号：27112044）还作为 PEA 广州群的时候，就已经打过许多次交道了。他们在广州开展培训是比较早的，也有找过其他一些朋友和我，希望我们做讲师或兼职讲师。不过那个时候的“多迪”刚刚起步，还很艰苦，工资开得非常非常低，所以最终没有展开合作。再后来，由于一小撮“不明事理”的“多迪”学员总是到 PEA 广州群上找“多迪”的麻烦，所以 PEA 广州群聚会的时候一合计，干脆大家另起炉灶省得烦扰。就有了现在的广州 PNP（PNP:Neighbor PHP）。哦，题外话，现在 PNP 也有 Python 群了（群号：64387469）。听说多迪现在的培训业务还是开展得有声有色的。 “慧的”是以前的 PEA 群友逆雪寒参与开办的。在广州 PNP 成立以后，逆雪寒就承担了 PEA 广州的主要工作。大概是由于他忙于 PEA 发展吧，在 PNP 群里有段时间没说话了。逆雪寒在当时的 PEA 群里知名度是很高的，不过由于群活动参加得少，大多数群友可能只是问其名，不识其人。这其中的具体的细节，老一点的 PEA 广州的成员大约都是知道的吧！ 还有就是“中山大学数学与计算科学学院”开设的“广州 PHP 培训课程”，之前我也不知道中大的计科院还有这么一个培训课程。大体看了一下他们的教学提纲，比较中规中矩一些，很有学院派风格。从 HTML 讲起，以企业网站收尾。 本来想点评一下每个培训的价格、内容、师资等等的。但是“我们也想做培训了”，所以反而有些不方便点评了。所以，干脆就介绍一下我们的想法吧。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-吹水分界线，以下是正经内容&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- 做培训这个想法其实酝酿了很久，也有不少朋友提过。在群里就讨论了很多次，有很多一时无法解决的困难，所以没能决定下来。在跟路神（熟悉路神的朋友都知道，“PEA+培训模式”是他策划的，深圳的试点培训当然也是路神亲自做了讲师）沟通了 n 次以后，最终决定还是尝试一下。成功或者不成功都算是一种历练吧。毕竟，我们，有我们自己的优势。 首先，有路神在 PEA 培训中的经验做铺垫。路神为 PEA 以及 PEA [...]]]></description>
			<content:encoded><![CDATA[<p>首先，在 google 做一个搜索，关键词“广州 PHP 培训”。大约有 1,230,000 项符合的结果。在百度上搜索相同的关键字，大约有 38,500 项符合的结果。</p>
<p>其中呢，“多迪”培训是占了大多数的，然后就是“慧的”培训。其实这两家都是老熟人了。<span id="more-301"></span></p>
<p>广州PNP （群号：27112044）还作为 PEA 广州群的时候，就已经打过许多次交道了。他们在广州开展培训是比较早的，也有找过其他一些朋友和我，希望我们做讲师或兼职讲师。不过那个时候的“多迪”刚刚起步，还很艰苦，工资开得非常非常低，所以最终没有展开合作。再后来，由于一小撮“不明事理”的“多迪”学员总是到 PEA 广州群上找“多迪”的麻烦，所以 PEA 广州群聚会的时候一合计，干脆大家另起炉灶省得烦扰。就有了现在的广州 PNP（PNP:Neighbor PHP）。哦，题外话，现在 PNP 也有 Python 群了（群号：64387469）。听说多迪现在的培训业务还是开展得有声有色的。</p>
<p>“慧的”是以前的 PEA 群友逆雪寒参与开办的。在广州 PNP 成立以后，逆雪寒就承担了 PEA 广州的主要工作。大概是由于他忙于 PEA 发展吧，在 PNP 群里有段时间没说话了。逆雪寒在当时的 PEA 群里知名度是很高的，不过由于群活动参加得少，大多数群友可能只是问其名，不识其人。这其中的具体的细节，老一点的 PEA 广州的成员大约都是知道的吧！</p>
<p>还有就是“中山大学数学与计算科学学院”开设的“广州 PHP 培训课程”，之前我也不知道中大的计科院还有这么一个培训课程。大体看了一下他们的教学提纲，比较中规中矩一些，很有学院派风格。从 HTML 讲起，以企业网站收尾。</p>
<p>本来想点评一下每个培训的价格、内容、师资等等的。但是<span style="color: #ff0000;"><strong>“我们也想做培训了”</strong></span>，所以反而有些不方便点评了。所以，干脆就介绍一下我们的想法吧。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-吹水分界线，以下是正经内容&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>做培训这个想法其实酝酿了很久，也有不少朋友提过。在群里就讨论了很多次，有很多一时无法解决的困难，所以没能决定下来。在跟<a href="http://www.mikale.org/" target="_blank">路神</a>（熟悉路神的朋友都知道，“PEA+培训模式”是他策划的，深圳的试点培训当然也是路神亲自做了讲师）沟通了 n 次以后，最终决定还是尝试一下。成功或者不成功都算是一种历练吧。毕竟，我们，有我们自己的优势。</p>
<p>首先，有路神在 PEA 培训中的经验做铺垫。路神为 PEA 以及 PEA 培训做了很多策划和实际工作，这对于培训的定位、开展、授课、实训、实习等等工作是非常有帮助的。</p>
<p>然后，有 PNP 这个圈子做后盾。各个公司、各种身份的朋友汇聚在 PNP。从业内讯息到就业推荐都有一定的实际保障。而不像其他那些那样，推荐一下简历或者在公司内干一个试用期的外包就踢开不管了。毕竟这个圈子能溶入进来，在珠三角立足应该是不难的。</p>
<p>最后，也是最关键的，不论是路神、我还是标哥，等等……有开展培训意向的，为人解惑、答疑的，都有许多年的实战 web 开发经验。各种各样的复杂实际环境、实际问题。一般纯做技术培训的人很难接触得到。而这些经验的东西并不是秘密，只是知道的人没时间说，有时间说的人不知道。</p>
<p>培训的内容，是大家一直以来讨论的焦点。基础培训肯定需要，比如 HTTP 协议、环境搭建、HTML 基础、javascript、PHP 语法基础、MySQL使用等；提高的内容肯定也需要有，比如面向对象分析与设计、关系数据库设计与优化、缓存应用等；专题肯定也需要讲讲，比如 Zend Framework 使用、高性能 Web 架构、php 的邮件处理、php 的图像处理……说起来很多很多。而我由于之前工作的关系，对 webgame 开发也积累了一些心得，似乎也是个不错的培训题材。</p>
<p>或许一次或一期培训根本无法将所有内容都讲清楚，但作为一个技术从业者，我是有一种理想主义倾向在其中的。我希望能让每一个参与培训的学员和每一个参与培训的讲师都在不同层次上有所收获和提高。这也是写这个文章的原因，希望大家能帮我们出谋划策，对于在广州开展的 PHP 和 web 开发的培训提出一些意见和建议。让我们在组织内容、划分难度、开展培训的时候更加的科学、合理。</p>
<p>PS：或许我们应该直接展开培训，用迭代开发的方式，使用过程改进来提升培训质量？恩，又或者实用 PHP 项目管理也是一个可讲的内容吧？ ^_^! 大家有砖的赶紧拍……</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/301/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>PHP框架的繁荣是正确的发展方向吗？</title>
		<link>http://www.mikespook.com/index.php/archives/286</link>
		<comments>http://www.mikespook.com/index.php/archives/286#comments</comments>
		<pubDate>Tue, 17 Feb 2009 15:52:35 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[框架]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=286</guid>
		<description><![CDATA[这个其实是源于 javaeye 上的这个讨论：http://www.javaeye.com/post/886707。最开始吸引我的是在 rails 板块上诸多专业玩 java 和 ruby 的人是如何评价 php 以及 php 框架的。在讨论中发现有一些值得学习和借鉴的地方。所以推荐大家完整阅读这个帖子。从技术性、知识面和娱乐性来讲，都是质量很高的。 我就简单说一下我对于 php 框架繁荣的看法： 1. “草根阶级”向“企业开发俱乐部”转变的必然途径。 用 php 的企业多了，市场占有率高了，经济效益就体现出来了。但是仅仅靠做做企业网站，搞搞论坛这个蛋糕还太小。同时 B2B、B2C 的繁荣，自然带来已有网站的改造问题。php 迈着坚定的步伐冲向“俱乐部”大门。但是门卫说了“贫民与狗不得入内”。于是 php 的规范化、可维护性发展如火如荼的展开了。首先是学习 java，从语言层面引入 java 的优点。然后是开发规范的建立，涌现出大批商业框架。包括 php 的后台老板 zend，也推出自己的 Zend Framework。 2. php 从骨子里就是一个善于借鉴吸收的语言。 php 诞生伊始，是 perl 的跟班。后来 perl 跟班作得不爽了，就直接找到 perl 的老大 c 做跟班。这一作就是十几年。从最初跟 perl 学习，到后来跟  c 学习。然后 java 火了，跟  java 学习。再后来框架开发逐渐成为主流的时候，又开始搞有 [...]]]></description>
			<content:encoded><![CDATA[<p>这个其实是源于 javaeye 上的这个讨论：<a href="http://www.javaeye.com/post/886707">http://www.javaeye.com/post/886707</a>。最开始吸引我的是在 rails 板块上诸多专业玩 java 和 ruby 的人是如何评价 php 以及 php 框架的。在讨论中发现有一些值得学习和借鉴的地方。所以推荐大家完整阅读这个帖子。从技术性、知识面和娱乐性来讲，都是质量很高的。</p>
<p>我就简单说一下我对于 php 框架繁荣的看法：<span id="more-286"></span></p>
<p>1. “草根阶级”向“企业开发俱乐部”转变的必然途径。</p>
<p>用 php 的企业多了，市场占有率高了，经济效益就体现出来了。但是仅仅靠做做企业网站，搞搞论坛这个蛋糕还太小。同时 B2B、B2C 的繁荣，自然带来已有网站的改造问题。php 迈着坚定的步伐冲向“俱乐部”大门。但是门卫说了“贫民与狗不得入内”。于是 php 的规范化、可维护性发展如火如荼的展开了。首先是学习 java，从语言层面引入 java 的优点。然后是开发规范的建立，涌现出大批商业框架。包括 php 的后台老板 zend，也推出自己的 Zend Framework。</p>
<p>2. php 从骨子里就是一个善于借鉴吸收的语言。</p>
<p>php 诞生伊始，是 perl 的跟班。后来 perl 跟班作得不爽了，就直接找到 perl 的老大 c 做跟班。这一作就是十几年。从最初跟 perl 学习，到后来跟  c 学习。然后 java 火了，跟  java 学习。再后来框架开发逐渐成为主流的时候，又开始搞有 php 特色的框架主义。当然还是延续原有风格与方法，好的东西一并吸收。吸收不良了再做改造。</p>
<p>3. php 框架是为了让php应用更加简单出现的。</p>
<p>我在 2004 年的时候搞过自己的一个小框架，实际上是整合了大量 pear 包的功能，自己利用 call_user_func_array 函数作为路由解析。使用 smarty 作为前端脚本。虽然有很多不足，但是在给朋友开发的几个项目中，“简单”这个原则体现得非常好。在只有美工和系统管理员的情况下，对网站进行了多次改版。并不是框架让我的朋友快速的学会了 php，而是框架让跳出语言细节的开发成为了可能。php 由于其发展方式决定了没有一个统一的功能调用界面，各种明明方式、调用方式混杂在一起，许多“学院派”对此尤为诟病。但是框架从一个新的高度上统一了这些本不统一的调用。从而使得开发更加简单、快捷。</p>
<p>好吧，最后我再说说许多 javaer 和 rubier 极力想证明的：“php 唯一的好处就是轻快，在套上沉重的框架枷锁后，它将没有任何优势同 java 或者 ruby 竞争。”其实这个问题就像老廖永远打不完的口水仗一样（老廖别急，这里纯粹调节气氛），没有最终的答案。不过有几点可以探讨：</p>
<p>1. php 已经有极高的市场占有率。并且回头客户很多。</p>
<p>2. php 在大型网站的应用不在少数，虽然许多是改造过的 php。</p>
<p>3. 性能在硬件发展迅猛的今天已经不是当年 64K 内存 2MHz 计算能力需要精打细算的年代。有更多事情远比性能重要。曾经道听途说过一种说法“与其高新聘请一个高级人才来优化程序，节约几十万的硬件成本。不如多花点钱用好硬件，弥补程序的不足。”想想也对，人才是在所有开发中最不靠谱的因素。</p>
<p>最后，我想用一句说得已经有点烂的话结束这个讨论：“事物总是在它应该出现的地方出现，应该消失的地方消失。”</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/index.php/archives/286/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
