<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[PHP - 葵中剑]]></title><description><![CDATA[Just Sword Wang's Blog]]></description><link>https://swordair.com/</link><image><url>https://swordair.com/favicon.png</url><title>PHP - 葵中剑</title><link>https://swordair.com/</link></image><generator>Ghost 3.42</generator><lastBuildDate>Fri, 16 Dec 2022 20:15:32 GMT</lastBuildDate><atom:link href="https://swordair.com/tag/php/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[修复Wordpress的Pingback]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>不知道是从何时起自己博客的Pingback挂掉了，自己也因为长期没有收到什么Pingback最终还是发觉了这个问题，只是，平时就比较繁忙加之这个功能缺失并无太大的影响，于是就一直搁置在一旁，结果一搁就是1年了。在多次自己文章Pingback失败之后我再也无法忍受这种文章的孤立感，在这种积怨的驱动下，我居然整整花了大约有1天时间来查原因，无奈双重问题让我走了一些弯路，不过最后还是顺利解决了。然后，我打算记录下这一路查错的过程，也许需要的人可能会用到。</p>
<p>一开始，我能想到的就是配置问题，我直接Google了 pingback wordpress not working，并查看了前三页所有的文章，结果没有一个有效。我尝试了很多配置，修改htaccess放宽权限、修改config文件等待，不过问题似乎不是出在这种地方。</p>
<p>随后我怀疑是主题的问题，但我切回默认主题后问题依旧。我尝试禁用所有的插件，但问题依旧(后来发觉并非如此)。我尝试升级wordpress到最新，还是无效。我的博客既发不出也收不到Pingback。</p>
<p>出于某种不爽的情绪，我索性阅读了 <a href="http://www.hixie.ch/specs/pingback/pingback">Pingback 1.0定义</a>。从这份定义文档里，以及 <a href="http://lists.automattic.com/pipermail/wp-hackers/2009-September/027425.html">Quest for Self Pingbacks</a> 一文里，我了解了wordpress的Pingback做了些什么：</p>
<ol>
<li>当一篇文章发布的时候，wordpress检测并根据设置，</li></ol>]]></description><link>https://swordair.com/fixing-wordpress-pingback/</link><guid isPermaLink="false">59fe0cf19855590d8c914738</guid><category><![CDATA[WordPress]]></category><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Sword Wang]]></dc:creator><pubDate>Fri, 17 Feb 2012 11:22:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>不知道是从何时起自己博客的Pingback挂掉了，自己也因为长期没有收到什么Pingback最终还是发觉了这个问题，只是，平时就比较繁忙加之这个功能缺失并无太大的影响，于是就一直搁置在一旁，结果一搁就是1年了。在多次自己文章Pingback失败之后我再也无法忍受这种文章的孤立感，在这种积怨的驱动下，我居然整整花了大约有1天时间来查原因，无奈双重问题让我走了一些弯路，不过最后还是顺利解决了。然后，我打算记录下这一路查错的过程，也许需要的人可能会用到。</p>
<p>一开始，我能想到的就是配置问题，我直接Google了 pingback wordpress not working，并查看了前三页所有的文章，结果没有一个有效。我尝试了很多配置，修改htaccess放宽权限、修改config文件等待，不过问题似乎不是出在这种地方。</p>
<p>随后我怀疑是主题的问题，但我切回默认主题后问题依旧。我尝试禁用所有的插件，但问题依旧(后来发觉并非如此)。我尝试升级wordpress到最新，还是无效。我的博客既发不出也收不到Pingback。</p>
<p>出于某种不爽的情绪，我索性阅读了 <a href="http://www.hixie.ch/specs/pingback/pingback">Pingback 1.0定义</a>。从这份定义文档里，以及 <a href="http://lists.automattic.com/pipermail/wp-hackers/2009-September/027425.html">Quest for Self Pingbacks</a> 一文里，我了解了wordpress的Pingback做了些什么：</p>
<ol>
<li>当一篇文章发布的时候，wordpress检测并根据设置，对文章里的链接进行Ping的操作。它会安排Ping回的事件并立即执行。</li>
<li>目标收到Ping之后，会检查源页面里是否含有目标页面的URL，并检查<code>title</code>等其它要素。</li>
<li>通过检测后，目标页生成一个新的评论。</li>
</ol>
<p>简单的搜索后没有发现合适的Pingback调试工具，无奈只好下载 xmlrpc for php 库，自己做客户端发送Pingback做测试。又是阅读了一堆使用文档，然后终于断断续续地写了这些测试代码：</p>
<pre><code>require_once('./lib/xmlrpc/xmlrpc.inc');

