<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>开源小站 &#187; php</title>
	<atom:link href="http://www.litrin.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.litrin.net</link>
	<description>It is Cool to OpenSource</description>
	<lastBuildDate>Fri, 03 Feb 2012 04:33:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP的普青、文青和2B青</title>
		<link>http://www.litrin.net/2011/11/05/php%e7%9a%84%e6%99%ae%e9%9d%92%e3%80%81%e6%96%87%e9%9d%92%e5%92%8c2b%e9%9d%92/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php%25e7%259a%2584%25e6%2599%25ae%25e9%259d%2592%25e3%2580%2581%25e6%2596%2587%25e9%259d%2592%25e5%2592%258c2b%25e9%259d%2592</link>
		<comments>http://www.litrin.net/2011/11/05/php%e7%9a%84%e6%99%ae%e9%9d%92%e3%80%81%e6%96%87%e9%9d%92%e5%92%8c2b%e9%9d%92/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 14:17:21 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[站长的blog]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[业界话题]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1587</guid>
		<description><![CDATA[之前看过一篇东西，大致上说：之所以PHP这么流行，主要是因为PHP太“下贱”。门槛太低，什么样的写法都有。这些年接触下来，也颇有共鸣。正巧赶上最近网上很流行“普青、文青、2B青”的恶搞，抱着“回字到底有几种写法”的态度，对同样的问题进行各种风格的编码，为了更多的体现算法，我剔除了注释。只为搏大家一笑，希望大家也不要拓展开来了。 题目：1只羊第二年后开始繁殖，每年一胎，每胎一只，直到第5年死亡，列出前十年的羊的数量。 首先照例是普青： &#60;?php function foo($n, $echo = true) { $i = 1; $a = 1; while($i &#60; = $n) { $c = $b; $b += $a; $a = $c; if ($i &#62; 5) { $b -= (foo($i -5, false) -1) } if ($echo) echo "The " . $ i ."th year: " . $b [...]]]></description>
			<content:encoded><![CDATA[<p>之前看过一篇东西，大致上说：之所以PHP这么流行，主要是因为PHP太“下贱”。门槛太低，什么样的写法都有。这些年接触下来，也颇有共鸣。正巧赶上最近网上很流行“普青、文青、2B青”的恶搞，抱着“回字到底有几种写法”的态度，对同样的问题进行各种风格的编码，为了更多的体现算法，我剔除了注释。只为搏大家一笑，希望大家也不要拓展开来了。</p>
<p><strong>题目：1只羊第二年后开始繁殖，每年一胎，每胎一只，直到第5年死亡，列出前十年的羊的数量。</strong></p>
<p><span id="more-1587"></span></p>
<p>首先照例是普青：</p>
<pre name=code class=php>&lt;?php
function foo($n, $echo = true)
{
    $i = 1;
    $a = 1;

    while($i &lt; = $n)
    {
        $c = $b;
        $b += $a;
        $a = $c;

        if ($i &gt; 5)
        {
            $b -= (foo($i -5, false) -1)
        }
        if ($echo)
            echo "The " . $ i ."th year: " . $b ."\n";
        i ++;
    }
}
foo(10);
?&gt;</pre>
<p>资质一般，仅仅是做出了题目而已，没有考虑之后代码的维护，以及层层递归造成的性能浪费</p>
<p>接下来是文青：<span class="Apple-style-span" style="font-family: Consolas, Monaco, monospace; font-size: 12px; line-height: 18px; white-space: pre;"> </span></p>
<pre name=code class=php>&lt;?php

function getSheepNumber($finalYear)
{
    if ($finalYear &lt; 1 ) return 0;
    $thisYear = 1;
    $histoyRecord = array ('1' = 1);

    while($thisYear &lt; = $finalYear)
    {
        $lastYear = $thisYear - 1;
        $theYearBeforLastYear = $lastYear - 1;
        if ($theYearBeforLastYear &lt; 0 )
            $historyRecord[$thisYear] = $historyRecord[$lastYear];
        else
            $historyRecord[$thisYear] =
                $historyRecord[$lastYear] + $historyRecord[$theYearBeforLastYea];

        if ($thisYear &gt; 5)
        {
            $theYearBefor5Years = $lastYear - 5;
            $historyRecord[$thisYear] -= $historyRecord[$theYearBefor5Years];
        }
        $thisYear ++;
    }
    return $historyRecord[$thisYear]
}

for ($year = 1; $year&lt;=10; $year++)
{
    switch ($year)
    {
        case 1:
            echo "The 1st year: ";
            break;
        case 2:
            echo "The 2nd year: ";
            break;
        case 3:
            echo "The 3rd year: ";
            break;
        default:
            echo "The " . $year ."th year: ";
            break;
    }

    $sheepCount = getSheepNumber($year);
    echo $sheepCount . "\n";
}
?&gt;</pre>
<p>足够优雅，也有了不错的优化。可惜为了这优雅，循环调用，导致尽管优化了性能但依旧有潜力可挖，而且代码也罗嗦的可以了。谁让文青都不食人间烟火呢？</p>
<p>接下来2B青闪亮登场：</p>
<pre name=code class=php>&lt;?php
function foo($n)
{
    $year_2 = $year_1 = 1;
    $loop = 2;

    while( $n &gt; 0 )
    {
        $last_year = "year_" . $loop;
        $last_2_year = "year_" . ($loop - 1);
        $loop ++;

        $this_year = "year_" . $loop;

        $$this_year = $$last_2_year + $$last_year;

        if ($loop &gt; 5)
            $$this_year -= ${substr($this_year, 0 , -2) . ($loop - 5)};
?&gt;
            The &lt;?php =$loop ?&gt;th year &lt;?php =$$this_year ?&gt;
&lt;?php
    }
}
foo(10);
?&gt;</pre>
<p><span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">好吧，我不得不承认PHP的特性真的很方便。为了特性而特性这就是2B。</span></p>
<p>NB青的,颇有爱尔兰(Erlang)风格：</p>
<pre name=code class=php>&lt;?php

function sheepBorn($n, &#038;$list)
{
    if ($list[$n]) return $list[$n];

    if $n < 1   return 0;
    if $n <= 2  return 1;

    $list[$n] = sheepBorn( $n - 1, $list ) + sheepBorn( $n - 2,  $list ) - sheepBorn( $n - 5,  $list );
    return $list[$n];
}

$list = array();
for ($year = 1; $year&lt;=10; $year++)
    echo "The " . $year ."th year: " . sheepBorn($year, $list) . "\n" ;
?&gt;</pre>
<p>够强！可这样的代码，除了表达一下自己的超强算法之外，给别人带来的困惑也会增加，要在注释上多下功夫了。</p>
<p>最终，真相帝降临：
</pre>
<pre name=code class=php>&lt;?php
for($i = 0; $i &lt;= 10; $i ++)
{
    if ($i &lt; 5)
        echo "The " . $i . "year is: 1 ";
    else
        echo "The " . $i . "year is: 0 ";
}</pre>
<p>只有一只羊的情况下确实不能繁殖。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/11/05/php%e7%9a%84%e6%99%ae%e9%9d%92%e3%80%81%e6%96%87%e9%9d%92%e5%92%8c2b%e9%9d%92/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>posix的特性——fork</title>
		<link>http://www.litrin.net/2011/08/31/posix%e7%9a%84%e7%89%b9%e6%80%a7%e2%80%94%e2%80%94fork/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=posix%25e7%259a%2584%25e7%2589%25b9%25e6%2580%25a7%25e2%2580%2594%25e2%2580%2594fork</link>
		<comments>http://www.litrin.net/2011/08/31/posix%e7%9a%84%e7%89%b9%e6%80%a7%e2%80%94%e2%80%94fork/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 05:28:42 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1541</guid>
		<description><![CDATA[记得之前曾经在一段Python中介绍过python的mulitprocess模块在windows的不兼容。其中提及了linux/Unix特有的fork方式，而windows无法实现导致的死循环。当时只是提到了一下，重点不同的关系，没有深究。 fork，顾名思义就是一把叉子，或者专业一点叫做复制叉。作为sys/type.h的一个函数，系统在每次调用fork()之后，将会以此为分叉，对进程本身进行复制，新的进程和旧进程有近乎完全一致的cpu时间和内存寄存器。 这本身并不重要，重要的是对于fork()函数的返回而言，父进程返回的是子进程的pid，而子进程返回的是0，当然还有一个-1的返回表示fork()的失败。对与C大致如此： #include &#60;unistd.h&#62;; #include &#60;sys/types.h&#62;; main () { pid_t pid; pid=fork(); if (pid &#60; 0) printf("error in fork!"); else { if (pid == 0) { printf("i am the child process, my process id is %d\n",getpid()); exit(); } else { printf("i am the parent process, my process id is %d\n",getpid()); exit(); } } } [...]]]></description>
			<content:encoded><![CDATA[<p>记得之前曾经在一段Python中介绍过<a title="python multiprocessing的问题" href="http://www.litrin.net/2010/06/23/python-multiprocessing%e7%9a%84%e9%97%ae%e9%a2%98/">python的mulitprocess模块在windows的不兼容</a>。其中提及了linux/Unix特有的fork方式，而windows无法实现导致的死循环。当时只是提到了一下，重点不同的关系，没有深究。</p>
<p>fork，顾名思义就是一把叉子，或者专业一点叫做复制叉。作为sys/type.h的一个函数，系统在每次调用fork()之后，将会以此为分叉，对进程本身进行复制，新的进程和旧进程有近乎完全一致的cpu时间和内存寄存器。</p>
<p><span id="more-1541"></span></p>
<p><img src="http://www.litrin.net/wp-content/uploads/2011/08/linux_fork.gif" alt="fork模型" title="fork模型" width="246" height="152" class="aligncenter size-full wp-image-1545" /></p>
<p>这本身并不重要，重要的是对于fork()函数的返回而言，父进程返回的是子进程的pid，而子进程返回的是0，当然还有一个-1的返回表示fork()的失败。对与C大致如此：</p>
<pre>#include &lt;unistd.h&gt;;
#include &lt;sys/types.h&gt;;

main ()
{
        pid_t pid;
        pid=fork();

        if (pid &lt; 0)
                printf("error in fork!");
        else
        {
			if (pid == 0)
                        {
                                 printf("i am the child process, my process id is %d\n",getpid());
		                 exit();
                        }
			else
                        {
                                printf("i am the parent process, my process id is %d\n",getpid());
				exit();
                         }
         }
}</pre>
<p>执行后，父进程和子进程分别将自己的Pid打印出来。</p>
<p>既然如此，对于我常用的php来说，可以同样做到后端执刑一些耗时的操作，从而达到异步的效果：</p>
<pre name=code class="php">function mulitProcess()/*{{{*/
{
        if (function_exists(pcntl_fork))
        {
            $pid = pcntl_fork();

		    if ( $pid === -1 )
		    {
		    	return false;
		    }
		    elseif ( $pid )
		    {
                        usleep(10);
                        exit();
                    }
                    else
                    {
                         doBackground();
                    }
        }
        // windows system or php not support PCNTL libs
        else
        {
			doBackground();
        }
}</pre>
<p>对于很多守护进程来说，脱离shell（即“脱壳”）正是利用了这种方式进行进程复制。对与PHP来说需要进行2次fork之后配合一个死循环即可,当然为了防止死循环真的“死掉”需要sleep()函数来进行休眠：</p>
<pre name=code class="php">function daemonize() /*{{{*/
{
    $pid    =   pcntl_fork();

    if (-1 == $pid)
    {
        return false;
    }
    elseif ($pid)  //parent process
    {
        usleep(500);
        exit();
    }
    $sid    =   posix_setsid();

    if (!$sid)
    {
        return false;
    }

    $pid    =   pcntl_fork();

    if ( -1 == $pid )
    {
        return false;
    }
    elseif ($pid)
    {
        usleep(500);
        exit(0);
    }

    // deny process display and io
    if (defined('STDIN'))
            fclose(STDIN);

    if (defined('STDOUT'))
            fclose(STDOUT);

    if (defined('STDERR'))
            fclose(STDERR);
    while(true)
            doSomeThing();

}/*}}}*/</pre>
<p>需要注意的是，windows没有fork()，php直接屏蔽了PCNL函数库，而python相对没有一棒子打死。Python采用的方式等于在命令行重新调用一次脚本，如果直接将没有考虑到这个问题的python脚本直接移植windows的话进程数量将会爆炸式增长，很快就会导致资源耗尽。由于我在windows上大多只是进行测试而已，多进程带来的性能优势不重要，习惯上我的方法就是使用threading模块替换掉mulitprocessing模块。写个示例：</p>
<pre name=code class="python">
try: #if os.name == 'posix':
    from multiprocessing import Process, Queue
except: #else:
    from threading import Thread as Process
    from Queue import Queue
</pre>
<p><img src="http://www.litrin.net/wp-content/uploads/2011/08/windows_fork_sim-300x125.gif" alt="windows模拟fork模型" title="悲催的windows模拟fork模型" width="300" height="125" class="aligncenter size-medium wp-image-1546" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/08/31/posix%e7%9a%84%e7%89%b9%e6%80%a7%e2%80%94%e2%80%94fork/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu上Coreseek+php的安装</title>
		<link>http://www.litrin.net/2011/06/16/ubuntu%e4%b8%8acoreseekphp%e7%9a%84%e5%ae%89%e8%a3%85/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ubuntu%25e4%25b8%258acoreseekphp%25e7%259a%2584%25e5%25ae%2589%25e8%25a3%2585</link>
		<comments>http://www.litrin.net/2011/06/16/ubuntu%e4%b8%8acoreseekphp%e7%9a%84%e5%ae%89%e8%a3%85/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 02:23:30 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[数据库应用]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1489</guid>
		<description><![CDATA[Coreseek是一个基于sphinx引擎，支持与mmseg中文分词模块合作完成中文的全文搜索引擎。相对sql这类操作，Coreseek负载可谓是微不足道。当然类似的索引服务器还有给予Java的solr等。我选择coreseek的主要原因之一是他可以通过配置后可以与现有的mysql客户端兼容，并可以直接嵌入到mysql中成为mysql的引擎之一。 首先，下载安装包，我选择的是最新的stable版， 不过不客气的说，即便是coreseek的stable版本，不论是从稳定性、兼容性还是灵活性上都不能算是完善，至少无法跟apache这类经典应用相提并论。 安装ubuntu开发包： apt-get install make gcc g++ automake libtool mysql-client libmysqlclient15-dev libxml2-dev libexpat1-dev   解压： tar xzvf coreseek-3.2.14.tar.gz cd coreseek-3.2.14 应该看到有mmseg csft testpack 至少3个目录 安装mmseg中文分词模块 cd mmseg-3.2.14 ./bootstrap ./configure &#8211;prefix=/usr/local/mmseg3 #不喜欢这个官方目录配置，更换目录后配置无法生效郁闷了很久，稍后再说 make make install cd ../testpack /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml #测试结果，请确保终端可以看到utf8中文，应该可以看到分词后的结果 安装Python包 虽然coreseek支持直接的mysql连接，但考虑到分词、分表的情况，这种设置不是很灵活。我的方案是通过python脚本的预处理，将mysql的数据整理后传输到coreseek建立索引。这样还有一个优势就是“万能数据源”——memcache、redis这类几乎不指望coreseek官方支持的妖异存储方案，只要有python的api，均可以索引。 官方的安装手册中介绍的python接口是基于ActivePython 替代系统python语言的方式进行的。ActivePython属于第三方封包，远没有系统自带python来的方便，刚开始用系统python测试了数次，均不成功，后来根据出错信息，找到了原因。 apt-get install python-dev python-sqlite python-mysqldb python-memcache 安装coreseek cd ../csft-3.2.14 [...]]]></description>
			<content:encoded><![CDATA[<p>Coreseek是一个基于sphinx引擎，支持与mmseg中文分词模块合作完成中文的全文搜索引擎。相对sql这类操作，Coreseek负载可谓是微不足道。当然类似的索引服务器还有给予Java的solr等。我选择coreseek的主要原因之一是他可以通过配置后可以与现有的mysql客户端兼容，并可以直接嵌入到mysql中成为mysql的引擎之一。</p>
<p>首先，下载安装包，我选择的是<a rel="nofollow" target="_blank" href="http://www.coreseek.cn/uploads/csft/3.2/coreseek-3.2.14.tar.gz">最新的stable版</a>， 不过不客气的说，即便是coreseek的stable版本，不论是从稳定性、兼容性还是灵活性上都不能算是完善，至少无法跟apache这类经典应用相提并论。</p>
<p><span id="more-1489"></span><br />
安装ubuntu开发包：<br />
apt-get install make gcc g++ automake libtool mysql-client libmysqlclient15-dev libxml2-dev libexpat1-dev</p>
<p><strong> </strong><br />
解压：<br />
tar xzvf coreseek-3.2.14.tar.gz<br />
cd coreseek-3.2.14</p>
<p>应该看到有mmseg csft testpack 至少3个目录</p>
<p><strong>安装mmseg中文分词模块</strong></p>
<p>cd mmseg-3.2.14<br />
./bootstrap<br />
./configure &#8211;prefix=/usr/local/mmseg3 #不喜欢这个官方目录配置，更换目录后配置无法生效郁闷了很久，稍后再说<br />
make<br />
make install<br />
cd ../testpack<br />
/usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml #测试结果，请确保终端可以看到utf8中文，应该可以看到分词后的结果</p>
<p><strong>安装Python包</strong></p>
<p>虽然coreseek支持直接的mysql连接，但考虑到分词、分表的情况，这种设置不是很灵活。我的方案是通过python脚本的预处理，将mysql的数据整理后传输到coreseek建立索引。这样还有一个优势就是“万能数据源”——memcache、redis这类几乎不指望coreseek官方支持的妖异存储方案，只要有python的api，均可以索引。</p>
<p>官方的安装手册中介绍的python接口是基于<a rel="nofollow" target="_blank" href="http://www.activestate.com/activepython" target="_blank">ActivePython</a> 替代系统python语言的方式进行的。ActivePython属于第三方封包，远没有系统自带python来的方便，刚开始用系统python测试了数次，均不成功，后来根据出错信息，找到了原因。</p>
<p>apt-get install python-dev python-sqlite python-mysqldb python-memcache</p>
<p><strong>安装coreseek</strong></p>
<p>cd ../csft-3.2.14<br />
./buildconf.sh<br />
./configure &#8211;prefix=/usr/local/coreseek &#8211;without-unixodbc &#8211;with-mmseg &#8211;with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ &#8211;with-mmseg-libs=/usr/local/mmseg3/lib/ &#8211;with-mysql &#8211;with-python<br />
make<br />
make install</p>
<p>cd ../testpack<br />
/usr/local/coreseek/bin/indexer -c etc/csft.conf &#8211;all<br />
/usr/local/coreseek/bin/search -c etc/csft.conf 网络搜索 #没什么问题了</p>
<p><strong>安装libsphinxclient</strong></p>
<p>coreseek官方教程中建议php使用直接include一个php文件进行操作，事实上php有独立的sphinx模块可以直接操作coreseek (coreseek就是sphinx！)已经进入了php的官方函数库，而且效率的提升不是一点点！但php模块依赖于libsphinxclient包。</p>
<p>cd ../csft-3.2.14/api/libsphinxclient<br />
./configure<br />
make<br />
make install<br />
ldconfig</p>
<p><strong>安装php-sphinx支持 </strong></p>
<p>apt-get install php5-dev<br />
wget http://pecl.php.net/get/sphinx-1.1.0.tgz<br />
tar vzxf  sphinx-1.1.0.tgz<br />
cd  sphinx-1.1.0<br />
phpize<br />
./configure<br />
make<br />
make install</p>
<p>确信成功后修改php.ini，还是遵从ubuntu的配置规则<br />
echo “extension=sphinx.so”  &gt; /etc/php5/conf.d/sphinx.ini</p>
<p>如果使用apache或者fast-cgi的话，请重起。察看phpinfo() 如下则安装成功。</p>
<h2><a name="module_sphinx">sphinx</a></h2>
<table border="0" cellpadding="3" width="600">
<tbody>
<tr>
<th>sphinx support</th>
<th>enabled</th>
</tr>
<tr>
<th>Version</th>
<th>1.1.0</th>
</tr>
<tr>
<th>Revision</th>
<th>$Revision: 303462 $</th>
</tr>
</tbody>
</table>
<p> </p>
<p><strong>配置coreseek</strong></p>
<p>说容易也容易，说麻烦也麻烦的工作，照贴一份吧前面说过，我用的是python数据源</p>
<p>/usr/local/coreseek/etc/coreseek.conf</p>
<pre>python
{
           path = /usr/local/coreseek/DBSource #python 数据源脚本的存放路径
}
source Blog #索引库1 “Blog”
{
          type = python #类型为python
          name = Blog.MainSource #调用python的class
}
index Blog
{
    source          = Blog #数据源名称
    path            = /data/sphinx/Blog #数据文件存放路径
    docinfo         = extern
    mlock           = 0
    morphology      = none
    min_word_len    = 1
    html_strip      = 0
   charset_dictpath = /usr/local/mmseg3/etc/ #mmseg中文分词库的位置，本文开头时我说不能修改mmseg的安装路径就错在这里
   charset_type        = zh_cn.utf-8
}
source UserInfo #索引库2 “UserInfo” 其余同上
{
    type = python
    name = UserInfo.MainSource
}
index UserInfo
{
     source          = UserInfo
     path            = /data/sphinx/UserInfo
     docinfo         = extern
     mlock           = 0
    morphology      = none
    min_word_len    = 1
    html_strip      = 0
    charset_dictpath = /usr/local/mmseg3/etc/
    charset_type        = zh_cn.utf-8
}

searchd #服务器配置
{
    listen          =   9312  #显而易见，默认的监听端口
    listen          =   172.18.196.90:3306:mysql41 #兼容mysql方式的监听，我们配置了php-sphinx，故除了命令行方式外意义不大，可以关闭
    pid_file        =   /var/run/coreseek.pid
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/06/16/ubuntu%e4%b8%8acoreseekphp%e7%9a%84%e5%ae%89%e8%a3%85/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LAMP的常用扩展安装</title>
		<link>http://www.litrin.net/2011/05/16/lamp%e7%9a%84%e5%b8%b8%e7%94%a8%e6%89%a9%e5%b1%95%e5%ae%89%e8%a3%85/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lamp%25e7%259a%2584%25e5%25b8%25b8%25e7%2594%25a8%25e6%2589%25a9%25e5%25b1%2595%25e5%25ae%2589%25e8%25a3%2585</link>
		<comments>http://www.litrin.net/2011/05/16/lamp%e7%9a%84%e5%b8%b8%e7%94%a8%e6%89%a9%e5%b1%95%e5%ae%89%e8%a3%85/#comments</comments>
		<pubDate>Mon, 16 May 2011 01:57:56 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[数据库应用]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1467</guid>
		<description><![CDATA[之前已经弄过许多篇关于LAMP搭建的东西，都是基于最简单包的，这次说说几个比较常用扩展的安装： FreeBSD + Apache + PHP + Mysql (恶搞版) FreeBSD + Apache + PHP + Mysql + Oracle Ubuntu + Apache + PHP + Mysql ，比较简单，正常server版安装结束的最后一步可以选择安装LAMP Ubuntu + nginx + php Ubuntu + php + Oracle Memcache 说起Memcache，这年头稍微大点的网站几乎是必不可少的。内存Key-value一对一数据库，但数据易失。新浪的团队也有个项目是memcachedb，就是以速度为代价，部分数据回写硬盘。但似乎不是memcache的本意，个人觉得不如直接写sql，仁者见仁吧。 For Ubuntu apt-get install memcached php5-memcache /etc/init.d/memcached start For FreeBSD cd /usr/ports/databases/memcached make install clean cd /usr/ports/databases/pecl-memcache make [...]]]></description>
			<content:encoded><![CDATA[<p>之前已经弄过许多篇关于LAMP搭建的东西，都是基于最简单包的，这次说说几个比较常用扩展的安装：</p>
<ul>
<li><a title="用FreeBSD的ports安装apache+php+mysql" href="http://www.litrin.net/2005/11/09/%e7%94%a8freebsd%e7%9a%84ports%e5%ae%89%e8%a3%85apachephpmysql/" target="_blank">FreeBSD + Apache + PHP + Mysql</a> (<a title="用FreeBSD的ports安装apache+php+mysql·改" href="http://www.litrin.net/2007/08/01/%e7%94%a8freebsd%e7%9a%84ports%e5%ae%89%e8%a3%85apachephpmysql%c2%b7%e6%94%b9/" target="_blank">恶搞版</a>)</li>
<li><a title="FreeBSD+apache+PHP+OCI支持Oracle" href="http://www.litrin.net/2009/06/15/freebsdapachephpoci%e6%94%af%e6%8c%81oracle/" target="_blank">FreeBSD + Apache + PHP + Mysql + Oracle</a></li>
<li>Ubuntu + Apache + PHP + Mysql ，比较简单，正常server版安装结束的最后一步可以选择安装LAMP</li>
<li><a title="Ubuntu下安装Nginx+php(FastCGI)" href="http://www.litrin.net/2010/10/27/ubuntu%e4%b8%8b%e5%ae%89%e8%a3%85nginxphpfastcgi/" target="_blank">Ubuntu + nginx + php</a></li>
<li><a title="配置Ubuntu的php支持OCI8" href="http://www.litrin.net/2009/09/15/%e9%85%8d%e7%bd%aeubuntu%e7%9a%84php%e6%94%af%e6%8c%81oci8/" target="_blank">Ubuntu + php + Oracle</a></li>
</ul>
<p><span id="more-1467"></span></p>
<p><strong>Memcache</strong></p>
<p>说起Memcache，这年头稍微大点的网站几乎是必不可少的。内存Key-value一对一数据库，但数据易失。新浪的团队也有个项目是memcachedb，就是以速度为代价，部分数据回写硬盘。但似乎不是memcache的本意，个人觉得不如直接写sql，仁者见仁吧。</p>
<ul>
<li>For Ubuntu<br />
apt-get install memcached php5-memcache<br />
/etc/init.d/memcached start</li>
<li>For FreeBSD<br />
cd /usr/ports/databases/memcached<br />
make install clean<br />
cd /usr/ports/databases/pecl-memcache<br />
make install clean<br />
echo”memcached_enable=YES” &gt;&gt; /etc/rc.conf<br />
/usr/local/etc/rc.d/memcached start</li>
</ul>
<p><strong>Redis</strong></p>
<p>也是一个Key-value数据库，比起Memcache速度慢一点，但会回写硬盘，数据不丢失。处理Feed之类SQL吃上劲的应用必备。</p>
<ul>
<li>For Ubuntu //11.04可行，8.04不行，官方似乎从904以后才加入的。之前的版本不妨用<a rel="nofollow" target="_blank" href="http://ftp.us.debian.org/debian/pool/main/r/redis/" target="_blank">debian包<br />
</a>apt-get install redis-server php-redis //同样的<a rel="nofollow" target="_blank" href="http://ftp.us.debian.org/debian/pool/main/p/php-radius/" target="_blank">debian包下载</a><br />
/etc/init.d/redis-server start</li>
<li>For Freebsd<br />
cd /usr/ports/databases/redis<br />
make install clean<br />
echo &#8216;redis_enable=”YES”&#8216; &gt;&gt; /etc/rc.conf<br />
/usr/local/etc/rc.d/redis restart<br />
cd /usr/ports/databases/php5-redis<br />
make install clean //敲的条件反射了</li>
</ul>
<p>说起redis的PHP支持类，由于redis是明文的传输，所以很多人会选择<a rel="nofollow" target="_blank" href="https://github.com/jdp/redisent" target="_blank">redisend</a>这类基于socket连接方式的php类——说白了就是模拟telnet 6379。根据实际测试的结果，C扩展至少有40%以上的提升，而且内存更少，加包和拆包的过程更迅速。更何况redisend的前一个版本一堆问题，后一个版本又是php5.3 only的天上一脚，地上一脚的维护也是麻烦。不是万不得已还是少用为妙。</p>
<p><strong>PHP-FPM</strong></p>
<p>这个是给Nginx做fastcgi扩展的，相比php-cgi, spawn-cgi不但性能上有提升，配置上也灵活的多，但FreeBSD不支持，Ubuntu也不官方推荐。这里使用了ubuntu的非官方库。</p>
<p>echo “deb <a rel="nofollow" target="_blank" href="http://php53.dotdeb.org">http://php53.dotdeb.org</a> stable all” &gt;&gt; /etc/apt/sources.list<br />
apt-get update; apt-get upgrade<br />
apt-get install php5-fpm</p>
<p>会直接覆盖之前官方支持的PHP包，请慎重考虑。</p>
<p>/etc/init.d/php5-fpm start</p>
<p><strong>PHP-GD</strong></p>
<p>最常见的缺失，但很容易。</p>
<ul>
<li>For Ubuntu<br />
apt-get install php5-gd</li>
<li>For FreeBSD<br />
cd /usr/ports/graphics/php5-gd<br />
make install clean</li>
</ul>
<p><strong>Minify</strong></p>
<p>Minify是一个基于PHP5的CSS/JS优化包，其实这不属于Php的扩展。</p>
<ol>
<li><a rel="nofollow" target="_blank" href="http://code.google.com/p/minify/">http://code.google.com/p/minify/</a> 下载最新的minify，解压后，将min目录拷贝至网站根目录下。</li>
<li>确认是否开启了apache 的mod_rewrite，Ubuntu默认不开启，需要a2enmod,选择rewrite后,/etc/init.d/apache2 restart 重起apache</li>
<li>网站根目录下编辑.htaccess内容如下：
<pre>RewriteEngine On
        RewriteBase /
         RewriteRule ^(.*\.(css|js))\S?$ min/index.php?f=$1 [L]</pre>
</li>
<li>如果系统已经安装了memcache包，不妨用MC替代文件方式存储优化后的信息，编辑min/config.php，末尾添加
<pre class="php">require 'lib/Minify/Cache/Memcache.php';
$memcache = new Memcache;
$memcache-&gt;connect('localhost', 11211); //根据本地配置调整
$min_cachePath = new Minify_Cache_Memcache($memcache);</pre>
</li>
</ol>
<p><strong>TokyoTyrant (ttServer)</strong></p>
<p>TykyoTyrant想必web game, social game的公司用的很多，大概是由于某家企鹅公司的框架所限吧。这东西就是一个“支持lua扩展并可持续化”的key-value。个人觉得完全可以通过memcache + redis两者取代。</p>
<ul>
<li>for Ubuntu (natty ok, hardy not support)<br />
apt-get install tokyotyrant<br />
/etc/init.d/tokyotyrant 52~53行稍作修改：<br />
52 #SERVERHOST=”$RUNDIR/$NAME.sock”<br />
53 SERVERPORT=1978<br />
即可通过/etc/init.d/tokyotyrant start命令启动1978端口的监听</li>
</ul>
<ul>
<li>for Freebsd<br />
cd /usr/ports/databases/tokyotyrant/<br />
make install clean</li>
</ul>
<div>tokyotyrant有自己的php模块，但习惯上都是通过memcache模块进行操作的，命令等价于memcahce的操作。</div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/05/16/lamp%e7%9a%84%e5%b8%b8%e7%94%a8%e6%89%a9%e5%b1%95%e5%ae%89%e8%a3%85/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ecshop的问题</title>
		<link>http://www.litrin.net/2011/04/28/ecshop%e7%9a%84%e9%97%ae%e9%a2%98/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ecshop%25e7%259a%2584%25e9%2597%25ae%25e9%25a2%2598</link>
		<comments>http://www.litrin.net/2011/04/28/ecshop%e7%9a%84%e9%97%ae%e9%a2%98/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 08:22:05 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[网络和安全]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1454</guid>
		<description><![CDATA[在看一台服务器的SQL-Slow日志，看到了如下的一纪录，惊出了一身冷汗！ SELECT pg.package_id, pg.goods_id, pg.goods_number, pg.admin_id, g.goods_sn, g.goods_name, g.market_price, g.goods_thumb, g.is_real, IFNULL(mp.user_price, g.shop_price * '1') AS rank_price FROM `ecs_`.`ecs_package_goods` AS pg LEFT JOIN `ecs_venusveil`.`ecs_goods` AS g ON g.goods_id = pg.goods_id LEFT JOIN `ecs_venusveil`.`ecs_member_price` AS mp ON mp.goods_id = g.goods_id AND mp.user_rank = '0' WHERE pg.package_id = -1 union all select 1,2,3,4,5,6,7,8,count(*),concat( (Select concat(0x5b,email,0x3a,user_name,0x5d) FROM ecs_users [...]]]></description>
			<content:encoded><![CDATA[<p>在看一台服务器的SQL-Slow日志，看到了如下的一纪录，惊出了一身冷汗！</p>
<pre class="sql" name='code'>
SELECT pg.package_id, pg.goods_id, pg.goods_number,
        pg.admin_id, g.goods_sn, g.goods_name, g.market_price, g.goods_thumb, g.is_real,
        IFNULL(mp.user_price, g.shop_price * '1') AS rank_price
FROM `ecs_`.`ecs_package_goods` AS pg
        LEFT JOIN `ecs_venusveil`.`ecs_goods` AS g ON g.goods_id = pg.goods_id
        LEFT JOIN `ecs_venusveil`.`ecs_member_price` AS mp ON mp.goods_id = g.goods_id AND mp.user_rank = '0'
WHERE pg.package_id = -1
union all
        select 1,2,3,4,5,6,7,8,count(*),concat(
                (Select concat(0x5b,email,0x3a,user_name,0x5d)
                        FROM ecs_users
                        LIMIT 9456,1), floor(rand(0)*2))x
         from information_schema.tables
         group by x
ORDER BY pg.package_id, pg.goods_id;</pre>
<p><span id="more-1454"></span><br />
不知看懂没有，反正这句SQL是解释不通的。由于网站跑在ECshop2.7.2的环境之上，问题肯定来自代码缺陷。之前似乎有发过<a href="http://www.litrin.net/2009/09/11/%E8%AF%B4%E8%AF%B4%E2%80%9C%E4%B8%93%E4%B8%9A%E2%80%9D/">ECShop的牢骚</a>，作为一个商业软件，而且是做交易平台的商业软件，竟然如此不专业种种的操作。特地浏览了一下代码，发觉代码里面的更加经典！几乎没有对任何变量进行校验和过滤！</p>
<p>由于程序不是我开发的，无法追溯源。只能根据日志进行反查，找到了根基</p>
<ol>
<li>flow.php中2157行中json来源可由客户端定义，导致2182行$package-&gt;package_id不可控。</li>
<li>include/lib_order.php中对include/lib_common.php 的function get_package_info($id)可以植入SQL</li>
<li>畸形SQL导致Mysql返回空信息</li>
<li>攻击者获得无限量优惠包，仅此而已。</li>
</ol>
<p>无话可说！引以为戒吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/04/28/ecshop%e7%9a%84%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>高负载的Lamp架构</title>
		<link>http://www.litrin.net/2011/04/20/%e9%ab%98%e8%b4%9f%e8%bd%bd%e7%9a%84lamp%e6%9e%b6%e6%9e%84/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e9%25ab%2598%25e8%25b4%259f%25e8%25bd%25bd%25e7%259a%2584lamp%25e6%259e%25b6%25e6%259e%2584</link>
		<comments>http://www.litrin.net/2011/04/20/%e9%ab%98%e8%b4%9f%e8%bd%bd%e7%9a%84lamp%e6%9e%b6%e6%9e%84/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 04:23:26 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[数据库应用]]></category>
		<category><![CDATA[硬件相关]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[网络和安全]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1435</guid>
		<description><![CDATA[记得那时是2005年10月，开源小站刚上线不久的一篇文章。那时的我还仅仅将网站的高可用性和大负载，大流量集中在“堆硬件”的层面上。包括之后的一篇文档，似乎也没有逃脱这个范畴。之后由于工作内容的关系，始终没有再继续探讨这个问题。仅仅只在一篇关于GAE的文章中讲述了一下架构的趋势。 时隔了5年多，不妨回头重新从新的高度上说说LAMP结构的网站如何支撑尽可能大的负载。同样说明，本文代表站长Litrin的个人意见，欢迎共同探讨，但喷子慎入。 首先声明的是，以下一堆相对无趣的文字仅针对一系列负载到了至少10W pv以上级别，对于较小规模的网站大可不必遵守，还是提倡成本优先的原则，到了对应的PV级别想必也会有足够的财力和物力去改版了。 初期规划 这里主要还是指设计模型等前期工作。MVC的设计结构深入人心，不得不承认确实大多架构设计师首选的设计结构必是MVC。事实上，在一个网站上最容易获取，最不缺的资源是CPU和内存，最大的瓶颈都是出现在IO。 作为LAMP架构最大的问题就是MVC的代价太大，层层的封包意味着重复判断；打开大量的程序文件只会严重拖累性能。网上很多免费的、开源的PHP框架，用过的几个诸如ThinkPHP, ZF等应付中小型网站绝对没有问题，但都不适合大负载的网站。甚至包括Smarty这样单纯的模版引擎，大量的IO操作会拖累整体性能。如果不考虑其他因素，我甚至都考虑过All in 1的垃圾结构——这当然不现实。但恰恰是这种all in 1却正是大负载最适合的结构。奇怪的悖论。 受GAE的影响，曾经想过API+XML的方式实现网站架构，但后来打消了这个念头。XML本身的结构冗余度很多，这也就意味着信息承载率低。在内部几台服务器之间的通讯状况想必都没有必要搞XML，如果要搞类似的模式，CSV方式反倒是不错的选择。XML是为了开放给第三方用户的。 数据库设计 读写分离这个是众所周知的秘密了。Mysql 的Master + Slaver的设计真的很方便！最多就是多搞几重的读写分离。 拆表、拆库、分机器，大表做纵拆，宽表做横拆，不关联的分机器；纵拆是为了省时间，横拆是为了省内存，分机器是为了分负载。Mysql在几百万行数据级别以下性能是很不错的，超过这个数量级，就算机器再强悍都会死的很难看，mysql垃圾的锁表机制会展现无疑。没有人愿等到30秒以上的Respone，何况我曾经遭遇一个45分钟以上的Select操作（一重操作，没有用到Like，使用索引）。曾经用过mysql 的分区表，感觉这种方法更像是在打补丁——改变数据库结构去适应程序，很奇怪的流程，更何况即便逃过这次不拆，迟早有一天还会回来拆的。 索引，该有的全都有，但对于写操作频繁的表，索引反倒成了累赘，不要让索引数占到字段数的30%以上这是约定俗成的标准吧。 memcache，没什么可以多说的，这玩意基本上就是铺硬件换时间的。 说道非关系型数据库，好像近期很热门。怎么说呢？越是复杂的网站越是能体现出它的优势，但问题是大多数网站都不会像twitter或者Facebook这么复杂，况且大多数程序员的逻辑还是SQL模式，贸进很可能搞砸。 WWW服务器拓扑设计 F5这类的设备是必须的，之前曾经觉得LVS可以替代F5这样的设备。用过之后才发现，这等于是将整个网站的身价性命都扔到了一台服务器上，一旦宕机或者被侵入呢？ 对于Apache还是nginx的争论持续了很久。nginx很快速，可以将单独的PHP负载分离出去，但没有apache来的灵活。要根据需求再做评价。 异步操作和缓存机制 这个貌似也没有什么花头，调整好负载之后可以将一部分操作异步到数据库相对空闲的时段进行，达到移峰填谷的效果。配合memcache或者其他的缓存机制本身也是动转静的手段之一。 自动和手动的问题 属于代码级别了吧。良好的编程规范对系统的优化是很显著的。漫山遍野的select *， 大量的变量不清空是高负载系统的忌讳。纵然php的内存处理机制再出色，它永远也不会理解你设置的变量什么时候失效，减少这看似寥寥无几的空间乘上惊人的pv数也是很可观的。]]></description>
			<content:encoded><![CDATA[<p>记得那时是2005年10月，<a title="开源小站" href="http://www.litrin.net" target="_blank">开源小站</a>刚上线不久的<a title="中国顶级门户网站架构分析" href="http://www.litrin.net/2005/10/27/%e4%b8%ad%e5%9b%bd%e9%a1%b6%e7%ba%a7%e9%97%a8%e6%88%b7%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84%e5%88%86%e6%9e%90/" target="_blank">一篇文章</a>。那时的我还仅仅将网站的高可用性和大负载，大流量集中在“堆硬件”的层面上。包括之后的<a href="http://www.litrin.net/2005/11/06/%e5%8c%96%e7%ae%80%e4%b8%ba%e7%b9%81%e2%80%94%e2%80%94%e4%bc%98%e5%8c%96%e4%bd%a0%e7%9a%84%e7%bd%91%e7%ab%99%e5%b1%82%e6%ac%a1/" target="_blank">一篇文档</a>，似乎也没有逃脱这个范畴。之后由于工作内容的关系，始终没有再继续探讨这个问题。仅仅只在一篇关于<a href="http://www.litrin.net/2010/12/21/%e4%bb%8egae%e7%9c%8b%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84%e8%b6%8b%e5%8a%bf/" target="_blank">GAE的文章</a>中讲述了一下架构的趋势。</p>
<p>时隔了5年多，不妨回头重新从新的高度上说说LAMP结构的网站如何支撑尽可能大的负载。同样说明，本文代表站长Litrin的个人意见，欢迎共同探讨，但喷子慎入。</p>
<p><span id="more-1435"></span></p>
<p>首先声明的是，以下一堆相对无趣的文字仅针对一系列负载到了至少10W pv以上级别，对于较小规模的网站大可不必遵守，还是提倡成本优先的原则，到了对应的PV级别想必也会有足够的财力和物力去改版了。</p>
<h2>初期规划</h2>
<p>这里主要还是指设计模型等前期工作。MVC的设计结构深入人心，不得不承认确实大多架构设计师首选的设计结构必是MVC。事实上，在一个网站上最容易获取，最不缺的资源是CPU和内存，最大的瓶颈都是出现在IO。</p>
<p>作为LAMP架构最大的问题就是MVC的代价太大，层层的封包意味着重复判断；打开大量的程序文件只会严重拖累性能。网上很多免费的、开源的PHP框架，用过的几个诸如ThinkPHP, ZF等应付中小型网站绝对没有问题，但都不适合大负载的网站。甚至包括Smarty这样单纯的模版引擎，大量的IO操作会拖累整体性能。如果不考虑其他因素，我甚至都考虑过All in 1的垃圾结构——这当然不现实。但恰恰是这种all in 1却正是大负载最适合的结构。奇怪的悖论。</p>
<p>受GAE的影响，曾经想过API+XML的方式实现网站架构，但后来打消了这个念头。XML本身的结构冗余度很多，这也就意味着信息承载率低。在内部几台服务器之间的通讯状况想必都没有必要搞XML，如果要搞类似的模式，CSV方式反倒是不错的选择。XML是为了开放给第三方用户的。</p>
<h2>数据库设计</h2>
<p>读写分离这个是众所周知的秘密了。Mysql 的Master + Slaver的设计真的很方便！最多就是多搞几重的读写分离。</p>
<p>拆表、拆库、分机器，大表做纵拆，宽表做横拆，不关联的分机器；纵拆是为了省时间，横拆是为了省内存，分机器是为了分负载。Mysql在几百万行数据级别以下性能是很不错的，超过这个数量级，就算机器再强悍都会死的很难看，mysql垃圾的锁表机制会展现无疑。没有人愿等到30秒以上的Respone，何况我曾经遭遇一个45分钟以上的Select操作（一重操作，没有用到Like，使用索引）。曾经用过mysql 的分区表，感觉这种方法更像是在打补丁——改变数据库结构去适应程序，很奇怪的流程，更何况即便逃过这次不拆，迟早有一天还会回来拆的。</p>
<p>索引，该有的全都有，但对于写操作频繁的表，索引反倒成了累赘，不要让索引数占到字段数的30%以上这是约定俗成的标准吧。</p>
<p>memcache，没什么可以多说的，这玩意基本上就是铺硬件换时间的。</p>
<p>说道非关系型数据库，好像近期很热门。怎么说呢？越是复杂的网站越是能体现出它的优势，但问题是大多数网站都不会像twitter或者Facebook这么复杂，况且大多数程序员的逻辑还是SQL模式，贸进很可能搞砸。</p>
<h2>WWW服务器拓扑设计</h2>
<p>F5这类的设备是必须的，之前曾经觉得LVS可以替代F5这样的设备。用过之后才发现，这等于是将整个网站的身价性命都扔到了一台服务器上，一旦宕机或者被侵入呢？</p>
<p>对于Apache还是nginx的争论持续了很久。nginx很快速，可以将单独的PHP负载分离出去，但没有apache来的灵活。要根据需求再做评价。</p>
<h2>异步操作和缓存机制</h2>
<p>这个貌似也没有什么花头，调整好负载之后可以将一部分操作异步到数据库相对空闲的时段进行，达到移峰填谷的效果。配合memcache或者其他的缓存机制本身也是动转静的手段之一。</p>
<h2>自动和手动的问题</h2>
<p>属于代码级别了吧。良好的编程规范对系统的优化是很显著的。漫山遍野的select *， 大量的变量不清空是高负载系统的忌讳。纵然php的内存处理机制再出色，它永远也不会理解你设置的变量什么时候失效，减少这看似寥寥无几的空间乘上惊人的pv数也是很可观的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/04/20/%e9%ab%98%e8%b4%9f%e8%bd%bd%e7%9a%84lamp%e6%9e%b6%e6%9e%84/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>重新认识下PHP的输出</title>
		<link>http://www.litrin.net/2011/01/16/%e9%87%8d%e6%96%b0%e8%ae%a4%e8%af%86%e4%b8%8bphp%e7%9a%84%e8%be%93%e5%87%ba/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e9%2587%258d%25e6%2596%25b0%25e8%25ae%25a4%25e8%25af%2586%25e4%25b8%258bphp%25e7%259a%2584%25e8%25be%2593%25e5%2587%25ba</link>
		<comments>http://www.litrin.net/2011/01/16/%e9%87%8d%e6%96%b0%e8%ae%a4%e8%af%86%e4%b8%8bphp%e7%9a%84%e8%be%93%e5%87%ba/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 09:24:47 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1383</guid>
		<description><![CDATA[大概在02 03年或者更早，我第一次接触了PHP lib中的模板类，后来又开始用了众人皆知的Smarty，以及各种框架内自带的模板引擎。这段时间就几乎没有再用过直接的echo输出——临时的脚本除外。似乎现在再去写个网站，一大堆echo嵌入到HTML里，会被同行笑话的，至少会被认为是学生作品吧。本文就重新捡回这个命令，重新认识下。 PHP程序员的逻辑： 数据经过加工，传输给模板引擎，模板引擎选择合适的模板填充，输出为页面通过www服务器传输给用户。 再此之前，请自查手册，熟悉ob_end_clean() flush()以及相关联的输出控制函数。 如果能看懂如下伪代码，并认为这是一团糟糕的死循环的话请继续： &#60;?php set_time_limit(300); header('Cache-control: Private'); ob_end_clean(); while (true) { if ($Count % 2 == 0){ echo "&#60;div&#62;"; echo time(); echo "&#60;/div&#62;"; flush(); } $Count ++;  sleep(1); } echo优势之一——用户体验的改善 尽管现在手机已经进入了3G时代，网速已经接近了有线宽带的水平，但作为手机网络而言，最令人头疼的就是它的不稳定。用传统的方式载入模板，所有的输出必须先行等待数据完全准备好之后才能一次性输出，这可能会需要等待很长时间。API要时刻考虑到可能会出现的断网问题，特别是在大段文件之后，较长时间的等待响应时间之中如果一旦出现网络间断（不是中断）就会让手机端白屏，影响用户体验。 利用此段代码正是n久之前，在没有大规模使用前端缓冲或者ajax技术的时候，很多网站经常看得到的那种分段式载入的效果。程序的逻辑是：step1完成，立即输出给www服务器，在用户等待数据下载的同时准备step2，依次类推。确保用户先“有东西看”。即便中途网络间断，照样可以获取网页内容。 echo优势之二——HTTP长链接的实现 现在很多网站都在搞微博或者网页版本的IM，山寨版本Kik之类的东西。特别是后两种，设置一个定时刷新的js如果间隔很大，等于没有意义；间隔很小的话，请自行领略F5卡住对服务器的影响。要知道对于www服务器而言，建立/中断一个HTTP连接的操作同样是一个高资源耗费的过程。 利用此段代码的逻辑就是将http通常使用的短连接方式模拟一个长链接，每一个用户开一个http通道后不再立刻关闭而是建立一个持久的信道，后台执行一个轮询，一旦有新的数据则第一时间通过此信道传输给客户端。这种方式配合Json可以完成相当一部分数据刷新的需求。或者可以尝试用这种方式简单实现一些BS之间的心跳效果。 其他一些稀奇古怪的用法 Firefox这类的Mozilla系浏览器可以通过自有的header命令撤销之前的输出，通过定时的发送这个命令就可以达到不刷新而刷新的效果。具体header命令请google。 利用此模型带来的问题： set_time_limit(300);只是防止php超时罢了，对于www服务器而言，它也有自己的时效性，请注意不要被www踢出来。特别是apache有个keep_alive的设置要注意。 通用性，有前端缓冲的网站就暂时别想了，就算能成功也不保险啊。对于近期比较风光的轻量级http服务器而言，由于是单进程的，长链接对他们来说也不是擅长的。 浏览器缓冲的问题。有些“智能型”浏览器会认为你的服务器响应不及时而自说自话的启用了n年前的缓冲页面。而且对于IE这类有一大堆“安全策略”的浏览器而言这样的结果反而会白屏（IE7以后256个字节以内的信息不会显示）所以header一定要写，上面的那段仅仅只是伪代码，我不愿保证这个可以在任何浏览器上调试通过。 代码的复杂度，不用我说了吧。All in 1的代码反正我不想读。]]></description>
			<content:encoded><![CDATA[<p>大概在02 03年或者更早，我第一次接触了PHP lib中的模板类，后来又开始用了众人皆知的Smarty，以及各种框架内自带的模板引擎。这段时间就几乎没有再用过直接的echo输出——临时的脚本除外。似乎现在再去写个网站，一大堆echo嵌入到HTML里，会被同行笑话的，至少会被认为是学生作品吧。本文就重新捡回这个命令，重新认识下。</p>
<p>PHP程序员的逻辑：</p>
<p>数据经过加工，传输给模板引擎，模板引擎选择合适的模板填充，输出为页面通过www服务器传输给用户。<br />
再此之前，请自查手册，熟悉ob_end_clean() flush()以及相关联的输出控制函数。</p>
<p>如果能看懂如下伪代码，并认为这是一团糟糕的死循环的话请继续：</p>
<p><span id="more-1383"></span></p>
<pre class="php" name='code'>
&lt;?php

set_time_limit(300);
header('Cache-control: Private');
ob_end_clean();

while (true) {
    if ($Count % 2 == 0){
        echo "&lt;div&gt;";
        echo time();
        echo "&lt;/div&gt;";

        flush();
    }

    $Count ++; 

    sleep(1);
}
</pre>
<p><strong>echo优势之一——用户体验的改善</strong></p>
<p>尽管现在手机已经进入了3G时代，网速已经接近了有线宽带的水平，但作为手机网络而言，最令人头疼的就是它的不稳定。用传统的方式载入模板，所有的输出必须先行等待数据完全准备好之后才能一次性输出，这可能会需要等待很长时间。API要时刻考虑到可能会出现的断网问题，特别是在大段文件之后，较长时间的等待响应时间之中如果一旦出现网络间断（不是中断）就会让手机端白屏，影响用户体验。</p>
<p>利用此段代码正是n久之前，在没有大规模使用前端缓冲或者ajax技术的时候，很多网站经常看得到的那种分段式载入的效果。程序的逻辑是：step1完成，立即输出给www服务器，在用户等待数据下载的同时准备step2，依次类推。确保用户先“有东西看”。即便中途网络间断，照样可以获取网页内容。<br />
<strong>echo优势之二——HTTP长链接的实现</strong></p>
<p>现在很多网站都在搞微博或者网页版本的IM，山寨版本Kik之类的东西。特别是后两种，设置一个定时刷新的js如果间隔很大，等于没有意义；间隔很小的话，请自行领略F5卡住对服务器的影响。要知道对于www服务器而言，建立/中断一个HTTP连接的操作同样是一个高资源耗费的过程。</p>
<p>利用此段代码的逻辑就是将http通常使用的短连接方式模拟一个长链接，每一个用户开一个http通道后不再立刻关闭而是建立一个持久的信道，后台执行一个轮询，一旦有新的数据则第一时间通过此信道传输给客户端。这种方式配合Json可以完成相当一部分数据刷新的需求。或者可以尝试用这种方式简单实现一些BS之间的心跳效果。<br />
<strong>其他一些稀奇古怪的用法</strong></p>
<p>Firefox这类的Mozilla系浏览器可以通过自有的header命令撤销之前的输出，通过定时的发送这个命令就可以达到不刷新而刷新的效果。具体header命令请google。</p>
<p><strong>利用此模型带来的问题：</strong><strong><br />
</strong>set_time_limit(300);只是防止php超时罢了，对于www服务器而言，它也有自己的时效性，请注意不要被www踢出来。特别是apache有个keep_alive的设置要注意。</p>
<ol>
<li>通用性，有前端缓冲的网站就暂时别想了，就算能成功也不保险啊。对于近期比较风光的轻量级http服务器而言，由于是单进程的，长链接对他们来说也不是擅长的。</li>
<li>浏览器缓冲的问题。有些“智能型”浏览器会认为你的服务器响应不及时而自说自话的启用了n年前的缓冲页面。而且对于IE这类有一大堆“安全策略”的浏览器而言这样的结果反而会白屏（IE7以后256个字节以内的信息不会显示）所以header一定要写，上面的那段仅仅只是伪代码，我不愿保证这个可以在任何浏览器上调试通过。</li>
<li>代码的复杂度，不用我说了吧。All in 1的代码反正我不想读。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2011/01/16/%e9%87%8d%e6%96%b0%e8%ae%a4%e8%af%86%e4%b8%8bphp%e7%9a%84%e8%be%93%e5%87%ba/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Gtalk通知机器人脚本</title>
		<link>http://www.litrin.net/2010/12/02/gtalk%e9%80%9a%e7%9f%a5%e6%9c%ba%e5%99%a8%e4%ba%ba%e8%84%9a%e6%9c%ac/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gtalk%25e9%2580%259a%25e7%259f%25a5%25e6%259c%25ba%25e5%2599%25a8%25e4%25ba%25ba%25e8%2584%259a%25e6%259c%25ac</link>
		<comments>http://www.litrin.net/2010/12/02/gtalk%e9%80%9a%e7%9f%a5%e6%9c%ba%e5%99%a8%e4%ba%ba%e8%84%9a%e6%9c%ac/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 06:08:53 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[网络和安全]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1356</guid>
		<description><![CDATA[服务器每天都有这样那样的信息需要实时推送。最初一直是Mail，最容易实现，成本也低。后来有了短信接口，就有了相对实时但要花钱的方式推送。 知道GAE可以直接跟gtalk挂钩推送消息，可能一直挂Gtalk的人远没有挂QQ和MSN的多（密之声：Gtalk又没有星星和钻石，挂也没劲），但有了Android + 3G的实时在线，这种方式却可以直接替代SMS这类花钱的服务，何乐不为？ 大致上完成了原型，制作了一个基于Python的命令行程序，不敢独享，分享给大家。希望大家能够一起加入这个项目完善它。 在此之前，请现将 server-say @@@ appspot.com （你懂的！）加为好友 #!/usr/bin/python # -*- coding:utf-8 -*- import sys import re import urllib class ServerSaid: ApiURL = 'http://server-say.appspot.com/api' # #请到http://server-said.appspot.com/注册您的Ip地址。没有注册的Ip每小时最多10条消息。 # Account = '' MessageBody = '' DefaultEncode = 'utf-8' def SendMessage(self): cleanMessage = self.MessageBody.encode(self.DefaultEncode) if (self.checkEmail(self.Account) and self.checkMessage(cleanMessage)): cleanMessage = self.MessageBody.encode('utf-8') url = self.ApiURL + '?account='+ [...]]]></description>
			<content:encoded><![CDATA[<p>服务器每天都有这样那样的信息需要实时推送。最初一直是Mail，最容易实现，成本也低。后来有了短信接口，就有了相对实时但要花钱的方式推送。</p>
<p>知道GAE可以直接跟gtalk挂钩推送消息，可能一直挂Gtalk的人远没有挂QQ和MSN的多（密之声：Gtalk又没有星星和钻石，挂也没劲），但有了Android + 3G的实时在线，这种方式却可以直接替代SMS这类花钱的服务，何乐不为？</p>
<p>大致上完成了原型，制作了一个基于Python的命令行程序，不敢独享，分享给大家。希望大家能够一起加入这个项目完善它。<br />
在此之前，请现将 server-say @@@ appspot.com （你懂的！）加为好友</p>
<p><span id="more-1356"></span></p>
<pre class="python" name='code'>
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import re
import urllib

class ServerSaid:

	ApiURL = 'http://server-say.appspot.com/api'
	#
	#请到http://server-said.appspot.com/注册您的Ip地址。没有注册的Ip每小时最多10条消息。
	#
	Account = ''
	MessageBody = ''
	DefaultEncode = 'utf-8'

	def SendMessage(self):
		cleanMessage = self.MessageBody.encode(self.DefaultEncode)
		if (self.checkEmail(self.Account) and self.checkMessage(cleanMessage)):
			cleanMessage = self.MessageBody.encode('utf-8')
			url = self.ApiURL + '?account='+ urllib.quote(self.Account) +'&#038;message=' + urllib.quote(cleanMessage)
		#	print url
			query = urllib.urlopen(url)
			if ( query.read() == '200' ):
				print 'Message be sent!\\n'

			else:
				print self.Error(0)
		else :
			print self.Error(1)

	def Error(self, code=0):
		return  'Message can\\'t be send! \\n'

	def checkEmail(self, Email):
		RegexString = r'^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,5}$'

		return re.match(RegexString, Email)

	def checkMessage(self, Message):

		RegexString = r'^.{1,140}$'
		return re.match(RegexString, Message)

if __name__ == '__main__':

	if (len(sys.argv)>1):
		handler = ServerSaid()
		handler.Account = sys.argv[1]

		Message = sys.argv[2]

		handler.MessageBody = Message.decode(handler.DefaultEncode)

		handler.SendMessage()
	else:
		print 'serversaid.py YOUR_GTALK MESSAGE '
</pre>
<p>这里为了防止消息的滥发，使用前最好先到 <a rel="nofollow" target="_blank" href="http://server-say.appspot.com/">http://server-say.appspot.com/ </a>注册一下。没有注册的IP每小时仅能发送10条消息，我想大部分情况下也够用了。注册了的用户可以无限制的发送消息了，除非我在GAE注册的那张信用卡里的钱花光——我会哭的。</p>
<p>啥也不说了，PHP接口也搞定了！</p>
<pre name='code' class='php'>
< ?php
/*
 *    Gtalk 通告机器人 Ver 0.1
 *
 *    Litrin Jiang 2010/12/02
 *
 * --------------------------------
 *  1. 2010/12: v0.1 原型实现
 *
 */

Class Gtalk{

	private $APIUrl = 'Http://server-say.appspot.com/api?';
	//Api 的地址，不要修改

	public $mothod = 'get';
	//默认的提交方式，现阶段仅支持get
	public $account = '';
	//接收人的Gtalk账户
	public $messageBody = '';
	//消息主体，最多支持140个字符

	public $Charset = 'UTF-8';

	public function Send($account=null, $messageBody=null){
		if (is_array($account)){
			foreach ($account as $key) {
				$this->Send($key);
			}
		}

		if ($account === null){
			$account = $this.account;
		}
		$this->CheckAccount($account);

		if($messageBody === null){
			$messageBody = $this->messageBody;
		}
		if ($this->Charset != 'UTF-8'){
			$messageBody = iconv("UTF-8", $this->Charset.'//IGNORE', $messageBody);
		}
		$this->CheckMessage($messageBody);

		$url = $this->APIUrl .'account=' . urlencode($account) . '&#038;message=' .  urlencode($messageBody);

		$query = file($url);
		/*
		if($query == '200'){
			return true;
		}else{
			return false;
		}*/

	}

	private function CheckAccount($account){
		$regexString = '^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,5}$';
		echo ereg($regexString, $account);
		if (ereg($regexString, $account) != true){
			#throw new Exception("Value not a Email account! ");
		}

	}

	private function CheckMessage($messageBody){
		$regexString = '^.{1,140}';
		if (ereg($regexString, $messageBody) != true){
			#throw new Exception("Message not a allowed format! ");
		}
	}
}

?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2010/12/02/gtalk%e9%80%9a%e7%9f%a5%e6%9c%ba%e5%99%a8%e4%ba%ba%e8%84%9a%e6%9c%ac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress google-syntax-highlighter 插件的问题</title>
		<link>http://www.litrin.net/2010/06/12/wordpress-google-syntax-highlighter-%e6%8f%92%e4%bb%b6%e7%9a%84%e9%97%ae%e9%a2%98/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress-google-syntax-highlighter-%25e6%258f%2592%25e4%25bb%25b6%25e7%259a%2584%25e9%2597%25ae%25e9%25a2%2598</link>
		<comments>http://www.litrin.net/2010/06/12/wordpress-google-syntax-highlighter-%e6%8f%92%e4%bb%b6%e7%9a%84%e9%97%ae%e9%a2%98/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 09:16:08 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[站长的blog]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">/?p=1251</guid>
		<description><![CDATA[小站上一直使用Google Syntax Highlighter for WordPress 插件实现代码高亮，就在上一篇文章发布之后，我发现了这个插件中存在的一个bug：windows + IE 8无法正常加亮python代码。 查阅了官方网站，发掘Google Syntax Highlighter for WordPress插件用的1.5版已经停止更新，只能使用2.0以上的版本，但2.0版本和之前的版本又存在兼容的问题，直接替换是不行的。不想每篇文章的修改&#60;pre&#62;标记，那就改插件喽。 下载最新版本的Syntax Highlighter，解压。 将原来/wp-content/plugins/google-syntax-highlighter目录下的Scripts和Styles目录清空后，分别用新版本的对应路径中的文件替换，注意大小写方式请不要变动。 修改google_syntax_highlighter.php文件，我用了minify的插件，这里就直接调用了。 &#60;?php function insert_header() {  $current_path = get_option('siteurl') .'/wp-content/plugins/' . basename(dirname(__FILE__)) .'/';  ?&#62;  &#60;link href="&#60;?php echo $current_path; ?&#62;Styles/shCore.css" type="text/css" rel="stylesheet" /&#62;  //可根据自己的需要选择不同的Styles &#60;link href="&#60;?php echo $current_path; ?&#62;Styles/shThemeEclipse.css" type="text/css" rel="stylesheet" /&#62;  &#60;?php } function insert_footer(){ $current_path = 'wp-content/plugins/' . [...]]]></description>
			<content:encoded><![CDATA[<p>小站上一直使用Google Syntax Highlighter for WordPress 插件实现代码高亮，就在上一篇文章发布之后，我发现了这个插件中存在的一个bug：windows + IE 8无法正常加亮python代码。</p>
<p>查阅了官方网站，发掘Google Syntax Highlighter for WordPress插件用的1.5版已经停止更新，只能使用2.0以上的版本，但2.0版本和之前的版本又存在兼容的问题，直接替换是不行的。不想每篇文章的修改&lt;pre&gt;标记，那就改插件喽。</p>
<p><span id="more-1251"></span></p>
<ol>
<li>下载<a rel="nofollow" target="_blank" href="http://alexgorbatchev.com/downloads/grab.php?name=sh" target="_blank">最新版本的Syntax Highlighter</a>，解压。</li>
<li>将原来/wp-content/plugins/google-syntax-highlighter目录下的Scripts和Styles目录清空后，分别用新版本的对应路径中的文件替换，注意大小写方式请不要变动。</li>
<li>修改google_syntax_highlighter.php文件，我用了minify的插件，这里就直接调用了。</li>
</ol>
<pre class="php" name='code'>&lt;?php

function insert_header() {
 $current_path = get_option('siteurl') .'/wp-content/plugins/' . basename(dirname(__FILE__)) .'/';
 ?&gt;
 &lt;link href="&lt;?php echo $current_path; ?&gt;Styles/shCore.css" type="text/css" rel="stylesheet" /&gt;
 //可根据自己的需要选择不同的Styles
 &lt;link href="&lt;?php echo $current_path; ?&gt;Styles/shThemeEclipse.css" type="text/css" rel="stylesheet" /&gt;
 &lt;?php
}

function insert_footer(){
$current_path = 'wp-content/plugins/' . basename(dirname(__FILE__)) .'/';
 ?&gt;
&lt;?php
/*
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shCore.js"&gt;&lt;/script&gt;

&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shLegacy.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushCSharp.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushPhp.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushJScript.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushJava.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushVb.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushSql.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushXml.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushDelphi.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushPython.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushRuby.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushCss.js"&gt;&lt;/script&gt;
&lt;script src="&lt;?php echo $current_path; ?&gt;Scripts/shBrushCpp.js"&gt;&lt;/script&gt;
*/
&lt;script src="/wp-content/plugins/wp-minify/min/?b=&lt;?php echo $current_path; ?&gt;Scripts&amp;f=shCore.js,shLegacy.js,shBrushPhp.js,shBrushSql.js,shBrushPython.js"&gt;&lt;/script&gt;
&lt;script&gt;
dp.SyntaxHighlighter.ClipboardSwf = '&lt;?php echo $current_path; ?&gt;Scripts/clipboard.swf';
SyntaxHighlighter.all();
dp.SyntaxHighlighter.HighlightAll('code');
&lt;/script&gt;
&lt;?php
}
add_action('wp_head','insert_header');
add_action('wp_footer','insert_footer');
?&gt;</pre>
<p>测试，通过！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2010/06/12/wordpress-google-syntax-highlighter-%e6%8f%92%e4%bb%b6%e7%9a%84%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>配置Ubuntu的php支持OCI8</title>
		<link>http://www.litrin.net/2009/09/15/%e9%85%8d%e7%bd%aeubuntu%e7%9a%84php%e6%94%af%e6%8c%81oci8/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e9%2585%258d%25e7%25bd%25aeubuntu%25e7%259a%2584php%25e6%2594%25af%25e6%258c%2581oci8</link>
		<comments>http://www.litrin.net/2009/09/15/%e9%85%8d%e7%bd%aeubuntu%e7%9a%84php%e6%94%af%e6%8c%81oci8/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 09:48:03 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[数据库应用]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1085</guid>
		<description><![CDATA[PHP的OCI模块支持Oracle总是比较让人头痛。这趟弄个ubuntu的安装文档。 通过ubuntu-server安装盘安装LAMP。当然，正常情况下，建议安装好openssh服务器，免得麻烦。 虽然ubuntu的server支持root直接登录，既然是ubutu，还是遵循它的sudo吧。 安装结束后，启动server。 首先，经典的更新 #sudo apt-get update; sudo apt-get upgrade 添加所需的包 #sudo apt-get install php5-dev build-essential php-pear libaio1 差点忘了，要装unzip： #sudo apt-get install unzip 按照oracle官方网站的要求http://www.oracle.com/technology/tech/oci/instantclient/index.html 下载Instant Client ，我老老实实的下载了basic和sdk两个包，理论上下载basic-lit和sdk就可以。 设立目录，解压缩： #sudo mkdir /opt/oracle #sudo cp ~/*.zip /opt/oracle #cd /opt/oracle #sudo unzip ./*.zip #sudo mv instantclient_11_1 instantclient 设置instantclient： #sudo ln –s libclntsh.so.11.1 libclntsh.so #sudo ln –s libocci.so.11.1 libocci.so [...]]]></description>
			<content:encoded><![CDATA[<p>PHP的OCI模块支持Oracle总是比较让人头痛。这趟弄个ubuntu的安装文档。</p>
<p>通过ubuntu-server安装盘安装LAMP。当然，正常情况下，建议安装好openssh服务器，免得麻烦。</p>
<p>虽然ubuntu的server支持root直接登录，既然是ubutu，还是遵循它的sudo吧。</p>
<p>安装结束后，启动server。</p>
<p>首先，经典的更新<br />
#sudo apt-get update; sudo apt-get upgrade</p>
<p><span id="more-1085"></span></p>
<p>添加所需的包<br />
#sudo apt-get install php5-dev build-essential php-pear libaio1</p>
<p>差点忘了，要装unzip：<br />
#sudo apt-get install unzip</p>
<p>按照oracle官方网站的要求<a rel="nofollow" target="_blank" href="http://www.oracle.com/technology/tech/oci/instantclient/index.html">http://www.oracle.com/technology/tech/oci/instantclient/index.html</a> 下载<span>Instant Client ，我老老实实的下载了basic和sdk两个包，理论上下载basic-lit和sdk就可以。</span></p>
<p>设立目录，解压缩：<br />
#sudo mkdir /opt/oracle<br />
#sudo cp ~/*.zip /opt/oracle<br />
#cd /opt/oracle<br />
#sudo unzip ./*.zip<br />
#sudo mv instantclient_11_1 instantclient</p>
<p>设置instantclient：<br />
#sudo ln –s libclntsh.so.11.1 libclntsh.so<br />
#sudo ln –s libocci.so.11.1 libocci.so<br />
#sudo export ORACLE_HOME=/opt/oracle/instantclien</p>
<p>添加lib库位置：<br />
#cd /etc/ld.so.conf.d<br />
#sudo nano liboci.conf  //添加一行：/opt/oracle/instantclient<br />
#sudo ldconfig</p>
<p>准备OCI8库：<br />
#sudo mkdir /tmp/src<br />
#cd /tmp/src<br />
#sudo pecl download oci8<br />
#sudo tar vzxf oci8-1.3.5.tgz //我下载的版本是135<br />
#cd oci8-1.3.5</p>
<p>编译OCI8：<br />
#sudo phpize //比较容易出错的地方，如果报错，你可能没有安装php5-dev包<br />
#sudo ./configure &#8211;with-oci8=share,instantclient,$ORACLE_HOME<br />
#sudo make; sudo make install</p>
<p>设置php5支持：<br />
正常情况下编译完成后会有提示：Installing shared extensions:     /usr/lib/php5/20060613/<br />
到此目录下确认是否存在oci8.so<br />
#cd /etc/php5/conf.d<br />
#sudo nano oci8.ini //添加一行：extension=oci8.so<br />
#sudo apache2ctl restart</p>
<p>经过上述步骤，oci8模块就会成功安装，可以通过phpinfo页面确认是否存在oci8模块</p>
<h2><a name="module_oci8">oci8</a></h2>
<table border="0" cellpadding="3" width="600">
<tbody>
<tr>
<td>OCI8 Support</td>
<td>enabled</td>
</tr>
<tr>
<td>Version</td>
<td>1.3.5</td>
</tr>
<tr>
<td>Revision</td>
<td>$Revision: 1.269.2.16.2.38.2.32 $</td>
</tr>
<tr>
<td>Active Persistent Connections</td>
<td>0</td>
</tr>
<tr>
<td>Active Connections</td>
<td>0</td>
</tr>
<tr>
<td>Oracle Instant Client Version</td>
<td>11.1</td>
</tr>
<tr>
<td>Temporary Lob support</td>
<td>enabled</td>
</tr>
<tr>
<td>Collections support</td>
<td>enabled</td>
</tr>
</tbody>
</table>
<p> </p>
<table border="0" cellpadding="3" width="600">
<tbody>
<tr>
<th>Directive</th>
<th>Local Value</th>
<th>Master Value</th>
</tr>
<tr>
<td>oci8.connection_class</td>
<td><em>no value</em></td>
<td><em>no value</em></td>
</tr>
<tr>
<td>oci8.default_prefetch</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>oci8.events</td>
<td>Off</td>
<td>Off</td>
</tr>
<tr>
<td>oci8.max_persistent</td>
<td>-1</td>
<td>-1</td>
</tr>
<tr>
<td>oci8.old_oci_close_semantics</td>
<td>Off</td>
<td>Off</td>
</tr>
<tr>
<td>oci8.persistent_timeout</td>
<td>-1</td>
<td>-1</td>
</tr>
<tr>
<td>oci8.ping_interval</td>
<td>60</td>
<td>60</td>
</tr>
<tr>
<td>oci8.privileged_connect</td>
<td>Off</td>
<td>Off</td>
</tr>
<tr>
<td>oci8.statement_cache_size</td>
<td>20</td>
<td>20</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2009/09/15/%e9%85%8d%e7%bd%aeubuntu%e7%9a%84php%e6%94%af%e6%8c%81oci8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>说说“专业”</title>
		<link>http://www.litrin.net/2009/09/11/%e8%af%b4%e8%af%b4%e2%80%9c%e4%b8%93%e4%b8%9a%e2%80%9d/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e8%25af%25b4%25e8%25af%25b4%25e2%2580%259c%25e4%25b8%2593%25e4%25b8%259a%25e2%2580%259d</link>
		<comments>http://www.litrin.net/2009/09/11/%e8%af%b4%e8%af%b4%e2%80%9c%e4%b8%93%e4%b8%9a%e2%80%9d/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 10:12:24 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[站长的blog]]></category>
		<category><![CDATA[网络和安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[业界话题]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1081</guid>
		<description><![CDATA[暂且不提中文里说你不专业是什么语气，至少来说，在英语语系里说一个人或者一家公司是“不专业的”，不管什么语境，总归是句很重的话。 公司的一家子公司，由于人少财弱，没有专职的网站开发人员。于是找了一个现在比较知名的免费网店全站程序。用的久了，不够用了，联系了那家公司进行开发。这本身也是符合免费软件生存法则的，没有什么不对。对方很专业的报价350块/小时。很是吓人的价钱。周瑜打黄盖，一个愿打一个愿挨。认了，付钱，问题才刚刚开始。 作为服务器的管理员，首先他们问我要root帐号，要知道，这台主机的网站差不多有几十个，谁会给？然后他们很发了顿牢骚。不得已，开了一个用户给他们，竟然蒙混过去，他们竟然以为得到了root，汗。 然后又是说ftp连不上，我很客气的说ftp没开，又是牢骚：“人家的linux都开ftp的，为什么？”我建议他们用sftp上传就OK，“不会用。”。又晕！嫌烦，现装了proftpd应付过去，又被人说密码太长太难记，彻底无语！ 大约一个礼拜左右（350块/小时，赚了不少吧？）我得知他们已经完成了网站的定制开发。OK，停ftp，删帐户。程序照旧是加密的php，一个根目录下的php.php引起了我的注意，好家伙！&#60;? phpinfo(); ?&#62; 嫌我的站点太安全了不成？仔细查找了一下发现根目录下还有一个data.zip文件，全是打包的程序文件，当然包括数据库配置的用户名和密码。一个“白版页面”只有一个文本栏和一个submit按钮，顺手输入了一句sql，很幸运的发现了这竟然是数据库的接口——甚至可以直接drop table。文件名，就叫做sql.php，当然还是在根目录下。 如果说他们是在测试机下，新手来做，我们可以理解，可要知道生产环境下的服务器，调试程序都会要了命。 如他们所说“以专业的功能、领先的技术以及快速的价值体现，获得了45万用户的肯定。”我只能说，最近黑客们的效率确实很低。如此厂商如何评价？]]></description>
			<content:encoded><![CDATA[<p>暂且不提中文里说你不专业是什么语气，至少来说，在英语语系里说一个人或者一家公司是“不专业的”，不管什么语境，总归是句很重的话。</p>
<p>公司的一家子公司，由于人少财弱，没有专职的网站开发人员。于是找了一个现在比较知名的免费网店全站程序。用的久了，不够用了，联系了那家公司进行开发。这本身也是符合免费软件生存法则的，没有什么不对。对方很专业的报价350块/小时。很是吓人的价钱。周瑜打黄盖，一个愿打一个愿挨。认了，付钱，问题才刚刚开始。</p>
<p><span id="more-1081"></span></p>
<p>作为服务器的管理员，首先他们问我要root帐号，要知道，这台主机的网站差不多有几十个，谁会给？然后他们很发了顿牢骚。不得已，开了一个用户给他们，竟然蒙混过去，他们竟然以为得到了root，汗。</p>
<p>然后又是说ftp连不上，我很客气的说ftp没开，又是牢骚：“人家的linux都开ftp的，为什么？”我建议他们用sftp上传就OK，“不会用。”。又晕！嫌烦，现装了proftpd应付过去，又被人说密码太长太难记，彻底无语！</p>
<p>大约一个礼拜左右（350块/小时，赚了不少吧？）我得知他们已经完成了网站的定制开发。OK，停ftp，删帐户。程序照旧是加密的php，一个根目录下的php.php引起了我的注意，好家伙！&lt;? phpinfo(); ?&gt; 嫌我的站点太安全了不成？仔细查找了一下发现根目录下还有一个data.zip文件，全是打包的程序文件，当然包括数据库配置的用户名和密码。一个“白版页面”只有一个文本栏和一个submit按钮，顺手输入了一句sql，很幸运的发现了这竟然是数据库的接口——甚至可以直接drop table。文件名，就叫做sql.php，当然还是在根目录下。</p>
<p>如果说他们是在测试机下，新手来做，我们可以理解，可要知道生产环境下的服务器，调试程序都会要了命。</p>
<p>如他们所说“以专业的功能、领先的技术以及快速的价值体现，获得了45万用户的肯定。”我只能说，最近黑客们的效率确实很低。如此厂商如何评价？</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2009/09/11/%e8%af%b4%e8%af%b4%e2%80%9c%e4%b8%93%e4%b8%9a%e2%80%9d/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>wordpress2.8的一个问题</title>
		<link>http://www.litrin.net/2009/07/15/wordpress2-8%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress2-8%25e7%259a%2584%25e4%25b8%2580%25e4%25b8%25aa%25e9%2597%25ae%25e9%25a2%2598</link>
		<comments>http://www.litrin.net/2009/07/15/wordpress2-8%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 05:37:25 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=1037</guid>
		<description><![CDATA[前一段时间把小站的wordpress升级到了2.8。升级结束后，发觉后台的特效全部出了问题。文章编辑栏也坏掉了。 搜索了google，很多人报类似的错误。说是google某个插件的lib和系统冲突。多次禁用全部的插件依然无果。 以为是php版本太低，升级了php，照旧。 反复折腾中2.81正式release了,更新，再度失望。 搭建了一套测试环境，整个系统搬过去却奇迹的解决了问题。OK，至少错误定位了，开始检查php.ini。 反复调试后，总算找到了问题所在：很不起眼的magic_quotes_gpc设置成了On，修改成了Off,一切解决！ 比较令人不解的是，这个不起眼的设置怎么会影响到JS的故障，很是郁闷。 PS:其实unreal写的那个Easy AdSense真的是很垃圾，强行插入链接，满屏的paypal“捐助请求”，又是替换你的广告代码——少赚广告费倒是算了，被怀疑作弊就麻烦大了。几乎一天一个版本的更新，真的是很“敬业”。只能自己重新写了一个。有想要的可以直接告诉我。]]></description>
			<content:encoded><![CDATA[<p>前一段时间把小站的wordpress升级到了2.8。升级结束后，发觉后台的特效全部出了问题。文章编辑栏也坏掉了。</p>
<p>搜索了google，很多人报类似的错误。说是google某个插件的lib和系统冲突。多次禁用全部的插件依然无果。</p>
<p>以为是php版本太低，升级了php，照旧。</p>
<p><span id="more-1037"></span>反复折腾中2.81正式release了,更新，再度失望。</p>
<p>搭建了一套测试环境，整个系统搬过去却奇迹的解决了问题。OK，至少错误定位了，开始检查php.ini。</p>
<p>反复调试后，总算找到了问题所在：很不起眼的magic_quotes_gpc设置成了On，修改成了Off,一切解决！</p>
<p>比较令人不解的是，这个不起眼的设置怎么会影响到JS的故障，很是郁闷。</p>
<p>PS:其实unreal写的那个Easy AdSense真的是很垃圾，强行插入链接，满屏的paypal“捐助请求”，又是替换你的广告代码——少赚广告费倒是算了，被怀疑作弊就麻烦大了。几乎一天一个版本的更新，真的是很“敬业”。只能自己重新写了一个。有想要的可以直接告诉我。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2009/07/15/wordpress2-8%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>说说WordPress和Drupal</title>
		<link>http://www.litrin.net/2009/05/05/%e8%af%b4%e8%af%b4wordpress%e5%92%8cdrupal/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e8%25af%25b4%25e8%25af%25b4wordpress%25e5%2592%258cdrupal</link>
		<comments>http://www.litrin.net/2009/05/05/%e8%af%b4%e8%af%b4wordpress%e5%92%8cdrupal/#comments</comments>
		<pubDate>Tue, 05 May 2009 06:14:26 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=980</guid>
		<description><![CDATA[上次就想把Wordpress和Drupal做一个对比，这次补上。 WordPress和Drupal都是目前比较流行的开源CMS，用户数量也比较多。以下将从比较常用的几个方面进行比较。 平台支持 作为典型的LAMP结构的应用软件，WP仅支持Mysql，而DP支持mysql和Pgsql两种数据库。从某种虽然像本站这样从pgsql迁移到mysql的平台几乎很少，而且国内很少有Pgsql的空间，作为一个开源项目，提供多个备选数据库还是不错的。 从响应时间上看，同样采用了Mysql的数据库，DP的响应速度快了WP不少，但换成了Pgsql之后，速度慢了整整一个数量级——这跟Pgsql本身有关。故可以认为同等数量下，DP的硬件要求相对较低。 数据结构 看了WP的数据结构，了了10张表，感觉很干净。每个表的字段命名方式也足够清晰。初学者不需要多少时间就能理解整个数据流程。而且默认会在表名前添加wp_前缀，方便那些虚拟主机用户添加别的系统。 DP的数据结构比较复杂，40几个表的数量相对比较惊人。冗余度很高表名，字段名，重复的很多，也有很多缩写，初学者很容易给吓住。默认没有前缀，虽然可以设置前缀，但相对比较麻烦。 逻辑结构 WP的逻辑结构是一个内核程序已经可以完成大部分的功能，其他的功能通过plugin的方式实现。DP的逻辑是整个程序是由若干个Module实现，每块的功能都可以通过设置进行开关设置。相对灵活性比较好，但设置自然而然的复杂了很多。 安装步骤 WP的安装步骤相对较多，很详细的流程向导。WP的安装只要设置好数据库就OK，但不够清晰，特别是管理员添加采用的方式，很容易让人迷糊，同时不注意的话，默认注册用户就会有管理员权限。 本地化实现 WP的本地化通过.mo文件实现，等于是基于内核的实现，速度几乎不受影响。DP的本地化基于Module实现，每出现一个词组就需要一次数据库查询，相对效率低下。 主题开发 由于DP特有的逻辑，主题方面本身也是一个Module，可以通过扩展的方式支持各种同样的模板引擎，很适合于大团队进行主题的开发。WP相对主题开发比较困难，默认不支持页面引擎扩展，主题制作需要一定的PHP基础。 插件开发 DP的插件相对比较复杂，涉及到很多内容，需要对整个系统有一定的了解才能完成。WP的插件相对比较简单，对于简单的插件只要明确“在什么地方出现什么”就可以完成，甚至默认还提供了一个Hello Dolly伪插件作为范例。 管理界面 DP的管理界面与用户界面高度统一，同时提供了详尽的日志方便查阅。WP采用独立的管理控制台，可查阅的内容不多。 其他 默认状况下，WP提供了一个反垃圾插件很是有效。 个人觉得，两个系统都各有所长： WP方便简单，很适合于个人网站的快速部署。DP功能很强，同时支持企业级的Pgsql，适合具有一定规模的网站。 WP很容易开发出一些小插件，但界面开发有一定难度，最好找个主题自己修改。DP可以很容易的进行大规模的模块、主题HACK且不会对系统做成太大影响，前提是你要对他有足够的了解。]]></description>
			<content:encoded><![CDATA[<p>上次就想把Wordpress和Drupal做一个对比，这次补上。</p>
<p>WordPress和Drupal都是目前比较流行的开源CMS，用户数量也比较多。以下将从比较常用的几个方面进行比较。</p>
<ol>
<li>平台支持<br />
作为典型的LAMP结构的应用软件，WP仅支持Mysql，而DP支持mysql和Pgsql两种数据库。从某种虽然像本站这样从pgsql迁移到mysql的平台几乎很少，而且国内很少有Pgsql的空间，作为一个开源项目，提供多个备选数据库还是不错的。<span id="more-980"></span><br />
从响应时间上看，同样采用了Mysql的数据库，DP的响应速度快了WP不少，但换成了Pgsql之后，速度慢了整整一个数量级——这跟Pgsql本身有关。故可以认为同等数量下，DP的硬件要求相对较低。</li>
<li>数据结构<br />
看了WP的数据结构，了了10张表，感觉很干净。每个表的字段命名方式也足够清晰。初学者不需要多少时间就能理解整个数据流程。而且默认会在表名前添加wp_前缀，方便那些虚拟主机用户添加别的系统。<br />
DP的数据结构比较复杂，40几个表的数量相对比较惊人。冗余度很高表名，字段名，重复的很多，也有很多缩写，初学者很容易给吓住。默认没有前缀，虽然可以设置前缀，但相对比较麻烦。</li>
<li>逻辑结构<br />
WP的逻辑结构是一个内核程序已经可以完成大部分的功能，其他的功能通过plugin的方式实现。DP的逻辑是整个程序是由若干个Module实现，每块的功能都可以通过设置进行开关设置。相对灵活性比较好，但设置自然而然的复杂了很多。</li>
<li>安装步骤<br />
WP的安装步骤相对较多，很详细的流程向导。WP的安装只要设置好数据库就OK，但不够清晰，特别是管理员添加采用的方式，很容易让人迷糊，同时不注意的话，默认注册用户就会有管理员权限。</li>
<li>本地化实现<br />
WP的本地化通过.mo文件实现，等于是基于内核的实现，速度几乎不受影响。DP的本地化基于Module实现，每出现一个词组就需要一次数据库查询，相对效率低下。</li>
<li>主题开发<br />
由于DP特有的逻辑，主题方面本身也是一个Module，可以通过扩展的方式支持各种同样的模板引擎，很适合于大团队进行主题的开发。WP相对主题开发比较困难，默认不支持页面引擎扩展，主题制作需要一定的PHP基础。</li>
<li>插件开发<br />
DP的插件相对比较复杂，涉及到很多内容，需要对整个系统有一定的了解才能完成。WP的插件相对比较简单，对于简单的插件只要明确“在什么地方出现什么”就可以完成，甚至默认还提供了一个Hello Dolly伪插件作为范例。</li>
<li>管理界面<br />
DP的管理界面与用户界面高度统一，同时提供了详尽的日志方便查阅。WP采用独立的管理控制台，可查阅的内容不多。</li>
<li>其他<br />
默认状况下，WP提供了一个反垃圾插件很是有效。</li>
</ol>
<p>个人觉得，两个系统都各有所长：</p>
<ul>
<li>WP方便简单，很适合于个人网站的快速部署。DP功能很强，同时支持企业级的Pgsql，适合具有一定规模的网站。</li>
<li>WP很容易开发出一些小插件，但界面开发有一定难度，最好找个主题自己修改。DP可以很容易的进行大规模的模块、主题HACK且不会对系统做成太大影响，前提是你要对他有足够的了解。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2009/05/05/%e8%af%b4%e8%af%b4wordpress%e5%92%8cdrupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress的家</title>
		<link>http://www.litrin.net/2009/03/17/wordpress%e7%9a%84%e5%ae%b6/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress%25e7%259a%2584%25e5%25ae%25b6</link>
		<comments>http://www.litrin.net/2009/03/17/wordpress%e7%9a%84%e5%ae%b6/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 05:50:59 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[站长的blog]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=558</guid>
		<description><![CDATA[几次思想斗争以后，总算下了狠心将小站迁移到了wordpress。 迁移的大致成绩如下： 所有文章页全部迁移成功，文章标签只能后续手工做。 评论迁移了大部分，部分评论由于格式问题无法被迁移。 网站模板全部丢弃。 其余的数据全部丢弃。 原先的链接全部碎掉，需要小幅的hack。 之前的小站使用drupal，由于系统的数据库仅支持postgresql，Drupal似乎是唯一的选择。等到网站上线后，忽然间发觉再要移植数据库几乎是不可能的。postgresql并不是那么普遍，只是至少在国内没有几家能够提供这个平台，兼容性成了问题。 wordpress可以说是最近发展最快的系统，对于Ajax和SEO也支持的绝佳，种种优势不言而喻。 litrin本人经过这一段时间，CSS和PHP的功力大幅下降——糟糕的页面布局就是最好的例证:-) 最后，奉上转移脚本，希望能够给同样困扰的朋友些许帮助。 &#60;?php //Wordpress的URL路径 $wpURL = ‘http://www.litrin.net/’; //目标数据库(mysql)设置 $mysqlServer = ‘localhost’; $mysqlUser = ”; $mysqlPasswd = ”; $mysqlDB = ”; //源数据库(pgsql)设置 $pgsqlServer = ‘localhost’; $pgsqlUser = ”; $pgsqlPasswd = ”; $pgsqlDB = ”; $mysql = mysql_connect($mysqlServer, $mysqlUser, $mysqlPasswd); mysql_select_db($mysqlDB); $pgsql = pg_connect(“host=”.$pgsqlServer.” port=5432 dbname=”.$pgsqlDB.” user=”.$pgsqlUser.” password=”.$pgsqlPasswd); [...]]]></description>
			<content:encoded><![CDATA[<pre>几次思想斗争以后，总算下了狠心将小站迁移到了<a rel="nofollow" target="_blank" href="http://wordpress.org" target="_blank">wordpress</a>。</pre>
<p>迁移的大致成绩如下：</p>
<ul>
<li>所有文章页全部迁移成功，文章标签只能后续手工做。</li>
<li>评论迁移了大部分，部分评论由于格式问题无法被迁移。</li>
<li>网站模板全部丢弃。</li>
<li>其余的数据全部丢弃。</li>
<li>原先的链接全部碎掉，需要小幅的hack。</li>
</ul>
<p>之前的小站使用drupal，由于系统的数据库仅支持postgresql，Drupal似乎是唯一的选择。等到网站上线后，忽然间发觉再要移植数据库几乎是不可能的。postgresql并不是那么普遍，只是至少在国内没有几家能够提供这个平台，兼容性成了问题。</p>
<p>wordpress可以说是最近发展最快的系统，对于Ajax和SEO也支持的绝佳，种种优势不言而喻。</p>
<p>litrin本人经过这一段时间，CSS和PHP的功力大幅下降——糟糕的页面布局就是最好的例证:-)</p>
<p>最后，奉上转移脚本，希望能够给同样困扰的朋友些许帮助。<br />
<span id="more-558"></span></p>
<div>
<pre name=code class=php>
&lt;?php

//Wordpress的URL路径
$wpURL = ‘http://www.litrin.net/’;

//目标数据库(<a title="mysql" href="http://www.litrin.net/tag/mysql/">mysql</a>)设置
$mysqlServer = ‘localhost’;
$mysqlUser = ”;
$mysqlPasswd = ”;
$mysqlDB = ”;

//源数据库(pgsql)设置
$pgsqlServer = ‘localhost’;
$pgsqlUser = ”;
$pgsqlPasswd = ”;
$pgsqlDB = ”;
$mysql = mysql_connect($mysqlServer, $mysqlUser, $mysqlPasswd);
mysql_select_db($mysqlDB);
$pgsql = pg_connect(“host=”.$pgsqlServer.” port=5432 dbname=”.$pgsqlDB.” user=”.$pgsqlUser.” password=”.$pgsqlPasswd);

//先期准备
echo ‘Start import…n’;

mysql_query(‘SET NAME UTF8′);
mysql_query(‘TRUNCATE `wp_posts`’);
mysql_query(‘TRUNCATE `wp_comments`’);

//文章导入
echo ‘Start import node…n’;

$SQL = “SELECT nid, title, body, created, changed FROM node ORDER BY nid “;
$result = pg_query($pgsql, $SQL);
while ( $arr = pg_fetch_array($result, NULL, PGSQL_ASSOC) ){

 $title = $arr[title];
 $body = $arr[body];
 $createDate = date(DATE_ATOM, $arr[created]);
 $createDate_gmt = date(DATE_ATOM, $arr[created] – 8 * 3600);
 $changedDate = date(DATE_ATOM, $arr[changed]);
 $changedDate_gmt = date(DATE_ATOM, $arr[changed] – 8 * 3600);
 $id = $arr[nid];
 $postType = $wpURL . “?p=” . $id ;
 

 $sqlIns = “INSERT INTO `wp_posts`
    (`ID`,`post_author`, `post_date`, `post_date_gmt`, `post_content`,
    `post_title`, `post_category`, `post_excerpt`, `post_status`, `comment_status`,
    `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`,
    `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`,
    `post_type`, `post_mime_type`, `comment_count`)
   VALUES (
         ”.$id.”,1, ‘”.$createDate.”‘, ‘”.$createDate_gmt.”‘, ‘”.$body.”‘,
    ’”.$title.”‘, 0, ”, ‘publish’, ‘open’, ‘open’,
    ”, ‘”.$title.”‘, ”, ”, ‘”.$changedDate.”‘, ‘”.$changedDate_gmt.”‘,
    ”, 0, ‘”.$postType.”‘, 0, ‘post’, ”, 0)”;
 
 $query = mysql_query($sqlIns);
 
}

//评论导入
echo ‘Start import comment… n ‘;

$SQL= “SELECT cid, nid, name, homepage, timestamp, comment FROM comments ORDER BY cid”;
$result = pg_query($pgsql, $SQL);
while ( $arr = pg_fetch_array($result, NULL, PGSQL_ASSOC) ){

 $sqlIns= “INSERT INTO `wp_comments`
    (`comment_ID`, `comment_post_ID`, `comment_author`, `comment_author_email`,
    `comment_author_url`, `comment_author_IP`, `comment_date`, `comment_date_gmt`,
    `comment_content`, `comment_karma`, `comment_approved`, `comment_agent`,
    `comment_type`, `comment_parent`, `user_id`)
   VALUES (“.$arr[cid].”, “.$arr[nid].”, ‘”.$arr[name].”‘, ”, ‘”.$arr[homepage].”‘,
    ”, ‘”.date(DATE_ATOM, $arr[timestamp]).”‘, ‘”.date(DATE_ATOM, $arr[timestamp] – 8 * 3600).”‘,
    ’”.$arr[comment].”‘, 0, ‘1′, ”, ”, 0, “.$arr[uid].”)”;
 
 $query = mysql_query($sqlIns); 
 

}

//评论整理
echo ‘Start arrage comment… n’;

$SQL= “SELECT comment_post_ID, count( `comment_ID` ) AS count FROM `wp_comments` GROUP BY `comment_post_ID` “;
$query = mysql_query($SQL);
while ($arr = mysql_fetch_array($query)){
 $sqlUp = “update wp_posts set comment_count = “.$arr[count].” where ID =”.$arr[comment_post_ID].”";
 mysql_query ($sqlUp);
}

mysql_close($mysql);
pg_close($pgsql);

echo ‘All finished! n’;

?&gt;
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2009/03/17/wordpress%e7%9a%84%e5%ae%b6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>再谈PHP</title>
		<link>http://www.litrin.net/2007/10/04/%e5%86%8d%e8%b0%88php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e5%2586%258d%25e8%25b0%2588php</link>
		<comments>http://www.litrin.net/2007/10/04/%e5%86%8d%e8%b0%88php/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 01:19:38 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=464</guid>
		<description><![CDATA[说起来用PHP做程序开发已经将近7年多了，从php3一直到php5，开发工具也从记事本一直到了Zend Stdio。php的优点自然不必说，随便哪个PHP技术论坛上一抓一把，可这么多项目做完了，总感觉上缺点什么。我不是&#8220;种族主义者&#8221;，只是谈一下作为开发人员或者项目管理人员最渴望PHP的功能。 内置函数不统一，PHP的内置函数命名可谓是乱得可以了，大写的、小写的、驼峰的、并列的、AtoB的、下划的&#8230;&#8230;几乎每种命名方式都能在php的内置函数中找到，够得上一个&#8220;函数命名方式博览会&#8221;的了 。很不利于开发人员记忆。 环境差异，看似PHP只存在版本差异，其实如果你在IDC那边的虚拟主机上部署PHP你就会发现，开不开Safe_mode就够弄半天的了，还有引用的这个库那个库的，如果是pear这样的库也就罢了，大不了自己重新include;拿GD库来讲，根本没有办法通过其他方法来代用。如果同时又有幸使用了Zend加密过的php代码&#8230;&#8230; 模板问题，现在用的最多的就属smarty了，可smarty的功能实在太强，里面的循环、判断和自动转换格式的部分，真不知道是给美工做还是给开发人员做更合适。如果不用模板，直接把php嵌入html中，同样的问题。 数据库访问，有很多数据库的访问接口，但始终无法摆脱fetch的命运，不论怎么封包，复杂的SQL语句总归要成了程序开发中的重点和系统运行中的瓶颈。 对象访问，php的对象在不断的增强，但还是有待增强。虽然不会把php当作java来用。 层次，企业环境开发，最希望的是能把系统访问和应用访问分开，界面和程序分开（即MVC），这一点PHP需要很大的工作量才可以做到，于是大多开发人员不得不选择了不分开。所有的代码集中到了一起，逻辑上很乱，也没有办法实现代码重用。 调试环境，相比java的调试环境，Zend Studio还远远不够。 框架，市面上流行的几个PHP框架，例如ZF，无一例外的都是模仿了Struct或者.net，没有真正表现出PHP自己的特色，这似乎成了一个怪圈&#8212;&#8212;如果别人用框架觉得好就可能从php转到struct或者.net，用得不好反而会得出php很烂的结论，从而转到其他语言。 总之，上面的牢骚只是希望php有所改善，并非是挑php的骨头。 &#160;]]></description>
			<content:encoded><![CDATA[<p>说起来用PHP做程序开发已经将近7年多了，从php3一直到php5，开发工具也从记事本一直到了Zend Stdio。php的优点自然不必说，随便哪个PHP技术论坛上一抓一把，可这么多项目做完了，总感觉上缺点什么。我不是&ldquo;种族主义者&rdquo;，只是谈一下作为开发人员或者项目管理人员最渴望PHP的功能。</p>
<p>内置函数不统一，PHP的内置函数命名可谓是乱得可以了，大写的、小写的、驼峰的、并列的、AtoB的、下划的&hellip;&hellip;几乎每种命名方式都能在php的内置函数中找到，够得上一个&ldquo;函数命名方式博览会&rdquo;的了 。很不利于开发人员记忆。</p>
<p>环境差异，看似PHP只存在版本差异，其实如果你在IDC那边的虚拟主机上部署PHP你就会发现，开不开Safe_mode就够弄半天的了，还有引用的这个库那个库的，如果是pear这样的库也就罢了，大不了自己重新include;拿GD库来讲，根本没有办法通过其他方法来代用。如果同时又有幸使用了Zend加密过的php代码&hellip;&hellip;</p>
<p>模板问题，现在用的最多的就属smarty了，可smarty的功能实在太强，里面的循环、判断和自动转换格式的部分，真不知道是给美工做还是给开发人员做更合适。如果不用模板，直接把php嵌入html中，同样的问题。</p>
<p>数据库访问，有很多数据库的访问接口，但始终无法摆脱fetch的命运，不论怎么封包，复杂的SQL语句总归要成了程序开发中的重点和系统运行中的瓶颈。</p>
<p>对象访问，php的对象在不断的增强，但还是有待增强。虽然不会把php当作java来用。</p>
<p>层次，企业环境开发，最希望的是能把系统访问和应用访问分开，界面和程序分开（即MVC），这一点PHP需要很大的工作量才可以做到，于是大多开发人员不得不选择了不分开。所有的代码集中到了一起，逻辑上很乱，也没有办法实现代码重用。</p>
<p>调试环境，相比java的调试环境，Zend Studio还远远不够。</p>
<p>框架，市面上流行的几个PHP框架，例如ZF，无一例外的都是模仿了Struct或者.net，没有真正表现出PHP自己的特色，这似乎成了一个怪圈&mdash;&mdash;如果别人用框架觉得好就可能从php转到struct或者.net，用得不好反而会得出php很烂的结论，从而转到其他语言。</p>
<p>总之，上面的牢骚只是希望php有所改善，并非是挑php的骨头。</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2007/10/04/%e5%86%8d%e8%b0%88php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>用FreeBSD的ports安装apache+php+mysql·改</title>
		<link>http://www.litrin.net/2007/08/01/%e7%94%a8freebsd%e7%9a%84ports%e5%ae%89%e8%a3%85apachephpmysql%c2%b7%e6%94%b9/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e7%2594%25a8freebsd%25e7%259a%2584ports%25e5%25ae%2589%25e8%25a3%2585apachephpmysql%25c2%25b7%25e6%2594%25b9</link>
		<comments>http://www.litrin.net/2007/08/01/%e7%94%a8freebsd%e7%9a%84ports%e5%ae%89%e8%a3%85apachephpmysql%c2%b7%e6%94%b9/#comments</comments>
		<pubDate>Wed, 01 Aug 2007 01:10:17 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=459</guid>
		<description><![CDATA[ 正如我一贯习惯于规律性的工作和生活一样，昨天，我按照惯例在以往的时间，用电脑里的outlook软件收信——天热，纵然室内空调的温度已经远远低于官方标准的26度，人毕竟还是没有冷天来的那么清醒。如果从心理学的角度上讲，也许那时的我正处在“意识朦胧状态”。除了正如以往枯燥的工作E-mail之外，我收到了一封网友的E-mail。出乎意料的是，不同于往常访客在浏览了我的个人网页以后会在文章后面发表评论，这次却是发了mail。既然如此，我觉得mail一定是重要的，至少体现了相当一部分访客的心情吧。 那篇E-mail不长，在我的电脑上显示下来仅仅只有三行不到的样子，大抵的内容无非是说本站如何如何的帮了忙，我不免沾沾自喜起来——正如往常的沾沾自喜一样，mail的结尾处指出了小站的几个问题，最重要的是说很多文章过于流程化了，没有一点文字上的修饰和润色，言外之意是字里行间缺乏应有的优雅和细致。要指明的是，所谓优雅和细致，正是目前白领文学或者说白领文化所擅长的。说到白领文化的代表，我想村上春树的小说（或者说林少华翻译的日本小说）、伍佰的歌词、汪家卫的台词、小女人的blog绝对可以作为代表。作为我，从来没有当作自己是白领的一员——乏味的代码、吵闹的机房、灰尘遍布的机架，也许能跟这些词句联系上的只有“体力劳动”一个词了。我固然写不出优雅和细致，字里行间唯独只有王朔依稀的身影。于是我决定做一个尝试，既然有这样的需求，按照目前常说的一句话似乎叫做“需求第一”吧，我决定润色并重写本站访问量最高的那篇文章……   以上，正如以往话剧前面总有一个人上来讲述故事背景一样，是本文的开场白，别急，正剧马上就要开始了，当然希望您读的时候也要用优雅而细致的语调默默的朗读。 那时大概在前年的下班年，我一个正处在技术大崩溃边缘的技术人员，为了给自己制作一个技术性的网站（正如您现在看到的那样，就是本站了），要用FreeBSD平台的操作系统build一个万维网系统。 在此之前，看了网上很多安装apache php以及mysql的文章，唯独可惜是，其中大多都是用在林纳克斯的OS中的，不知为何，大多是用源代码编译的步骤教程，而其余的，Rpm（redhat programs manager )又占去了绝大部分。几乎寻觅不到FreeBSD平台下有关于Ports安装的一点讯息。于是我决定写一篇这样的东西，以免让大家舍近求远。 需要在所有的工作开始之前confirm的是，将您的主机连接到互联网之上且网路配置吻合，虽然这是句笑话，但似乎很多人都在这里遇到了坎坷。 连接好控制台，轻击键盘，键入命令： cvsup -h cvsup.freebsd.org /usr/share/example/cvsup/ports-supfile 这条命令的大体意思是从互联网上同步一下ports，以防止后续的工作中出现不必要的麻烦。 接下来的步骤就是要安装database了，Mysql纵然在严酷而恶劣下的环境还可以迅即的完成数据检索，为此Mysql成了我的首选。我的手指轻轻滑过键盘，屏幕出现了： cd /usr/ports/databases/mysql50-server/ make install clean ;rehash 不知过了多久，在我回忆了我虚度的童年时光之后——也许吧，可能时光流逝的还要慢一点，总之，一阵漫长的时光度过之后，Mysql已经成为了电脑中的一分子。接下来呢？配置mysql吧：cp /usr/local/share/mysql/my-small.cnf /etc/my.cnf 可见我电脑中资源少的可怜，我仅仅只有权力使用小内存模式启动mysql，如果条件允许您这样做的话，您可以尝试 my-big.cnf 甚至于 my-huge.cnf mysql_install_db -u mysql ; mysqld_safe -u mysql &#38; 看看mysql是否已经能够start]]></description>
			<content:encoded><![CDATA[<p> 正如我一贯习惯于规律性的工作和生活一样，昨天，我按照惯例在以往的时间，用电脑里的outlook软件收信——天热，纵然室内空调的温度已经远远低于官方标准的26度，人毕竟还是没有冷天来的那么清醒。如果从心理学的角度上讲，也许那时的我正处在“意识朦胧状态”。除了正如以往枯燥的工作E-mail之外，我收到了一封网友的E-mail。出乎意料的是，不同于往常访客在浏览了我的个人网页以后会在文章后面发表评论，这次却是发了mail。既然如此，我觉得mail一定是重要的，至少体现了相当一部分访客的心情吧。</p>
<p>那篇E-mail不长，在我的电脑上显示下来仅仅只有三行不到的样子，大抵的内容无非是说本站如何如何的帮了忙，我不免沾沾自喜起来——正如往常的沾沾自喜一样，mail的结尾处指出了小站的几个问题，最重要的是说很多文章过于流程化了，没有一点文字上的修饰和润色，言外之意是字里行间缺乏应有的优雅和细致。要指明的是，所谓优雅和细致，正是目前白领文学或者说白领文化所擅长的。说到白领文化的代表，我想村上春树的小说（或者说林少华翻译的日本小说）、伍佰的歌词、汪家卫的台词、小女人的blog绝对可以作为代表。作为我，从来没有当作自己是白领的一员——乏味的代码、吵闹的机房、灰尘遍布的机架，也许能跟这些词句联系上的只有“体力劳动”一个词了。我固然写不出优雅和细致，字里行间唯独只有王朔依稀的身影。于是我决定做一个尝试，既然有这样的需求，按照目前常说的一句话似乎叫做“需求第一”吧，我决定润色并重写本站访问量最高的<a href="http://www.litrin.net/2005/11/09/%E7%94%A8freebsd%E7%9A%84ports%E5%AE%89%E8%A3%85apachephpmysql/" target="_blank">那篇文章……</a></p>
<p> <span id="more-459"></span></p>
<p>以上，正如以往话剧前面总有一个人上来讲述故事背景一样，是本文的开场白，别急，正剧马上就要开始了，当然希望您读的时候也要用优雅而细致的语调默默的朗读。</p>
<p>那时大概在前年的下班年，我一个正处在技术大崩溃边缘的技术人员，为了给自己制作一个技术性的网站（正如您现在看到的那样，就是本站了），要用FreeBSD平台的操作系统build一个万维网系统。</p>
<p>在此之前，看了网上很多安装apache php以及mysql的文章，唯独可惜是，其中大多都是用在林纳克斯的OS中的，不知为何，大多是用源代码编译的步骤教程，而其余的，Rpm（redhat programs manager )又占去了绝大部分。几乎寻觅不到FreeBSD平台下有关于Ports安装的一点讯息。于是我决定写一篇这样的东西，以免让大家舍近求远。</p>
<p>需要在所有的工作开始之前confirm的是，将您的主机连接到互联网之上且网路配置吻合，虽然这是句笑话，但似乎很多人都在这里遇到了坎坷。</p>
<p>连接好控制台，轻击键盘，键入命令：<br />
cvsup -h cvsup.freebsd.org /usr/share/example/cvsup/ports-supfile<br />
这条命令的大体意思是从互联网上同步一下ports，以防止后续的工作中出现不必要的麻烦。</p>
<p>接下来的步骤就是要安装database了，Mysql纵然在严酷而恶劣下的环境还可以迅即的完成数据检索，为此Mysql成了我的首选。我的手指轻轻滑过键盘，屏幕出现了：<br />
cd /usr/ports/databases/mysql50-server/<br />
make install clean ;rehash<br />
不知过了多久，在我回忆了我虚度的童年时光之后——也许吧，可能时光流逝的还要慢一点，总之，一阵漫长的时光度过之后，Mysql已经成为了电脑中的一分子。接下来呢？配置mysql吧：cp /usr/local/share/mysql/my-small.cnf /etc/my.cnf<br />
可见我电脑中资源少的可怜，我仅仅只有权力使用小内存模式启动mysql，如果条件允许您这样做的话，您可以尝试 my-big.cnf 甚至于 my-huge.cnf<br />
mysql_install_db -u mysql ; mysqld_safe -u mysql &amp;<br />
看看mysql是否已经能够start</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2007/08/01/%e7%94%a8freebsd%e7%9a%84ports%e5%ae%89%e8%a3%85apachephpmysql%c2%b7%e6%94%b9/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP问题请教（Not Found）</title>
		<link>http://www.litrin.net/2006/10/31/php%e9%97%ae%e9%a2%98%e8%af%b7%e6%95%99%ef%bc%88not-found%ef%bc%89/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php%25e9%2597%25ae%25e9%25a2%2598%25e8%25af%25b7%25e6%2595%2599%25ef%25bc%2588not-found%25ef%25bc%2589</link>
		<comments>http://www.litrin.net/2006/10/31/php%e9%97%ae%e9%a2%98%e8%af%b7%e6%95%99%ef%bc%88not-found%ef%bc%89/#comments</comments>
		<pubDate>Tue, 31 Oct 2006 09:09:58 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=411</guid>
		<description><![CDATA[我在Linux下安装并配置了apache2 tomcat5 mysql4.1.12 然后测试http://localhost 成功，但http://localhost/test.php Not Found the requested URL /test.php was not found on this server. Apache/2.0.52(Red Hat)Server at localhost Port 80 查了资料，说是卸载旧版本，我也照做了，可是也不行。请各位高手指点一下。谢谢！]]></description>
			<content:encoded><![CDATA[<p> 我在Linux下安装并配置了apache2 tomcat5 mysql4.1.12<br />
然后测试http://localhost 成功，但http://localhost/test.php<br />
Not Found<br />
the requested URL /test.php was not found on this server.<br />
Apache/2.0.52(Red Hat)Server at localhost Port 80<br />
查了资料，说是卸载旧版本，我也照做了，可是也不行。请各位高手指点一下。谢谢！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2006/10/31/php%e9%97%ae%e9%a2%98%e8%af%b7%e6%95%99%ef%bc%88not-found%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>写了一个验证身份证的class</title>
		<link>http://www.litrin.net/2006/09/13/%e5%86%99%e4%ba%86%e4%b8%80%e4%b8%aa%e9%aa%8c%e8%af%81%e8%ba%ab%e4%bb%bd%e8%af%81%e7%9a%84class/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e5%2586%2599%25e4%25ba%2586%25e4%25b8%2580%25e4%25b8%25aa%25e9%25aa%258c%25e8%25af%2581%25e8%25ba%25ab%25e4%25bb%25bd%25e8%25af%2581%25e7%259a%2584class</link>
		<comments>http://www.litrin.net/2006/09/13/%e5%86%99%e4%ba%86%e4%b8%80%e4%b8%aa%e9%aa%8c%e8%af%81%e8%ba%ab%e4%bb%bd%e8%af%81%e7%9a%84class/#comments</comments>
		<pubDate>Wed, 13 Sep 2006 02:02:30 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=397</guid>
		<description><![CDATA[PHP做的，支持从身份证中获得出生日期和性别，以及新、旧版本的互换，更重要的是支持验证新版本的身份证号码。]]></description>
			<content:encoded><![CDATA[<p>PHP做的，支持从身份证中获得出生日期和性别，以及新、旧版本的互换，更重要的是支持验证新版本的身份证号码。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2006/09/13/%e5%86%99%e4%ba%86%e4%b8%80%e4%b8%aa%e9%aa%8c%e8%af%81%e8%ba%ab%e4%bb%bd%e8%af%81%e7%9a%84class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IP到实际地址的查询接口</title>
		<link>http://www.litrin.net/2006/08/14/ip%e5%88%b0%e5%ae%9e%e9%99%85%e5%9c%b0%e5%9d%80%e7%9a%84%e6%9f%a5%e8%af%a2%e6%8e%a5%e5%8f%a3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ip%25e5%2588%25b0%25e5%25ae%259e%25e9%2599%2585%25e5%259c%25b0%25e5%259d%2580%25e7%259a%2584%25e6%259f%25a5%25e8%25af%25a2%25e6%258e%25a5%25e5%258f%25a3</link>
		<comments>http://www.litrin.net/2006/08/14/ip%e5%88%b0%e5%ae%9e%e9%99%85%e5%9c%b0%e5%9d%80%e7%9a%84%e6%9f%a5%e8%af%a2%e6%8e%a5%e5%8f%a3/#comments</comments>
		<pubDate>Mon, 14 Aug 2006 07:21:13 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=382</guid>
		<description><![CDATA[上次曾经做过一个从IP到实际物理地址的PHP页面，现在我做了一个PHP的Class把这个接口开放。 其实也没有什么大的难度，大家可以看我附带的那个example.php 当然还希望大家不要太过分的调用。那边的服务器只是一个单CPU的Xeon2.8，每秒也只能查询700次以]]></description>
			<content:encoded><![CDATA[<p>上次曾经做过一个从IP到实际物理地址的PHP页面，现在我做了一个PHP的Class把这个接口开放。</p>
<p>其实也没有什么大的难度，大家可以看我附带的那个example.php</p>
<p>当然还希望大家不要太过分的调用。那边的服务器只是一个单CPU的Xeon2.8，每秒也只能查询700次以<img src="/modules/fckeditor/lib/editor/images/smiley/msn/tounge_smile.gif" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2006/08/14/ip%e5%88%b0%e5%ae%9e%e9%99%85%e5%9c%b0%e5%9d%80%e7%9a%84%e6%9f%a5%e8%af%a2%e6%8e%a5%e5%8f%a3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于虚拟主机的PHP配置</title>
		<link>http://www.litrin.net/2006/04/26/%e5%9f%ba%e4%ba%8e%e8%99%9a%e6%8b%9f%e4%b8%bb%e6%9c%ba%e7%9a%84php%e9%85%8d%e7%bd%ae/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e5%259f%25ba%25e4%25ba%258e%25e8%2599%259a%25e6%258b%259f%25e4%25b8%25bb%25e6%259c%25ba%25e7%259a%2584php%25e9%2585%258d%25e7%25bd%25ae</link>
		<comments>http://www.litrin.net/2006/04/26/%e5%9f%ba%e4%ba%8e%e8%99%9a%e6%8b%9f%e4%b8%bb%e6%9c%ba%e7%9a%84php%e9%85%8d%e7%bd%ae/#comments</comments>
		<pubDate>Wed, 26 Apr 2006 05:45:49 +0000</pubDate>
		<dc:creator>Litrin</dc:creator>
				<category><![CDATA[www]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.litrin.net/?p=307</guid>
		<description><![CDATA[有个朋友想在我的主机上安置一个站点，PHP的。安置了以后才发现，他的系统默认是session.auto_start的。正好与我这个站点的设置有冲突，使用统一个PHP设置不太可能了。查看了官方的手册，找到了解决方案： 我用PHP5配置为： 打开服务器的AllowOverride 权限 AllowOverride All &#60;IfModule mod_php5.c&#62; php_value include_path &#34;.:/usr/local/lib/php&#34; php_admin_flag safe_mode on&#60;/IfModule&#62; PHP4的： &#60;IfModule mod_php4.c&#62; php_value include_path &#34;.:/usr/local/lib/php&#34; php_admin_flag safe_mode on&#60;/IfModule&#62; 文物级的PHP3：&#60;IfModule mod_php3.c&#62; php3_include_path &#34;.:/usr/local/lib/php&#34; php3_safe_mode on&#60;/IfModule&#62; 找到PHP.ini中的配置选项后替换掉上面例子中的配置就可以了。其中，php_admin_flag使用与&#8220;是非型&#8221;、&#8220;整数型&#8221;以及&#8220;浮点数型&#8221;的php配置；而php_value则对应了&#8220;字符型&#8221;。放置在&#60;VirtualHost &#62;之间就可以实现为每个虚拟主机设置不同的配置了。 最后还是提醒PHP的广大开发者：尽量使用PHP的默认配置作为基础环境，如果必须修改相关的设置参数，可以使用php的ini_set()函数来实现。]]></description>
			<content:encoded><![CDATA[<p>有个朋友想在我的主机上安置一个站点，PHP的。安置了以后才发现，他的系统默认是session.auto_start的。正好与我这个站点的设置有冲突，使用统一个PHP设置不太可能了。查看了官方的手册，找到了解决方案：</p>
<p>我用PHP5配置为：</p>
<p>打开服务器的AllowOverride 权限 <br />AllowOverride All</p>
<pre class="ini">&lt;IfModule mod_php5.c&gt;  php_value include_path &quot;.:/usr/local/lib/php&quot;   php_admin_flag safe_mode on&lt;/IfModule&gt;

PHP4的：

&lt;IfModule mod_php4.c&gt;  php_value include_path &quot;.:/usr/local/lib/php&quot;  php_admin_flag safe_mode on&lt;/IfModule&gt;

文物级的PHP3：&lt;IfModule mod_php3.c&gt;  php3_include_path &quot;.:/usr/local/lib/php&quot;  php3_safe_mode on&lt;/IfModule&gt;</pre>
<p>找到PHP.ini中的配置选项后替换掉上面例子中的配置就可以了。其中，php_admin_flag使用与&ldquo;是非型&rdquo;、&ldquo;整数型&rdquo;以及&ldquo;浮点数型&rdquo;的php配置；而php_value则对应了&ldquo;字符型&rdquo;。放置在&lt;VirtualHost &gt;之间就可以实现为每个虚拟主机设置不同的配置了。</p>
<p>最后还是提醒PHP的广大开发者：尽量使用PHP的默认配置作为基础环境，如果必须修改相关的设置参数，可以使用php的ini_set()函数来实现。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.litrin.net/2006/04/26/%e5%9f%ba%e4%ba%8e%e8%99%9a%e6%8b%9f%e4%b8%bb%e6%9c%ba%e7%9a%84php%e9%85%8d%e7%bd%ae/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

