<?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>Fwolf's Blog &#187; PHP - Fwolf's Blog</title>
	<atom:link href="http://www.fwolf.com/blog/post/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fwolf.com/blog</link>
	<description>随心·随意·随缘·努力～</description>
	<lastBuildDate>Sun, 29 Aug 2010 14:52:23 +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>Curl奇怪的403错误</title>
		<link>http://www.fwolf.com/blog/post/444</link>
		<comments>http://www.fwolf.com/blog/post/444#comments</comments>
		<pubDate>Tue, 30 Jun 2009 17:27:33 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[403]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[tunnel]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/?p=444</guid>
		<description><![CDATA[自己用的小PHP应用，使用curl抓网页下来处理，为了穿墙方便，使用Privoxy作为代理，便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题，访问google baidu这些网站居然都返回403错误，而访问其他的一些网站没事，如果设置为不使用proxy则都能正常访问。 难道google baidu就不让用proxy连接么？显然不可能，所以打开curl的信息输出（curl_setopt($this-&#62;mSh, CURLOPT_VERBOSE, 1);）看看，得到以下结果： * Trying 127.0.0.1... * connected * Connected to 127.0.0.1 (127.0.0.1) port 8118 (#0) * Establish HTTP proxy tunnel to www.baidu.com:80 &#62; CONNECT www.baidu.com:80 HTTP/1.0 Host: www.baidu.com:80 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Proxy-Connection: Keep-Alive &#60; HTTP/1.0 403 Connection not allowable &#60; X-Hint: If you read this [...]]]></description>
			<content:encoded><![CDATA[<p>自己用的小PHP应用，使用curl抓网页下来处理，为了穿墙方便，使用Privoxy作为代理，便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题，访问google baidu这些网站居然都返回403错误，而访问其他的一些网站没事，如果设置为不使用proxy则都能正常访问。</p>

<p>难道google baidu就不让用proxy连接么？显然不可能，所以打开curl的信息输出（<code>curl_setopt($this-&gt;mSh, CURLOPT_VERBOSE, 1);</code>）看看，得到以下结果：</p>

<pre><code>*   Trying 127.0.0.1... * connected
* Connected to 127.0.0.1 (127.0.0.1) port 8118 (#0)
* Establish HTTP proxy tunnel to www.baidu.com:80
&gt; CONNECT www.baidu.com:80 HTTP/1.0
Host: www.baidu.com:80
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Proxy-Connection: Keep-Alive

&lt; HTTP/1.0 403 Connection not allowable
&lt; X-Hint: If you read this message interactively, then you know why this happens ,-)
&lt; 
* The requested URL returned error: 403
* Received HTTP code 403 from proxy after CONNECT
* Closing connection #0
... Failed.
</code></pre>

<p>可以看到proxy服务器工作正常，的确是baidu返回了403错误，但原因肯定还在我这边。终于，从网上（<a href="http://curl.haxx.se/mail/archive-2006-04/0054.html">1of2</a>, <a href="http://curl.haxx.se/mail/archive-2006-04/0055.html">2of2</a>）得到了点启发──我使用的是proxytunnel而非proxy。</p>

<p>在代码中，有这么一句：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mSh</span><span style="color: #339933;">,</span> CURLOPT_HTTPPROXYTUNNEL<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">mSh</span><span style="color: #339933;">,</span> CURLOPT_PROXY<span style="color: #339933;">,</span> <span style="color: #000088;">$phost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>php文档中没有详细说明，不过<code>man curl</code>中有详细解释，两者都是代理，proxytunnel（<code>-p参数</code>）允许其他协议通过http代理传输，而proxy（<code>-x参数</code>）则只能走http协议。所以我猜测，google baidu的服务器和curl的proxytunnel不和，所以返回403。</p>

<p>禁用掉上面2行代码的第一句后，curl访问恢复正常。</p>

<p>比较奇怪的是，几种操作系统下还不一样，一台MAC OSX就要显式的禁用proxytunnel才可以，curl版本：</p>

<pre><code>$ curl --version
curl 7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Protocols: tftp ftp telnet dict ldap http file https ftps 
Features: GSS-Negotiate IPv6 Largefile NTLM SSL libz 
</code></pre>

<p>而另外一台ubuntu则完全不受影响，怎么都能用，curl版本：</p>

<pre><code>$ curl --version
curl 7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.10
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz 
</code></pre>

<p>MT主机上的centos也没事，curl版本：</p>

<pre><code>$ curl --version
curl 7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
Protocols: tftp ftp telnet dict ldap http file https ftps 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz 
</code></pre>

<p>看来不完全是curl版本问题，MAC OSX的确与众不同啊。</p>

<p>还有一个原因也会导致curl返回403错误，如果设置了：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_NOBODY<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</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: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_CUSTOMREQUEST<span style="color: #339933;">,</span> <span style="color: #0000ff;">'GET'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>不然会因为http服务器不允许 HEAD 命令而返回403错误。参考：<a href="http://forums.devshed.com/php-development-5/trouble-with-a-curl-request-in-php-445222.html">Trouble with a cURL request in PHP</a>。MAC OSX上curl之所以特殊，也不排除是这种原因吧。</p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/403" title="403" rel="tag">403</a>, <a href="http://www.fwolf.com/blog/post/tag/curl" title="curl" rel="tag">curl</a>, <a href="http://www.fwolf.com/blog/post/tag/error" title="error" rel="tag">error</a>, <a href="http://www.fwolf.com/blog/post/tag/http" title="http" rel="tag">http</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/proxy" title="proxy" rel="tag">proxy</a>, <a href="http://www.fwolf.com/blog/post/tag/tunnel" title="tunnel" rel="tag">tunnel</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/411" title="由一个错误学到的一些php安全配置问题 (2008-07-13)">由一个错误学到的一些php安全配置问题</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/391" title="adodb5连接sybase的一个错误 (2008-03-25)">adodb5连接sybase的一个错误</a> (0)</li>
	<li><a href="http://www.fwolf.com/blog/post/300" title="针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (2007-03-18)">针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS）</a> (3)</li>
	<li><a href="http://www.fwolf.com/blog/post/443" title="配置安全的共享web服务器（抛砖引玉） (2009-06-09)">配置安全的共享web服务器（抛砖引玉）</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/400" title="选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (2008-05-03)">选择Eclipse PHP Development Tools(PDT)作为PHP开发工具</a> (8)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/444/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>配置安全的共享web服务器（抛砖引玉）</title>
		<link>http://www.fwolf.com/blog/post/443</link>
		<comments>http://www.fwolf.com/blog/post/443#comments</comments>
		<pubDate>Tue, 09 Jun 2009 10:26:35 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[safe]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sftp]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/?p=443</guid>
		<description><![CDATA[本文所讲的共享web服务器，并非共享文件的服务器，而是多人一起使用的web服务器，各有各自的网站、管理自己的文件，互不干涉，且对系统无影响。鉴于功力较浅，只敢对较信得过的朋友开放这种账号，本文涉及的范围也有限，所以安全漏洞可能还有，请诸位切勿直接用于生产环境。 服务器环境：Ubuntu 8.10, OpenSSH_5.1p1 Debian-3ubuntu1, Apache 2.2.9, PHP 5.2.6-2ubuntu4 登录 &#8211; SFTP 传统的 FTP 肯定是不如这个安全，telnet 更不用说了。使用 SFTP 还有一个起始想法是想配置证书自动登录，后来发现 SFTP 客户端（FileZilla）没这功能，就没再作下去，命令行下 scp 的自动登录倒是 和 ssh 的一样很好配置。 网上很多文章介绍把 sftp 用户限制在 $HOME 目录下的方法，使用的是 sshd 的 ChrootGroups 选项，这个选项在我的版本里没有找到，找到另外一篇参考文章使用的是 ChrootDirectory，也很好用。 创建一个用户组，作为所有 sftp 用户的用户组： $ sudo groupadd sftp 创建用户，设置密码，并归入 sftp 组： $ sudo useradd -m friend $ sudo passwd friend $ [...]]]></description>
			<content:encoded><![CDATA[<p>本文所讲的共享web服务器，并非共享文件的服务器，而是多人一起使用的web服务器，各有各自的网站、管理自己的文件，互不干涉，且对系统无影响。鉴于功力较浅，只敢对较信得过的朋友开放这种账号，本文涉及的范围也有限，所以安全漏洞可能还有，请诸位切勿直接用于生产环境。</p>

<p>服务器环境：Ubuntu 8.10, OpenSSH_5.1p1 Debian-3ubuntu1, Apache 2.2.9, PHP 5.2.6-2ubuntu4</p>

<h3>登录 &#8211; SFTP</h3>

<p>传统的 FTP 肯定是不如这个安全，telnet 更不用说了。使用 SFTP 还有一个起始想法是想配置证书自动登录，后来发现 SFTP 客户端（FileZilla）没这功能，就没再作下去，命令行下 scp 的自动登录倒是 和<a href="279"> ssh 的</a>一样很好配置。</p>

<p>网上很多文章介绍把 sftp 用户限制在 <code>$HOME</code> 目录下的方法，使用的是 sshd 的 ChrootGroups 选项，这个选项在我的版本里没有找到，找到<a href="http://shapeshed.com/journal/chroot_sftp_users_on_ubuntu_intrepid/">另外一篇参考文章</a>使用的是 ChrootDirectory，也很好用。</p>

<p>创建一个用户组，作为所有 sftp 用户的用户组：</p>

<pre><code>$ sudo groupadd sftp
</code></pre>

<p>创建用户，设置密码，并归入 sftp 组：</p>

<pre><code>$ sudo useradd -m friend
$ sudo passwd friend
$ sudo usermod -g sftp friend
</code></pre>

<p>为了进一步增强安全性，还可以将用户的登录 shell 设置为 <code>/bin/false</code>，是个好习惯，但在本例中并非必须，下面的 sshd 设置也会让用户无法登录 shell （我观察的结果）。</p>

<pre><code>$ sudo usermod -s /bin/false friend
</code></pre>

<p>下来就要配置 sshd 了，编辑配置文件 <code>/etc/ssh/sshd_config</code>：</p>

<pre><code># 修改下面这句
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
</code></pre>

<p>然后在此配置文件末尾添加：</p>

<pre><code>Match group sftp
    X11Forwarding no
    ChrootDirectory %h
    AllowTcpForwarding no
    ForceCommand internal-sftp
</code></pre>

<p>配置含义大概为：凡是 sftp 组的用户，关闭 X 转发，chroot 到 <code>$HOME</code> 目录，关闭 TCP 转发（无法使用隧道了？），强制使用 internal-sftp（这个不明白）。</p>

<p>现在，重启 ssh 服务，用户就只能通过 sftp 访问 <code>/home/friend</code> 下的文件了。</p>

<p>PS: 我发现 sshd 如果配置错误，在 restart 服务的时候会先检查，而不是直接 stop 服务然后在 start 的时候出现错误，搞得服务启不来。大概是考虑到很多人都是远程 ssh 上来进行维护，服务 down 了以后就麻烦了，很贴心的设置。</p>

<h3>Apache &amp; PHP</h3>

<p>Apache 配置简单，创建 <code>/home/friend/www</code> 目录，约定网站文件都放在这个目录下，然后弄个 Alias 指向就可以了。</p>

<p>但有一个极大的安全隐患需要堵上，用户可以通过编写 PHP 程序，读取系统中任何 www-data 用户有权限访问的文件，包括系统的 shadow 文件，包括 其它用户的网站文件等等。解决这个问题，一种是开启 PHP 的 safe_mode ，安全模式下 PHP 将只能访问 owner 为自己（也就是 www-data）的文件；另外一种是使用 <a href="http://cn2.php.net/manual/en/ini.sect.safe-mode.php">open_basedir</a>，这将限制 PHP 只能打开某一目录树下的文件，并且不可能通过符号链接避开此限制。显然 safe_mode 的副作用太多，后一种方法更适合我的这种情况，配置写到 Apache 的 conf 里就行了：</p>

<pre><code>&lt;Directory /home/friend&gt;
    php_admin_value open_basedir "/home/friend/"
&lt;/Directory&gt;
</code></pre>

<p>注意open_basedir 后面的参数只代表文件路径的前缀，所以要带上末尾的斜杠，明确指出是目录。</p>

<p>不使用 safe_mode 的另外一个原因是在未来的 PHP6 里就要删掉它了。</p>

<h3>缺点</h3>

<p>最大的缺点就是 sftp 用户无法自己更改密码，除非自己写个守护程序啥的。这个程序在写的时候要非常小心，因为操作的是系统用户文件，如果遗留有安全漏洞可能会使别人获得其它用户权限。一个折中的方法是写个程序，定期更改密码并通过邮件告知用户，虽不方便但安全性要好一些。</p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/apache" title="Apache" rel="tag">Apache</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/safe" title="safe" rel="tag">safe</a>, <a href="http://www.fwolf.com/blog/post/tag/security" title="security" rel="tag">security</a>, <a href="http://www.fwolf.com/blog/post/tag/sftp" title="sftp" rel="tag">sftp</a>, <a href="http://www.fwolf.com/blog/post/tag/ssh" title="ssh" rel="tag">ssh</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/411" title="由一个错误学到的一些php安全配置问题 (2008-07-13)">由一个错误学到的一些php安全配置问题</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/300" title="针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (2007-03-18)">针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS）</a> (3)</li>
	<li><a href="http://www.fwolf.com/blog/post/347" title="升级MT dv 3.0主机到php5 (2007-08-09)">升级MT dv 3.0主机到php5</a> (9)</li>
	<li><a href="http://www.fwolf.com/blog/post/127" title="利用SVN更新网站 (2006-01-19)">利用SVN更新网站</a> (7)</li>
	<li><a href="http://www.fwolf.com/blog/post/395" title="防止垃圾评论的另类方法 (2008-04-10)">防止垃圾评论的另类方法</a> (6)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/443/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>小巧的编辑器Geany</title>
		<link>http://www.fwolf.com/blog/post/439</link>
		<comments>http://www.fwolf.com/blog/post/439#comments</comments>
		<pubDate>Mon, 20 Apr 2009 11:05:20 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[geany]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/439</guid>
		<description><![CDATA[我对PHP编辑器的要求不高，不过很多软件却不合我意： 首先，最好是免费的，所以挺好用的Zend Studio落选了。并且我发现似乎Zend Studio与ibus或者ubuntu jaunty有点冲突，有时候中文就出不来了。 其次，小巧，java的最好不要，所以Eclipse也落选了。 最后，最小功能集：语法高亮（废话）以及类函数列表（可以帮助我快速定位）。就这两项功能，淘汰了gedit（支持得不好）、vim（无法列出类函数）等工具。 当然，隐含要求，支持中文输入法，所以gphpedit也不能用，正好也不喜欢它的颜色高亮模式（色彩搭配）。 所以，选来选去，今天才算碰到一个比较满意的────Geany，ubuntu源中有，目前版本0.14，看来开发历史并不长。使用gtk2，操作流畅。除了类函数列表以外，还有一些贴心的小功能，比如自动补齐文件末尾的空行、保存时自动删除行尾空格等。 默认的，Geany的快捷键Complete Word与中文输入法冲突，还好，可以通过设置删掉：双击--&#62;Del--&#62;回车。 可怜的gphpedit也是这种快捷键冲突，不过我没找到设置方法。 其实Geany不仅能够处理PHP文件，还能够编辑多种脚本文件，新建文件时有内置模板可选，能够自动生成文件头的copyright及GPL声明。 总之，到目前的感觉，挺好用的。 Update @ 2009-12-29 ubuntu 中 geany 的版本更新较慢，喜欢追新的可以自行添加它的 PPA源。 Tags: editor, geany, gtk, PHP, Tools Related posts 选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (8) 针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (3) 配置安全的共享web服务器（抛砖引玉） (4) 让phpmailer支持中文名称的附件 (5) 终于能够通过phpmailer使用gmail账号发送邮件了 (50)]]></description>
			<content:encoded><![CDATA[<p>我对PHP编辑器的要求不高，不过很多软件却不合我意：</p>

<p>首先，最好是免费的，所以挺好用的Zend Studio落选了。并且我发现似乎Zend Studio与ibus或者ubuntu jaunty有点冲突，有时候中文就出不来了。</p>

<p>其次，小巧，java的最好不要，所以Eclipse也落选了。</p>

<p>最后，最小功能集：语法高亮（废话）以及类函数列表（可以帮助我快速定位）。就这两项功能，淘汰了gedit（支持得不好）、vim（无法列出类函数）等工具。</p>

<p>当然，隐含要求，支持中文输入法，所以gphpedit也不能用，正好也不喜欢它的颜色高亮模式（色彩搭配）。</p>

<p>所以，选来选去，今天才算碰到一个比较满意的────<a href="http://www.geany.org/">Geany</a>，ubuntu源中有，目前版本0.14，看来开发历史并不长。使用gtk2，操作流畅。除了类函数列表以外，还有一些贴心的小功能，比如自动补齐文件末尾的空行、保存时自动删除行尾空格等。</p>

<p><a href="http://www.flickr.com/photos/fwolf/3458410611/" title="geany screenshot by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3577/3458410611_da81400fef_m.jpg" width="240" height="204" alt="geany screenshot" /></a></p>

<p>默认的，Geany的快捷键<code>Complete Word</code>与中文输入法冲突，还好，可以通过设置删掉：<code>双击--&gt;Del--&gt;回车</code>。</p>

<p><a href="http://www.flickr.com/photos/fwolf/3458399643/" title="geany-solve-conflict-with-input-method by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3645/3458399643_e4b4ac046e_m.jpg" width="240" height="234" alt="geany-solve-conflict-with-input-method" /></a></p>

<p>可怜的gphpedit也是这种快捷键冲突，不过我没找到设置方法。</p>

<p>其实Geany不仅能够处理PHP文件，还能够编辑多种脚本文件，新建文件时有内置模板可选，能够自动生成文件头的copyright及GPL声明。</p>

<p>总之，到目前的感觉，挺好用的。</p>

<h4>Update @ 2009-12-29</h4>

<p>ubuntu 中 geany 的版本更新较慢，喜欢追新的可以自行添加它的 <a href="https://launchpad.net/~geany-dev/+archive/ppa">PPA源</a>。</p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/editor" title="editor" rel="tag">editor</a>, <a href="http://www.fwolf.com/blog/post/tag/geany" title="geany" rel="tag">geany</a>, <a href="http://www.fwolf.com/blog/post/tag/gtk" title="gtk" rel="tag">gtk</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/tools" title="Tools" rel="tag">Tools</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/400" title="选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (2008-05-03)">选择Eclipse PHP Development Tools(PDT)作为PHP开发工具</a> (8)</li>
	<li><a href="http://www.fwolf.com/blog/post/300" title="针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (2007-03-18)">针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS）</a> (3)</li>
	<li><a href="http://www.fwolf.com/blog/post/443" title="配置安全的共享web服务器（抛砖引玉） (2009-06-09)">配置安全的共享web服务器（抛砖引玉）</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/176" title="让phpmailer支持中文名称的附件 (2006-05-23)">让phpmailer支持中文名称的附件</a> (5)</li>
	<li><a href="http://www.fwolf.com/blog/post/155" title="终于能够通过phpmailer使用gmail账号发送邮件了 (2006-04-14)">终于能够通过phpmailer使用gmail账号发送邮件了</a> (50)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/439/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>在GLPI中输出中文PDF文件</title>
		<link>http://www.fwolf.com/blog/post/434</link>
		<comments>http://www.fwolf.com/blog/post/434#comments</comments>
		<pubDate>Wed, 01 Apr 2009 17:19:00 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[ezpdf]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[GLPI]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[TCPDF]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/434</guid>
		<description><![CDATA[PDF，好东西，就是麻烦，以前鼓捣ThingkingRock的时候打过交道，感觉挺复杂，现在捣鼓GLPI时又遇到了，GLPI用的是ezpdf。 先说点闲话，有些比较偏门的东西是真难找啊，比如今天要说的，算不上是学术问题，也没有企业级的支持（如果你愿意打电话咨询GLPI官方又懂法语我没话说），只能在网上大海捞针的找，一方面这是很辛苦的，查阅各类资料几十篇（前提还是你得能找到），写下来也就寥寥百余字，所以我一般愿意把我翻到的资料列在后面作为参考，或许能为别人省点力气；另一方面就是搜索引擎的功劳了，记得还没有google和百度的时候，只有一个yahoo分类目录，要搜问题就得到几个大型论坛比如CSDN里去翻，信息量就窄多了，另外搜索引擎的质量在这里也起到了很大的作用，信息重复率高不高、能否最快速度找到原创内容、信息关联度、是否有用等因素都关系到用户花费时间的多少，这也是我很少用百度的原因之一，还有就是感觉百度的英文资料差太多了。────谨以此纪念我几乎24小时的连续工作以及疲惫的眼睛和脖子。 EZPDF EZPDF一般是不支持unicode多字节编码的，不过还是作了一些尝试，毕竟是GLPI内置的，搞定了用着方便。首先EZPDF使用afm字体，要得到afm字体，需要用到ttf2tex，在pdfTeX包里： $ aptitude install ttf2tex 转换字体，这次我不用宋体了，用于打印的，还是仿宋看着舒服，用了个方正仿宋简体： $ ttf2afm -e T1-WGL4.enc -o fzfangsong.afm fzfangsong.TTF 试了试不能用，然后用afm2font处理： $ php5 afm2font.php fzfangsong 得到php_fzfangsong.font等文件，但这些文件无论怎么套上ezpdf都是不行，什么文字都没了，pdf文件中倒是显示了正确的字体名： fzfangsong Type1 Not embedded 再在网上翻资料，简直就是钻到TeX用户堆儿里去了，忽然发现windows字体应该是TrueType字体，而ezpdf使用的难道是Type1字体，两者之间还需要转换？终于查到基于texlive2008的中文绿色免安装tex系统中有打包的字体，这里面有给TeX用的Type1字体，就是大了点，“dottexlive2008.tar.bz2 仅包含全部字体包和相关宏包”一共是685M，拉下来，好在网速还算很快。把里面的afm字体单独解压出来： $ tar xjvf /big1/dottexlive2008.tar.bz2 .texlive2008/texmf-var/fonts/afm/ $ cd .texlive2008/texmf-var/fonts/afm/cjk/gbkfs $ cat gbkfs??.afm &#62; gbkfs.afm 拿这个gbkfs.afm配置到ezpdf里，能打出字来了，但中文还是问号，估计是因为数据是utf-8编码，而字体是gbk编码的？修改class.ezpdf.php，在function ezProcessText的第一行加上（参考：ezpdf打印德文的处理）： $text = mb_convert_encoding&#40;$text, 'gbk', 'utf-8'&#41;; 还是问号，难道字体要嵌入pdf才行？ 结果又查到一篇Choosing a PHP PDF generation library [...]]]></description>
			<content:encoded><![CDATA[<p>PDF，好东西，就是麻烦，以前<a href="419">鼓捣ThingkingRock</a>的时候打过交道，感觉挺复杂，现在捣鼓GLPI时又遇到了，GLPI用的是ezpdf。</p>

<p>先说点闲话，有些比较偏门的东西是真难找啊，比如今天要说的，算不上是学术问题，也没有企业级的支持（如果你愿意打电话咨询GLPI官方又懂法语我没话说），只能在网上大海捞针的找，一方面这是很辛苦的，查阅各类资料几十篇（前提还是你得能找到），写下来也就寥寥百余字，所以我一般愿意把我翻到的资料列在后面作为参考，或许能为别人省点力气；另一方面就是搜索引擎的功劳了，记得还没有google和百度的时候，只有一个yahoo分类目录，要搜问题就得到几个大型论坛比如CSDN里去翻，信息量就窄多了，另外搜索引擎的质量在这里也起到了很大的作用，信息重复率高不高、能否最快速度找到原创内容、信息关联度、是否有用等因素都关系到用户花费时间的多少，这也是我很少用百度的原因之一，还有就是感觉百度的英文资料差太多了。────谨以此纪念我几乎24小时的连续工作以及疲惫的眼睛和脖子。</p>

<h2>EZPDF</h2>

<p>EZPDF一般是不支持unicode多字节编码的，不过还是作了一些尝试，毕竟是GLPI内置的，搞定了用着方便。首先EZPDF使用afm字体，要得到afm字体，需要用到ttf2tex，在<a href="http://www.tug.org/applications/pdftex/">pdfTeX包</a>里：</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	$ <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> ttf2tex</pre></div></div>


<p>转换字体，这次我不用宋体了，用于打印的，还是仿宋看着舒服，用了个方正仿宋简体：</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	$ ttf2afm <span style="color: #660033;">-e</span> T1-WGL4.enc <span style="color: #660033;">-o</span> fzfangsong.afm fzfangsong.TTF</pre></div></div>


<p>试了试不能用，然后用<a href="http://ez.no/developer/contribs/hacks/afm2font__1">afm2font</a>处理：</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	$ php5 afm2font.php fzfangsong</pre></div></div>


<p>得到php_fzfangsong.font等文件，但这些文件无论怎么套上ezpdf都是不行，什么文字都没了，pdf文件中倒是显示了正确的字体名：</p>

<pre><code>fzfangsong
Type1
Not embedded
</code></pre>

<p>再在网上翻资料，简直就是钻到TeX用户堆儿里去了，忽然发现windows字体应该是TrueType字体，而ezpdf使用的难道是Type1字体，两者之间还需要转换？终于查到<a href="http://thinfilm.ustc.edu.cn/~liangzi/software/CTeXlive/">基于texlive2008的中文绿色免安装tex系统</a>中有打包的字体，这里面有给TeX用的Type1字体，就是大了点，“dottexlive2008.tar.bz2 仅包含全部字体包和相关宏包”一共是685M，拉下来，好在网速还算很快。把里面的afm字体单独解压出来：</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xjvf <span style="color: #000000; font-weight: bold;">/</span>big1<span style="color: #000000; font-weight: bold;">/</span>dottexlive2008.tar.bz2 .texlive2008<span style="color: #000000; font-weight: bold;">/</span>texmf-var<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>afm<span style="color: #000000; font-weight: bold;">/</span>
	$ <span style="color: #7a0874; font-weight: bold;">cd</span> .texlive2008<span style="color: #000000; font-weight: bold;">/</span>texmf-var<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>afm<span style="color: #000000; font-weight: bold;">/</span>cjk<span style="color: #000000; font-weight: bold;">/</span>gbkfs
	$ <span style="color: #c20cb9; font-weight: bold;">cat</span> gbkfs??.afm <span style="color: #000000; font-weight: bold;">&gt;</span> gbkfs.afm</pre></div></div>


<p>拿这个gbkfs.afm配置到ezpdf里，能打出字来了，但中文还是问号，估计是因为数据是utf-8编码，而字体是gbk编码的？修改<code>class.ezpdf.php</code>，在<code>function ezProcessText</code>的第一行加上（参考：<a href="http://issues.ez.no/6574">ezpdf打印德文的处理</a>）：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mb_convert_encoding</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gbk'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>还是问号，难道字体要嵌入pdf才行？</p>

<p>结果又查到一篇<a href="http://dokeoslead.wordpress.com/2007/12/28/choosing-a-php-pdf-generation-library-for-dokeos/">Choosing a PHP PDF generation library for Dokeos</a>，说ezpdf根本、确实、100%就不支持utf-8编码，合着白折腾了。</p>

<p>到<a href="http://www.ros.co.nz/pdf/">ezpdf官网</a>确认一下，最近的新闻是<code>17 June 2006</code>的，比上面那篇文章还晚，看来ezpdf确实是没法用了。用tcpdf吧，不过在<a href="https://dev.indepnet.net/glpi/roadmap">glpi的roadmap</a>里，<a href="https://dev.indepnet.net/glpi/ticket/712">换上tcpdf</a>是要在0.80实现的，前面还有100+ ticket没完成，也是遥遥无期啊，只好自己动手，丰衣足食了。</p>

<h2>TCPDF</h2>

<p>从官网下载<a href="http://www.tcpdf.org/">tcpdf</a>放到php的include路径下，对照<a href="http://www.tecnick.com/public/code/cp_dpage.php?aiocp_dp=tcpdf_fonts">字体设置方法</a>来准备字体：</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	$ <span style="color: #7a0874; font-weight: bold;">cd</span> tcpdf<span style="color: #000000; font-weight: bold;">/</span>fonts
	<span style="color: #666666; font-style: italic;"># Simsun字体好像还不是truetype（嵌入了点阵字体），转换有些问题，先拿方正字体来用，正好方正仿宋简体打印用更好看</span>
	<span style="color: #666666; font-style: italic;">#$ ln -s /big2/fonts/xpfonts/simsun.ttf</span>
	<span style="color: #666666; font-style: italic;"># 注意文件名转为小写</span>
	$ <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>big2<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>fzfont<span style="color: #000000; font-weight: bold;">/</span>fzfangsong.TTF fzfangsong.ttf
	$ utils<span style="color: #000000; font-weight: bold;">/</span>ttf2ufm <span style="color: #660033;">-a</span> <span style="color: #660033;">-F</span> fzfangsong.ttf 
	<span style="color: #666666; font-style: italic;"># 生成了3个新文件</span>
	$ <span style="color: #c20cb9; font-weight: bold;">ls</span>
	fzfangsong.ufm fzfangsong.t1a fzfangsong.afm	
	<span style="color: #666666; font-style: italic;"># 我选的这个方正字体应该是TrueTypeUnicode字体，用TrueType转的不显字</span>
	<span style="color: #666666; font-style: italic;"># 文中有说明，在ttf ufm后面还可以跟参数，这里的false代表不将字体嵌入PDF文档，</span>
	<span style="color: #666666; font-style: italic;"># 那样会使pdf文件大小增大为自身+字体文件大小，很恐怖的</span>
	$ php5 <span style="color: #660033;">-q</span> utils<span style="color: #000000; font-weight: bold;">/</span>makefont.php fzfangsong.ttf fzfangsong.ufm <span style="color: #c20cb9; font-weight: bold;">false</span>
	<span style="color: #666666; font-style: italic;"># 生成可用的文件了</span>
	<span style="color: #007800;">$ls</span>
	fzfangsong.z fzfangsong.php</pre></div></div>


<p>现在弄个简单的例子，能够用tcpdf输出pdf文件了，里面要有这么一句：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFont</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fzfangsong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>现在文件尺寸还是太大，因为字体依然是全嵌入的（如果是embedded subset更好，不过TCPDF现在还做不到）。按照那篇文章修改fzfangsong.php文件：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;">//$type='TrueTypeUnicode';</span>
	<span style="color: #000088;">$type</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'cidfont0'</span><span style="color: #339933;">;</span>
	<span style="color: #339933;">...</span>
	<span style="color: #666666; font-style: italic;">//$dw=600;</span>
	<span style="color: #000088;">$dw</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1000</span><span style="color: #339933;">;</span>
	<span style="color: #339933;">...</span>
	<span style="color: #666666; font-style: italic;">//$enc='';</span>
	<span style="color: #000088;">$diff</span><span style="color: #339933;">=</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">//$file='fzfangsong.z';</span>
	<span style="color: #666666; font-style: italic;">//$ctg='fzfangsong.ctg.z';</span>
	<span style="color: #000088;">$originalsize</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">3548232</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Chinese Simplified</span>
	<span style="color: #000088;">$enc</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'UniGB-UTF16-H'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$cidinfo</span><span style="color: #339933;">=</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Registry'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Adobe'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Ordering'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'GB1'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Supplement'</span><span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/uni2cid_ag15.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>现在生成的pdf文件尺寸倒是很小了，但用eivnce看文字全部是空白，这是在Linux下看，跑到windows下看正常，而且完美，gb和big5编码都能显示。又用其它一些字体试了试，都是windows正常但linux下看不了，应该是刚才作的步骤正确，但与平台配合起来还欠点什么。</p>

<p>仔细对比了上面生成的两种pdf文件，以及另外一个用openoffice.org生成的pdf文件（这个应该比较标准吧），发现还是openoffice.org生成的文件又小、效果又好，用的是“已嵌入子集/embedded subset”方式，</p>

<p>最终查到，我基本上已经作好了，问题出在evince身上，安装<code>poppler-data</code>包（evince用这个来处理中文）后，完美解决，字体为非嵌入not embedded方式。生成的pdf文件非常小，用windows和evince浏览也都正常。混合gb2312和big5编码的内容也没问题：evince下中文出西欧字符不出，windows下Adobe Reader只出gb2312的字，Foxit Reader全部中文和西欧字符完美。而在全内嵌字体的情况下，用evince查看big5字符都是小黑块。</p>

<h2>hack GLPI</h2>

<p>接下来是大工程，把ezpdf换成tcpdf。修改<code>inc/export.function.php</code>的<code>function displaySearchFooter</code>函数，把<code>case PDF_OUTPUT_LANDSCAPE</code>和<code>case PDF_OUTPUT_PORTRAIT</code>两部分的内容都换成TCPDF的处理，源数据还借用原来的<code>$PDF_HEADER</code>,<code>$PDF_ARRAY</code>。除了纸张参数不一样，两部分的处理是相同的，下面是一个简单的例子：</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;">// --------</span>
	<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tcpdf/tcpdf.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$PDF_HEADER</span><span style="color: #339933;">,</span><span style="color: #000088;">$PDF_ARRAY</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// create new PDF document</span>
	<span style="color: #000088;">$pdf</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TCPDF<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'L'</span><span style="color: #339933;">,</span> PDF_UNIT<span style="color: #339933;">,</span> PDF_PAGE_FORMAT<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'UTF-8'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
	<span style="color: #666666; font-style: italic;">// set document information</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetCreator</span><span style="color: #009900;">&#40;</span>PDF_CREATOR<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetAuthor</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Fwolf'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetTitle</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$title</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetSubject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'GLPI Export'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetKeywords</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'TCPDF, PDF, GLPI, export, fwolf, work, asset'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// set header and footer fonts</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeaderFont</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>PDF_FONT_NAME_MAIN<span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> PDF_FONT_SIZE_MAIN<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFooterFont</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>PDF_FONT_NAME_DATA<span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> PDF_FONT_SIZE_DATA<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// remove default header/footer</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPrintHeader</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPrintFooter</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
	<span style="color: #666666; font-style: italic;">// set default monospaced font</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetDefaultMonospacedFont</span><span style="color: #009900;">&#40;</span>PDF_FONT_MONOSPACED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//set margins</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetMargins</span><span style="color: #009900;">&#40;</span>PDF_MARGIN_LEFT<span style="color: #339933;">,</span> PDF_MARGIN_TOP <span style="color: #339933;">-</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> PDF_MARGIN_RIGHT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetHeaderMargin</span><span style="color: #009900;">&#40;</span>PDF_MARGIN_HEADER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFooterMargin</span><span style="color: #009900;">&#40;</span>PDF_MARGIN_FOOTER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//set auto page breaks</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetAutoPageBreak</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #339933;">,</span> PDF_MARGIN_BOTTOM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//set some language-dependent strings</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLanguageArray</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$l</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
	<span style="color: #666666; font-style: italic;">// ---------------------------------------------------------</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// add a page</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">AddPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Column width, by conteng max length</span>
	<span style="color: #000088;">$w_max</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPageWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> PDF_MARGIN_LEFT <span style="color: #339933;">-</span> PDF_MARGIN_RIGHT<span style="color: #339933;">;</span>
	<span style="color: #000088;">$w</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$PDF_ARRAY</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// Chinese utf8 2 words length=6, should be 4 here</span>
			<span style="color: #000088;">$cell</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$l</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mb_strwidth</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cell</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// FZFangSong is not fixed font, so add some to en chars</span>
			<span style="color: #666666; font-style: italic;">// eg: 哈哈abc</span>
			<span style="color: #666666; font-style: italic;">// strlen = 6 + 3 = 9</span>
			<span style="color: #666666; font-style: italic;">// mbstrlen = 5</span>
			<span style="color: #666666; font-style: italic;">// mbstrwidth = 7</span>
			<span style="color: #000088;">$l</span> <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$l</span> <span style="color: #339933;">+</span> <span style="color: #990000;">mb_strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cell</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">*</span> <span style="color:#800080;">0.3</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$l</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$l</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$l</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// Compare with max width, maybe below 0</span>
	<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$w_max</span> <span style="color: #339933;">-</span> <span style="color: #990000;">array_sum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// Add back spaces left to each width</span>
	<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">/</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$k</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$v</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
	<span style="color: #666666; font-style: italic;">// Table title</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFont</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fzfangsong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">14</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Write</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'设备一览表'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'C'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// set font</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFont</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fzfangsong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Table header</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFillColor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">208</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">220</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetTextColor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$PDF_HEADER</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$head</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Cell</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">7</span><span style="color: #339933;">,</span> <span style="color: #000088;">$head</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'C'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Ln</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Rows</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetFillColor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">224</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">235</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">SetTextColor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$fill</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$PDF_ARRAY</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Cell</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">6</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cell</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'LR'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'L'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fill</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Ln</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$fill</span><span style="color: #339933;">=!</span><span style="color: #000088;">$fill</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Cell</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_sum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'T'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
	<span style="color: #666666; font-style: italic;">// ---------------------------------------------------------</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Close and output PDF document</span>
	<span style="color: #000088;">$pdf</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Output</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'glpi.pdf'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'I'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
	<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></pre></div></div>


<p>总体上这个例子是照着<a href="http://www.tecnick.com/pagefiles/tcpdf/example_011.phps">官网Colored Tables例子</a>来的。</p>

<p>最后，把这个文件中所有的utf8_decode处理都去掉，完成。</p>

<h4>参考</h4>

<ul>
<li><a href="http://junist.googlepages.com/latex.html">LaTeX说明</a></li>
<li><a href="http://ez.no/ezpublish/documentation/incoming/truetype_font_in_pdf">Truetype font in PDF</a></li>
<li><a href="http://www.joomla.org.tw/phpbb3/viewtopic.php?f=39&amp;t=3040&amp;st=0&amp;sk=t&amp;sd=a&amp;start=30">1.5 PDF中文顯示（大家協助測試~）</a></li>
<li><a href="http://hi.baidu.com/yangzetao888/blog/item/ab10bbd412214106a18bb7cd.html">tcpdf的使用（中文）</a></li>
<li><a href="http://twpug.net/modules/newbb/viewtopic.php?post_id=9348">請問有關 tcpdf 的問題</a></li>
<li><a href="http://drupal.org/node/303499">Make &#8220;Enable/Disable Unicode Mode&#8221; optional?</a></li>
<li><a href="http://drupaltaiwan.org/module/print_friendly_pages">Print Friendly Pages</a></li>
<li><a href="http://joomlab15.exonsoft.com/zh-cn/articles/joomla!15x/50-generatelightweightchinesepdf?showall=1">产生轻薄短小的中文 PDF</a></li>
<li><a href="http://www.wazu.jp/gallery/Fonts_ChineseTraditional.html">U_fonts Traditional Chinese</a></li>
<li><a href="http://www.wazu.jp/gallery/Fonts_ChineseSimplified.html">U_fonts Simplified Chinese</a></li>
<li><a href="http://www.joomla.org.tw/phpbb3/viewtopic.php?f=39&amp;t=3040&amp;p=9785">1.5 PDF中文顯示（大家協助測試~）</a></li>
<li><a href="http://www.lakeice.com/?action=show&amp;id=6">FPDF中文应用攻略</a></li>
<li><a href="http://www.zhaipeng.cn/2008/01/29/php%E4%BD%BF%E7%94%A8fpdf%E5%88%9B%E5%BB%BApdf/">PHP使用FPDF创建PDF</a></li>
</ul>

<h4>Update @ 2009-11-06</h4>

<p>Print to pdf 的时候，Historical 中的 Comments 如何显示？默认的不好，可以考虑换成 diff 信息，如果又不愿用 pear 里的 <a href="http://pear.php.net/package/Text_Diff">xdiff</a>，可以考虑它的前身──用 php 直接实现的 <a href="http://software.zuavra.net/inline-diff/">PHP inline diff</a>。</p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/chinese" title="chinese" rel="tag">chinese</a>, <a href="http://www.fwolf.com/blog/post/tag/diff" title="diff" rel="tag">diff</a>, <a href="http://www.fwolf.com/blog/post/tag/export" title="export" rel="tag">export</a>, <a href="http://www.fwolf.com/blog/post/tag/ezpdf" title="ezpdf" rel="tag">ezpdf</a>, <a href="http://www.fwolf.com/blog/post/tag/font" title="font" rel="tag">font</a>, <a href="http://www.fwolf.com/blog/post/tag/glpi" title="GLPI" rel="tag">GLPI</a>, <a href="http://www.fwolf.com/blog/post/tag/pdf" title="pdf" rel="tag">pdf</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/tcpdf" title="TCPDF" rel="tag">TCPDF</a>, <a href="http://www.fwolf.com/blog/post/tag/utf8" title="utf8" rel="tag">utf8</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/133" title="截取固定长度的中文字符串 (2006-02-06)">截取固定长度的中文字符串</a> (2)</li>
	<li><a href="http://www.fwolf.com/blog/post/400" title="选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (2008-05-03)">选择Eclipse PHP Development Tools(PDT)作为PHP开发工具</a> (8)</li>
	<li><a href="http://www.fwolf.com/blog/post/176" title="让phpmailer支持中文名称的附件 (2006-05-23)">让phpmailer支持中文名称的附件</a> (5)</li>
	<li><a href="http://www.fwolf.com/blog/post/170" title="[Ubuntu]明明白白安装中文字体 (2006-05-17)">[Ubuntu]明明白白安装中文字体</a> (20)</li>
	<li><a href="http://www.fwolf.com/blog/post/315" title="Ubuntu FeistyFawn中文字体配置的变化 (2007-04-22)">Ubuntu FeistyFawn中文字体配置的变化</a> (3)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/434/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>teamol=WebCollab</title>
		<link>http://www.fwolf.com/blog/post/432</link>
		<comments>http://www.fwolf.com/blog/post/432#comments</comments>
		<pubDate>Sat, 28 Feb 2009 16:19:33 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[GTD]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[webcollab]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/?p=432</guid>
		<description><![CDATA[如果你曾经在国内某个php源码下载网站下载过一个叫teamol的团队任务分配软件，不知你有没有注意到，它和国外开源项目WebCollab之间似乎有着亲密的联系。 本来我也没注意，可这个teamol下载回来以后安装颇不顺利，文档TeamOL setup.doc和安装界面有不一样的地方，虽然国内开源项目用doc写文档不算奇怪，但这个文档内容也太少了。代码注释中有个“官方网站”http://www.inodea.cn是打不开的，代码中很多地方标的版本号是0.1，可下载时我记得说的出3.0或者3.2版本。 开始安装以后有个地方卡壳了，还没安装数据库，就要从数据库里信息来验证用户是否有权限安装。hack安装之后，path配置也有问题，模板中还有一些错误，比如明明这段函数内没有$title这个变量却多次使用，要知道即使是global $title也是没有值的。 反正歪歪扭扭总算把程序配置得能运转了，开始试试，功能倒还有点让我满意的意思，除了日期选择的弹出窗口我极其不喜欢。然后我就发现了一件让我大跌眼镜的事情，这么一个错误百出或者说有点像半成品的“国产开源”作品，居然不仅有英、中文支持，还有一个看似排版比较成熟的英文帮助页面： 好奇的我挑了帮助页面中的一句话上G一搜，便找到了WebCollab。仔细比较下来，两者的目录结构也几乎一样： 结果应该不用我说了，也或许teamol的作者原想只是以webcollab为蓝本边学习边制作一个全新的系统吧，从注释中的版本0.1和修改过使用frame的页面框架中能够看出作者还是付出了些劳动的。 回到主题，用于小组内工作任务分配跟踪，倒是可以试试WebCollab，界面是简陋了点，基本的内容算是都有了。但这类软件，至今没找到一个特别好用的，包括很多在线的GTD或者项目管理系统。 Tags: GTD, opensource, PHP, webcollab Related posts 针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (3) 配置安全的共享web服务器（抛砖引玉） (4) 选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (8) 让phpmailer支持中文名称的附件 (5) 终于能够通过phpmailer使用gmail账号发送邮件了 (50)]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/fwolf/3315783583/" title="Team Online 项目管理系统 by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3364/3315783583_6549d775e4_o.png" width="354" height="263" alt="Team Online 项目管理系统" /></a></p>

<p>如果你曾经在国内某个php源码下载网站下载过一个叫teamol的团队任务分配软件，不知你有没有注意到，它和国外开源项目<a href="http://webcollab.sourceforge.net/">WebCollab</a>之间似乎有着亲密的联系。</p>

<p>本来我也没注意，可这个teamol下载回来以后安装颇不顺利，文档<code>TeamOL setup.doc</code>和安装界面有不一样的地方，虽然国内开源项目用doc写文档不算奇怪，但这个文档内容也太少了。代码注释中有个“官方网站”http://www.inodea.cn是打不开的，代码中很多地方标的版本号是0.1，可下载时我记得说的出3.0或者3.2版本。</p>

<p>开始安装以后有个地方卡壳了，还没安装数据库，就要从数据库里信息来验证用户是否有权限安装。hack安装之后，path配置也有问题，模板中还有一些错误，比如明明这段函数内没有<code>$title</code>这个变量却多次使用，要知道即使是<code>global $title</code>也是没有值的。</p>

<p>反正歪歪扭扭总算把程序配置得能运转了，开始试试，功能倒还有点让我满意的意思，除了日期选择的弹出窗口我极其不喜欢。然后我就发现了一件让我大跌眼镜的事情，这么一个错误百出或者说有点像半成品的“国产开源”作品，居然不仅有英、中文支持，还有一个看似排版比较成熟的英文帮助页面：</p>

<p><a href="http://www.flickr.com/photos/fwolf/3315826755/" title="webcollab-help by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3640/3315826755_5522fc9314_m.jpg" width="240" height="123" alt="webcollab-help" /></a></p>

<p>好奇的我挑了帮助页面中的一句话上G一搜，便找到了<a href="http://webcollab.sourceforge.net/">WebCollab</a>。仔细比较下来，两者的目录结构也几乎一样：</p>

<p><a href="http://www.flickr.com/photos/fwolf/3316666910/" title="dir structure of teamol and webcollab by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3664/3316666910_9b69bd7dc4_m.jpg" width="240" height="165" alt="dir structure of teamol and webcollab" /></a></p>

<p>结果应该不用我说了，也或许teamol的作者原想只是以webcollab为蓝本边学习边制作一个全新的系统吧，从注释中的版本0.1和修改过使用frame的页面框架中能够看出作者还是付出了些劳动的。</p>

<p>回到主题，用于小组内工作任务分配跟踪，倒是可以试试<a href="http://webcollab.sourceforge.net/">WebCollab</a>，界面是简陋了点，基本的内容算是都有了。但这类软件，至今没找到一个特别好用的，包括很多在线的GTD或者项目管理系统。</p>

<p><a href="http://www.flickr.com/photos/fwolf/3316619628/" title="WebCollab login by fwolf, on Flickr"><img src="http://farm4.static.flickr.com/3595/3316619628_fcbf0f7500_m.jpg" width="240" height="197" alt="WebCollab login" /></a></p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/gtd" title="GTD" rel="tag">GTD</a>, <a href="http://www.fwolf.com/blog/post/tag/opensource" title="opensource" rel="tag">opensource</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/webcollab" title="webcollab" rel="tag">webcollab</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/300" title="针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (2007-03-18)">针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS）</a> (3)</li>
	<li><a href="http://www.fwolf.com/blog/post/443" title="配置安全的共享web服务器（抛砖引玉） (2009-06-09)">配置安全的共享web服务器（抛砖引玉）</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/400" title="选择Eclipse PHP Development Tools(PDT)作为PHP开发工具 (2008-05-03)">选择Eclipse PHP Development Tools(PDT)作为PHP开发工具</a> (8)</li>
	<li><a href="http://www.fwolf.com/blog/post/176" title="让phpmailer支持中文名称的附件 (2006-05-23)">让phpmailer支持中文名称的附件</a> (5)</li>
	<li><a href="http://www.fwolf.com/blog/post/155" title="终于能够通过phpmailer使用gmail账号发送邮件了 (2006-04-14)">终于能够通过phpmailer使用gmail账号发送邮件了</a> (50)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/432/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