$site_linking_from = &quot;http://www.swordair.com/blog/2011/07/666&quot;;
$site_linking_to = &quot;http://www.swordair.com/blog/2010/12/522&quot;;

$host_url = &quot;swordair.com&quot;;

$xmlrpc_client = new xmlrpc_client(&quot;/blog/xmlrpc.php&quot;, $host_url, 80);
$xmlrpc_client-&gt;setDebug(1);

$xmlrpc_message = new xmlrpcmsg(&quot;pingback.ping&quot;, array(new xmlrpcval($site_linking_from),new xmlrpcval($site_linking_to)));
$xmlrpc_response = $xmlrpc_client-&gt;send($xmlrpc_message);

echo $xmlrpc_response-&gt;faultString();
</code></pre>
<p>但光有这些还不够，我还得trace下wordpress的部分代码。在最新版3.3.1里，处理xmlrpc的是 <code>xmlrpc.php</code>，在页面中由下面的代码指定：</p>
<pre><code>&lt;link rel=&quot;pingback&quot; href=&quot;http://www.swordair.com/blog/xmlrpc.php&quot; /&gt;
</code></pre>
<p>这个文件里，真正处理xmlrpc的wordpress xmlrpc实现是其引用的 <code>class-wp-xmlrpc-server.php</code>，在 <code>class-wp-xmlrpc-server.php</code> 第3409行就是处理pingback的回调函数：</p>
<pre><code>/**
 * Retrieves a pingback and registers it.
 *
 * @since 1.5.0
 *
 * @param array $args Method parameters.
 * @return array
 */
