<?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>睡到25点 &#187; mogilefs</title>
	<atom:link href="http://www.voidman.com/tag/mogilefs/feed" rel="self" type="application/rss+xml" />
	<link>http://www.voidman.com</link>
	<description>个人博客，记录与分享，仅此而已。</description>
	<lastBuildDate>Fri, 30 Jul 2010 09:54:38 +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>在 Discuz 中应用 MogileFS 分布式文件存储系统</title>
		<link>http://www.voidman.com/2009/05/mogilefs-for-discuz.html</link>
		<comments>http://www.voidman.com/2009/05/mogilefs-for-discuz.html#comments</comments>
		<pubDate>Sun, 10 May 2009 06:38:51 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[discuz]]></category>
		<category><![CDATA[mogilefs]]></category>

		<guid isPermaLink="false">http://www.voidman.com/?p=286</guid>
		<description><![CDATA[本文讨论内容基于 Discuz 7, Red Hat Enterprise Linux AS 4, MogileFs Server 2.17, MogileFS Client 1.08, MogileFS Utils 2.14 MogileFS 安装和配置 安装 基本安装顺序是 mogilefs-server（服务端）， MogileFS-Client（客户端）， MogileFS-Utils（工具包）。安装 MogileFS 其实并不复杂，但有些耗时，因为大多数据时间都被用在安装依赖包上了。在安装 MogileFS 之前有几个包是必需的： Sys-Syscall-0.22.tar.gz Danga-Socket-1.56.tar.gz String-CRC32-1.4.tar.gz Gearman-1.07.tar.gz Gearman-Client-Async-0.93 Net-Netmask-1.9015.tar.tar Perlbal-1.70.tar.tar 若在安装过程中还提示其它包不存在，可以根据提示到search.cpan.org搜索相应的包装上。具体安装步骤可以参考这里或这里。 安装成功后，会提示安装了以下文件，在下文的 MogileF S配置部分中会提到。 /usr/bin/mogilefsd /usr/bin/mogstored /usr/bin/mogdbsetup /usr/bin/mogautomount /usr/bin/mogtool /usr/bin/mogadm 数据库配置 MogileFS 通过数据库来维护文件的存储节点和存储份数等相关属性。 创建一个数据库命名为 mogilefs，创建一个用户 mogile，设置密码为 mogile # mysql [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
本文讨论内容基于 Discuz 7, Red Hat Enterprise Linux AS 4, MogileFs Server 2.17, MogileFS Client 1.08, MogileFS Utils 2.14
</p></blockquote>
<h3>MogileFS 安装和配置</h3>
<p><strong>安装</strong><br />
基本安装顺序是 <a href="http://search.cpan.org/~bradfitz/mogilefs-server/">mogilefs-server</a>（服务端）， <a href="http://search.cpan.org/~bradfitz/MogileFS-Client-1.08/">MogileFS-Client</a>（客户端）， <a href="http://search.cpan.org/CPAN/authors/id/D/DO/DORMANDO/MogileFS-Utils-2.14.tar.gz">MogileFS-Utils</a>（工具包）。安装 MogileFS 其实并不复杂，但有些耗时，因为大多数据时间都被用在安装依赖包上了。在安装 MogileFS 之前有几个包是必需的：</p>

<div class="wp_syntax"><pre class="ini">Sys-Syscall<span style="">-0.22</span>.tar.gz
Danga-Socket<span style="">-1.56</span>.tar.gz
String-CRC32<span style="">-1.4</span>.tar.gz
Gearman<span style="">-1.07</span>.tar.gz
Gearman-Client-Async<span style="">-0.93</span>
Net-Netmask<span style="">-1.9015</span>.tar.tar 
Perlbal<span style="">-1.70</span>.tar.tar</pre></div>

<p>若在安装过程中还提示其它包不存在，可以根据提示到<a href="search.cpan.org">search.cpan.org</a>搜索相应的包装上。具体安装步骤可以参考<a href="http://mogilefs.pbworks.com/HowTo">这里</a>或<a href="http://durrett.net/mogilefs_setup.html">这里</a>。<br />
<span id="more-286"></span><br />
安装成功后，会提示安装了以下文件，在下文的 MogileF S配置部分中会提到。</p>

<div class="wp_syntax"><pre class="bash">/usr/bin/mogilefsd
/usr/bin/mogstored
/usr/bin/mogdbsetup
/usr/bin/mogautomount
/usr/bin/mogtool
/usr/bin/mogadm</pre></div>

<p><strong>数据库配置</strong><br />
MogileFS 通过数据库来维护文件的存储节点和存储份数等相关属性。 创建一个数据库命名为 mogilefs，创建一个用户 mogile，设置密码为 mogile</p>

<div class="wp_syntax"><pre class="mysql"><span style="color: #008200; font-style: italic;"># mysql</span>
mysql&gt; <span style="color: #0000FF; ">CREATE DATABASE</span> mogilefs;
mysql&gt; <span style="color: #0000FF; ">GRANT</span> ALL ON mogilefs.* TO <span style="color: #FF00FF;">'mogile'</span>@<span style="color: #FF00FF;">'%'</span>;
mysql&gt; <span style="color: #0000FF; ">SET</span> PASSWORD FOR <span style="color: #FF00FF;">'mogile'</span>@<span style="color: #FF00FF;">'%'</span> = PASSWORD<span style="color: #000;">&#40;</span><span style="color: #FF00FF;">'mogile'</span><span style="color: #000;">&#41;</span>;
mysql&gt; FLUSH <span style="color: #0000FF; ">PRIVILEGES</span>;
mysql&gt; quit</pre></div>

<p>然后通过 MogileFs 自带的工具创建表</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># /usr/bin/mogdbsetup --dbhost=db.yourdomain.com --dbname=mogilefs --dbuser=mogile --dbpassword=mogile</span></pre></div>

<p><strong>tracker 配置</strong><br />
编辑 /etc/mogilefs/mogilefsd.conf</p>

<div class="wp_syntax"><pre class="ini">db_dsn DBI:mysql:mogilefs
db_user mogile 
db_pass mogile 
conf_port <span style="">6001</span> 
listener_jobs <span style="">5</span></pre></div>

<p><strong>存储节点配置</strong></p>
<ul>
<li>
<p>先编辑配置文件 /etc/moiglefs/mogstored.conf</p>

<div class="wp_syntax"><pre class="ini"><span style="color: #000099;">httplisten</span>=<span style="color: #660066;"><span style="">192.168</span><span style="">.0</span><span style="">.7</span>:<span style="">7500</span> </span>
<span style="color: #000099;">mgmtlisten</span>=<span style="color: #660066;"><span style="">192.168</span><span style="">.0</span><span style="">.7</span>:<span style="">7501</span> </span>
<span style="color: #000099;">docroot</span>=<span style="color: #660066;">/var/mogdata</span></pre></div>

</li>
<li>
<p>向系统添加存储节点主机，并查看是否添加成功。这里我们添加的主机名称是 file.yourdomain.com，IP为192.168.0.7</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 host add file.yourdomain.com --ip=192.168.0.7 --port=7500 --status=alive</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 host list</span></pre></div>

</li>
<li>
<p>向系统添加存储节点设备，并查看是否添加成功</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># mkdir /var/mogdata/dev1</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 device add file.yourdomain.com 1</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 device list</span></pre></div>

<p>这里的 1 代表 file.yourdomain.com 主机下的存储设备编号，对应存储目录为 /var/mogdata/dev1</p>
</li>
<li>
<p>添加存储域。在 MogileFs 中，文件通过 KEY 来引用，KEY 在某个存储域下是唯一的。我们添加一个 bbs.yourdomain.com 域，论坛里的附件都存储到该域下。</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 domain add bbs.yourdomain.com</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 domain list</span></pre></div>

</li>
<li>
<p>添加存储类别。在 MogileFs 中可以设置不同的存储类别存储不同份数的文件副本。我们添加一个 attach 类，每个文件至少存储 2 份</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 class add bbs.yourdomain.com attach --mindevcount=2</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 class list</span></pre></div>

</li>
</ul>
<p>最后在防火墙配置上述几个端口访问规则。现在可以启动 MogileFs，并查看进程与服务状态。</p>

<div class="wp_syntax"><pre class="bash"><span style="color: #666666; font-style: italic;"># /usr/bin/mogstored --daemon</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogilefsd -c /etc/mogilefs/mogilefsd.conf --daemon</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># ps -fe |grep mogstored</span>
<span style="color: #666666; font-style: italic;"># ps -fe |grep mogilefsd</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 check</span>
<span style="color: #666666; font-style: italic;"># /usr/bin/mogadm --trackers=192.168.0.7:6001 stats</span></pre></div>

<p>注：上述配置例子基于tracker，存储节点均在同一台主机，而实际使用上需要将存储节点分配到不同主机上才是真正意义上的分布式存储。甚至于  tracker 也可以是多个。</p>
<h3>安装 MogileFS PHP 扩展</h3>
<p>从 <a href="http://svn.usrportage.de/php-mogilefs/trunk/">http://svn.usrportage.de/php-mogilefs/trunk/</a> 获取源代码编译安装：</p>

<div class="wp_syntax"><pre class="bash">$ phpize
$ ./configure
$ <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div>

<p>将生成的 php-mogilefs.so 复制到 PHP 扩展目录，在 php.ini 添加一行扩展配置：</p>

<div class="wp_syntax"><pre class="ini"><span style="color: #000099;">extension</span>=<span style="color: #660066;">php-mogilefs.so</span></pre></div>

<p>重启 WEB 服务，用 phpinfo() 函数测试，如果显示结果如下图显示则表示安装成功<br />
<a href="http://img.voidman.com/wp/2009/05/mogilefs.png"><img src="http://img.voidman.com/wp/2009/05/mogilefs.png" alt="mogilefs" title="mogilefs" width="541" height="104" class="grayborder alignnone size-full wp-image-289" /></a><br />
该扩展提供的<a href="http://svn.usrportage.de/php-mogilefs/trunk/README">方法和函数</a>可以直接使用，不过为了方便维护，可以对之进行一下简单的封装。</p>
<h3>改造 Discuz 的附件系统</h3>
<blockquote><p>
接下来会应用到 WordPress 的 Hook 机制，详见<a href="http://www.voidman.com/2009/05/using-wordpress-plugin-api-hack-discuz.html">WordPress 的 Hook 机制在 Discuz 二次开发中的应用</a>
</p></blockquote>
<p><strong>附件上传</strong></p>
<p>在 Discuz 7 中附件的上传由<code>include/post.func.php</code>文件里的<code>attach_upload()</code>函数处理，我们在其中增加将附件添加到 MogileFS 的处理。由于 Discuz 7 支持远程上传附件到 FTP，并且可以设置成只上传到远程 FTP，这会删除上传到 WEB 服务器的原始附件，所以要在这之前处理。</p>

<div class="wp_syntax"><pre class="php"><span style="color: #008000; font-style: italic;">// begin of hack</span>
dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_upload'</span>, <span style="color: #008080;">$attach</span>, <span style="color: #008080;">$target</span><span style="color: #800000;">&#41;</span>;
<span style="color: #008000; font-style: italic;">// end of hack</span>
&nbsp;
<span style="color: #008000; font-style: italic;">// 找到以下这行代码，在这之前添加以上代码</span>
<span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'remote'</span><span style="color: #800000;">&#93;</span> = !<span style="color: #008080;">$swfupload</span> ? ftpupload<span style="color: #800000;">&#40;</span><span style="color: #008080;">$target</span>, <span style="color: #008080;">$attach</span><span style="color: #800000;">&#41;</span> : <span style="color: #800080;">0</span>;</pre></div>

<p>mogilefs_attachment_upload 函数用来处理往 MoigleFs 添加附件。在前面提到，MogileFs 通过 KEY 来引用文件，我采用的 KEY 的规则是：</p>

<div class="wp_syntax"><pre class="ini">attach_<span style="">&#123;</span>attachment_md5<span style="">&#125;</span>_<span style="">&#123;</span>ext<span style="">&#125;</span>
attach_<span style="">&#123;</span>attachment_md5<span style="">&#125;</span>_thumb_jpg</pre></div>

<p>{md5} 是 Discuz 附件表 attachment 字段的 MD5 值，{ext} 是附件的扩展名。注意，Discuz 存储文件时会把部分可能不安全附件的后缀名更改为 attach。Discuz 中图片附件的缩略图均为 JPG 格式，所以 thumb_jpg 表示 JPG 格式缩略图的意思。</p>
<p>mogilefs_attachment_upload() 函数的处理流程:</p>
<ol>
<li>判断 MogileFs 扩展是否加载，否则退出处理</li>
<li>获取 MogileFs 单个操作实例</li>
<li>根据传入的附件信息（$target, $attach）生成 attach_key，然后往 MogileFs 提交文件</li>
<li>如果附件是图片，检查图片的缩略图是否存在，如果存在，则生成 thumb_key ，然后往 MogileFs 提交缩略图文件</li>
</ol>
<p><strong>附件删除</strong></p>
<p>Discuz 7 中附件文件的删除由<code>include/global.func.php</code>文件里的<code>dunlink()</code>函数处理，我们在该函数结束之前添加 MogileFs 的文件删除处理：</p>

<div class="wp_syntax"><pre class="php">dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_delete'</span>, <span style="color: #008080;">$filename</span>, <span style="color: #008080;">$havethumb</span><span style="color: #800000;">&#41;</span>;</pre></div>

<p>mogilefs_attachment_delete() 函数的处理流程:</p>
<ol>
<li>判断 MogileFs 扩展是否加载，否则退出处理</li>
<li>获取 MogileFs 单个操作实例</li>
<li>根据传入的附件路径 $filename 生成 attach_key，然后通过 MogileFs 提供的方法删除文件</li>
<li>根据 $havethumb 判断是否存在缩略图，若存在则生成 thumb_key，然后通过 MogileFs 提供的方法删除文件</li>
</ol>
<p>由于附件的上传中可能出现错误，Discuz 7 会做回滚处理删除本次上传出现错误之前已经正常上传的附件，而这些文件同样已经被上传到 MogileFs，故也要做删除处理：<br />
修改<code>include/post.func.php</code>文件里的<code>upload_error()</code>函数和<code>ftpupload_error()</code>：</p>

<div class="wp_syntax"><pre class="php"><span style="color: blue;">function</span> upload_error<span style="color: #800000;">&#40;</span><span style="color: #008080;">$message</span>, <span style="color: #008080;">$attacharray</span> = <span style="color: blue;">array</span><span style="color: #800000;">&#40;</span><span style="color: #800000;">&#41;</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
  <span style="color: blue;">if</span><span style="color: #800000;">&#40;</span>!<span style="color: blue;">empty</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$attacharray</span><span style="color: #800000;">&#41;</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
    <span style="color: blue;">foreach</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$attacharray</span> <span style="color: blue;">as</span> <span style="color: #008080;">$attach</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
      @<span style="color: #ff0000;">unlink</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$GLOBALS</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'attachdir'</span><span style="color: #800000;">&#93;</span>.<span style="color: #ff00ff;">'/'</span>.<span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'attachment'</span><span style="color: #800000;">&#93;</span><span style="color: #800000;">&#41;</span>;
      <span style="color: #008000; font-style: italic;">// begin of hack</span>
      dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_delete'</span>, <span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'attachment'</span><span style="color: #800000;">&#93;</span>, <span style="color: blue;">true</span><span style="color: #800000;">&#41;</span>;
      <span style="color: #008000; font-style: italic;">// end of hack</span>
    <span style="color: #800000;">&#125;</span>
  <span style="color: #800000;">&#125;</span>
  showmessage<span style="color: #800000;">&#40;</span><span style="color: #008080;">$message</span><span style="color: #800000;">&#41;</span>;
<span style="color: #800000;">&#125;</span>
&nbsp;
<span style="color: blue;">function</span> ftpupload_error<span style="color: #800000;">&#40;</span><span style="color: #008080;">$source</span>, <span style="color: #008080;">$attach</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
  @<span style="color: #ff0000;">unlink</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$source</span><span style="color: #800000;">&#41;</span>;
  <span style="color: blue;">if</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'thumb'</span><span style="color: #800000;">&#93;</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
    @<span style="color: #ff0000;">unlink</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$source</span>.<span style="color: #ff00ff;">'.thumb.jpg'</span><span style="color: #800000;">&#41;</span>;
  <span style="color: #800000;">&#125;</span>
  <span style="color: #008000; font-style: italic;">// begin of hack</span>
  dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_delete'</span>, <span style="color: #008080;">$source</span>, <span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'thumb'</span><span style="color: #800000;">&#93;</span><span style="color: #800000;">&#41;</span>;
  <span style="color: #008000; font-style: italic;">// end of hack</span>
  showmessage<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'post_attachment_remote_save_error'</span><span style="color: #800000;">&#41;</span>;
<span style="color: #800000;">&#125;</span></pre></div>

<p><strong>附件读取</strong><br />
附件的读取需要在 Discuz 后台打开“下载附件来路检查”选项，因为附件的读取操作是 hook 在<code>attachment.php</code>文件上的。</p>
<ul>
<li>
<p>缩略图处理</p>

<div class="wp_syntax"><pre class="php"><span style="color: #008000; font-style: italic;">// begin of hack</span>
dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_fetch'</span>, <span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'attachment'</span><span style="color: #800000;">&#93;</span>, <span style="color: blue;">true</span><span style="color: #800000;">&#41;</span>;
<span style="color: #008000; font-style: italic;">// end of hack</span>
&nbsp;
<span style="color: #008000; font-style: italic;">//找到下面这行代码，在此之前添加上述代码</span>
getlocalfile<span style="color: #800000;">&#40;</span><span style="color: #008080;">$attachdir</span>.<span style="color: #ff00ff;">'/'</span>.<span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'attachment'</span><span style="color: #800000;">&#93;</span>.<span style="color: #ff00ff;">'.thumb.jpg'</span><span style="color: #800000;">&#41;</span>;</pre></div>

</li>
<li>
<p>其他附件处理<br />
    先删除<code>attachment.php</code>中的以下代码</p>

<div class="wp_syntax"><pre class="php"><span style="color: blue;">if</span><span style="color: #800000;">&#40;</span>!<span style="color: #008080;">$attach</span><span style="color: #800000;">&#91;</span><span style="color: #ff00ff;">'remote'</span><span style="color: #800000;">&#93;</span> &amp;&amp; !<span style="color: #ff0000;">is_readable</span><span style="color: #800000;">&#40;</span><span style="color: #008080;">$filename</span><span style="color: #800000;">&#41;</span><span style="color: #800000;">&#41;</span> <span style="color: #800000;">&#123;</span>
  showmessage<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'attachment_nonexistence'</span><span style="color: #800000;">&#41;</span>;
<span style="color: #800000;">&#125;</span></pre></div>

<p>然后将以下代码添加到<code>getlocalfile()</code>函数的起始处，接管该函数读取本地附件的处理。</p>

<div class="wp_syntax"><pre class="php"><span style="color: #008000; font-style: italic;">// begin of hack</span>
dz_do_action<span style="color: #800000;">&#40;</span><span style="color: #ff00ff;">'mogilefs_attachment_fetch'</span>, <span style="color: #008080;">$filename</span><span style="color: #800000;">&#41;</span>;
<span style="color: #008000; font-style: italic;">// end of hack</span></pre></div>

</li>
</ul>
<p>mogilefs_attachment_fetch() 的处理流程</p>
<ol>
<li>判断 MogileFs 扩展是否加载，否则退出处理</li>
<li>获取 MogileFs 单个操作实例</li>
<li>根据传入参数判断读取的是缩略图还是原附件，生成 thumb_key 或 attach_key</li>
<li>通过 MogileFs 扩展提供的方法读取文件内容</li>
<li>输出</li>
</ol>
<p>当然，此外还有一些细节处理，如文件大小，文件头响应输出等，不再赘述。</p>
<h4>Related Posts</h4><ul class="related_post"><li><a href="http://www.voidman.com/2009/05/using-wordpress-plugin-api-hack-discuz.html" title="WordPress 的 Hook 机制在 Discuz 二次开发中的应用">WordPress 的 Hook 机制在 Discuz 二次开发中的应用</a></li></ul><hr /><a href="http://www.voidman.com">Voidman.com</a> | Link: <a href="http://www.voidman.com/2009/05/mogilefs-for-discuz.html">http://www.voidman.com/2009/05/mogilefs-for-discuz.html</a><br /><img alt="linezing" width="1" height="1" src="http://img.tongji.linezing.com/288120/tongji.gif" />]]></content:encoded>
			<wfw:commentRss>http://www.voidman.com/2009/05/mogilefs-for-discuz.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