function pingback_ping($args) {
</code></pre>
<p>然后，浏览了一下这个处理函数，其中的错误信息正好就是 <a href="http://www.hixie.ch/specs/pingback/pingback">Pingback 1.0定义</a> 里的错误类型，只是wordpress检测时的顺序稍有差异：</p>
<pre><code>ERROR 33: The specified target URL cannot be used as a target. It either doesn't exist, or it is not a pingback-enabled resource.
ERROR 00: The source URL and the target URL cannot both point to the same resource.
ERROR 48: The pingback has already been registered.
ERROR 16: The source URL does not exist.
ERROR 32: We cannot find a title on that page.
</code></pre>
<p>根据函数代码，这些错误表示下面的意思(光从错误信息其实还比较抽象，但是直接看代码就明白了它是如何检测的)：</p>
<ul>
<li>ERROR 33: 无法解析的URL，页面ID不存在或者Ping没有开启</li>
<li>ERROR 00: 一个地址不能同时作为源和目标</li>
<li>ERROR 48: 说明这个pingback之前已经被录入</li>
<li>ERROR 16: wp_remote_fopen 返回false，即无法建立连接</li>
<li>ERROR 32: 源页没有标题</li>
</ul>
<p>这样一来，工具就齐全了。出于一些原因，我不得不在线上直接调试，于是我还特意找来Disable RSS插件禁用了wordpress的RSS生成。用上面的测试代码，加上对处理函数的分析，再加上错误信息的列表，一遍遍调试终于，Ping通了。</p>
<p>然而讽刺的是，当我运行测试代码，从输出力看到最后那条错误信息的时候，相当无语：Error: Please enter a valid seccode. 居然是验证码插件在作怪！</p>
<p>这次真心大意了，费了九牛二虎之力，居然问题出在一个插件上。尽管一开始我就禁用插件测试，但似乎是受到了当时服务器阻塞的影响，让我放松了对插件的嫌疑。实际上我从很早以前就开始使用的这个wp-seccode验证码插件一直工作良好，以前也并没有屏蔽过Pingback。不过我记得我曾经升级过一次，也许就是因为那次的升级，wp-seccode就将所有的Pingback挡在门外了。</p>
<p>wp-seccode简单小巧，是我喜欢的主要原因。而且垃圾评论实在很多，把验证码一关掉就蹦出来好多。所以我没打算放弃使用，而是决定直接修改插件。</p>
<p>在 <code>pingback_ping</code> 函数的最后可以看到评论是如何生成的：</p>
<pre><code>$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_content', 'comment_type');

$comment_ID = wp_new_comment($commentdata);
do_action('pingback_post', $comment_ID);

return sprintf(__('Pingback from %1$s to %2$s registered. Keep the web talking! :-)'), $pagelinkedfrom, $pagelinkedto);
</code></pre>
<p>于是我赶紧找了一下 <code>wp_new_comment</code> 的参考，果然，它有个 <code>preprocess_comment</code> 的 Hook。然后在到wp-seccode插件目录里，找到在 <code>run.php</code> 里的 <code>preprocess_comment</code> 函数，在判断位置添加了下面的代码，让插件直接略过pingback的处理：</p>
<pre><code>if($commentdata['comment_type'] != 'pingback'){}
</code></pre>
<p>至此，Pingback终于回来了。</p>
<p>一番折腾终于有了结果，我不用更换插件，Pingback也能继续工作。虽然此次问题的成因非常简单，但是种种原因让我在初期错过了识别，结果导致了杀鸡用牛刀。为此我额外地阅读了Pingback的定义以及xmlrpc库的使用文档，真够蛋疼的...但以后如果再有什么有关xmlrpc以及pingback的问题，我自己都可以回来阅读此文，因为无论是在国内外，这里对于Pingback的调试说得已经相当详细:)</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[JavaScript字符串连接性能]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>起初今天碰到的字符串拼接的性能问题并不是关于JavaScript的，而是有关PHP的，名为<a href="http://blogs.sitepoint.com/2010/10/05/high-performance-string-concatenation-in-php/">PHP中的高性能字符串连接</a>( High-Performance String Concatenation in PHP )。众所周知，PHP是用“点”来连接字符串的：</p>
<pre><code>$str = 'a' . 'b';
$str .= 'c';
</code></pre>
<p>并且和JavaScript类似，PHP也可以通过Array来拼接字符串：</p>
<pre><code>$str = implode(array('a', 'b', 'c'));
</code></pre>
<p>问题就是，当拼接达到上万的数量级之后，哪一种性能更好呢？</p>
<pre><code>// standard string append
$str = '';
for ($i = 30000; $i &gt; 0; $i--) {
	$str .= 'String concatenation. ';
}
</code></pre>
<pre><code>// array join
$str = '';
$sArr</code></pre>]]></description><link>https://swordair.com/javascript-string-concatenation-performance/</link><guid isPermaLink="false">59fe0cf19855590d8c9146eb</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Sword Wang]]></dc:creator><pubDate>Wed, 06 Oct 2010 20:36:09 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>起初今天碰到的字符串拼接的性能问题并不是关于JavaScript的，而是有关PHP的，名为<a href="http://blogs.sitepoint.com/2010/10/05/high-performance-string-concatenation-in-php/">PHP中的高性能字符串连接</a>( High-Performance String Concatenation in PHP )。众所周知，PHP是用“点”来连接字符串的：</p>
<pre><code>$str = 'a' . 'b';
$str .= 'c';
</code></pre>
<p>并且和JavaScript类似，PHP也可以通过Array来拼接字符串：</p>
<pre><code>$str = implode(array('a', 'b', 'c'));
</code></pre>
<p>问题就是，当拼接达到上万的数量级之后，哪一种性能更好呢？</p>
<pre><code>// standard string append
$str = '';
for ($i = 30000; $i &gt; 0; $i--) {
	$str .= 'String concatenation. ';
}
</code></pre>
<pre><code>// array join
$str = '';
$sArr = array();
for ($i = 30000; $i &gt; 0; $i--) {
	$sArr[] = 'String concatenation. ';
}
$str = implode($sArr);
</code></pre>
<p>如果看过 Zakas 的《JavaScript高级程序设计》的话，一定会记得那个在第85页关于字符串连接性能的问题。</p>
<p>其实和其他很多语言一样，JS的字符串是不可变的。每次在字符串上的改变，都会存在一个废弃旧的实例并重新创建一个新实例的过程。单单两个字符串的简单拼接，就涉及好几个这样的过程。一旦这种冗余的过程被重复上万的数量级，就会遇到性能问题。然而数组则不会，它只是在一开始不断扩展数组的大小，并在最后只创建拼接结果的字符串一次，从而省去了上万实例化的开销。并且按照Zakas给出的方法测试的结果，可以节省50%以上的时间。</p>
<p>但上面PHP的执行结果却并非如此。虽然我没有自己测试，但援引 Craig Buckler 的表述，结果就很清楚了。</p>
<blockquote>
<p>Unsurprisingly, PHP is optimized for string handling and the dot operator will be the fastest concatenation method in most cases.</p>
</blockquote>
<p>甚至，这可能不仅仅只是一个性能上的问题，如果数组开的太大面临的是内存的压力。难道 Zakas 错了？当然不可能，且不说把JS的理论直接放到PHP上是否合适，但就当时IE6时代 Zakas 完全正确，可惜放到现在，可能就略显过时了。</p>
<p>下面的是一段 Zakas 的测试使用加号和使用数组的join方法性能的代码：</p>
<pre><code>function StringBuffer() {
	this.__strings__ = new Array;
}

StringBuffer.prototype.append = function (str) {
	this.__strings__.push(str);
	//this.__strings__[this.__strings__.length] = str;
};

StringBuffer.prototype.toString = function () {
	return this.__strings__.join(&quot;&quot;);
};

var d1 = new Date();
var str = &quot;&quot;;
for (var i=0; i &lt; 10000; i++) {
	str += &quot;I am the bone of my sword ...&quot;;
}
var d2 = new Date();
 
document.write(&quot;Concatenation with plus: &quot; + (d2.getTime() - d1.getTime()) + &quot; milliseconds&quot;);
 
var buffer = new StringBuffer();
d1 = new Date();
for (var i=0; i &lt; 10000; i++) {
	buffer.append(&quot;I am the bone of my sword ...&quot;);
}
var result = buffer.toString();
d2 = new Date();
 
document.write(&quot;&lt;br /&gt;Concatenation with StringBuffer: &quot; + (d2.getTime() - d1.getTime()) + &quot; milliseconds&quot;);

</code></pre>
<p>在拼接的字符串那里，我使用的是下面这段话：</p>
<blockquote>
<p>I am the bone of my sword. Steel is my body and the fire is my blood. I have created over a thousand blades. Unknow to death, nor know to life. Have withstood plain to create many weapons. Yet those hands will never hold anything. So as I play, unlimited blade works.</p>
</blockquote>
<p>顺便扯点别的，这周我刚看完 fate / stay night UBW，那情节真够破碎的，真是大感失望。可怜的 Archer 连个咒语都没时间念全。这里就让这段话出个场吧~</p>
<p>现在如果你点击<a href="http://www.swordair.com/demos/string-concatenation-plus-vs-stringbuffer/">这里</a>，可以看到我写好的Demo在各个浏览器的运行效果。如果不想亲自尝试，请看我列出的表格。</p>
<table>
	<tr><th>浏览器</th><th>加号连接</th><th>Join连接</th></tr>
	<tr><td>Chrome 6.0.479.0</td><td>1毫秒</td><td>5毫秒</td></tr>
	<tr><td>Opera 10.62</td><td>18毫秒</td><td>19毫秒</td></tr>
	<tr><td>Firefox 3.6.8</td><td>26毫秒</td><td>31毫秒</td></tr>
	<tr><td>Safari 5.33.18.5</td><td>2毫秒</td><td>34毫秒</td></tr>
	<tr><td>IE6</td><td>38437毫秒</td><td>94毫秒</td></tr>
</table>
<p>这张表是在一台AMD X2 4000+ 2G内存的台式机上测得的。你没看错IE的数值，当然我也没笔误。由于我的机器上只有IE6，所以IE7和IE8以及新的FF4、IE9beta都尚未测试，但是凭感觉，IE7的情况应该和IE6类似，IE8的情况应该和FF3.6.8类似。所以 Zakas 那段优化代码几乎完全没用武之地，刚才PHP的情况几乎是直接复制到JS身上。要说的是，Chrome和Safari，特别是Chrome，真的很恐怖，这么多的操作居然1毫秒都几乎不用。</p>
<p>难道是浏览器对于加法拼接做了什么优化？也许吧。但是不管怎么说，String总归是一个不可变的数据，在不改变处理方式的情况下，如何能将性能提升到这种地步？我的猜测是现代JS引擎对于对象废弃和创建已经非常快速，快到这种过程在上万数量级完全感觉不到瓶颈一般。Zakas 在写书的时候还没有Chrome，浏览器对于某些执行性能的颠覆，完全出人意料。</p>
<p>当然还有些有趣的其他情况，当测试数据，这里指的是待拼接的字符串的长度变化后，也会得到写不同的结果。比如，将上面那段字符串加长一倍，Chrome 和 Safari 的加法连接的表现仍旧抢眼。Opera 则是始终拥有非常相近的数据结果。FF在字符串加长后，加法连接性能会有明显的下降.....等等。</p>
<p>这次也许能有一个结论，那就是，<strong>尽管无论出于代码的可读性还是执行性能考虑，我们都应该使用加号拼接字符串，然而，使用数组对于IE6、7的提升是如此的巨大以至于最为保守折中的做法仍然是使用数组</strong>，因为相对于IE6、7的提升，其他浏览器用加号的做法带来的提升甚至可以忽略不计。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[为PHP增加SVN扩展]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>这次涉及到一个网上资料很少的问题，PHP的SVN扩展。</p>
<p>windows平台下，最简单的php服务器搭建无疑是xampp。但是当前版本的xampp(1.7.3)并不带有svn的扩展，即php_svn.dll。从版本更新中得知2009.1.23的xampp做了如下的变化：</p>
<pre><code>23. Jan 2009 1.7.0 pl1 beta3 
Delete php\ext\php_svn.dll 
Delete php\php5.ini 
Delete mysql-gui-tools-noinstall-5.0-r15 
New build xampp-control.exe 
Patching phpMyAdmin\main.php (305-318)
</code></pre>
<p>也是在这个版本开始，xampp移除了对svn扩展的支持。</p>
<p>在PECL的网站上仍然可以下载到最新的SVN扩展源码:</p>
<p><a href="http://pecl.php.net/package/svn">http://pecl.</a></p>]]></description><link>https://swordair.com/add-svn-extends-for-php/</link><guid isPermaLink="false">59fe0cf19855590d8c9146b0</guid><category><![CDATA[PHP]]></category><category><![CDATA[SVN]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[XAMPP]]></category><dc:creator><![CDATA[Sword Wang]]></dc:creator><pubDate>Thu, 28 Jan 2010 10:47:12 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>这次涉及到一个网上资料很少的问题，PHP的SVN扩展。</p>
<p>windows平台下，最简单的php服务器搭建无疑是xampp。但是当前版本的xampp(1.7.3)并不带有svn的扩展，即php_svn.dll。从版本更新中得知2009.1.23的xampp做了如下的变化：</p>
<pre><code>23. Jan 2009 1.7.0 pl1 beta3 
Delete php\ext\php_svn.dll 
Delete php\php5.ini 
Delete mysql-gui-tools-noinstall-5.0-r15 
New build xampp-control.exe 
Patching phpMyAdmin\main.php (305-318)
</code></pre>
<p>也是在这个版本开始，xampp移除了对svn扩展的支持。</p>
<p>在PECL的网站上仍然可以下载到最新的SVN扩展源码:</p>
<p><a href="http://pecl.php.net/package/svn">http://pecl.php.net/package/svn</a></p>
<p>当前的版本是0.5.1，发布于2009.9.23，状态仍然是beta。查看其在php.net上的文档:</p>
<p><a href="http://www.php.net/manual/en/book.svn.php">http://www.php.net/manual/en/book.svn.php</a></p>
<p>但是由于文档不全仍然让人一头雾水。起初是想为我的windows下添加以下svn扩展的，但是却看到了这样一句 'A DLL for this PECL extension is currently unavailable' ，又是一盆冷水。跳转链接指向如何在windows下编译PHP。于是我装Visual C++ 2008 Express Edition，装了Windows Platform SDK，捣鼓了一阵，还是没能成功。</p>
<p>随后我又去网上直接下了php_svn.dll文件，把他丢进ext目录里，在php.ini里添加extension = php_svn.dll，重启，还是失败...最终我还是放弃了windows的扩展搭建，把目标转向了Linux。</p>
<p>我一直都很喜欢Ubuntu，这次用的照旧还是Ubuntu。习惯性的，在Ubuntu server-9.04上已经安装了LAMP，所以我先是安装了一个svn，快速建了一个库：</p>
<pre><code>apt-get install subversion
mkdir /var/svn
cd /var/svn
svnadmin create MyCategory
svnserve -d -r /var/svn
</code></pre>
<p>subversion的安装不是必须的。似乎现在还没有基于Debian的发布版有这个扩展的二进制包。所以要在ubuntu上使用这个扩展就必须手动安装</p>
<p>然后安装必要的组件：</p>
<pre><code>apt-get install build-essential
apt-get install php-pear php5-dev libsvn-dev
</code></pre>
<p>build-essential是必要的编译环境，通常这个都会预先安好。接下去就是三个依赖，php-pear php5-dev libsvn-dev 。如果用下面的命令搜索</p>
<pre><code>apt-cache search pecl
</code></pre>
<p>那么结果会是这样的</p>
<pre><code>dh-make-php - Creates Debian source packages for PHP PEAR and PECL extensions
php-auth - PHP PEAR modules for creating an authentication system
php5-radius - PECL radius module for PHP 5
php5-remctl - PECL module for Kerberos-authenticated command execution
php-pear - PEAR - PHP Extension and Application Repository
</code></pre>
<p>出现php-pear的原因，是PEAR和PECL共享了相同的包和分发机制。适当PHP开发包也是必要的,比如说php5-dev。</p>
<p>最后，就是Subversion的头文件，即libsvn-dev，被用来在没有安装Subversion的环境中编译svn扩展。</p>
<p>下一步，安装扩展：</p>
<pre><code>sudo pecl install svn
</code></pre>
<p>由于当前版本是0.5.1，所以命令变更如下：</p>
<pre><code>sudo pecl install svn-0.5.1
</code></pre>
<p>这一步会下载svn扩展的源代码，编译成svn.so文件然后再把它安装到PHP能找到它的地方。但是，编译到一半，问题就来了:</p>
<pre><code>/usr/bin/ld: cannot find -lsasl2
collect2: ld returned 1 exit status
make: *** [svn.la] Error 1
</code></pre>
<p>出现这个问题，我一时没能google到什么信息。直到我在google第6页找到了Ubuntu论坛里一位朋友的解决方法:</p>
<p><strong>搜索sasl2而不是lsasl2</strong>，然后安装。</p>
<pre><code>apt-cache search sasl2
sudo apt-get install libsasl2-dev libsasl2-modules-ldap
</code></pre>
<p>之后继续刚才安装svn-0.5.1的命令，报错的内容变化了：</p>
<pre><code>/usr/bin/ld: cannot find -lneon-gnutls
</code></pre>
<p>需要继续搜索和安装缺失的包</p>
<pre><code>apt-cache search neon gnutls
sudo apt-get install libneon27-gnutls-dev
</code></pre>
<p>至此，终于通过编译，并在完成的最后提示在php.ini中增加一行：</p>
<pre><code>extension=svn.so
</code></pre>
<p>重启Apache</p>
<pre><code>/etc/init.d/apache2 reload
</code></pre>
<p>通过查看phpinfo()，可以看到多出了svn一项。</p>
<table border="0" cellpadding="3" width="600">
<tr style="background-color:#9999cc; font-weight: bold; color: #000000;"><th style="border: 1px solid #000000;vertical-align: baseline;background-color:#9999cc;color:#000000">svn support</th><th style="border: 1px solid #000000;vertical-align: baseline;background-color:#9999cc;color:#000000">enabled</th></tr>
<tr><td style="background-color: #ccccff; font-weight: bold; color: #000000;border: 1px solid #000000; vertical-align: baseline;">svn client version </td><td style="background-color: #cccccc; border: 1px solid #000000; vertical-align: baseline;">1.5.4 </td></tr>
<tr><td style="background-color: #ccccff; font-weight: bold; color: #000000;border: 1px solid #000000; vertical-align: baseline;">svn extension version </td><td style="background-color: #cccccc; border: 1px solid #000000; vertical-align: baseline;">0.5.1 </td></tr>
</table>
<p>写一个脚本测试一下，成功。</p>
<pre><code>&lt;?php
svn_checkout('svn://localhost/MyCategory', dirname(__FILE__) . '/MyCategory');
?&gt; 
</code></pre>
<h4 id>参考资料：</h4>
<ul>
<li><a href="http://ubuntuforums.org/showthread.php?t=1158439">http://ubuntuforums.org/showthread.php?t=1158439</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Hello world!]]></title><description><![CDATA[<p>第一篇文章总是要有些来龙去脉，就如同第一个程序总是要来个Hello world!一样</p><p>以前不止一次搭建过wordpress，但最终都宣告失败。原因多种多样，忙碌者有之，兴尽者有之，或者，无墨者亦有之。但终究是不想放弃的。</p><p>过去的几年，学了很多，但都疏于梳理，以至荒废。</p><p>VB C C++ Java C# XHTML+CSS JavaScript PHP ActionScript Ruby Perl</p><p>Photoshop Flash Fireworks Illustrator CorelDRAW AutoCAD 3DsMax Maya</p><p>渐行渐远的内容，以及愈发冗长的行径线路，都充斥着迷惑。当再次回首时忽然有一种冲动，摘录、梳理、铭记，一路走来，挺有趣的。</p><!--kg-card-begin: markdown--><pre><code>/*C*/
#include &lt;stdio.h&</code></pre>]]></description><link>https://swordair.com/wordpress-hello-world/</link><guid isPermaLink="false">59fe0cf19855590d8c9146a9</guid><category><![CDATA[ActionScript3]]></category><category><![CDATA[C]]></category><category><![CDATA[Java]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Perl]]></category><category><![CDATA[PHP]]></category><category><![CDATA[Ruby]]></category><dc:creator><![CDATA[Sword Wang]]></dc:creator><pubDate>Fri, 15 Jan 2010 01:14:35 GMT</pubDate><content:encoded><![CDATA[<p>第一篇文章总是要有些来龙去脉，就如同第一个程序总是要来个Hello world!一样</p><p>以前不止一次搭建过wordpress，但最终都宣告失败。原因多种多样，忙碌者有之，兴尽者有之，或者，无墨者亦有之。但终究是不想放弃的。</p><p>过去的几年，学了很多，但都疏于梳理，以至荒废。</p><p>VB C C++ Java C# XHTML+CSS JavaScript PHP ActionScript Ruby Perl</p><p>Photoshop Flash Fireworks Illustrator CorelDRAW AutoCAD 3DsMax Maya</p><p>渐行渐远的内容，以及愈发冗长的行径线路，都充斥着迷惑。当再次回首时忽然有一种冲动，摘录、梳理、铭记，一路走来，挺有趣的。</p><!--kg-card-begin: markdown--><pre><code>/*C*/
#include &lt;stdio.h&gt;
int main()
{
	printf(&quot;Hello,world!\n&quot;);
	return 0;
}
```

```
//C++
#include &lt;iostream&gt;
using namespace std;
int main()
{
	cout&lt;&lt;&quot;Hello,world!&quot;&lt;&lt;endl;
	return 0;
}
```

```
//Java
public class Hello{
	public static void main(String args[]) {
		System.out.println(&quot;Hello,world!&quot;);
	}
}
```

```
//C#
using System;
class Hello
{
	public static void Main(){
		Console.WriteLine(&quot;Hello,world!&quot;);
	}
}
```


```
//JavaScript
alert(&quot;Hello,world!&quot;);
```

```
//PHP
&lt;?php
	echo &quot;Hello,world!&quot;;
?&gt;
```

```
//ActionScript
class Hello{
	function Hello():void{
		trace(&quot;Hello,world!&quot;);
	}
}
```

```
#ruby
puts &quot;Hello,world!&quot;;
```

```
#perl
print &quot;Hello,world!&quot;;
```</code></pre>
<!--kg-card-end: markdown--><p><strong>20 December 2013</strong>: 这篇是用wordpress发布的第一篇文章，虽然在2014年我会开始使用Ghost来搭建我的网站和博客，不过还是要怀念一下这4年来的wordpress体验。从这篇文章开始，我陆续要将我迁移的所有文章更新到markdown的格式，虽然传统的<code>html</code>也可以正常在Ghost里工作，不过还是希望做一个完整的迁移。要做的工作还有很多，需要做链接和图片的修补。对于整个网站来说，还有很大部分的静态内容需要一起迁移。我希望能在2014年前完成这些工作，在新年能有一个新的开始。</p>]]></content:encoded></item></channel></rss>