<?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>温室小花.技术.博客 --纯粹的unix技术博客 &#187; 脚本语言</title>
	<atom:link href="http://www.evanjiang.net.cn/archives/category/scripting_language/feed" rel="self" type="application/rss+xml" />
	<link>http://www.evanjiang.net.cn</link>
	<description>红颜弹指老，刹那芳华，与其天涯思君，恋恋不舍，莫若相忘于江湖！</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Zend Framework使用实例</title>
		<link>http://www.evanjiang.net.cn/archives/1332.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1332.html#comments</comments>
		<pubDate>Wed, 14 Oct 2009 06:43:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1332</guid>
		<description><![CDATA[<p>


 <p>一、Zend Framework简介</p>
<p>Zend Framework使用模型-视图-控制器（Model-View-Controller（MVC））结构。这个用来把你的程序分离成不同部分使得开发和维护变得容易。</p>
<p>运行Zend Framework需要：PHP 5.1.4 (或更高) 、Web 服务器支持 mod_rewrite功能，本实例采用Apache。 </p>
<p>从这里http://framework.zend.com/download 下载 Zend Framework,有两种格式.zip或者.tar.gz。 </p>
<p>二、Zend Framework的配置</p>
<p>1、目录结构</p>
<p>虽然Zend Framework 没有强求使用一个标准的目录结构，但是还是有一些通用的目录结构。这个目录结构假设你完全控制Apache 的配置。（下面以本机做例子，各位需根据自己的情况进行更改，我的服务器的根目录指向的是Web文件夹）</p>
<p>Web/</p>
<p>        test/ </p>
<p>                /webapp</p>
<p>            [...]]]></description>
			<content:encoded><![CDATA[<p style="float: left;margin: 4px;"><script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 160x600, 创建于 10-2-7 */
google_ad_slot = "8970910006";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p> <p>一、Zend Framework简介</p>
<p>Zend Framework使用模型-视图-控制器（Model-View-Controller（MVC））结构。这个用来把你的程序分离成不同部分使得开发和维护变得容易。</p>
<p>运行Zend Framework需要：PHP 5.1.4 (或更高) 、Web 服务器支持 mod_rewrite功能，本实例采用Apache。 </p>
<p>从这里http://framework.zend.com/download 下载 Zend Framework,有两种格式.zip或者.tar.gz。 </p>
<p>二、Zend Framework的配置</p>
<p>1、目录结构</p>
<p>虽然Zend Framework 没有强求使用一个标准的目录结构，但是还是有一些通用的目录结构。这个目录结构假设你完全控制Apache 的配置。（下面以本机做例子，各位需根据自己的情况进行更改，我的服务器的根目录指向的是Web文件夹）</p>
<p>Web/</p>
<p>        test/ </p>
<p>                /webapp</p>
<p>             /controllers </p>
<p>             /models </p>
<p>             /templates</p>
<p>             /templates_c             </p>
<p>       /library </p>
<p>       /webroot</p>
<p>             /images </p>
<p>             /js</p>
<p>             /css </p>
<p>我们已经把程序中的模型、视图和控制器的文件分离到不同的子目录中。支持的图像，脚本和CSS 文件被存放在webroot 目录下的不同子目录中。下载的Zend Framework 文件放在 library 目录下。如果我们还需要其他库文件，都可以放在这里。在这个实例中，我们使用到了Smarty模版技术，所以Smarty 的库文件我们也应该放在library文件下！</p>
<p>2、启动文件</p>
<p>1) 配置.htaccess</p>
<p>我们使用单一的入口文件index.php来对我们的程序进行访问，这给我们提供了程序中所有页面的中心点并确保运行环境配置正确。我们用.htaccess 文件来实现这个目的，添加.htaccess 文件在test 的根目录中，内容如下：</p>
<p>RewriteEngine on</p>
<p>RewriteRule !&#8221;.(js|ico|gif|jpg|png|css)$ index.php<br />
<span id="more-1332"></span><br />
2）配置Apache</p>
<p>与此同时，我们还需要对apache进行一些设置，打开apache的配置文件 httpd.conf。</p>
<p>1、找到“#LoadModule rewrite_module modules/mod_rewrite.so 这句话，把前面的#去掉！</p>
<p>2、然后再找到“AllowOverride None   改成AllowOverride All，重新启动apache即可。</p>
<p>3 ) 启动文件index.php</p>
<p>index.php放在test的根目录下，下面是index.php的内容</p>
<p>PHP代码如下:</p>
<p><?php </p>
<p>//打开错误提示</p>
<p>error_reporting(E_ALL|E_STRICT); </p>
<p>//设定时区</p>
<p>date_default_timezone_set('Asia/Shanghai'); </p>
<p>//指明引用文件的路径</p>
<p>set_include_path('.' .</p>
<p>PATH_SEPARATOR . './library/'.</p>
<p>PATH_SEPARATOR . './webapp/models/'.</p>
<p>PATH_SEPARATOR . get_include_path());</p>
<p>//必须手动加载Loader.php</p>
<p>include "Zend/Loader.php"; </p>
<p>//自动加载类，使用时，直接实例化使用</p>
<p>function __autoload($class){</p>
<p>    Zend_Loader::loadClass($class);</p>
<p>}</p>
<p>   //getInstance()方法用来获取前端控制器实例</p>
<p>   $frontController = Zend_Controller_Front::getInstance(); </p>
<p>   //设定前端路由器的工作目录</p>
<p>   $frontController->setControllerDirectory(array(&#8220;default&#8221;=>&#8217;./webapp/controllers&#8217;)); </p>
<p>   //抛出异常</p>
<p>   $frontController->throwExceptions(true); </p>
<p>   //设置基地址,方便以后url的跳转用户,.注意，区分大小写！</p>
<p>   $frontController->setBaseUrl(&#8216;/test&#8217;); </p>
<p>   //使用smarty模版需关闭本身的视图助手. </p>
<p> $frontController->setParam(&#8216;noViewRenderer&#8217;, true); </p>
<p> // 关闭错误提示，发生请求错误时候，转到ErrorController的errorAction控制器</p>
<p> //$frontController->throwExceptions(false);</p>
<p>//对。。进行注册</p>
<p>   Zend_Registry::set(&#8216;font&#8217;, $frontController);</p>
<p> //&#8212;&#8212;&#8212;&#8212;配置Smarty模版 &#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>include &#8216;Smarty/Smarty.class.php&#8217;; </p>
<p>/**</p>
<p> * 对smarty模版进行初始化</p>
<p>**/</p>
<p>$views = new Smarty();</p>
<p>//$views->left_delimiter = &#8220;{{&#8220;;</p>
<p>//$views->right_delimiter = &#8220;}}&#8221;;</p>
<p>$views->compile_dir = &#8216;./webapp/templates_c&#8217;;</p>
<p>$views->cache_dir = &#8216;./webapp/templates_c/cache_c&#8217;;</p>
<p>$views->template_dir = &#8220;./webapp/templates&#8221;;</p>
<p>function smarty_block_dynamic($param,$content,&#038;$views)</p>
<p>{</p>
<p>      return $content;</p>
<p> } </p>
<p>$views->register_block(&#8216;dynamic&#8217;,'smarty_block_dynamic&#8217;,false);</p>
<p>Zend_Registry::set(&#8216;views&#8217;, $views);</p>
<p>//开始运行程序</p>
<p> $frontController->dispatch(); </p>
<p>   ?></p>
<p>4）启动文件说明</p>
<p>Zend Framework 是这样设计的，所有的文件必须包含在 include_path 中。我们也把我们的模型目录包含在 include path 中，这样我们以后就能很容易加载我们的模型类。一开始，我们必须 include Zend/Loader.php，这样我们就能访问Zend_Loader 类,在Zend_Loader 类中有静态方法使我们能够加载其他Zend Framework 类，例如： Zend_Loader::loadClass(&#8216;Zend_Controller_Front&#8217;); </p>
<p>Zend_Loader::loadClass 加载已经命名的类。它是把下划线转换成路径隔离符来实现的，并在最后加上.php 后缀。这样，类Zend_Controller_Front 将从Zend/Controller/font.php 加载。如果你在你的类库里使用相同的命名规则，就可以用Zend_Loader::loadCass()来加载它们。我们需要加载控制器类和路由类。 </p>
<p>前端控制器用路由类来映射请求的 URL 到正确的 PHP 函数，然后显示页面。为了能使路由工作，需要解决 URL 的哪一部分是指向index.php 的路径，这样它就可以在那个点后面寻找url 元素。</p>
<p>我们需要配置前端路由器，这样它就知道从哪个目录里找出我们的控制器。</p>
<p>$frontController = Zend_Controller_Front::getInstance(); </p>
<p>$frontController->setControllerDirectory(&#8216;./application/controllers&#8217;); </p>
<p>设置抛出异常，但是在服务器真正工作以后，我们不应该显示错误信息给用户看。</p>
<p>$frontController->throwExceptions(true);。</p>
<p>由于在本实例中我们使用Smarty模版技术。所以我们关闭ZF本身自带的view。$frontController->setParam(&#8216;noViewRenderer&#8217;, true);设置基地址,方便以后设置url来进行跳转。$frontController->setBaseUrl(&#8216;/test&#8217;);Zend_Registry::set(&#8216;font&#8217;, $frontController);接下来，我们对Smarty进行设置。首先我们在类库中引用了Smarty.class.php这个类。并且对它的路径进行了设置，以便让ZF知道它的位置。</p>
<p>include &#8216;Smarty/Smarty.class.php&#8217;; </p>
<p>/**</p>
<p> * 对smarty模版进行初始化</p>
<p>**/</p>
<p>$views = new Smarty();</p>
<p>//$views->left_delimiter = &#8220;{{&#8220;;</p>
<p>//$views->right_delimiter = &#8220;}}&#8221;;</p>
<p>$views->compile_dir = &#8216;./webapp/templates_c&#8217;;</p>
<p>$views->cache_dir = &#8216;./webapp/templates_c/cache_c&#8217;;</p>
<p>$views->template_dir = &#8220;./webapp/templates&#8221;;</p>
<p>function smarty_block_dynamic($param,$content,&#038;$views)</p>
<p>{</p>
<p>      return $content;</p>
<p> } </p>
<p>$views->register_block(&#8216;dynamic&#8217;,'smarty_block_dynamic&#8217;,false);</p>
<p>在这里，我们用ZF的对象注册表(Registry)来对$view来进行存贮，这样，在程序的任何对方，我们都可以调用它来进行操作。Zend_Registry::set(&#8216;views&#8217;, $views);设置好了以后，运行程序。$frontController->dispatch();</p>
<p>这个时候，你如果运行http://127.0.0.1/test 来进行测试。会发现有个错误类似 Fatal error: Uncaught exception &#8216;Zend_Controller_Dispatcher_Exception&#8217; with message &#8216;Invalid controller specified (index)&#8217; in…这个是因为我们还没有设置好我们程序。</p>
<p>3、设置程序</p>
<p>在设置文件以前，理解Zend Framework 如何组织页面很重要。每个应用程序的页面叫做 action ，许多 action 组成控制器。例如，对于这样一个格式的 URL http://localhost/test/news/view/id/1 来说，控制器是news, action 是view,后面的id和1,分别是往这个actionView传递的参数和值。</p>
<p>Zend Framework 控制器把 index 作为一个缺省的action 而保留为特别的action。这样，对于http://localhost/test/news/ 这样的url，在news控制器里的 index action将被执行。Zend Framework 也保留了一个缺省的控制器，也叫做index。这样，http://localhost/test/ 将执行 index控制器下的 action index。</p>
<p>4、设置控制器</p>
<p>   现在可以设置控制器了。在Zend Framework 里，控制器是一个必需被叫做{Controller name}Controller 的类。注意{Controller name}必需以大写字母开头。并且，这个类必须在叫做{Controller name}Controller.php这样的文件中，这个文件还必需在特定的控制器目录中。强调一下，{Controller name}必需以大写字母开头并其他字母一定是小写。每个action是在控制器类里的public 函数，名字必需是{action name}Action。在这里，{action name}应该以小写字母开头。这样在文件 test/webapp/controllers/IndexController.php 里我们的控制器类叫做 IndexController：</p>
<p>位置：test/webapp/controllers/IndexController.php </p>
<p>PHP代码如下:</p>
<p><?php </p>
<p>   class IndexController extends Zend_Controller_Action </p>
<p> { </p>
<p>      function init()</p>
<p>      {</p>
<p>   } </p>
<p>      function indexAction() </p>
<p>      { </p>
<p>      } </p>
<p>      function addAction() </p>
<p>      { </p>
<p>      } </p>
<p> } </p>
<p>?></p>
<p>我们现在有三个我们想使用的action，直到我们设置好视图，它们才工作。其中function init是个特殊的函数，简单的说，它就是在controller中的构造函数时调用的函数。</p>
<p>每个action的 URL 如下： </p>
<p>http://localhost/test/            in IndexController::indexAction() </p>
<p> http://localhost/test/index/add     in IndexController::addAction()</p>
<p>现在，我们在程序里有个能工作的路由器和每个页面的 action。</p>
<p>5、设置视图</p>
<p>   因为本实例使用的的是Smarty模版，所以和ZF本身的View视图在实现过程中，稍微有点区别！下面我直接介绍在ZF里是任何使用Smarty的。</p>
<p>在使用Smarty之前，我们应该先取出在index.php里定义的$view,并且定义好，需要在模版显示的变量。</p>
<p>PHP代码如下:</p>
<p>class IndexController extends Zend_Controller_Action </p>
<p>   { </p>
<p>     var $views;   /*模板对象*/</p>
<p>     var $data;    /*传递模版变量的对象*/</p>
<p>      function init()</p>
<p>      {</p>
<p>             //拿回注册过的对象</p>
<p>             $this->views = Zend_Registry::get(&#8216;views&#8217;);      </p>
<p>    } </p>
<p>      function indexAction() </p>
<p>      { </p>
<p>             //定义模版显示的变量 </p>
<p>             $data[｀title′]=〞hello world〞；</p>
<p>             //传递变量到模版</p>
<p>             $this->views->assign($data);</p>
<p>             //显示模版</p>
<p>             $this->views->display(&#8216;index/index.tpl&#8217;);     </p>
<p>    } </p>
<p>      function addAction() </p>
<p>      { </p>
<p>      } </p>
<p>   }</p>
<p>下面我们开始做视图文件，它们的位置是test/webapp/templates/index/index.tpl</p>
<p>PHP代码如下:</p>
<p><head></p>
<p><meta content="text/html; charset=UTF-8" http-equiv="content-type" /></p>
<p></head></p>
<p><body></p>
<h1>{$title}<br />
<h1>
<p></body></p>
<p></html></p>
<p>这个时候，输入http://127.0.0.1/test看看。应该会出现“hello world 了。</p>
<p>这样，一个简单的实例就完成了。下面我们结合Xmlrpc技术来实现一个稍微复杂一点的实例！</p>
<p>三、XMLRPC</p>
<p>1、什么是XMLRPC</p>
<p>    XMLRPC，顾名思义,就是应用了XML技术的RPC。那么什么是XML和RPC了？ </p>
<p>   RPC是Remote Procedure Call的缩写，翻译成中文就是远程过程调用，是一种在本地的机器上调用远端机器上的一个过程（方法）的技术，这个过程也被大家称为“分布式计算 ，是为了提高各个分立机器的“互操作性 而发明出来的技术。</p>
<p>XML和RPC一样也是一个东西的缩写，这个东西就是eXtensible Markup Language，中文意思就是可扩展标记语言，标记语言就是那种用尖括号（<>)括来括去的那种语言，比如说HTML。XML的可扩展性也体现在它只定义了语言的格式，而并没有定义过多的关键字，也就是通常所说的标记（Tag），所以用户可以自由地选择定义标记。它的这种自由和简单的语法规则也使得它广为流传，用来表示各种数据。</p>
<p>2、在ZF中使用XMLRPC</p>
<p>1)创建IndexController.php</p>
<p>下面我们来完成一个实例，为了方便起见，就不建立新的Controller，把刚才我们建立的IndexController修改一下，就能使用了！另外我们还需要建立一个XMLRPC的服务端程序。位置在WEB服务器的根目录上（在本机中，也就是在test文件的上级目录中，取名为1.php），由于XMLRPC使用到了类库，我们还需要下载libphpxmlrpc放在library文件夹下！</p>
<p>文件位置：test/webapp/controller/IndexController.php</p>
<p>PHP代码如下:</p>
<p>class IndexController extends Zend_Controller_Action </p>
<p>   {</p>
<p>         var $views;   /*模板对象*/</p>
<p>         var $data;    /*传递模版变量的对象*/</p>
<p>        public    function init()</p>
<p>        {</p>
<p>                //拿回注册过的对象</p>
<p>                $this->views = Zend_Registry::get(&#8216;views&#8217;);      </p>
<p>                $this->font = Zend_Registry::get(&#8216;font&#8217;);   </p>
<p>             //得到基地址           </p>
<p>                $this->baseurl=$this->font->getBaseUrl();</p>
<p>         }</p>
<p>          function indexAction() </p>
<p>          {             </p>
<p>               @include &#8220;libphpxmlrpc/xmlrpc.inc&#8221;;</p>
<p>               @include &#8220;libphpxmlrpc/xmlrpcs.inc&#8221;;                              </p>
<p>                if (isset($_POST['var1']) &#038;&#038; isset($_POST['var2'])) </p>
<p>                { </p>
<p>//创建客户端</p>
<p>                      $client = new xmlrpc_client(&#8216;http://127.0.0.1/1.php&#8217;);</p>
<p>                    //创建一个实例</p>
<p>                   @ $msg = new xmlrpcmsg(&#8220;add&#8221;, array(</p>
<p>                               new xmlrpcval($_POST['var1'], &#8220;int&#8221;),</p>
<p>                               new xmlrpcval($_POST['var2'], &#8220;int&#8221;)));</p>
<p>               //发送信息，</p>
<p>           $response=$client->send($xmlrpc_message);，服务器返回xmlrpcresp的一个实例</p>
<p>               $retval =   $client->send($msg);</p>
<p>               if ($retval->faultCode()) </p>
<p>              {</p>
<p>                     print_r(&#8220;发生一个错误: &#8220;);                    </p>
<p>                   print_r(&#8220;原因: &#8221; . htmlspecialchars($retval->faultString()));         </p>
<p>} </p>
<p>               else </p>
<p>              {</p>
<p>                     //$retval->value()获取应答的xmlrpcval（也就是服务器端返回的结果），</p>
<p>               $retval->value()->scalarval();得到描述应答结果的PHP变量</p>
<p>                     $sum = $retval->value()->scalarval();</p>
<p>               }</p>
<p>        }</p>
<p>             @$data['var1']=$_POST['var1'];</p>
<p>            @$data['var2']=$_POST['var2'];</p>
<p>            @$data['sum']=$sum;    </p>
<p>            @$data[｀action′]= &#8220;$this->baseurl/index/&#8221;;             </p>
<p>           //构造完整的url给模版     </p>
<p>           $time=date(&#8220;Y-m-d H:i:s&#8221;)</p>
<p>           @$data['url']=&#8221;$this->baseurl/index/add/id/$sum/time/$time&#8221;;            </p>
<p>            /传递变量到模版</p>
<p>           $this->views->assign($data);</p>
<p>           //显示模版</p>
<p>             $this->views->display(&#8216;index/index.tpl&#8217;);                       </p>
<p>       } </p>
<p> function addAction() </p>
<p>          { </p>
<p>               $data['title']=&#8221;实验一下&#8221;; </p>
<p>             //得到传递的值               </p>
<p>              $id=$this->_request->getParam(&#8220;id&#8221;);</p>
<p>              $time=$this->_request->getParam(&#8220;time&#8221;); </p>
<p>              $data['id']=&#8221;$id&#8221;;</p>
<p>              $data['time']=&#8221;$time&#8221;;</p>
<p>              $this->views->assign($data);</p>
<p>              $this->views->display(&#8216;index/add.tpl&#8217;);             </p>
<p>          }</p>
<p>}</p>
<p>2）创建显示模版文件</p>
<p>位置：test/webapp/templates/index/index.tpl</p>
<p>PHP代码如下:</p>
<p><html xmlns="http://www.w3.org/1999/xhtml"></p>
<p><head></p>
<p>    <meta content="text/html; charset=UTF-8" http-equiv="content-type" /></p>
<p></head></p>
<h3>hello,下面演示的是利用Xmlrpc调用远程服务器方法的实例！并且我们把得到的结果传递到另外的一个函数中去！<br />
<h3>
<p> <body></p>
<form method="POST" action="/test/index/" >
<input type="text" name="var1" value="{$var1}" />
<p>    +</p>
<input type="text" name="var2" value="{$var2}" />
<input type="submit" value="="/>
<input type="text" name="sum" value="{$sum}" />
<p>    {if $sum}</p>
<p>    <a href="{$url}">点一下看看！</a></p>
<p>    {/if}</p></form>
<p> </body></p>
<p></html></p>
<p>位置： test/webapp/templates/index/add.tpl</p>
<p>PHP代码如下：</p>
<p> <html> </p>
<p>   <head> </p>
<p>   <meta content="text/html; charset=UTF-8" http-equiv="content-type" /></p>
<p>   </head> </p>
<p>   <body> </p>
<p>   现在是{$time}</p>
<h1>{$title}</h1>
<p> 你刚才传递的是 {$id}</a></p>
<p>   </body> </p>
<p>   </html></p>
<p>3）创建XMLRPC服务器端程序</p>
<p>位置：web/1.php</p>
<p>PHP代码如下:</p>
<p><?php</p>
<p>@include ("libphpxmlrpc/xmlrpc.inc");</p>
<p>@include ("libphpxmlrpc/xmlrpcs.inc");</p>
<p> if ($_SERVER['REQUEST_METHOD'] != 'POST')</p>
<p> {</p>
<p>            exit(0);</p>
<p> }</p>
<p> $add_sig = array(array($xmlrpcString, $xmlrpcInt, $xmlrpcInt));</p>
<p> $add_doc = "Add the two integer together";</p>
<p> function add($params)</p>
<p> {</p>
<p>                //引入用户错误代码值</p>
<p>                global $xmlrpcerruser;</p>
<p>                //返回一个PHP数组</p>
<p>                $val = php_xmlrpc_decode($params);</p>
<p>                $ret = $val[0] + $val[1];</p>
<p>                return new xmlrpcresp(new xmlrpcval($ret, "int"));</p>
<p> }</p>
<p> //创建一个xmlrpc_server的实例：</p>
<p> $server = new xmlrpc_server(array(</p>
<p>                "add" => array(</p>
<p>                        &#8220;function&#8221; => &#8220;add&#8221;,</p>
<p>                         &#8220;signature&#8221; => $add_sig,</p>
<p>                         &#8220;docstring&#8221; => $add_doc</p>
<p>        )));</p>
<p>?></p>
<p> OK，现在打开http;//127.0.0.1/test/看看。刚才建立的那个XMLRPC应该已经建立起来，输入数字，测试一下吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1332.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>今晚抽空给服务器环境补上gd库支持环境</title>
		<link>http://www.evanjiang.net.cn/archives/1292.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1292.html#comments</comments>
		<pubDate>Wed, 26 Aug 2009 16:56:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1292</guid>
		<description><![CDATA[<p style="float: right;margin: 4px;">


</p> <p>今晚抽空给服务器环境补上GD库存支持环境..多余的说明,改日再加上,先记录下安装流程吧..</p>
<p>环境所需要的相应的文件的下载:
gd:	http://www.boutell.com/gd/
zlib:	http://www.zlib.net/zlib-1.2.3.tar.gz
jpeg:	ftp://ftp.uu.net/graphics/jpeg/
libpng:		http://www.libpng.org/pub/png/libpng.html
freetype:	http://www.freetype.org
xpm:	http://koala.ilog.fr/ftp/pub/xpm/
php	http://www.php.net</p>
<p>先后安装相应的文件:
六、安装jpeg6
#cd /home/tiger/evan
# tar -zxvf jpegsrc.v6b.tar.gz
# cd jpeg-6b/</p>
<p>mkdir /home/tiger/evan/libjpeg
mkdir /home/tiger/evan/libjpeg/include
mkdir /home/tiger/evan/libjpeg/bin
mkdir /home/tiger/evan/libjpeg/lib
mkdir /home/tiger/evan/libjpeg/man
mkdir /home/tiger/evan/libjpeg/man/man1</p>
<p># ./configure &#8211;prefix=/usr/local/ding9/jpeg6 &#8211;enable-shared
# make
# make test

# make install-lib
# make install
在安装过程中，提示找不到路径而出错，那就按照提示建立相应的路径。用mkdir 命令，直到编译通过为止。
七、安装libpng:
# cd /home/tiger/evan
# tar -zxf libpng-1.2.7-config.tar.gz
# cd libpng-1.2.7-config
cp scripts/makefile.linux makefile
# ./configure &#8211;prefix=/home/tiger/evan/libpng2
# make
# make install
八、安装freetype:
# cd /home/tiger/evan
# tar -zxf freetype-2.1.9.tar.gz
# cd freetype-2.1.9
# ./configure &#8211;prefix=//home/tiger/evan/freetype2
# make
# make install
九、安装zlib
# cd [...]]]></description>
			<content:encoded><![CDATA[<p>今晚抽空给服务器环境补上GD库存支持环境..多余的说明,改日再加上,先记录下安装流程吧..</p>
<p>环境所需要的相应的文件的下载:<br />
gd:	http://www.boutell.com/gd/<br />
zlib:	http://www.zlib.net/zlib-1.2.3.tar.gz<br />
jpeg:	ftp://ftp.uu.net/graphics/jpeg/<br />
libpng:		http://www.libpng.org/pub/png/libpng.html<br />
freetype:	http://www.freetype.org<br />
xpm:	http://koala.ilog.fr/ftp/pub/xpm/<br />
php	http://www.php.net</p>
<p>先后安装相应的文件:<br />
六、安装jpeg6<br />
#cd /home/tiger/evan<br />
# tar -zxvf jpegsrc.v6b.tar.gz<br />
# cd jpeg-6b/</p>
<p>mkdir /home/tiger/evan/libjpeg<br />
mkdir /home/tiger/evan/libjpeg/include<br />
mkdir /home/tiger/evan/libjpeg/bin<br />
mkdir /home/tiger/evan/libjpeg/lib<br />
mkdir /home/tiger/evan/libjpeg/man<br />
mkdir /home/tiger/evan/libjpeg/man/man1</p>
<p># ./configure &#8211;prefix=/usr/local/ding9/jpeg6 &#8211;enable-shared<br />
# make<br />
# make test<br />
<span id="more-1292"></span><br />
# make install-lib<br />
# make install<br />
在安装过程中，提示找不到路径而出错，那就按照提示建立相应的路径。用mkdir 命令，直到编译通过为止。<br />
七、安装libpng:<br />
# cd /home/tiger/evan<br />
# tar -zxf libpng-1.2.7-config.tar.gz<br />
# cd libpng-1.2.7-config<br />
cp scripts/makefile.linux makefile<br />
# ./configure &#8211;prefix=/home/tiger/evan/libpng2<br />
# make<br />
# make install<br />
八、安装freetype:<br />
# cd /home/tiger/evan<br />
# tar -zxf freetype-2.1.9.tar.gz<br />
# cd freetype-2.1.9<br />
# ./configure &#8211;prefix=//home/tiger/evan/freetype2<br />
# make<br />
# make install<br />
九、安装zlib<br />
# cd /home/tiger/evan<br />
# tar -zxvf zlib-1.2.2.tar.gz<br />
# cd zlib-1.2<br />
# ./configure &#8211;prefix=//home/tiger/evan/zlib2<br />
# make<br />
# make install</p>
<p>十、安装GD<br />
# cd /home/tiger/evan<br />
# tar -zvxf gd-2.0.26gif.tar.gz<br />
# cd gd-2.0.26gif<br />
# ./configure &#8211;prefix=/home/tiger/evan/gd2 &#8211;with-zlib=/u/home/tiger/evan/zlib2/ &#8211;with-png=/usr/home/tiger/evan/libpng2/ &#8211;with-jpeg=/home/tiger/evan/jpeg6/ &#8211;with-freetype=/home/tiger/evan/freetype2/<br />
# make<br />
# make install</p>
<p>安装编译 php<br />
# cd  /home/tiger/evan<br />
# tar -zxvf  php-5.1.1.tar.gz<br />
# mv php-5.1.1 php5<br />
# cd php5/<br />
&#8216;./configure&#8217; &#8216;&#8211;prefix=/home/tiger/evan/php5-fastcgi&#8217; &#8216;&#8211;with-mysql=/usr/local/mysql&#8217; &#8216;&#8211;enable-gd-native-ttf&#8217; &#8216;&#8211;with-gd&#8217; &#8216;&#8211;enable-ftp&#8217; &#8216;&#8211;with-iconv&#8217; &#8216;&#8211;with-gettext&#8217; &#8216;&#8211;enable-fastcgi&#8217; &#8216;&#8211;enable-zend-multibyte&#8217; &#8216;&#8211;without-pear&#8217; &#8216;&#8211;enable-force-cgi-redirect&#8217; &#8216;&#8211;enable-discard-path&#8217; &#8216;&#8211;with-bz2&#8242; &#8216;&#8211;enable-zip&#8217; &#8216;&#8211;with-calendar&#8217; &#8216;&#8211;enable-mbstring&#8217; &#8216;&#8211;with-curl&#8217; &#8216;&#8211;enable-exif&#8217; &#8216;&#8211;with-xmlrpc&#8217; &#8216;&#8211;enable-soap&#8217; &#8216;&#8211;enable-sockets&#8217; &#8216;&#8211;enable-dba&#8217; &#8216;&#8211;with-gdbm&#8217; &#8216;&#8211;with-kerberos&#8217; &#8216;&#8211;enable-pcntl&#8217; &#8216;&#8211;with-zlib&#8217; &#8216;&#8211;with-config-file-path=/home/tiger/evan/etc&#8217;</p>
<p>make<br />
#如果make遇到报错,可以先运行make clean 再执行make<br />
make clean<br />
make<br />
make test<br />
make install</p>
<p>简音的记录就是这样.以后有时间再详细补充&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1292.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debian 配置 LAMP (debian5.0+apache2.2+mysql5.0+php5.0 )</title>
		<link>http://www.evanjiang.net.cn/archives/1271.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1271.html#comments</comments>
		<pubDate>Sat, 08 Aug 2009 07:17:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1271</guid>
		<description><![CDATA[<p>一、安装基本程式
~#apt-get install apache2 mysql-server php5 php5-mysql  phpmyadin pear php5-gd
#在安装过程序会提示你设置mysql的root用户密码。</p>
<p>在Debian下只要安装相关软体，无需修改任何配置文件，把网页程序上传到/var/www目录，更改权限为777，服务器就能够工作！
二、LAMP简单配置
经过前面的步骤，服务器就能够正常运行，但是有时候达不到我们的要求，所以掌握基本配置方法是很有必要的。</p>
<p>1、建立mysql数据库，并添一个仅拥有这些数据库权限的用户，以便网页程序使用，提高服务器的安全性。
~#mysql -h127.1 -uroot -pabcabc
#连接mysql服务器，其中-h是主机，-u是用户名，-p是密码。注意各参数与附值之间没有空格。
> create database lamp;
#创建数据库lamp，注意mysql内部命令必需以“;”结尾。
>show databases;
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+
&#124; Database           &#124;
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+
&#124; information_schema &#124;
&#124; lamp               &#124;
&#124; mysql        [...]]]></description>
			<content:encoded><![CDATA[<p>一、安装基本程式<br />
~#apt-get install apache2 mysql-server php5 php5-mysql  phpmyadin pear php5-gd<br />
#在安装过程序会提示你设置mysql的root用户密码。</p>
<p>在Debian下只要安装相关软体，无需修改任何配置文件，把网页程序上传到/var/www目录，更改权限为777，服务器就能够工作！<br />
二、LAMP简单配置<br />
经过前面的步骤，服务器就能够正常运行，但是有时候达不到我们的要求，所以掌握基本配置方法是很有必要的。</p>
<p>1、建立mysql数据库，并添一个仅拥有这些数据库权限的用户，以便网页程序使用，提高服务器的安全性。<br />
~#mysql -h127.1 -uroot -pabcabc<br />
#连接mysql服务器，其中-h是主机，-u是用户名，-p是密码。注意各参数与附值之间没有空格。<br />
> create database lamp;<br />
#创建数据库lamp，注意mysql内部命令必需以“;”结尾。<br />
>show databases;<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
| Database           |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
| information_schema |<br />
| lamp               |<br />
| mysql              |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
4 rows in set (0.00 sec)<br />
#查看数据库。<br />
>grant all on lamp.* to lyb@localhost identified by &#8216;abc123&#8242;;<br />
#建立用户名lyb，只允许本地登录，密码为“abc123”，仅拥有数据库lamp的完全权限。l<br />
<span id="more-1271"></span><br />
2、apache2配置文件介绍。<br />
Debian 5.0 的apache2的配置文件全在/etc/apache2/目录下面。<br />
apache2.conf<br />
#apache的全局配置文件。<br />
envvars<br />
#定义apache的用户环境。<br />
ports.conf<br />
#定义监听端口。<br />
httpd.conf<br />
#默认为空文件，一般用户自已添加的选项写入这里。<br />
mods-available<br />
#以load文件结尾的是加载相应模块选项，以conf文件结尾的是相应模块选项。<br />
mods-enabled<br />
#都是指向mods-available下面的文件的链接文件，需要启用那些模块就在此建立相关链接即可。<br />
sites-available<br />
#虚拟主机配置文件<br />
sites-enabled<br />
#指向sites-available目录下文件的链接。<br />
conf.d<br />
#定义字符编码和其它选项。<br />
三、性能调优<br />
1、内核优化，vim /etc/sysctl.conf<br />
# Use TCP syncookies when needed<br />
net.ipv4.tcp_syncookies = 1<br />
# Enable TCP window scaling<br />
net.ipv4.tcp_window_scaling: = 1<br />
# Increase TCP max buffer size<br />
net.core.rmem_max = 16777216<br />
net.core.wmem_max = 16777216<br />
# Increase Linux autotuning TCP buffer limits<br />
net.ipv4.tcp_rmem = 4096 87380 16777216<br />
net.ipv4.tcp_wmem = 4096 65536 16777216<br />
# Increase number of ports available<br />
net.ipv4.ip_local_port_range = 1024 65000<br />
2、优化磁盘<br />
在文件系统上禁用 atime 日志记录特性。atime 是最近访问文件的时间，每当访问文件时，底层文件系统必须记录这个时间戳。因为系统管理员很少使用atime，禁用它可以减少磁盘访问时间。禁用这个特性的方法是，在 /etc/fstab 的第四列中添加 noatime 选项。<br />
例如：LABEL=/boot             /boot                   ext3    defaults,noatime        1 2<br />
3、调优Apache<br />
需要伸缩性的站点可以选择worker或event线程化的MPM，而需要稳定性和兼容性的站点可以用prefork。<br />
一个经典 worker MPM 配置：<br />
ServerLimit 128<br />
StartServers 8<br />
MaxClients 3000<br />
MinSpareThreads 128<br />
MaxSpareThreads 1024<br />
ThreadsPerChild 32<br />
一个 perfoxk MPM 配置实例：<br />
StartServers 32<br />
MinSpareServers 32<br />
MaxSpareServers 64<br />
MaxClients 1024<br />
MaxRequestsPerChild 4000</p>
<p>有效的使用选项和重写<br />
<Directory /><br />
    AllowOverride None<br />
    Options FollowSymLinks<br />
</Directory><br />
如果使用 -FollowSymLinks，该特性就会被禁用。如果禁用了 FollowSymLinks，Apache 就必须检查使用该文件名的所有组件（目录和文件本身），以确保它们不是符号连接。这会带来额外的开销（磁盘操作）。<br />
AllowOverride None 是不允许重写，这能消除 Apache 检查 .htaccess 的需求。<br />
HostnameLookups off 指令禁用 DNS 查找，因为试图反向解析连接到您的服务器的所有 IP 地址无疑是浪费资源。</p>
<p>持久连接<br />
KeepAlive On<br />
KeepAliveTimeout 5</p>
<p>关闭DNS查询<br />
HostnameLookups off</p>
<p>合理配置缓冲模块<br />
mod_cache<br />
mod_disk_cache<br />
mod_mem_cache<br />
mod_file_cache</p>
<p>4、优化 php.ini ，四个重要的控制设置 PHP 可以使用多少系统资源。<br />
max_execution_time 一个脚本可使用多少 CPU 秒，建议值 30<br />
max_input_time 一个脚本等待输入数据的时间有多长（秒），建议值 60<br />
memory_limit 在被取消之前，一个脚本可使用多少内存（字节），建议值 32M<br />
output_buffering 数据发送给客户机之前，有多少数据（字节）需要缓存，建议值 4096<br />
PHP 可执行的日志记录数是可配置的。在生产环境中，禁用除最重要的日志以外的一切日志记录能够减少磁盘写操作。如果需要使用日志来排除问题，那么可以按需启用日志记录。error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR 将启用足够的日志记录，使您发现问题，同时从脚本中消除大量无用的内容。<br />
5、优化MySQL<br />
参考：<br />
三、应用 php 加速<br />
1、安装 XCache 或 eAccelerator<br />
下载：apt-get install php5-xcache<br />
下载：http://bart.eaccelerator.net/source/0.9.5.3/eaccelerator-0.9.5.3.tar.bz2</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1271.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>$_request与$_post、$_get的区别和特点</title>
		<link>http://www.evanjiang.net.cn/archives/1268.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1268.html#comments</comments>
		<pubDate>Sat, 08 Aug 2009 02:05:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1268</guid>
		<description><![CDATA[<p>php中有$_request与$_post、$_get用于接受表单数据，那么他们有何种区别，什么时候用那种最好呢？</p>
<p>一、$_request与$_post、$_get的区别和特点</p>
<p>$_REQUEST[]具用$_POST[] $_GET[]的功能,但是$_REQUEST[]比较慢。通过post和get方法提交的所有数据都可以通过$_REQUEST数组获得</p>
<p>二、$_post、$_get的区别和特点</p>
<p>   1. get是从服务器上获取数据，post是向服务器传送数据。
   2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中，值和表单内各个字段一一对应，在URL中可以看到。post是通过HTTP post机制，将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
   3. 对于get方式，服务器端用Request.QueryString获取变量的值，对于post方式，服务器端用Request.Form获取提交的数据。
   4. get传送的数据量较小，不能大于2KB。post传送的数据量较大，一般被默认为不受限制。但理论上，IIS4中最大量为80KB，IIS5中为100KB。
   5. get安全性非常低，post安全性较高。</p>
<p>举例：mypage?id=1这种就是GET方式传值，可以用$_request和$_get接受传值。 </p>
<p>隐藏域HIDDEN </p>
<p>隐藏域在页面中对于用户是不可见的，在表单中插入隐藏域的目的在于收集或发送信息，以利于被处理表单的程序所使用。浏览者单击发送按钮发送表单的时候，隐藏域的信息也被一起发送到浏览器。</p>
]]></description>
			<content:encoded><![CDATA[<p>php中有$_request与$_post、$_get用于接受表单数据，那么他们有何种区别，什么时候用那种最好呢？</p>
<p>一、$_request与$_post、$_get的区别和特点</p>
<p>$_REQUEST[]具用$_POST[] $_GET[]的功能,但是$_REQUEST[]比较慢。通过post和get方法提交的所有数据都可以通过$_REQUEST数组获得</p>
<p>二、$_post、$_get的区别和特点</p>
<p>   1. get是从服务器上获取数据，post是向服务器传送数据。<br />
   2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中，值和表单内各个字段一一对应，在URL中可以看到。post是通过HTTP post机制，将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。<br />
   3. 对于get方式，服务器端用Request.QueryString获取变量的值，对于post方式，服务器端用Request.Form获取提交的数据。<br />
   4. get传送的数据量较小，不能大于2KB。post传送的数据量较大，一般被默认为不受限制。但理论上，IIS4中最大量为80KB，IIS5中为100KB。<br />
   5. get安全性非常低，post安全性较高。</p>
<p>举例：mypage?id=1这种就是GET方式传值，可以用$_request和$_get接受传值。 </p>
<p>隐藏域HIDDEN </p>
<p>隐藏域在页面中对于用户是不可见的，在表单中插入隐藏域的目的在于收集或发送信息，以利于被处理表单的程序所使用。浏览者单击发送按钮发送表单的时候，隐藏域的信息也被一起发送到浏览器。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1268.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>搜索引擎技术核心揭密(PHP)</title>
		<link>http://www.evanjiang.net.cn/archives/1264.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1264.html#comments</comments>
		<pubDate>Mon, 03 Aug 2009 03:31:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1264</guid>
		<description><![CDATA[<p>　　谈到网页搜索引擎时，大多数人都会想到雅虎。的确，雅虎开创了一个互联网络的搜索时代。然而，雅虎目前用于搜索网页的技术却并非该公司原先自己开发的。2000年8月，雅虎采用了Google（www.google.com）这家由斯坦福大学学生创建的风险公司的技术。理由非常简单，Google的搜索引擎比雅虎先前使用的技术能更快、更准确搜索到所需要的信息。 </p>
<p>　　让我们自己来设计、开发一个强劲、高效的搜索引擎和数据库恐怕短时间内在技术、资金等方面是不可能的，不过，既然雅虎都在使用别人的技术，那么我们是不是也可以使用别人现成的搜索引擎网站呢？ </p>
<p>剖析编程思路 </p>
<p>　　我们可以这样设想：模拟一个查询，向某个搜索引擎网站发出相应格式的搜索命令，然后传回搜索结果，对结果的HTML代码进行分析，剥离多余的字符和代码，最后按所需要的格式显示在我们自己的网站页面里。 </p>
<p>　　这样，问题的关键就在于，我们要选定一个搜索信息准确（这样我们的搜索才会更有意义啊）、速度快（因为我们分析搜索结果并显示需要额外的时间），搜索结果简洁（便于进行HTML源代码分析和剥离）的搜索网站，由于新一代搜索引擎Google的各种优良特性，这里我们选择它为例，来看看用PHP怎样实现后台对Google(www.google.com)搜索、前台个性化显示这一过程。 </p>
<p>　　我们先来看看Google的查询命令的构成。进入www.google.com网站，在查询栏中输入“abcd”，点击查询按钮，我们可以发现浏览器的地址栏变成：&#8221;http://www.google.com/search?q=abcd&#038;btnG=Google%CB%D1%CB%F7&#038;hl=zh-CN&#038;lr=&#8221;，可见，Google是通过表单的get方式来传递查询参数并递交查询命令的。我们可以使用PHP中的file()函数来模拟这个查询过程。 </p>
<p>了解File（）函数 </p>
<p>　　语法: array file(string filename); </p>
<p>　　返回值为数组，将文件全部读入数组变量中。这里的文件可以是本地的，也可以是远程的，远程文件必须指明所使用的协议。例如： result=file(“http://www.google.com/search?q=abcd&#038;btnG=Google%CB%D1%CB%F7&#038;hl=zh-CN&#038;lr=”)，该语句将模拟我们在Google上查询单词“abcd”的过程，并将搜索结果以每行为元素，传回到数组变量 result中。因为这里读取的文件是远程的，所以协议名“http://”不能缺少。

　　如果要让用户输入搜索字符进行任意搜索，我们可以做一个输入文本框和提交按钮，并将上文中的被搜索字符“abcd”用变量替换：
]]></description>
			<content:encoded><![CDATA[<p>　　谈到网页搜索引擎时，大多数人都会想到雅虎。的确，雅虎开创了一个互联网络的搜索时代。然而，雅虎目前用于搜索网页的技术却并非该公司原先自己开发的。2000年8月，雅虎采用了Google（www.google.com）这家由斯坦福大学学生创建的风险公司的技术。理由非常简单，Google的搜索引擎比雅虎先前使用的技术能更快、更准确搜索到所需要的信息。 </p>
<p>　　让我们自己来设计、开发一个强劲、高效的搜索引擎和数据库恐怕短时间内在技术、资金等方面是不可能的，不过，既然雅虎都在使用别人的技术，那么我们是不是也可以使用别人现成的搜索引擎网站呢？ </p>
<p>剖析编程思路 </p>
<p>　　我们可以这样设想：模拟一个查询，向某个搜索引擎网站发出相应格式的搜索命令，然后传回搜索结果，对结果的HTML代码进行分析，剥离多余的字符和代码，最后按所需要的格式显示在我们自己的网站页面里。 </p>
<p>　　这样，问题的关键就在于，我们要选定一个搜索信息准确（这样我们的搜索才会更有意义啊）、速度快（因为我们分析搜索结果并显示需要额外的时间），搜索结果简洁（便于进行HTML源代码分析和剥离）的搜索网站，由于新一代搜索引擎Google的各种优良特性，这里我们选择它为例，来看看用PHP怎样实现后台对Google(www.google.com)搜索、前台个性化显示这一过程。 </p>
<p>　　我们先来看看Google的查询命令的构成。进入www.google.com网站，在查询栏中输入“abcd”，点击查询按钮，我们可以发现浏览器的地址栏变成：&#8221;http://www.google.com/search?q=abcd&#038;btnG=Google%CB%D1%CB%F7&#038;hl=zh-CN&#038;lr=&#8221;，可见，Google是通过表单的get方式来传递查询参数并递交查询命令的。我们可以使用PHP中的file()函数来模拟这个查询过程。 </p>
<p>了解File（）函数 </p>
<p>　　语法: array file(string filename); </p>
<p>　　返回值为数组，将文件全部读入数组变量中。这里的文件可以是本地的，也可以是远程的，远程文件必须指明所使用的协议。例如： result=file(“http://www.google.com/search?q=abcd&#038;btnG=Google%CB%D1%CB%F7&#038;hl=zh-CN&#038;lr=”)，该语句将模拟我们在Google上查询单词“abcd”的过程，并将搜索结果以每行为元素，传回到数组变量 result中。因为这里读取的文件是远程的，所以协议名“http://”不能缺少。<br />
<span id="more-1264"></span><br />
　　如果要让用户输入搜索字符进行任意搜索，我们可以做一个输入文本框和提交按钮，并将上文中的被搜索字符“abcd”用变量替换：<br />
<?php<br />
echo '<br />
<form>&#8216;; //没有参数的form，默认提交方式为get，提交到本身<br />
echo &#8216;<br />
<input type="text" name="keywords">&#8216;; //构造一个文本输入框<br />
echo &#8216;<br />
<input type="submit" value="查询">&#8216;; //构造一个提交查询按钮<br />
echo &#8216;</form>
<p>&#8216;; </p>
<p>if (isset( keywords)) //提交后PHP会生成变量 kwywords,即要求下面的程序在提交后运行<br />
{<br />
urlencode( keywords); //对用户输入内容进行URL编码<br />
result=file(&#8220;http://www.google.com/search?q=&#8221;. keywords.&#8221;&#038;btnG=Google%CB%D1%CB%F7&#038;hl=zh-CN&#038;lr=&#8221;);<br />
//对查询语句进行变量替换,将查询结果保存在数组变量 result中<br />
result_string=join(&#8221; &#8220;, result); //将数组$result合并成字符串，各数组元素之间用空格粘和<br />
&#8230; //进一步处理<br />
}<br />
?> </p>
<p>　　上面的这段程序已经能按用户输入内容进行查询，并将返回的结果合成一个字符串变量$result_string。请注意要使用urlencode()函数将用户输入内容进行URL编码，才可以正常地对输入的汉字、空格以及其他特殊字符进行查询，这样做也是尽可能逼真地模拟Google的查询命令，保证搜索结果的正确性。 </p>
<p>对Google的分析 </p>
<p>　　为了便于理解，现在假设我们所真正需要的东西是：搜索结果的标题。网址和简介等，这是一个简洁而典型的需求。这样，我们所要做的便是：去除Google搜索结果的台头和脚注，包括一个Google的标志、再次搜索的输入框和搜索结果说明等，并且在剩余的搜索结果各项条目中剥离原来的HTML格式标记，替换成我们想要的格式。 </p>
<p>　　要做到这一点，我们必须仔细地分析Google搜索结果的HTML源码，找到其中的规律。不难发现，在Google的搜索结果的正文总是包含在源码的第一个
<p>标记和倒数第二个
<p>标记之间，并且倒数第二个
<p>标记后紧跟table字符，而且这个组合“<br />
<table”在源码中也仅有一次，利用这个特点，我们可以这样去除Google的台头和脚注。 </p>
<p>　　以下所有程序均依次接续在上文程序的“进一步处理”处。 </p>
<p>　　result_string = strstr( result_string, "<p>&#8220;); //取 result_string从第一个
<p>开始后的字符串，以去除Google台头<br />
position= strpos( result_string,&#8221;
<p>table符号的位置<br />
result_string= substr( result_string,0, position);//截取第一个
<p>table符号之前的字符串,以去除脚注 </p>
<p>应用与实现 </p>
<p>　　OK，现在我们已经得到有用的HTML源码主干了，剩下的问题是如何自主地显示这些内容。我们再分析一下这些搜索结果条目，发现每个条目之间也是很有规律的用<br />
分隔，也就是各成一个段落，按这个特点我们用explode()函数把每个条目切开： </p>
<p>　　语法：explode(string separator, string string); </p>
<p>　　返回一个数组，按separator切开后的各个小字串被保存在数组中。 </p>
<p>　　于是：<br />
result_array=explode(&#8220;
<p>&#8220;, result_string); //用字串&#8221;
<p>&#8220;把结果切开 </p>
<p>　　我们就得到一个数组 result_array，其中每个元素都是一个搜索结果条目。我们所要做的仅仅是研究每个条目及其HTML显示格式代码，然后按要求替换就行了。下面用循环来处理 result_array中的每个条目。<br />
for( i=0; i {<br />
&#8230; //处理每个条目<br />
} </p>
<p>　　对于每个条目，我们也很容易找到一些特点：每个条目都由标题、摘要、简介、类别、网址等组成，每个部分都换行，即包含<br />标记，于是再次分割：（以下处理程序放在上文的循环中）<br />
every_item=explode(&#8220;<br />&#8220;, result_array[ i]); </p>
<p>　　这样我们得到一个数组 every_item，其中 every_item[0]就是标题， every_item[1]和 every_item[2]两行为摘要， every_item[3]和 every_item[4]等等的头部如果包含“<font size=-1 color=#6f6f6f >简介:</font>”、“< font size=-1 color=#6f6f6f>类别:< /font>”字符，则是简介或类别（因为有的结果条目没有该项），如果头部包含“< font color=green>”则肯定就是网址啦，这种对比判断我们常使用正则表达式（略），如果要替换也很方便，比如包含标题的$every_item[0]，其本身是有链接的，我们希望修改这个链接属性，让它在新窗口打开链接：<br />
echo eregi_replace(&#8216; {<br />
&#8230; //处理每个条目中除去第一项（第一项为标题，已经显示）的每一项<br />
&#8230; //更多格式修改<br />
} </p>
<p>　　这样就修改了链接属性，其余很多显示格式的修改、剥离、替换都能用正则替换eregi_replace()来完成。 </p>
<p>　　至此我们已经得到了每个搜索条目的每一项，并能任意修改每项的格式，甚至可以给他套上漂亮的表格。然而一个好的程序应该能适应各种运行环境的，这里也不例外，我们其实还只是讨论了搜索结果的HTML剥离的一种框架方法，真正要做得完美，还要考虑很多内容，比如要显示一共搜索出多少结果，分成多少页等等，甚至还可以刨除与Google相关的那些“类别”、“简介”等代码，让客户根本看不到原始网站。不过这些内容和要求我们都能通过分析HTML进行剥离得到。现在大家完全能自己动手，做个极富个性化的搜索引擎.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1264.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux 下的lighttpd不能加载zend Optimizer的解决方法</title>
		<link>http://www.evanjiang.net.cn/archives/1252.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1252.html#comments</comments>
		<pubDate>Sat, 01 Aug 2009 06:36:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[www]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1252</guid>
		<description><![CDATA[<p>    在 Fedora 10 安装 lighttpd php5 mysql5 zend Optimizer前 3个均可以用 yum 进行安装，很方便。</p>
<p>　　在 Fedora 10 安装 lighttpd php5 mysql5 zend Optimizer</p>
<p>　　前 3个均可以用 yum 进行安装，很方便。</p>
<p>　　而 zend Optimizer 需要下载解压后，到解压目录输入 # ./install.sh 就会出现界面提示安装。安装后重启 lighttpd却没有成功启动 zend Optimizer 。</p>
<p>　　解决经过：</p>
<p>　　1. 开始认为是 php.ini 没有设置好。 打目录中找 #find / -name php.ini ，后发现网页输出 就有 Loaded Configuration File : /usr/local/Zend/etc/php.ini 显示 php.ini 文件已被加载。</p>
<p>　　2. [...]]]></description>
			<content:encoded><![CDATA[<p>    在 Fedora 10 安装 lighttpd php5 mysql5 zend Optimizer前 3个均可以用 yum 进行安装，很方便。</p>
<p>　　在 Fedora 10 安装 lighttpd php5 mysql5 zend Optimizer</p>
<p>　　前 3个均可以用 yum 进行安装，很方便。</p>
<p>　　而 zend Optimizer 需要下载解压后，到解压目录输入 # ./install.sh 就会出现界面提示安装。安装后重启 lighttpd却没有成功启动 zend Optimizer 。</p>
<p>　　解决经过：</p>
<p>　　1. 开始认为是 php.ini 没有设置好。 打目录中找 #find / -name php.ini ，后发现网页输出 就有 Loaded Configuration File : /usr/local/Zend/etc/php.ini 显示 php.ini 文件已被加载。</p>
<p>　　2. 是否 zend Optimizer 版本问题,安装最新版还是不成功。</p>
<p>　　3. 在网络查找解决方法多是说 php.ini 设置问题。最终将几个方法总结才解决：</p>
<p>　　具体解决方法:</p>
<p>　　1. 对于 php.ini文件路径有问题( 我的在 phpinfo()显示php.ini路径正确，我就不用这个方法 )</p>
<p>　　解决方法</p>
<p>　　php -i | grep php.ini 就可以找到当前php使用的php.ini文件</p>
<p>　　比如, 编译安装时没有指定php.ini存放路径, 那么默认php.ini会放在/usr/local/lib下面</p>
<p>　　最好是在编译PHP时指定PHP配置文件的路径 如: &#8211;with-config-file-path=/usr/local/etc</p>
<p>　　而一般zend默认安装 php.ini在/etc/目录下面或/usr/local/Zend/etc 所以需要在安装的时候手工指定我们php.ini文件存放的位置</p>
<p>　　如果, 不知道现在的PHP 的配置文件具体位置的话 可以查看一下:</p>
<p>　　php -i | grep php.ini</p>
<p>　　如果php optimizer安装好 却发现不能加载的话可以 手工指定读取php.ini文件的位置</p>
<p>　　php -c /etc/ -v 如果可以看到zend opt正确加载</p>
<p>　　那么做个连接就好 连接到php默认读取的php.ini路径下面</p>
<p>　　<span id="more-1252"></span><br />
比如</p>
<p>　　ln -sf /etc/php.ini /usr/local/lib</p>
<p>　　[root@localhost /]# php -v</p>
<p>HP 5.2.5 (cli) (built: Jan 22 2006 12:59:19)</p>
<p>　　Copyright (c) 1997-2006 The PHP Group</p>
<p>　　Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies</p>
<p>　　with Zend Extension Manager v1.0.9, Copyright (c) 2003-2006, by Zend Technologies</p>
<p>　　with Zend Optimizer v3.3.2, Copyright (c) 1998-2006, by Zend Technologies</p>
<p>　　Ok 正常 phpinfo()看到的当然也是一样的</p>
<p>　　2. 调用库文件的问题</p>
<p>　　有的时候还有一些情况下 php -i 或php -v 在控制台下可以看到zend opt,</p>
<p>　　但是 apache 执行phpinfo的输出里面却看不到</p>
<p>　　一般是因为 调用php的时候zend模块不能加载, 比如AS4里面 就是这样的</p>
<p>　　如as4下面默认的php安装后读取库文件的路径 是在/usr/lib下面 ，</p>
<p>　　而php.ini文件中加载zend模块是在zend安装路径的lib目录中</p>
<p>　　比如/usr/local/Zend/lib 这时apache在执行php时 不能加载zend模块 所以 在控制台里php -v 可以正常</p>
<p>　　但是apache 却没有加载zend。</p>
<p>　　解决办法</p>
<p>　　先把zend模块copy到</p>
<p>　　/usr/lib里面 然后改一下php.ini里面zend加载模块部分</p>
<p>　　( 我在 php -i 中显示 Failed loading /usr/local/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so: /usr/local/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so: cannot restore segment prot after reloc: Permission denied</p>
<p>　　看这个原来是权限问题)</p>
<p>　　3. 最恶心的SElinux问题</p>
<p>　　SElinux导致PHP不能使用zend/lib下的库文件。所以，即便是做link也不行。只能够拷贝库文件到有权限的目录。或者直接关掉SElinux</p>
<p>　　但我已 在 /etc/selinux/config 的 SELINUX=disabled 关掉SElinux 还是不行, 再网络查询发现</p>
<p>　　在你保证SElinux 被disable后.还执行下</p>
<p>　　chcon -t texrel_shlib_t 命令</p>
<p>　　如: chcon -t texrel_shlib_t /usr/local/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so (这个文件视具体执行文件.)</p>
<p>　　就可以。</p>
<p>　　我的解决的情况是:</p>
<p>　　1. 关闭SElinux</p>
<p>　　2. 运行 #chcon -t texrel_shlib_t /usr/local/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so</p>
<p>　　就可以。</p>
<p>还有一个最终的解决办法，就是使用低版本的php源代码来编译安装php.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1252.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP cookie和session的分析</title>
		<link>http://www.evanjiang.net.cn/archives/1238.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1238.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 09:40:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/archives/1238.html</guid>
		<description><![CDATA[<p>1. PHP的COOKIE</p>
<p>cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。
PHP在http协议的头信息里发送cookie, 因此 setcookie() 函数必须在其它信息被输出到浏览器前调用，这和对 header() 函数的限制类似。</p>
<p>1.1 设置cookie:
    可以用 setcookie() 或 setrawcookie() 函数来设置 cookie。也可以通过向客户端直接发送http头来设置.
1.1.1 使用setcookie()函数设置cookie:
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure [, bool httponly]]]]]] )
     name:   cookie变量名
     value: [...]]]></description>
			<content:encoded><![CDATA[<p>1. PHP的COOKIE</p>
<p>cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。<br />
PHP在http协议的头信息里发送cookie, 因此 setcookie() 函数必须在其它信息被输出到浏览器前调用，这和对 header() 函数的限制类似。</p>
<p>1.1 设置cookie:<br />
    可以用 setcookie() 或 setrawcookie() 函数来设置 cookie。也可以通过向客户端直接发送http头来设置.<br />
1.1.1 使用setcookie()函数设置cookie:<br />
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure [, bool httponly]]]]]] )<br />
     name:   cookie变量名<br />
     value:   cookie变量的值<br />
     expire:  有效期结束的时间,<br />
     path:    有效目录,<br />
     domain: 有效域名,顶级域唯一<br />
     secure:  如果值为1,则cookie只能在https连接上有效,如果为默认值0,则http和https都可以.<br />
例子:<br />
<?php<br />
$value = 'something from somewhere';</p>
<p>setcookie("TestCookie", $value); /* 简单cookie设置 */<br />
setcookie("TestCookie", $value, time()+3600); /* 有效期1个小时 */<br />
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1); /* 有效目录 /~rasmus,有效域名example.com及其所有子域名 */<br />
?><br />
设置多个cookie变量: setcookie(&#8216;var[a]&#8216;,&#8217;value&#8217;);用数组来表示变量,但他的下标不用引号.这样就可以用$_COOKIE[‘var’][‘a’]来读取该COOKIE变量.</p>
<p>1.1.2. 使用header()设置cookie;<br />
header(&#8220;Set-Cookie: name=$value[;path=$path[;domain=xxx.com[;...]]&#8221;);<br />
后面的参数和上面列出setcookie函数的参数一样.<br />
比如:</p>
<p>$value = &#8216;something from somewhere&#8217;;<br />
header(&#8220;Set-Cookie:name=$value&#8221;);</p>
<p>1.2 Cookie的读取:</p>
<p>直接用php内置超级全局变量 $_COOKIE就可以读取浏览器端的cookie.<br />
上面例子中设置了cookie&#8221;TestCookie&#8221;,现在我们来读取:</p>
<p>print $_COOKIE['TestCookie'];</p>
<p>COOKIE是不是被输出了?!<br />
<span id="more-1238"></span><br />
1.3 删除cookie<br />
只需把有效时间设为小于当前时间, 和把值设置为空.例如:<br />
setcookie(&#8220;name&#8221;,&#8221;",time()-1);<br />
用header()类似.</p>
<p>1.4 常见问题解决:</p>
<p>1) 用setcookie()时有错误提示,可能是因为调用setcookie()前面有输出或空格.也可能你的文档使从其他字符集转换过来,文档后面可能带有BOM签名(就是在文件内容添加一些隐藏的BOM字符).解决的办法就是使你的文档不出现这种情况.还有通过使用ob_start()函数有也能处理一点.<br />
2) $_COOKIE受magic_quotes_gpc影响,可能自动转义<br />
3) 使用的时候,有必要测试用户是否支持cookie<br />
<!--[if !supportLineBreakNewLine]--></p>
<p>1.5 cookie工作机理:</p>
<p>有些学习者比较冲动,没心思把原理研究,所以我把它放后面.<br />
a) 服务器通过随着响应发送一个http的Set-Cookie头,在客户机中设置一个cookie(多个cookie要多个头).<br />
b) 客户端自动向服务器端发送一个http的cookie头,服务器接收读取.</p>
<p>HTTP/1.x 200 OK<br />
X-Powered-By: PHP/5.2.1<br />
Set-Cookie: TestCookie=something from somewhere; path=/<br />
Expires: Thu, 19 Nov 2007 18:52:00 GMT<br />
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0<br />
Pragma: no-cache<br />
Content-type: text/html</p>
<p>这一行实现了cookie功能,收到这行后<br />
Set-Cookie: TestCookie=something from somewhere; path=/<br />
浏览器将在客户端的磁盘上创建一个cookie文件,并在里面写入:</p>
<p>TestCookie=something from somewhere;<br />
/</p>
<p>这一行就是我们用setcookie(&#8216;TestCookie&#8217;,'something from somewhere&#8217;,'/&#8217;);的结果.也就是用header(&#8216;Set-Cookie: TestCookie=something from somewhere; path=/&#8217;);的结果.<br />
<!--[endif]--></p>
<p>2. PHP的Session</p>
<p>session使用过期时间设为0的cookie,并且将一个称为session ID的唯一标识符(一长串字符串),在服务器端同步生成一些session文件(可以自己定义session的保存类型),与用户机关联起来.web应用程序存贮与这些session相关的数据,并且让数据随着用户在页面之间传递.</p>
<p>访问网站的来客会被分配一个唯一的标识符，即所谓的会话 ID。它要么存放在客户端的 cookie，要么经由 URL 传递。 </p>
<p>会话支持允许用户注册任意数目的变量并保留给各个请求使用。当来客访问网站时，PHP 会自动（如果 session.auto_start 被设为 1）或在用户请求时（由 session_start() 明确调用或 session_register() 暗中调用）检查请求中是否发送了特定的会话 ID。如果是，则之前保存的环境就被重建。 </p>
<p>2.1 sessionID的传送</p>
<p>2.1.1 通过cookie传送sessin ID</p>
<p>     使用session_start()调用session,服务器端在生成session文件的同时,生成session ID哈希值和默认值为PHPSESSID的session name,并向客户端发送变量为(默认的是)PHPSESSID(session name),值为一个128位的哈希值.服务器端将通过该cookie与客户端进行交互.<br />
   session变量的值经php内部系列化后保存在服务器机器上的文本文件中,和客户端的变量名默认情况下为PHPSESSID的coolie进行对应交互.<br />
     即服务器自动发送了http头:header(&#8216;Set-Cookie: session_name()=session_id(); path=/&#8217;);<br />
即setcookie(session_name(),session_id());<br />
    当从该页跳转到的新页面并调用session_start()后,PHP将检查与给定ID相关联的服务器端存贮的session数据,如果没找到,则新建一个数据集.</p>
<p>2.1.2 通过URL传送session ID<br />
只有在用户禁止使用cookie的时候才用这种方法,因为浏览器cookie已经通用,为安全起见,可不用该方法.<br />
<a href="p.php?<?php print session_name() ?>=<?php print session_id() ?>&#8220;>xxx</a>,也可以通过POST来传递session值.</p>
<p>2.2 session基本用法实例</p>
<p><?php<br />
// page1.php<br />
session_start();<br />
echo 'Welcome to page #1';<br />
/* 创建session变量并给session变量赋值 */<br />
$_SESSION['favcolor'] = 'green';<br />
$_SESSION['animal'] = 'cat';<br />
$_SESSION['time'] = time();</p>
<p>// 如果客户端使用cookie,可直接传递session到page2.php<br />
echo '<br /><a href="page2.php">page 2</a>&#8216;;</p>
<p>// 如果客户端禁用cookie<br />
echo &#8216;<br /><a href="page2.php?' . SID . '">page 2</a>&#8216;;<br />
/*<br />
 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session<br />
 对应的cookie已经存在,那么SID将为(未定义)空<br />
 */<br />
?></p>
<p><?php<br />
// page2.php<br />
session_start();<br />
print $_SESSION['animal']; // 打印出单个session<br />
var_dump($_SESSION); // 打印出page1.php传过来的session值<br />
?></p>
<p>2.3 使用session函数控制页面缓存.<br />
    很多情况下,我们要确定我们的网页是否在客户端缓存,或要设置缓存的有效时间,比如我们的网页上有些敏感内容并且要登录才能查看,如果缓存到本地了,可以直接打开本地的缓存就可以不登录而浏览到网页了.</p>
<p>    使用session_cache_limiter(&#8216;private&#8217;);可以控制页面客户端缓存,必须在session_start()之前调用.<br />
更多参数见http://blog.chinaunix.net/u/27731/showart.php?id=258087的客户端缓存控制.</p>
<p>     控制客户端缓存时间用 session_cache_expire(int);单位(s).也要在session_start()前调用.</p>
<p>    这只是使用session的情况下控制缓存的方法,我们还可以在header()中控制控制页面的缓存.</p>
<p>2.4 删除session</p>
<p>要三步实现.<br />
<?php<br />
session_destroy();                                      // 第一步: 删除服务器端session文件,这使用<br />
setcookie(session_name(),'',time()-3600);  // 第二步: 删除实际的session:<br />
$_SESSION = array();                                  // 第三步: 删除$_SESSION全局变量数组<br />
?></p>
<p>2.5 session在PHP大型web应用中的使用</p>
<p>对于访问量大的站点,用默认的session存贮方式并不适合,目前最优的方法是用数据库存取session.这时,函数bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )就是提供给我们解决这个问题的方案.<br />
该函数使用的6个函数如下:</p>
<p>1.   bool open() 用来打开会话存储机制,</p>
<p>2.   bool close() 关闭会话存储操作.</p>
<p>3.  mixde read() 从存储中装在session数据时使用这个函数</p>
<p>4.   bool write() 将给定session ID的所有数据写到存储中</p>
<p>5.   bool destroy() 破坏与指定的会话ID相关联的数据</p>
<p>6.   bool gc()  对存储系统中的数据进行垃圾收集</p>
<p>例子见php手册session_set_save_handler() 函数.<br />
如果用类来处理,用<br />
session_set_save_handler(<br />
    array(&#8216;className&#8217;,'open&#8217;),<br />
    array(&#8216;className&#8217;,'close&#8217;),<br />
    array(&#8216;className&#8217;,'read&#8217;),<br />
    array(&#8216;className&#8217;,'write&#8217;),<br />
    array(&#8216;className&#8217;,'destroy&#8217;),<br />
    array(&#8216;className&#8217;,'gc&#8217;),<br />
)<br />
调用className类中的6个静态方法.className可以换对象就不用调用静态方法,但是用静态成员不用生成对象,性能更好.</p>
<p>2.6 常用session函数:</p>
<p>bool   session_start(void); 初始化session<br />
bool   session_destroy(void): 删除服务器端session关联文件。<br />
string session_id() 当前session的id<br />
string session_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认PHPSESSID。<br />
array  session_get_cookie_params() 与这个session相关联的session的细节.<br />
string session_cache_limiter() 控制使用session的页面的客户端缓存<br />
ini    session_cache_expire() 控制客户端缓存时间<br />
bool   session_destroy()     删除服务器端保存session信息的文件<br />
void   session_set_cookie_params ( int lifetime [, string path [, string domain [, bool secure [, bool httponly]]]] )设置与这个session相关联的session的细节<br />
bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)<br />
bool session_regenerate_id([bool delete_old_session]) 分配新的session id</p>
<p>2.7 session安全问题<br />
攻击者通过投入很大的精力尝试获得现有用户的有效会话ID,有了会话id,他们就有可能能够在系统中拥有与此用户相同的能力.<br />
因此,我们主要解决的思路是效验session ID的有效性.</p>
<p><?php<br />
if(!isset($_SESSION['user_agent'])){<br />
    $_SESSION['user_agent'] = $_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'];<br />
}</p>
<p>/* 如果用户session ID是伪造 */<br />
elseif ($_SESSION['user_agent'] != $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) {<br />
    session_regenerate_id();<br />
}<br />
?></p>
<p>2.8 Session通过cookie传递和通过SID传递的不同:<br />
在php5.2.1的session的默认配置的情况下,当生成session的同时,服务器端将在发送header set-cookie同时生成预定义超级全局变量SID(也就是说,写入cookie和抛出SID是等价的.),当$_COOKIE['PHPSESSID']存在以后,将不再写入cookie,也不再生成超级全局变量SID,此时,SID将是空的.</p>
<p>2.9 session使用实例<br />
<?php<br />
/**<br />
 * 效验session的合法性<br />
 *<br />
 */<br />
function sessionVerify() {<br />
    if(!isset($_SESSION['user_agent'])){<br />
        $_SESSION['user_agent'] = MD5($_SERVER['REMOTE_ADDR']<br />
        .$_SERVER['HTTP_USER_AGENT']);<br />
    }<br />
    /* 如果用户session ID是伪造,则重新分配session ID */<br />
    elseif ($_SESSION['user_agent'] != MD5($_SERVER['REMOTE_ADDR']<br />
    . $_SERVER['HTTP_USER_AGENT'])) {<br />
        session_regenerate_id();<br />
    }<br />
}</p>
<p>/**<br />
 * 销毁session<br />
 * 三步完美实现,不可漏<br />
 *<br />
 */<br />
function sessionDestroy() {<br />
    session_destroy();<br />
    setcookie(session_name(),'',time()-3600);<br />
    $_SESSION = array();<br />
}<br />
?></p>
<p>注明:<br />
    session 出现头信息已经发出的原因与cookie一样.<br />
    在php5中,所有php session 的注册表配置选项都是编程时可配置的,一般情况下,我们是不用修改其配置的.要了解php的session注册表配置选项,请参考手册的Session 会话处理函数处.<br />
      session的保存数据的时候，是通过系列化$_SESSION数组来存贮，所以有系列化所拥有的问题，可能有特殊字符的值要用base64_encode函数编码，读取的时候再用base64_decode解码</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1238.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP服务器变量$_SERVER详解</title>
		<link>http://www.evanjiang.net.cn/archives/1237.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1237.html#comments</comments>
		<pubDate>Tue, 21 Jul 2009 03:37:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/archives/1237.html</guid>
		<description><![CDATA[<p>PHP服务器变量$_SERVER详解
1、$_SESSION['PHP_SELF'] — 获取当前正在执行脚本的文件名。
将得到浏览器请求页面的文件名, 并剥掉问号 ? 后的内容, 注意:不包含路径, 比如在客户端里请求 http://localhost:8080/test.php?age=20&#038;name=Tom,那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php”。”age=20&#038;name=Tom”被剥掉。
而如果客户端里请求 http://localhost:8080/test.php/age=20&#038;name=Tom,那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php/age=20&#038;name=Tom”。
2、$_SERVER['SERVER_PROTOCOL'] — 请求页面时通信协议的名称和版本。例如，“HTTP/1.0”。
3、$_SERVER['REQUEST_TIME'] — 请求开始时的时间戳。从 PHP 5.1.0 起有效。和time函数效果一样。
4、$_SERVER['argv'] — 传递给该脚本的参数。我试了下，get方法可以得到$_SERVER['argv'][0]；post方法无法给他赋值。
5、$_SERVER['SERVER_NAME'] — 返回当前主机名。
6、$_SERVER['SERVER_SOFTWARE'] — 服务器标识的字串，在响应请求时的头信息中给出。 如Microsoft-IIS/6.0
7、$_SERVER['REQUEST_METHOD'] — 访问页面时的请求方法。例如：“GET”、“HEAD”，“POST”，“PUT”。
8、$_SERVER['QUERY_STRING'] – 查询（query）的字符串（URL 中第一个问号 ? 之后的内容）。
9、$_SERVER['DOCUMENT_ROOT'] — 当前运行脚本所在的文档根目录。在服务器配置文件中定义。 如E:\server
10、$_SERVER['HTTP_ACCEPT'] — 当前请求的 Accept: 头信息的内容。
11、$_SERVER['HTTP_ACCEPT_CHARSET'] — 当前请求的 Accept-Charset: 头信息的内容。例如：“iso-8859-1,*,utf-8”。
12、$_SERVER['HTTP_ACCEPT_ENCODING'] — [...]]]></description>
			<content:encoded><![CDATA[<p>PHP服务器变量$_SERVER详解<br />
1、$_SESSION['PHP_SELF'] — 获取当前正在执行脚本的文件名。<br />
将得到浏览器请求页面的文件名, 并剥掉问号 ? 后的内容, 注意:不包含路径, 比如在客户端里请求 http://localhost:8080/test.php?age=20&#038;name=Tom,那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php”。”age=20&#038;name=Tom”被剥掉。<br />
而如果客户端里请求 http://localhost:8080/test.php/age=20&#038;name=Tom,那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php/age=20&#038;name=Tom”。<br />
2、$_SERVER['SERVER_PROTOCOL'] — 请求页面时通信协议的名称和版本。例如，“HTTP/1.0”。<br />
3、$_SERVER['REQUEST_TIME'] — 请求开始时的时间戳。从 PHP 5.1.0 起有效。和time函数效果一样。<br />
4、$_SERVER['argv'] — 传递给该脚本的参数。我试了下，get方法可以得到$_SERVER['argv'][0]；post方法无法给他赋值。<br />
5、$_SERVER['SERVER_NAME'] — 返回当前主机名。<br />
6、$_SERVER['SERVER_SOFTWARE'] — 服务器标识的字串，在响应请求时的头信息中给出。 如Microsoft-IIS/6.0<br />
7、$_SERVER['REQUEST_METHOD'] — 访问页面时的请求方法。例如：“GET”、“HEAD”，“POST”，“PUT”。<br />
8、$_SERVER['QUERY_STRING'] – 查询（query）的字符串（URL 中第一个问号 ? 之后的内容）。<br />
9、$_SERVER['DOCUMENT_ROOT'] — 当前运行脚本所在的文档根目录。在服务器配置文件中定义。 如E:\server<br />
10、$_SERVER['HTTP_ACCEPT'] — 当前请求的 Accept: 头信息的内容。<br />
11、$_SERVER['HTTP_ACCEPT_CHARSET'] — 当前请求的 Accept-Charset: 头信息的内容。例如：“iso-8859-1,*,utf-8”。<br />
12、$_SERVER['HTTP_ACCEPT_ENCODING'] — 当前请求的 Accept-Encoding: 头信息的内容。例如：“gzip”。<br />
13、$_SERVER['HTTP_ACCEPT_LANGUAGE'] — 当前请求的 Accept-Language: 头信息的内容。例如：“en”。<br />
14、$_SERVER['HTTP_CONNECTION'] — 当前请求的 Connection: 头信息的内容。例如：“Keep-Alive”。<br />
15、$_SERVER['HTTP_HOST'] — 当前请求的 Host: 头信息的内容。<br />
16、$_SERVER['HTTP_REFERER'] — 链接到当前页面的前一页面的 URL 地址。<br />
17、$_SERVER['HTTP_USER_AGENT'] — 返回用户使用的浏览器信息。也可以使用 get_browser() 得到此信息。<br />
18、$_SERVER['HTTPS'] — 如果通过https访问，则被设为一个非空的值，否则返回off.<br />
19、$_SERVER['REMOTE_ADDR'] — 正在浏览当前页面用户的 IP 地址。<br />
20、$_SERVER['REMOTE_HOST'] — 正在浏览当前页面用户的主机名。反向域名解析基于该用户的 REMOTE_ADDR。如本地测试返回127.0.0.1<br />
<span id="more-1237"></span><br />
21、$_SERVER['REMOTE_PORT'] — 用户连接到服务器时所使用的端口。我在本机测试没通过，不知道什么原因。<br />
22、$_SERVER['SCRIPT_FILENAME'] — 当前执行脚本的绝对路径名。如返回E:\server\index.php<br />
23、$_SERVER['SERVER_ADMIN'] — 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上，则该值是那个虚拟主机的值<br />
24、$_SERVER['SERVER_PORT'] — 服务器所使用的端口。默认为“80”。如果使用 SSL 安全连接，则这个值为用户设置的 HTTP 端口。<br />
25、$_SERVER['SERVER_SIGNATURE'] — 包含服务器版本和虚拟主机名的字符串。<br />
26、$_SERVER['PATH_TRANSLATED'] — 当前脚本所在文件系统（不是文档根目录）的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 Apache 2 用 户可以使用 httpd.conf 中的 AcceptPathInfo On 来定义 PATH_INFO。<br />
27、$_SERVER['SCRIPT_NAME'] — 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 包含当前文件的绝对路径和文件名（例如包含文件）。<br />
将得到浏览器请求的页面文件的文件名,注意: 与 $_SERVER["SCRIPT_NAME"] 不同, 此变量只得到文件名而不包含路径,在test.php 与 test_dir/test2.php 用$_SERVER["SCRIPT_NAME"] 得到的都将是 test.php.<br />
当然, 在test.php 与 test_dir/test2.php 执行 basename($_SERVER["SCRIPT_FILENAME"]) 与 $_SERVER["SCRIPT_NAME"] 相同.执行 在test.php 与 test_dir/test2.php 执行 realpath(”test.php”) 得到的结果与 $_SERVER["SCRIPT_FILENAME"] 相同<br />
28、$_SERVER['REQUEST_URI'] — 访问此页面所需的 URI。例如，“/index.html”。<br />
29、$_SERVER['PHP_AUTH_DIGEST'] — 当作为 Apache 模块运行时，进行 HTTP Digest 认证的过程中，此变量被设置成客户端发送的“Authorization”HTTP 头内容（以便作进一步的认证操作）。<br />
30、$_SERVER['PHP_AUTH_USER']– 当 PHP 运行在 Apache 或 IIS（PHP 5 是 ISAPI）模块方式下，并且正在使用 HTTP 认证功能，这个变量便是用户输入的用户名。<br />
31、$_SERVER['PHP_AUTH_PW'] — 当 PHP 运行在 Apache 或 IIS（PHP 5 是 ISAPI）模块方式下，并且正在使用 HTTP 认证功能，这个变量便是用户输入的密码。<br />
32、$_SERVER['AUTH_TYPE']–当 PHP 运行在 Apache 模块方式下，并且正在使用 HTTP 认证功能，这个变量便是认证的类型。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1237.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>配置Linux+Apache+PHP+Informix</title>
		<link>http://www.evanjiang.net.cn/archives/1235.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1235.html#comments</comments>
		<pubDate>Mon, 20 Jul 2009 14:43:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[informix]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1235</guid>
		<description><![CDATA[<p>1.配置Apache+PHP
Apache与PHP配置可以使用一套集成环境XAMPP，可以免去编译配置的繁琐工作。
>下载XAMPP的以及对应的开发包
1）xampp-linux-1.7.2.tar.gz
2）xampp-linux-devel-1.7.2.tar.gz
>安装Lampp
使用root用户</p>
<p>tar xvfz xampp-linux-1.7.2.tar.gz -C /opt
tar xvfz xampp-linux-devel-1.7.2.tar.gz -C /opt</p>
<p>即将lampp安装到/opt/目录下</p>
<p>2.Informix &#038; CSDK
Informix的安装在这里不做过多说明，需要注意的是PHP连接Informix需要CSDK 2.81以上版本的支持，CSDK安装到$INFORMIXDIR。
如果php访问远端Informix server，还需要在php所属服务器上安装unixODBC</p>
<p>3.配置PDO_INFORMIX模块
由于我们使用的LAMPP集成环境，所以PHP是已经编译好的，这时需要增加PHP的扩展pdo_informix.so就要用到phpize预编译工具。
>phpize
需要autoconf支持，下载pdo_informix安装包PDO_INFORMIX-1.2.6.tgz
使用root用户：
解开安装包
tar xvfz PDO_INFORMIX-1.2.6.tgz
进入安装包目录
cd PDO_INFORMIX-1.2.6
运行phpize工具</p>
<p>/opt/lamp/bin/phpize
./configure -–with-php-config=/opt/lamp/bin/php-config</p>
<p>如果提示&#8211;with-pdo-informix=dir，则需要先加载informix环境变量</p>
]]></description>
			<content:encoded><![CDATA[<p>1.配置Apache+PHP<br />
Apache与PHP配置可以使用一套集成环境XAMPP，可以免去编译配置的繁琐工作。<br />
>下载XAMPP的以及对应的开发包<br />
1）xampp-linux-1.7.2.tar.gz<br />
2）xampp-linux-devel-1.7.2.tar.gz<br />
>安装Lampp<br />
使用root用户</p>
<p>tar xvfz xampp-linux-1.7.2.tar.gz -C /opt<br />
tar xvfz xampp-linux-devel-1.7.2.tar.gz -C /opt</p>
<p>即将lampp安装到/opt/目录下</p>
<p>2.Informix &#038; CSDK<br />
Informix的安装在这里不做过多说明，需要注意的是PHP连接Informix需要CSDK 2.81以上版本的支持，CSDK安装到$INFORMIXDIR。<br />
如果php访问远端Informix server，还需要在php所属服务器上安装unixODBC</p>
<p>3.配置PDO_INFORMIX模块<br />
由于我们使用的LAMPP集成环境，所以PHP是已经编译好的，这时需要增加PHP的扩展pdo_informix.so就要用到phpize预编译工具。<br />
>phpize<br />
需要autoconf支持，下载pdo_informix安装包PDO_INFORMIX-1.2.6.tgz<br />
使用root用户：<br />
解开安装包<br />
tar xvfz PDO_INFORMIX-1.2.6.tgz<br />
进入安装包目录<br />
cd PDO_INFORMIX-1.2.6<br />
运行phpize工具</p>
<p>/opt/lamp/bin/phpize<br />
./configure -–with-php-config=/opt/lamp/bin/php-config</p>
<p>如果提示&#8211;with-pdo-informix=dir，则需要先加载informix环境变量</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1235.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ubuntu9.04 安装curl for php5 笔记</title>
		<link>http://www.evanjiang.net.cn/archives/1051.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1051.html#comments</comments>
		<pubDate>Sun, 17 May 2009 17:45:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1051</guid>
		<description><![CDATA[<p>由于oscommerce 和 zen-cart 都需要cURL 支持，故尝试在Ubuntu上安装cURL for PHP5。</p>
<p>准备先在笔记本上测试通过后再安装到服务器. 笔记本运行的是Ubuntu Destop 9.04, 服务器上跑的是Ubuntu Server 904,估计应该出入不大。</p>
<p>安装命令: sudo apt-get install curl libcurl3 libcurl3-dev php5-curl</p>
<p>一试安装成功</p>
<p>curl 是什么?</p>
<p>curl是一个利用URL语法在命令行方式下工作的文件传输工具。它支持很多协议：FTP, FTPS, HTTP, HTTPS, GOPHER,  TELNET, DICT, FILE 以及 LDAP。curl同样支持HTTPS认证，HTTP POST方法, HTTP PUT方法, FTP 上传, kerberos认证, HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传, 上载文件断点续传,  http代理服务器管道（ proxy tunneling）, 甚至它还支持IPv6, socks5代理服务器, 通过http代理服务器上传文件到FTP服务器等等，功能十分强大。Windows操作系统下的网络蚂蚁，网际快车(FlashGet)的功能它都可以做到。准确的说，curl支
持文件的上传和下载，所以是一个综合传输工具，但是按照传统，用户习惯称curl为下载工具。 </p>
<p>curl是瑞典curl组织开发的，您可以访问http://curl.haxx.se/获取它的源代码和相关说明。鉴于curl在Linux上的广泛使用，IBM在AIX Linux Toolbox的光盘中包含了这个软件，并且您可以访问IBM网站http://www- 1.ibm.com/servers/aix/products/aixos/linux/altlic.html下载它。curl的最新版本是 7.10.8，IBM网站上提供的版本为7.9.3。在AIX下的安装很简单，IBM网站上下载的rpm格式的包。
 [...]]]></description>
			<content:encoded><![CDATA[<p>由于oscommerce 和 zen-cart 都需要cURL 支持，故尝试在Ubuntu上安装cURL for PHP5。</p>
<p>准备先在笔记本上测试通过后再安装到服务器. 笔记本运行的是Ubuntu Destop 9.04, 服务器上跑的是Ubuntu Server 904,估计应该出入不大。</p>
<p>安装命令: sudo apt-get install curl libcurl3 libcurl3-dev php5-curl</p>
<p>一试安装成功</p>
<p>curl 是什么?</p>
<p>curl是一个利用URL语法在命令行方式下工作的文件传输工具。它支持很多协议：FTP, FTPS, HTTP, HTTPS, GOPHER,  TELNET, DICT, FILE 以及 LDAP。curl同样支持HTTPS认证，HTTP POST方法, HTTP PUT方法, FTP 上传, kerberos认证, HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传, 上载文件断点续传,  http代理服务器管道（ proxy tunneling）, 甚至它还支持IPv6, socks5代理服务器, 通过http代理服务器上传文件到FTP服务器等等，功能十分强大。Windows操作系统下的网络蚂蚁，网际快车(FlashGet)的功能它都可以做到。准确的说，curl支<br />
持文件的上传和下载，所以是一个综合传输工具，但是按照传统，用户习惯称curl为下载工具。 </p>
<p>curl是瑞典curl组织开发的，您可以访问http://curl.haxx.se/获取它的源代码和相关说明。鉴于curl在Linux上的广泛使用，IBM在AIX Linux Toolbox的光盘中包含了这个软件，并且您可以访问IBM网站http://www- 1.ibm.com/servers/aix/products/aixos/linux/altlic.html下载它。curl的最新版本是 7.10.8，IBM网站上提供的版本为7.9.3。在AIX下的安装很简单，IBM网站上下载的rpm格式的包。<br />
 <span id="more-1051"></span><br />
在http://curl.haxx.se/docs/，您可以下载到UNIX格式的man帮助，里面有详细的curl工具的使用说明。curl的用法为：curl [options] [URL...] 其中 options是下载需要的参数，大约有80多个，curl的各个功能完全是依靠这些参数完成的。具体参数的使用，用户可以参考curl的man帮助。 </p>
<p>下面，本文就将结合具体的例子来说明怎样利用curl进行下载。<br />
1、获得一张页面<br />
使用命令：curl http://curl.haxx.se<br />
这是最简单的使用方法。用这个命令获得了http://curl.haxx.se指向的页面，同样，如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。如果下载的是HTML文档，那么缺省的将不显示文件头部，即HTML 文档的header。要全部显示，请加参数 -i，要只显示头部，用参数 -I。任何时候，可以使用 -v 命令看curl是怎样工作的，它向服务器发送的所有命令都会显示出来。为了断点续传，可以使用-r参数来指定传输范围。 </p>
<p>2、表单（Form）的获取<br />
在WEB页面设计中，form是很重要的元素。Form通常用来收集并向网站提交信息。提交信息的方法有两种，GET方法和POST方法。先讨论GET方法，例如在页面中有这样一段： </p>
<form method="GET" action="junk.cgi">
<input type=text name="birthyear">
<input type=submit name=press value="OK">
</form>
<p>那么浏览器上会出现一个文本框和一个标为“OK”的按钮。按下这个按钮，表单就用GET方法向服务器提交文本框的数据。例如原始页面是在  www.hotmail.com/when/birth.html看到的，然后您在文本框中输入1905，然后按OK按钮，那么浏览器的URL现在应该是：“www.hotmail.com/when/junk.cgi?birthyear=1905&#038;press=OK”<br />
对于这种网页，curl可以直接处理，例如想获取上面的网页，只要输入：<br />
curl &#8220;www.hotmail.com/when/junk.cgi?birthyear=1905&#038;press=OK&#8221;<br />
就可以。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
表单用来提交信息的第二种方法叫做POST方法，POST方法和GET方法的区别在于GET方法使用的时候，浏览器中会产生目标URL，而POST不会。类似GET，这里有一个网页： </p>
<form method="POST" action="junk.cgi">
<input type=text name="birthyear">
<input type=submit name=press value="OK">
</form>
<p>浏览器上也会出现一个文本框和一个标为“OK”的按钮。按下这个按钮，表单用POST方法向服务器提交数据。这时的URL是看不到的，因此需要使用特殊的方法来抓取这个页面：<br />
curl -d &#8220;birthyear=1905&#038;press=OK&#8221; www.hotmail.com/when/junk.cgi<br />
这个命令就可以做到。<br />
1995年年末，RFC 1867定义了一种新的POST方法，用来上传文件。主要用于把本地文件上传到服务器。此时页面是这样写的： </p>
<form method="POST" enctype='multipart/form-data' action="upload.cgi">
<input type=file name=upload>
<input type=submit name=press value="OK">
</form>
<p>对于这种页面，curl的用法不同：<br />
curl -F upload=@localfilename -F press=OK [URL]<br />
这个命令的实质是将本地的文件用POST上传到服务器。有关POST还有不少用法，用户可以自己摸索。 </p>
<p>3、使用PUT方法。<br />
HTTP协议文件上传的标准方法是使用PUT，此时curl命令使用-T参数：<br />
curl -T uploadfile www.uploadhttp.com/receive.cgi </p>
<p>4、有关认证。<br />
curl可以处理各种情况的认证页面，例如下载用户名/密码认证方式的页面（在IE中通常是出现一个输入用户名和密码的输入框）：<br />
curl -u name:password www.secrets.com<br />
如果网络是通过http代理服务器出去的，而代理服务器需要用户名和密码，那么输入：<br />
curl -U proxyuser:proxypassword http://curl.haxx.se<br />
任何需要输入用户名和密码的时候，只在参数中指定用户名而空着密码，curl可以交互式的让用户输入密码。 </p>
<p>5、引用。<br />
有些网络资源访问的时候必须经过另外一个网络地址跳转过去，这用术语来说是：referer，引用。对于这种地址的资源，curl也可以下载：<br />
curl -e http://curl.haxx.se daniel.haxx.se<br />
 
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
6、指定用户客户端。<br />
有些网络资源首先需要判断用户使用的是什么浏览器，符合标准了才能够下载或者浏览。此时curl可以把自己“伪装”成任何其他浏览器：<br />
curl -A &#8220;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&#8221; [URL]<br />
这个指令表示curl伪装成了IE5.0，用户平台是Windows 2000。（对方服务器是根据这个字串来判断客户端的类型的，所以即使使用AIX也无所谓）。使用：<br />
curl -A &#8220;Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)&#8221; [URL]<br />
此时curl变成了Netscape，运行在PIII平台的Linux上了。 </p>
<p>7、COOKIES<br />
Cookie是服务器经常使用的一种记忆客户信息的方法。如果cookie被记录在了文件中，那么使用命令：<br />
curl -b stored_cookies_in_file www.cookiesite.com<br />
curl可以根据旧的cookie写出新cookie并发送到网站：<br />
curl -b cookies.txt -c newcookies.txt www.cookiesite.com </p>
<p>8、加密的HTTP——HTTPS。<br />
如果是通过OpenSSL加密的https协议传输的网页，curl可以直接访问：<br />
curl https://that.secure.server.com </p>
<p>9、http认证。<br />
如果是采用证书认证的http地址，证书在本地，那么curl这样使用：<br />
curl -E mycert.pem https://that.secure.server.com </p>
<p>参考读物和注意事项：curl非常博大，用户要想使用好这个工具，除了详细学习参数之外，还需要深刻理解http的各种协议与URL的各个语法。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1051.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php面向对象技术</title>
		<link>http://www.evanjiang.net.cn/archives/1043.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1043.html#comments</comments>
		<pubDate>Thu, 14 May 2009 06:33:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1043</guid>
		<description><![CDATA[<p>本部分一共包括以下一些技术点：
1.面向对象的概念
2.什么是类，什么是对象，类和对象这间的关系
3.什么是面向对象编程呢？
4.如何抽象出一个类？
5.如何实例化对象？
6.如何去使用对象中的成员？
7.特殊的引用“$this”的使用
8.构造方法与析构方法
9.封装性
10.__set()、 __get()、 __isset()、 __unset()四个方法的应用</p>
<p>1.面向对象的概念
  面向对象编程（Object Oriented Programming, OOP, 面向对象程序设计）是一种计算机编程架构，OOP的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成，OOP达到了软件工程的三个目标：重用性、灵活性和扩展性。为了实现整体运算，每个对象都能够接收信息、处理数据和向其它对象发送信息。面向对象一直是软件开发领域内比较热门的话题，首先，面向对象符合人类看待事物的一般规律。其次，采用面向对象方法可以使系统各部分各司其职、各尽所能。为编程人员敞开了一扇大门，使其编程的代码更简洁、更易于维护，并且具有更强的可重用性。有人说PHP不是一个真正的面向对象的语言，这是事实。PHP 是一个混合型语言，你可以使用OOP，也可以使用传统的过程化编程。然而，对于大型项目，你可能需要在PHP 中使用纯的OOP去声明类，而且在你的项目里只用对象和类。这个概念我先不多说了，因为有很多朋友远离面向对象编程的主要原因就是一接触面向对象概念的时候就理解不上去， 所以就不想去学下去了。等读者看完整体内容后再去把概念搞明白吧。</p>
<p>2.什么是类，什么是对象，类和对象这间的关系
类的概念：类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述，其内部包括属性和服务两个主要部分。在面向对象的编程语言中，类是一个独立的程序单位，它应该有一个类名并包括属性说明和服务说明两个主要部分。对象的概念：对象是系统中用来描述客观事物的一个实体，它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象的角度来说，对象是问题域或实现域中某些事物的一个抽象，它反映该事物在系统中需要保存的信息和发挥的作用；它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成的。
类与对象的关系就如模具和铸件的关系，类的实例化结果就是对象，而对一类对象的抽象就是类。类描述了一组有相同特性（属性）和相同行为（方法）的对象。
上面大概就是它们的定义吧，也许你是刚接触面向对象的朋友， 不要被概念的东西搞晕了，给你举个例子吧，如果你去中关村想买几台组装的PC机，到了那里你第一步要干什么，是不是装机的工程师和你坐在一起，按你提供的信息和你一起完成一个装机的配置单呀，这个配置单就可以想象成是类，它就是一张纸，但是它上面记录了你要买的PC机的信息，如果用这个配置单买10台机器，那么这10台机子，都是按这个配置单组成的，所以说这10台机子是一个类型的，也可以说是一类的。那么什么是对象呢，类的实例化结果就是对象,用这个配置单配置出来（实例化出来）的机子就是对象，是我们可以操作的实体，10台机子，10个对象。每台机子都是独立的，只能说明他们是同一类的，对其中一个机做任何动作都不会影响其它9台机器，但是我对类修改，也就是在这个配置单上加一个或少一个配件，那么装出来的9个机子都改变了，这是类和对象的关系(类的实例化结果就是对象)。</p>
<p>
3.什么是面向对象编程呢？
就不说他的概念，如果你想建立一个电脑教室，首先要有一个房间， 房间里面要有N台电脑，有N张桌子， N把椅子， 白板， 投影机等等，这些是什么，刚才咱们说了， 这就是对象，能看到的一个个的实体，可以说这个电脑教室的单位就是这一个个的实体对象， 它们共同组成了这个电脑教室，那么我们是做程序，这和面向对象有什么关系呢？开发一个系统程序和建一个电脑教室类似，你把每个独立的功能模块抽象成类，形成对象，由多个对象组成这个系统，这些对象之间都能够接收信息、处理数据和向其它对象发送信息等等相互作用。就构成了面向对象的程序。</p>
<p>4.如何抽象出一个类？
 上面已经介绍过了，面向对象程序的单位就是对象，但对象又是通过类的实例化出来的，所以我们首先要做的就是如何来声明类，做出来一个类很容易，只要掌握基本的程序语法定义规则就可以做的出来，那么难点在那里呢？一个项目要用到多少个类，用多少个对象，在那要定义类，定义一个什么样的类，这个类实例化出多少个对象，类里面有多少个属性，有多少个方法等等,这就需要读者通过在实际的开发中就实际问题分析设计和总结了。
类的定义：
class 类名{
}
使用一个关键字class和后面加上一个你想要的类名以及加上一对大括号， 这样一个类的结构就定义出来了，只要在里面写代码就可以了， 但是里面写什么？ 能写什么？怎样写才是一个完整的类呢？上面讲过来，使用类是为了让它实例出对象来给我们用，这就要知道你想要的是什么样的对象了，像上面我们讲的一个装机配置单上写什么，你装出来的机子就有什么。比如说，一个人就是一个对象，你怎么把一个你看好的人推荐给你们领导呢？当然是越详细越好了：首先，你会介绍这个人姓名、性别、年龄、身高、体重、电话、家庭住址等等。然后，你要介绍这个人能做什么，可以开车，会说英语，可以使用电脑等等。
  只要你介绍多一点，别人对这个人就多一点了解，这就是我们对一个人的描述， 现在我们总结一下，所有的对象我们用类去描述都是类似的，从上面人的描述可以看到， 做出一个类来，从定义的角度分两部分，第一是从静态上描述，第二是从动态上描述， 静态上的描述就是我们所说的属性，像上面我们看到的，人的姓名、性别、年龄、身高、体重、电话、家庭住址等等。动态上也就是人的这个对象的功能，比如这个人可以开车，会说英语，可以使用电脑等等，抽象成程序时，我们把动态的写成函数或者说是方法，函数和方法是一样的。所以，所有类都是从属性和方法这两方面去写， 属性又叫做这个类的成员属性，方法叫做这个类的成员方法。
class 人{
 成员属性：姓名、性别、年龄、身高、体重、电话、家庭住址
  成员方法：可以开车， 会说英语， 可以使用电脑
}
属性：
通过在类定义中使用关键字&#8221; var  &#8220;来声明变量，即创建了类的属性,虽然在声明成员属性的时候可以给定初始值， 但是在声明类的时候给成员属性初使值是没有必要的，比如说要是把人的姓名赋上“张三”,那么用这个类实例出几十个人，这几十个人都叫张三了，所以没有必要， 我们在实例出对象后给成员属性初始值就可以了。
如：　var  $somevar;
方法(成员函数)：
通过在类定义中声明函数，即创建了类的方法。
如：　function  somefun(参数列表)
{      &#8230; &#8230;   [...]]]></description>
			<content:encoded><![CDATA[<p>本部分一共包括以下一些技术点：<br />
1.面向对象的概念<br />
2.什么是类，什么是对象，类和对象这间的关系<br />
3.什么是面向对象编程呢？<br />
4.如何抽象出一个类？<br />
5.如何实例化对象？<br />
6.如何去使用对象中的成员？<br />
7.特殊的引用“$this”的使用<br />
8.构造方法与析构方法<br />
9.封装性<br />
10.__set()、 __get()、 __isset()、 __unset()四个方法的应用</p>
<p>1.面向对象的概念<br />
  面向对象编程（Object Oriented Programming, OOP, 面向对象程序设计）是一种计算机编程架构，OOP的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成，OOP达到了软件工程的三个目标：重用性、灵活性和扩展性。为了实现整体运算，每个对象都能够接收信息、处理数据和向其它对象发送信息。面向对象一直是软件开发领域内比较热门的话题，首先，面向对象符合人类看待事物的一般规律。其次，采用面向对象方法可以使系统各部分各司其职、各尽所能。为编程人员敞开了一扇大门，使其编程的代码更简洁、更易于维护，并且具有更强的可重用性。有人说PHP不是一个真正的面向对象的语言，这是事实。PHP 是一个混合型语言，你可以使用OOP，也可以使用传统的过程化编程。然而，对于大型项目，你可能需要在PHP 中使用纯的OOP去声明类，而且在你的项目里只用对象和类。这个概念我先不多说了，因为有很多朋友远离面向对象编程的主要原因就是一接触面向对象概念的时候就理解不上去， 所以就不想去学下去了。等读者看完整体内容后再去把概念搞明白吧。</p>
<p>2.什么是类，什么是对象，类和对象这间的关系<br />
类的概念：类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述，其内部包括属性和服务两个主要部分。在面向对象的编程语言中，类是一个独立的程序单位，它应该有一个类名并包括属性说明和服务说明两个主要部分。对象的概念：对象是系统中用来描述客观事物的一个实体，它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象的角度来说，对象是问题域或实现域中某些事物的一个抽象，它反映该事物在系统中需要保存的信息和发挥的作用；它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成的。<br />
类与对象的关系就如模具和铸件的关系，类的实例化结果就是对象，而对一类对象的抽象就是类。类描述了一组有相同特性（属性）和相同行为（方法）的对象。<br />
上面大概就是它们的定义吧，也许你是刚接触面向对象的朋友， 不要被概念的东西搞晕了，给你举个例子吧，如果你去中关村想买几台组装的PC机，到了那里你第一步要干什么，是不是装机的工程师和你坐在一起，按你提供的信息和你一起完成一个装机的配置单呀，这个配置单就可以想象成是类，它就是一张纸，但是它上面记录了你要买的PC机的信息，如果用这个配置单买10台机器，那么这10台机子，都是按这个配置单组成的，所以说这10台机子是一个类型的，也可以说是一类的。那么什么是对象呢，类的实例化结果就是对象,用这个配置单配置出来（实例化出来）的机子就是对象，是我们可以操作的实体，10台机子，10个对象。每台机子都是独立的，只能说明他们是同一类的，对其中一个机做任何动作都不会影响其它9台机器，但是我对类修改，也就是在这个配置单上加一个或少一个配件，那么装出来的9个机子都改变了，这是类和对象的关系(类的实例化结果就是对象)。</p>
<p><span id="more-1043"></span><br />
3.什么是面向对象编程呢？<br />
就不说他的概念，如果你想建立一个电脑教室，首先要有一个房间， 房间里面要有N台电脑，有N张桌子， N把椅子， 白板， 投影机等等，这些是什么，刚才咱们说了， 这就是对象，能看到的一个个的实体，可以说这个电脑教室的单位就是这一个个的实体对象， 它们共同组成了这个电脑教室，那么我们是做程序，这和面向对象有什么关系呢？开发一个系统程序和建一个电脑教室类似，你把每个独立的功能模块抽象成类，形成对象，由多个对象组成这个系统，这些对象之间都能够接收信息、处理数据和向其它对象发送信息等等相互作用。就构成了面向对象的程序。</p>
<p>4.如何抽象出一个类？<br />
 上面已经介绍过了，面向对象程序的单位就是对象，但对象又是通过类的实例化出来的，所以我们首先要做的就是如何来声明类，做出来一个类很容易，只要掌握基本的程序语法定义规则就可以做的出来，那么难点在那里呢？一个项目要用到多少个类，用多少个对象，在那要定义类，定义一个什么样的类，这个类实例化出多少个对象，类里面有多少个属性，有多少个方法等等,这就需要读者通过在实际的开发中就实际问题分析设计和总结了。<br />
类的定义：<br />
class 类名{<br />
}<br />
使用一个关键字class和后面加上一个你想要的类名以及加上一对大括号， 这样一个类的结构就定义出来了，只要在里面写代码就可以了， 但是里面写什么？ 能写什么？怎样写才是一个完整的类呢？上面讲过来，使用类是为了让它实例出对象来给我们用，这就要知道你想要的是什么样的对象了，像上面我们讲的一个装机配置单上写什么，你装出来的机子就有什么。比如说，一个人就是一个对象，你怎么把一个你看好的人推荐给你们领导呢？当然是越详细越好了：首先，你会介绍这个人姓名、性别、年龄、身高、体重、电话、家庭住址等等。然后，你要介绍这个人能做什么，可以开车，会说英语，可以使用电脑等等。<br />
  只要你介绍多一点，别人对这个人就多一点了解，这就是我们对一个人的描述， 现在我们总结一下，所有的对象我们用类去描述都是类似的，从上面人的描述可以看到， 做出一个类来，从定义的角度分两部分，第一是从静态上描述，第二是从动态上描述， 静态上的描述就是我们所说的属性，像上面我们看到的，人的姓名、性别、年龄、身高、体重、电话、家庭住址等等。动态上也就是人的这个对象的功能，比如这个人可以开车，会说英语，可以使用电脑等等，抽象成程序时，我们把动态的写成函数或者说是方法，函数和方法是一样的。所以，所有类都是从属性和方法这两方面去写， 属性又叫做这个类的成员属性，方法叫做这个类的成员方法。<br />
class 人{<br />
 成员属性：姓名、性别、年龄、身高、体重、电话、家庭住址<br />
  成员方法：可以开车， 会说英语， 可以使用电脑<br />
}<br />
属性：<br />
通过在类定义中使用关键字&#8221; var  &#8220;来声明变量，即创建了类的属性,虽然在声明成员属性的时候可以给定初始值， 但是在声明类的时候给成员属性初使值是没有必要的，比如说要是把人的姓名赋上“张三”,那么用这个类实例出几十个人，这几十个人都叫张三了，所以没有必要， 我们在实例出对象后给成员属性初始值就可以了。<br />
如：　var  $somevar;<br />
方法(成员函数)：<br />
通过在类定义中声明函数，即创建了类的方法。<br />
如：　function  somefun(参数列表)<br />
{      &#8230; &#8230;     }</p>
<p><?php<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name;   //人的名子<br />
var $sex;   //人的性别<br />
var $age;   //人的年龄<br />
//下面是人的成员方法<br />
function say() //这个人可以说话的方法<br />
{<br />
echo "这个人在说话";<br />
}<br />
function run() //这个人可以走路的方法<br />
{<br />
echo "这个人在走路";<br />
}<br />
}<br />
?><br />
上面就是一个类的声明，从属性和方法上声明出来的一个类，但是成员属性最好在声明的时候<br />
不要给初始的值，因为我们做的人这个类是一个描述信息，将来用它实例化对象，比如实例化出来10个人对象，那么这10个人， 每一个人的名子，性别， 年龄都是不一样的，所以最好不要在这个地方给成员属性赋初值，而是对每个对象分别赋值的。<br />
用同样的办法可以做出你想要的类了， 只要你能用属性和方法能描述出来的实体都可以定义成类，去实例化对象。<br />
为了加强你对类的理解，我们再做一个类，做一个形状的类，形状的范围广了点， 我们就做个矩形吧，先分析一下，想一想从两方面分析，矩形的属性都有什么？矩形的功能都有什么？<br />
class 矩形</p>
<p>{<br />
 //矩形的属性<br />
 矩形的长；<br />
 矩形的宽；</p>
<p>//矩形的方法<br />
 矩形的周长；<br />
 矩形的面积；<br />
}</p>
<p><?php<br />
class Rect<br />
{<br />
var $kuan;<br />
var $gao;<br />
function zhouChang()<br />
{<br />
计算矩形的周长；<br />
}<br />
function mianJi()<br />
{<br />
计算矩形的面积；<br />
}<br />
}<br />
?><br />
如果用这个类来创建出多个矩形对象，每个矩形对象都有自己的长和宽， 都可以求出自己的周长和面积了。<br />
类的声明我们就到这里吧！！</p>
<p>5.如何实例化对象<br />
我们上面说过面向对象程序的单位就是对象，但对象又是通过类的实例化出来的，既然我们类会声明了，下一步就是实例化对象了。<br />
当定义好类后，我们使用new关键字来生成一个对象。<br />
     $对象名称 = new 　类名称（）；<br />
<?php<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name;   //人的名子</p>
<p>var $sex;   //人的性别<br />
var $age;   //人的年龄<br />
//下面是人的成员方法<br />
function say() //这个人可以说话的方法<br />
{<br />
echo "这个人在说话";<br />
}<br />
function run() //这个人可以走路的方法<br />
{<br />
echo "这个人在走路";<br />
}<br />
}<br />
$p1=new Person();<br />
$p2=new Person();</p>
<p>$p3=new Person();<br />
?><br />
$p1=new Person();<br />
这条代码就是通过类产生实例对象的过程，$p1就是我们实例出来的对象名称，同理，$p2, $p3也是我们实例出来的对象名称，一个类可以实例出多个对象，每个对象都是独立的，上面的代码相当于实例出来3个人来，每个人之间是没有联系的，只能说明他们都是人类，每个人都有自己的姓名，性别和年龄的属性，每个人都有说话和走路的方法，只要是类里面体现出来的成员属性和成员方法，实例化出来的对象里面就包含了这些属性和方法。<br />
对像在PHP里面和整型、浮点型一样，也是一种数据类，都是存储不同类型数据用的，在运行的时候都要加载到内存中去用， 那么对象在内存里面是怎么体现的呢？内存从罗辑上说大体上是分为4段， 栈空间段、堆空间段、代码段、 初始化静态段，程序里面不同的声明放在不同的内存段里面，栈空间段是存储占用相同空间长度并且占用空间小的数据类型的地方，比如说整型1， 10， 100， 1000， 10000， 100000等等，在内存里面占用空间是等长的，都是64位4个字节。 那么数据长度不定长，而且占有空间很大的数据类型的数据放在那内存的那个段里面呢？这样的数据是放在堆内存里面的。栈内存是可以直接存取的，而堆内存是不可以直接存取的内存。对于我们的对象来数就是一种大的数据类型而且是占用空间不定长的类型，所以说对象是放在堆里面的，但对象名称是放在栈里面的，这样通过对象名称就可以使用对象了。<br />
$p1=new Person();<br />
对于这个条代码， $p1是对象名称在栈内存里面，new Person()是真正的对象是在堆内存里面的，$p1=new Person();等号右边是真正的对象实例，在堆内存里面的实体，每个对象之间都是相互独立的，使用自己的空间，在PHP里面，只要有一个new这个关键字出现就会实例化出来一个对象，在堆里面开辟一块自己的空间。<br />
每个在堆里面的实例对象是存储属性的，比如说，现在堆里面的实例对象里面都存有姓名、性别和年龄。每个属性又都有一个地址。$p1=new Person();等号的右边$p1是一个引用变量，通过赋值运算符“=”把对象的首地址赋给“$p1”这个引用变量，所以$p1是存储对象首地址的变量，$p1放在栈内存里边，$p1相当于一个指针指向堆里面的对象，所以我们可以通过$p1这个引用变量来操作对象,通常我们也称对象引用为对象。</p>
<p>6.如何去使用对象中的成员<br />
上面看到PHP对象中的成员有两种一种是成员属性，一种是成员方法。对象我们已经可以声明了，$p1=new Person();怎么去使用对象的成员呢？要想访问对象中的成员就要使用一个特殊的操作符“->”来完成对象成员的访问：<br />
  对象->属性    $p1->name;  $p2->age;  $p3->sex;<br />
  对象->方法   $p1->say();  $p2->run();<br />
如下面实例:<br />
<?php<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name;   //人的名子<br />
var $sex;   //人的性别<br />
var $age;   //人的年龄<br />
//下面是人的成员方法<br />
function say() //这个人可以说话的方法<br />
{<br />
echo "这个人在说话";<br />
}<br />
function run() //这个人可以走路的方法<br />
{<br />
echo "这个人在走路";<br />
}<br />
}<br />
$p1=new Person(); //创建实例对象$p1<br />
$p2=new Person(); //创建实例对象$p2<br />
$p3=new Person(); //创建实例对象$p3<br />
//下面三行是给$p1对象属性赋值<br />
$p1->name=”张三”;<br />
$p1->sex=”男”;<br />
$p1->age=20;<br />
//下面三行是访问$p1对象的属性<br />
echo “p1对象的名子是：”.$p1->name.”<br />”;<br />
echo “p1对象的性别是：”.$p1->sex.”<br />”;<br />
echo “p1对象的年龄是：”.$p1->age.”<br />”;<br />
//下面两行访问$p1对象中的方法<br />
$p1->say();</p>
<p>$p1->run();<br />
//下面三行是给$p2对象属性赋值<br />
$p2->name=”李四”;<br />
$p2->sex=”女”;<br />
$p2->age=30;<br />
//下面三行是访问$p2对象的属性<br />
echo “p2对象的名子是：”.$p2->name.”<br />”;<br />
echo “p2对象的性别是：”.$p2->sex.”<br />”;<br />
echo “p2对象的年龄是：”.$p2->age.”<br />”;<br />
//下面两行访问$p2对象中的方法<br />
$p2->say();<br />
$p2->run();<br />
//下面三行是给$p3对象属性赋值<br />
$p3->name=”王五”;<br />
$p3->sex=”男”;<br />
$p3->age=40;</p>
<p>//下面三行是访问$p3对象的属性<br />
echo “p3对象的名子是：”.$p3->name.”<br />”;<br />
echo “p3对象的性别是：”.$p3->sex.”<br />”;<br />
echo “p3对象的年龄是：”.$p3->age.”<br />”;<br />
//下面两行访问$p3对象中的方法<br />
$p3->say();<br />
$p3->run();<br />
?></p>
<p>从上例中可以看出只是对象里面的成员就要使用对象->属性、对象->方法 形式访问，再没有第二种方法来访问对象中的成员了。</p>
<p>7.特殊的引用“$this”的使用<br />
现在我们知道了如何访问对象中的成员，是通过“对象->成员”的方式访问的,这是在对象的外部去访问对象中成员的形式，那么如果我想在对象的内部，让对象里的方法访问本对象的属性，或是对象中的方法去调用本对象的其它方法这时我们怎么办？因为对象里面的所有的成员都要用对象来调用，包括对象的内部成员之间的调用，所以在PHP里面给我提供了一个本对象的引用$this， 每个对象里面都有一个对象的引用$this来代表这个对象，完成对象内部成员的调用, this的本意就是“这个”的意思， 上面的实例里面，我们实例化三个实例对象$P1、 $P2、 $P3，这三个对象里面各自存在一个$this分别代表对象$p1、$p2、$p3 。</p>
<p>通过上图我们可以看到，$this就是对象内部代表这个对象的引用，在对象内部和调用本对象的成员和对象外部调用对象的成员所使用的方式是一样的。<br />
$this->属性    $this->name;  $this->age;  $this->sex;<br />
  $this->方法   $this->say();  $this->run();<br />
修改一下上面的实例，让每个人都说出自己的名字，性别和年龄：<br />
<?php<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name;   //人的名子<br />
var $sex;   //人的性别<br />
var $age;   //人的年龄<br />
//下面是人的成员方法<br />
function say() //这个人可以说话的方法<br />
{</p>
<p>echo "我的名子叫：".$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
function run() //这个人可以走路的方法<br />
{<br />
echo &#8220;这个人在走路&#8221;;<br />
}<br />
}<br />
$p1=new Person(); //创建实例对象$p1<br />
$p2=new Person(); //创建实例对象$p2<br />
$p3=new Person(); //创建实例对象$p3<br />
//下面三行是给$p1对象属性赋值<br />
$p1->name=&#8221;张三&#8221;;<br />
$p1->sex=&#8221;男&#8221;;<br />
$p1->age=20;<br />
//下面访问$p1对象中的说话方法<br />
$p1->say();<br />
//下面三行是给$p2对象属性赋值<br />
$p2->name=&#8221;李四&#8221;;<br />
$p2->sex=&#8221;女&#8221;;<br />
$p2->age=30;<br />
//下面访问$p2对象中的说话方法<br />
$p2->say();<br />
//下面三行是给$p3对象属性赋值<br />
$p3->name=&#8221;王五&#8221;;<br />
$p3->sex=&#8221;男&#8221;;<br />
$p3->age=40;<br />
//下面访问$p3对象中的说话方法<br />
$p3->say();<br />
?><br />
输出结果为：<br />
我的名子叫：张三 性别：男 我的年龄是：20<br />
我的名子叫：李四 性别：女 我的年龄是：30<br />
我的名子叫：王五 性别：男 我的年龄是：40<br />
分析一下这个方法：<br />
function say() //这个人可以说话的方法<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
在$p1、$p2和$p3这三个对象中都有say()这个方法，$this分别代表这三个对象， 调用相应的属性，打印出属性的值，这就是在对象内部访问对象属性的方式， 如果相在say()这个方法里调用run()这个方法也是可以的，在say()这个方法中使用$this->run()的方式来完成调用。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
8.构造方法与析构方法<br />
大多数类都有一种称为构造函数的特殊方法。当创建一个对象时，它将自动调用构造函数，也就是使用new这个关键字来实例化对象的时候自动调用构造方法。<br />
构造函数的声明与其它操作的声明一样，只是其名称必须是__construct( )。这是PHP5中的变化，以前的版本中，构造函数的名称必须与类名相同，这种在PHP5中仍然可以用，但现在以经很少有人用了，这样做的好处是可以使构造函数独立于类名，当类名发生改变时不需要改相应的构造函数名称了。为了向下兼容，如果一个类中没有名为__construct( )的方法，PHP将搜索一个php4中的写法,与类名相同名的构造方法。<br />
格式：function __construct ( [参数] ) { &#8230; &#8230; }<br />
在一个类中只能声明一个构造方法，而是只有在每次创建对象的时候都会去调用一次构造方法，不能主动的调用这个方法，所以通常用它执行一些有用的初始化任务。比如对成属性在创建对象的时候赋初值。<br />
<?<br />
//创建一个人类<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name;   //人的名子<br />
var $sex;   //人的性别<br />
var $age;   //人的年龄<br />
//定义一个构造方法参数为姓名$name、性别$sex和年龄$age<br />
function __construct($name, $sex, $age)<br />
{<br />
//通过构造方法传进来的$name给成员属性$this->name赋初使值<br />
$this->name=$name;<br />
//通过构造方法传进来的$sex给成员属性$this->sex赋初使值<br />
$this->sex=$sex;<br />
//通过构造方法传进来的$age给成员属性$this->age赋初使值<br />
$this->age=$age;<br />
}<br />
//这个人的说话方法<br />
function say()<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
}<br />
//通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄<br />
$p1=new Person(“张三”，”男”, 20);<br />
$p2=new Person(“李四”，”女”, 30);<br />
$p3=new Person(“王五”，”男”, 40);<br />
//下面访问$p1对象中的说话方法<br />
$p1->say();<br />
//下面访问$p2对象中的说话方法<br />
$p2->say();<br />
//下面访问$p3对象中的说话方法<br />
$p3->say();<br />
?><br />
输出结果为：<br />
我的名子叫：张三 性别：男 我的年龄是：20<br />
我的名子叫：李四 性别：女 我的年龄是：30<br />
我的名子叫：王五 性别：男 我的年龄是：40</p>
<p>析构函数：<br />
    与构造函数相对的就是析构函数。析构函数是PHP5新添加的内容，在PHP4中没有析构函数。析构函数允许在销毁一个类之前执行的一些操作或完成一些功能，比如说关闭文件，释放结果集等，析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行，也就是对象在内存中被销毁前调用析构函数。与构造函数的名称类似，一个类的析构函数名称必须是__destruct( )。析构函数不能带有任何参数。<br />
　格式：function __destruct ( ) { &#8230; &#8230; }<br />
<?<br />
//创建一个人类<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
var $name; //人的名子<br />
var $sex; //人的性别<br />
var $age; //人的年龄<br />
//定义一个构造方法参数为姓名$name、性别$sex和年龄$age</p>
<p>function __construct($name, $sex, $age)<br />
{<br />
//通过构造方法传进来的$name给成员属性$this->name赋初使值<br />
$this->name=$name;<br />
//通过构造方法传进来的$sex给成员属性$this->sex赋初使值<br />
$this->sex=$sex;<br />
//通过构造方法传进来的$age给成员属性$this->age赋初使值<br />
$this->age=$age;<br />
}<br />
//这个人的说话方法<br />
function say()<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
//这是一个析构函数，在对象销毁前调用<br />
function __destruct()<br />
{<br />
echo “再见”.$this->name.”<br />”;</p>
<p>}<br />
//通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄<br />
$p1=new Person(“张三”，”男”, 20);<br />
$p2=new Person(“李四”，”女”, 30);<br />
$p3=new Person(“王五”，”男”, 40);<br />
//下面访问$p1对象中的说话方法<br />
$p1->say();<br />
//下面访问$p2对象中的说话方法<br />
$p2->say();<br />
//下面访问$p3对象中的说话方法<br />
$p3->say();<br />
?><br />
输出结果为：<br />
我的名子叫：张三 性别：男 我的年龄是：20<br />
我的名子叫：李四 性别：女 我的年龄是：30<br />
我的名子叫：王五 性别：男 我的年龄是：40<br />
再见张三<br />
再见李四<br />
再见王五</p>
<p>9.封装性<br />
    封装性是面向对象编程中的三大特性之一，封装性就是把对象的属性和服务结合成一个独立的相同单位，并尽可能隐蔽对象的内部细节，包含两个含义:1.把对象的全部属性和全部服务结合在一起，形成一个不可分割的独立单位（即对象）。2.信息隐蔽，即尽可能隐蔽对象的内部细节，对外形成一个边界〔或者说形成一道屏障〕，只保留有限的对外接口使之与外部发生联系。<br />
    封装的原则在软件上的反映是：要求使对象以外的部分不能随意存取对象的内部数据（属性），从而有效的避免了外部错误对它的&#8221;交叉感染&#8221;，使软件错误能够局部化，大大减少查错和排错的难度。<br />
   用个实例来说明吧，假如某个人的对象中有年龄和工资等属性，像这样个人隐私的属性是不想让其它人随意就能获得到的，如果你不使用封装，那么别人想知道就能得到，但是如果你封装上之后别人就没有办法获得封装的属性，除非你自己把它说出去，否则别人没有办法得到。再比如说，个人电脑都有一个密码，不想让其它人随意的登陆，在你的电脑里面拷贝和粘贴。还有就是像人这个对象，身高和年龄的属性，只能是自己来增涨，不可以让别人随意的赋值等等。使用private这个关键字来对属性和方法进行封装：<br />
原来的成员:<br />
var $name;   //声明人的姓名<br />
var $sex;    //声明人的性别<br />
var $age;    //声明人的年龄<br />
function run(){…….}<br />
改成封装的形式：<br />
private $name;          //把人的姓名使用private关键字进行封装<br />
private $sex;      //把人的性别使用private关键字进行封装<br />
private $age;      //把人的年龄使用private关键字进行封装</p>
<p>private function run(){……}  //把人的走路方法使用private关键字进行封装<br />
注意：只要是成员属性前面有其它的关键字就要去掉原有的关键字“var”。<br />
通过private就可以把人的成员（成员属性和成员方法）封装上了。封装上的成员就不能被类外面直接访问了，只有对象内部自己可以访问；下面的代码会产生错误：<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
private $name; //人的名子，被private封装上了<br />
private $sex; //人的性别, 被private封装上了<br />
private $age; //人的年龄, 被private封装上了<br />
//这个人可以说话的方法<br />
function say()<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
//这个人可以走路的方法, 被private封装上了<br />
private function run()<br />
{<br />
echo &#8220;这个人在走路&#8221;;<br />
}<br />
}<br />
//实例化一个人的实例对象<br />
$p1=new Person();<br />
//试图去给私有的属性赋值， 结果会发生错误<br />
$p1->name=&#8221;张三&#8221;;<br />
$p1->sex=&#8221;男&#8221;;<br />
$p1->age=20;<br />
//试图去打印私有的属性， 结果会发生错误<br />
echo $p1->name.”<br />”;<br />
echo $p1->sex.”<br />”;<br />
echo $p1->age.”<br />”<br />
//试图去打印私有的成员方法， 结果会发生错误<br />
$p1->run();<br />
输出结果为：<br />
Fatal error: Cannot access private property Person::$name<br />
Fatal error: Cannot access private property Person::$sex<br />
Fatal error: Cannot access private property Person::$age<br />
Fatal error: Cannot access private property Person::$name<br />
Fatal error: Call to private method Person::run() from context &#8221;</p>
<p>从上面的实例可以看到， 私有的成员是不能被外部访问的， 因为私有成员只能在本对象内部自己访问，比如，$p1这个对象自己想把他的私有属性说出去，在say()这个方法里面访问了私有属性，这样是可以。（没有加任何访问控制，默认的是public的，任何地方都可以访问）<br />
//这个人可以说话的方法, 说出自己的私有属性，在这里也可以访问私有方法<br />
function say()<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
//在这里也可以访问私有方法<br />
//$this->run();<br />
}<br />
因为成员方法say()是公有的， 所以我们在类的外部调用say()方法是可以的，改变上面的代码；</p>
<p>class Person<br />
{<br />
//下面是人的成员属性<br />
private $name;   //人的名子，被private封装上了<br />
private $sex;   //人的性别, 被private封装上了<br />
private $age;   //人的年龄, 被private封装上了<br />
//定义一个构造方法参数为私有的属性姓名$name、性别$sex和年龄$age进行赋值<br />
function __construct($name, $sex, $age)<br />
{<br />
//通过构造方法传进来的$name给私有成员属性$this->name赋初使值<br />
$this->name=$name;<br />
//通过构造方法传进来的$sex给私有成员属性$this->sex赋初使值<br />
$this->sex=$sex;<br />
//通过构造方法传进来的$age给私有成员属性$this->age赋初使值<br />
$this->age=$age;<br />
}<br />
//这个人可以说话的方法, 说出自己的私有属性，在这里也可以访问私有方法<br />
function say()<br />
{<br />
echo &#8220;我的名子叫：&#8221;.$this->name.&#8221; 性别：&#8221;.$this->sex.&#8221; 我的年龄是：&#8221;.$this->age.&#8221;<br />&#8220;;<br />
}<br />
}<br />
//通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄<br />
$p1=new Person(“张三”，”男”, 20);<br />
$p2=new Person(“李四”，”女”, 30);<br />
$p3=new Person(“王五”，”男”, 40);<br />
//下面访问$p1对象中的说话方法<br />
$p1->say();<br />
//下面访问$p2对象中的说话方法<br />
$p2->say();<br />
//下面访问$p3对象中的说话方法</p>
<p>$p3->say();<br />
输出结果为：<br />
我的名子叫：张三 性别：男 我的年龄是：20<br />
我的名子叫：李四 性别：女 我的年龄是：30<br />
我的名子叫：王五 性别：男 我的年龄是：40<br />
因为构造方法是默认的公有方法（构造方法不要设置成私有的），所以在类的外面可以访问到，这样就可以使用构造方法创建对象， 另外构造方法也是类里面的函数，所以可以用构造方法给私有的属性赋初值。Say()的方法是默认公有的， 所以在外面也可以访问的到， 说出他自己的私有属性。<br />
从上面的例子中我们可以看到，私有的成员只能在类的内部使用，不能被类外部直接来存取，但是在类的内部是有权限访问的，所以有时候我们需要在类的外面给私有属性赋值和读取出来，也就是给类的外部提供一些可以存取的接口，上例中构造方法就是一种赋值的形式，但是构造方法只是在创建对象的时候赋值，如果我们已经有一个存在的对象了，想对这个存在的对象赋值，这个时候，如果你还使用构造方法传值的形式传值，那么就创建了一个新的对象，并不是这个已存在的对象了。所以我们要对私有的属性做一些可以被外部存取的接口，目的就是可以在对象存在的情况下，改变和存取属性的值，但要注意，只有需要让外部改变的属性才这样做，不想让外面访问的属性是不做这样的接口的，这样就能达到封装的目的，所有的功能都是对象自己来完成，给外面提供尽量少的操作。</p>
<p>如果给类外部提供接口，可以为私有属性在类外部提供设置方法和获取方法，来操作私有属性.例如：<br />
prvate $age; //私有的属性年龄<br />
function setAge($age)   //为外部提供一个公有设置年龄的方法<br />
{<br />
if($age<0 || $age>130)   //在给属性赋值的时候，为了避免非法值设置给属性<br />
return;<br />
$this->age=$age;<br />
}<br />
function getAge()    //为外部提供一个公有获取年龄的方法<br />
{<br />
return($this->age);<br />
}<br />
 上面的方法是为一个成员属性设置和获取值， 当然你也可以为每个属性用同样的方法对其进行赋值和取值的操作，完成在类外部的存取工作。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
10.__set() __get() __isset() __unset()四个方法的应用<br />
一般来说，总是把类的属性定义为private，这更符合现实的逻辑。但是， 对属性的读取和赋值操作是非常频繁的，因此在PHP5中，预定义了两个函数“__get()”和“__set()”来获取和赋值其属性,以及检查属性的“__isset()”和删除属性的方法“__unset()”。<br />
上一节中，我们为每个属性做了设置和获取的方法，在PHP5中给我们提供了专门为属性设置值和获取值的方法，“__set()”和“__get()”这两个方法，这两个方法不是默认存在的， 而是我们手工添加到类里面去的，像构造方法(__construct())一样, 类里面添加了才会存在，可以按下面的方式来添加这两个方法，当然也可以按个人的风格来添加：<br />
//__get()方法用来获取私有属性<br />
private function __get($property_name)<br />
{</p>
<p>if(isset($this->$property_name))<br />
{<br />
return($this->$property_name);<br />
}else<br />
{<br />
return(NULL);<br />
}<br />
}<br />
//__set()方法用来设置私有属性<br />
private function __set($property_name, $value)<br />
{<br />
$this->$property_name = $value;<br />
}<br />
__get()方法：这个方法用来获取私有成员属性值的,有一个参数， 参数传入你要获取的成员属性的名称，返回获取的属性值， 这个方法不用我们手工的去调用，因为我们也可以把这个方法做成私有的方法， 是在直接获取私有属性的时候对象自动调用的。因为私有属性已经被封装上了，是不能直接获取值的（比如：“echo $p1->name” 这样直接获取是错误的），但是如果你在类里面加上了这个方法，在使用“echo $p1->name” 这样的语句直接获取值的时候就会自动调用__get($property_name)方法，将属性name传给参数$property_name，通过这个方法的内部执行，返回我们传入的私有属性的值。如果成员属性不封装成私有的，对象本身就不会去自动调用这个方法。<br />
__set()方法：这个方法用来为私有成员属性设置值的，有两个参数，第一个参数为你要为设置值的属性名，第二个参数是要给属性设置的值，没有返回值。这个方法同样不用我们手工去调用，它也可以做成私有的，是在直接设置私有属性值的时候自动调用的，同样属性私有的已经被封装上了， 如果没有__set()这个方法，是不允许的， 比如：$this->name=‘zhangsan’, 这样会出错，但是如果你在类里面加上了__set($property_name, $value)这个方法，在直接给私有属性赋值的时候，就会自动调用它，把属性比如name传给$property_name, 把要赋的值“zhangsan”传给$value，通过这个方法的执行，达到赋值的目的。如果成员属性不封装成私有的，对象本身就不会去自动调用这个方法。为了不传入非法的值， 还可以在这个方法给做一下判断。代码如下：<br />
<?php<br />
class Person<br />
{<br />
//下面是人的成员属性， 都是封装的私有成员<br />
private $name;   //人的名子<br />
private $sex;    //人的性别<br />
private $age;    //人的年龄<br />
//__get()方法用来获取私有属性<br />
private function __get($property_name)<br />
{<br />
echo "在直接获取私有属性值的时候，自动调用了这个__get()方法<br />&#8220;;<br />
if(isset($this->$property_name))<br />
{<br />
return($this->$property_name);<br />
}<br />
else<br />
{<br />
return(NULL);<br />
}<br />
}<br />
//__set()方法用来设置私有属性<br />
private function __set($property_name, $value)<br />
{<br />
echo &#8220;在直接设置私有属性值的时候，自动调用了这个__set()方法为私有属性赋值<br />&#8220;;</p>
<p>$this->$property_name = $value;<br />
}<br />
}<br />
$p1=new Person();<br />
//直接为私有属性赋值的操作， 会自动调用__set()方法进行赋值<br />
$p1->name=&#8221;张三&#8221;;<br />
$p1->sex=&#8221;男&#8221;;<br />
$p1->age=20;<br />
//直接获取私有属性的值， 会自动调用__get()方法，返回成员属性的值<br />
echo &#8220;姓名：&#8221;.$p1->name.&#8221;<br />&#8220;;<br />
echo &#8220;性别：&#8221;.$p1->sex.&#8221;<br />&#8220;;<br />
echo &#8220;年龄：&#8221;.$p1->age.&#8221;<br />&#8220;;<br />
?></p>
<p>程序执行结果：<br />
在直接设置私有属性值的时候，自动调用了这个__set()方法为私有属性赋值<br />
在直接设置私有属性值的时候，自动调用了这个__set()方法为私有属性赋值<br />
在直接设置私有属性值的时候，自动调用了这个__set()方法为私有属性赋值<br />
在直接获取私有属性值的时候，自动调用了这个__get()方法<br />
姓名：张三<br />
在直接获取私有属性值的时候，自动调用了这个__get()方法<br />
性别：男<br />
在直接获取私有属性值的时候，自动调用了这个__get()方法<br />
年龄：20</p>
<p>以上代码如果不加上__get()和__set()方法，程序就会出错，因为不能在类的外部操作私有成员，而上面的代码是通过自动调用__get()和__set()方法来帮助我们直接存取封装的私有成员的。</p>
<p>__isset() 方法：在看这个方法之前我们看一下“isset()”函数的应用，isset()是测定变量是否设定用的函数，传入一个变量作为参数，如果传入的变量存在则传回true，否则传回false。那么如果在一个对象外面使用“isset()”这个函数去测定对象里面的成员是否被设定可不可以用它呢？分两种情况，如果对象里面成员是公有的，我们就可以使用这个函数来测定成员属性， 如果是私有的成员属性，这个函数就不起作用了，原因就是因为私有的被封装了，在外部不可见。那么我们就不可以在对象的外部使用“isset()”函数来测定私有成员属性是否被设定了呢？可以，你只要在类里面加上一个“__isset()”方法就可以了，当在类外部使用”isset()”函数来测定对象里面的私有成员是否被设定时， 就会自动调用类里面的“__isset()”方法了帮我们完成这样的操作，“__isset()”方法也可以做成私有的。你可以在类里面加上下面这样的代码就可以了：<br />
private function __isset($nm)<br />
{<br />
echo &#8220;当在类外部使用isset()函数测定私有成员$nm时，自动调用<br />&#8220;;<br />
return isset($this->$nm);<br />
}</p>
<p>__unset()方法：看这个方法之前呢，我们也先来看一下“unset()”这个函数，“unset()”这个函数的作用是删除指定的变量且传回true，参数为要删除的变量。那么如果在一个对象外部去删除对象内部的成员属性用“unset()”函数可不可以呢， 也是分两种情况，如果一个对象里面的成员属性是公有的， 就可以使用这个函数在对象外面删除对象的公有属性， 如果对象的成员属性是私有的，我使用这个函数就没有权限去删除，但同样如果你在一个对象里面加上“__unset()”这个方法，就可以在对象的外部去删除对象的私有成员属性了。在对象里面加上了“__unset()”这个方法之后，在对象外部使用“unset()”函数删除对象内部的私有成员属性时，自动调用“__unset()”函数来帮<br />
我们删除对象内部的私有成员属性，这个方法也可以在类的内部定义成私有的。在对象里面加上下面的代码就可以了：<br />
private function __unset($nm)<br />
{<br />
echo &#8220;当在类外部使用unset()函数来删除私有成员时自动调用的<br />&#8220;;<br />
unset($this->$nm);<br />
}<br />
我们来看一个完整的实例：<br />
<?php<br />
class Person<br />
{<br />
//下面是人的成员属性<br />
private $name;   //人的名子<br />
private $sex;   //人的性别<br />
private $age;   //人的年龄<br />
//__get()方法用来获取私有属性<br />
private function __get($property_name)<br />
{<br />
if(isset($this->$property_name))<br />
{<br />
return($this->$property_name);<br />
}else {<br />
return(NULL);<br />
}<br />
}<br />
//__set()方法用来设置私有属性<br />
private function __set($property_name, $value)<br />
{</p>
<p>$this->$property_name = $value;<br />
}<br />
//__isset()方法<br />
private function __isset($nm)<br />
{<br />
echo &#8220;isset()函数测定私有成员时，自动调用<br />&#8220;;<br />
return isset($this->$nm);<br />
}<br />
//__unset()方法<br />
private function __unset($nm)<br />
{<br />
echo &#8220;当在类外部使用unset()函数来删除私有成员时自动调用的<br />&#8220;;<br />
unset($this->$nm);<br />
}<br />
}<br />
$p1=new Person();<br />
$p1->name=&#8221;this is a person name&#8221;;<br />
//在使用isset()函数测定私有成员时，自动调用__isset()方法帮我们完成，返回结果为true<br />
echo var_dump(isset($p1->name)).&#8221;<br />&#8220;;<br />
echo $p1->name.&#8221;<br />&#8220;;<br />
//在使用unset()函数删除私有成员时，自动调用__unset()方法帮我们完成，删除name私有属性<br />
unset($p1->name);<br />
//已经被删除了， 所这行不会有输出<br />
echo $p1->name;<br />
?><br />
输出结果为：<br />
isset()函数测定私有成员时，自动调用<br />
bool(true)<br />
this is a person name<br />
当在类外部使用unset()函数来删除私有成员时自动调用的<br />
__set()、__get()、__isset()、__unset() 这四个方法都是我们添加到对象里面的，在需要时自动调用的，来完成在对象外部对对象内部私有属性的操作。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1043.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php技术常见问题汇总解答(程序实例）</title>
		<link>http://www.evanjiang.net.cn/archives/1039.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1039.html#comments</comments>
		<pubDate>Thu, 14 May 2009 06:24:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1039</guid>
		<description><![CDATA[<p>1:为什么得不到变量 </p>
<p>　　 在一网页向另一网页POST数据name，为什么输出$name时却得不到任何值? </p>
<p>　　 在PHP4.2以后的版本中reGISter_global默认为off
　　 若想取得从另一页面提交的变量: </p>
<p>　　 方法一:在PHP.ini中找到register_global，并把它设置为on.
　　 方法二:在接收网页最前面放上这个extract($_POST);extract($_GET);(注意extract($_SESSION)前必须要有Session_Start()).
　　 方法三:一个一个读取变量$a=$_GET["a"];$b=$_POST["b"]等，这种方法虽然麻烦，但比较安全. </p>
<p>　　 2：调试你的程序 </p>
<p>　　 在运行时必须知道某个变量为何值。我是这样做的，建立一文件debug.php,其内容如下: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP
　　 Ob_Start();
　　 Session_Start();
　　 Echo &#8220;＜pre>&#8221;; </p>
<p>　　 Echo &#8220;本页得到的_GET变量有:&#8221;;
　　 Print_R($_GET); </p>
<p>　　 Echo &#8220;本页得到的_POST变量有:&#8221;;
　　 Print_R($_POST); </p>
<p>　　 Echo &#8220;本页得到的_COOKIE变量有:&#8221;;
　　 Print_R($_COOKIE);

　　 Echo &#8220;本页得到的_SESSION变量有:&#8221;;
　　 Print_R($_SESSION); </p>
<p>　　 Echo &#8220;＜/pre>&#8221;;
　　 ?> </p>
<p>　　 然后在php.ini中设置：include_path = &#8220;c:/php&#8221;，并将debug.php放在此文件夹,以后就可以在每个网页里包含此文件，查看得到的变量名和值. </p>
<p>　　 3：如何使用session </p>
<p>　　 凡是与session有关的,之前必须调用函数session_start(); </p>
<p>　　 为session付值很简单,如: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php
　　 [...]]]></description>
			<content:encoded><![CDATA[<p>1:为什么得不到变量 </p>
<p>　　 在一网页向另一网页POST数据name，为什么输出$name时却得不到任何值? </p>
<p>　　 在PHP4.2以后的版本中reGISter_global默认为off<br />
　　 若想取得从另一页面提交的变量: </p>
<p>　　 方法一:在PHP.ini中找到register_global，并把它设置为on.<br />
　　 方法二:在接收网页最前面放上这个extract($_POST);extract($_GET);(注意extract($_SESSION)前必须要有Session_Start()).<br />
　　 方法三:一个一个读取变量$a=$_GET["a"];$b=$_POST["b"]等，这种方法虽然麻烦，但比较安全. </p>
<p>　　 2：调试你的程序 </p>
<p>　　 在运行时必须知道某个变量为何值。我是这样做的，建立一文件debug.php,其内容如下: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 Ob_Start();<br />
　　 Session_Start();<br />
　　 Echo &#8220;＜pre>&#8221;; </p>
<p>　　 Echo &#8220;本页得到的_GET变量有:&#8221;;<br />
　　 Print_R($_GET); </p>
<p>　　 Echo &#8220;本页得到的_POST变量有:&#8221;;<br />
　　 Print_R($_POST); </p>
<p>　　 Echo &#8220;本页得到的_COOKIE变量有:&#8221;;<br />
　　 Print_R($_COOKIE);<br />
<span id="more-1039"></span><br />
　　 Echo &#8220;本页得到的_SESSION变量有:&#8221;;<br />
　　 Print_R($_SESSION); </p>
<p>　　 Echo &#8220;＜/pre>&#8221;;<br />
　　 ?> </p>
<p>　　 然后在php.ini中设置：include_path = &#8220;c:/php&#8221;，并将debug.php放在此文件夹,以后就可以在每个网页里包含此文件，查看得到的变量名和值. </p>
<p>　　 3：如何使用session </p>
<p>　　 凡是与session有关的,之前必须调用函数session_start(); </p>
<p>　　 为session付值很简单,如: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php<br />
　　 Session_start();<br />
　　 $Name = &#8220;这是一个Session例子&#8221;;<br />
　　 Session_Register(&#8220;Name&#8221;);//注意,不要写成：Session_Register(&#8220;$Name&#8221;);<br />
　　 Echo $_SESSION["Name"];<br />
　　 //之后$_SESSION["Name"]为&#8221;这是一个Session例子&#8221;<br />
　　 ?> </p>
<p>　　 在php4.2之后,可以为session直接付值: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 Session_Start();<br />
　　 $_SESSION["name"]=&#8221;value&#8221;;<br />
　　 ?> </p>
<p>　　 取消session可以这样:<br />
　　PHP代码: </p>
<p>　　 ＜?php<br />
　　 session_start();<br />
　　 session_unset();<br />
　　 session_destroy();<br />
　　 ?> </p>
<p>　　 取消某个session变量在php4.2以上还有BUG. </p>
<p>　　 注意: </p>
<p>　　 1:在调用Session_Start()之前不能有任何输出.例如下面是错误的.<br />
　　 ==========================================<br />
　　 1行<br />
　　 2行 3行 Session_Start();//之前在第一行已经有输出<br />
　　 4行 &#8230;..<br />
　　 5行 ?><br />
　　 ========================================== </p>
<p>　　 提示1: </p>
<p>　　 凡是出现&#8221; &#8230;&#8230;..headers already sent&#8230;&#8230;&#8230;. &#8220;,就是Session_Start()之前向浏览器输出信息.去掉输出就正常,（COOKIE也会出现这种错误,错误原因一样） </p>
<p>　　 提示2: </p>
<p>　　 如果你的Session_Start()放在循环语句里,并且很难确定之前哪里向浏览器输出信息,可以用下面这种方法:<br />
　　 1行 ＜?PHP Ob_Start(); ?><br />
　　 &#8230;&#8230;..这里是你的程序&#8230;&#8230; </p>
<p>　　 2:这是什么错误 </p>
<p>　　 Warning: session_start(): open(/tmp\sess_7d190aa36b4c5ec13a5c1649cc2da23f, O_RDWR) failed:&#8230;.<br />
因为你没有指定session文件的存放路径. </p>
<p>　　 解决方法:<br />
　　 (1)在c盘建立文件夹tmp<br />
　　 (2)打开php.ini,找到session.save_path,修改为session.save_path= &#8220;c:/tmp&#8221; </p>
<p>　　 4:为什么我向另一网页传送变量时,只得到前半部分,以空格开头的则全部丢失 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php<br />
　　 $Var=&#8221;hello php&#8221;;//修改为$Var=&#8221; hello php&#8221;;试试得到什么结果<br />
　　 $post= &#8220;receive.php?Name=&#8221;.$Var;<br />
　　 header(&#8220;location:$post&#8221;);<br />
　　 ?> </p>
<p>　　 receive.php的内容: </p>
<p>　　 PHP代码:<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　 ＜?PHP<br />
　　 Echo &#8220;＜pre>&#8221;;<br />
　　 Echo $_GET["Name"];<br />
　　 Echo &#8220;＜/pre>&#8221;;<br />
　　 ?> </p>
<p>　　 正确的方法是: </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php<br />
　　 $Var=&#8221;hello php&#8221;;<br />
　　 $post= &#8220;receive.php?Name=&#8221;.urlencode($Var);<br />
　　 header(&#8220;location:$post&#8221;);<br />
　　 ?> </p>
<p>　　 在接收页面你不需要使用Urldecode(),变量会自动编码. </p>
<p>　　5:我怎么知道系统默认支持什么函数 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php<br />
　　 $arr = get_defined_functions();<br />
　　 Function php() {<br />
　　 }<br />
　　 echo &#8220;＜pre>&#8221;;<br />
　　 Echo &#8220;这里显示系统所支持的所有函数,和自定以函数php\n&#8221;;<br />
　　 print_r($arr);<br />
　　 echo &#8220;＜/pre>&#8221;;<br />
　　 ?> </p>
<p>　　6:如何比较两个日期相差几天 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 $Date_1=&#8221;2003-7-15&#8243;;//也可以是:$Date_1=&#8221;2003-7-15 23:29:14&#8243;;<br />
　　 $Date_2=&#8221;1982-10-1&#8243;;<br />
　　 $d1=strtotime($Date_1);<br />
　　 $d2=strtotime($Date_2);<br />
　　 $Days=round(($d1-$d2)/3600/24);<br />
　　 Echo &#8220;偶已经奋斗了 $Days 天^_^&#8221;;<br />
　　 ?> </p>
<p>　　 7:为什么我升级PHP后,原来的程序出现满屏的 Notice: Undefined variable: </p>
<p>　　 这是警告的意思,由于变量未定义引起的.<br />
　　 打开php.ini,找到最下面的error_reporting,修改为error_reporting = E_ALL &#038; ~E_NOTICE </p>
<p>　　 对于Parse error错误<br />
　　 error_reporting(0)无法关闭.<br />
　　 如果你想关闭任何错误提示,打开php.ini,找到display_errors,设置为display_errors = Off.以后任何错误都不会提示. </p>
<p>　　 那什么是error_reporting? </p>
<p>　　 8:我想在每个文件最前，最后面都加上一文件.但一个一个添加很麻烦 </p>
<p>　　 1:打开php.ini文件<br />
　　 设置 include_path= &#8220;c:&#8221; </p>
<p>　　 2:写两个文件<br />
　　 auto_prepend_file.php 和 auto_append_file.php 保存在c盘,他们将自动依附在每个php文件的头部和尾部. </p>
<p>　　 3:在php.ini中找到:<br />
　　 Automatically add files before or after any PHP document.<br />
　　 auto_prepend_file = auto_prepend_file.php;依附在头部<br />
　　 auto_append_file = auto_append_file.php;依附在尾部 </p>
<p>　　 以后你每个php文件就相当于 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?php<br />
　　 Include &#8220;auto_prepend_file.php&#8221; ; </p>
<p>　　 &#8230;&#8230;.//这里是你的程序 </p>
<p>　　 Include &#8220;auto_append_file.php&#8221;;<br />
　　 ?><br />
　　9:如何利用PHP上传文件 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜html>＜head><br />
　　 ＜title>上载文件表单＜/title>＜/head><br />
　　 ＜body><br />
　　 ＜form enctype=&#8221;multipart/form-data&#8221; action=&#8221;" method=&#8221;post&#8221;><br />
　　 请选择文件： ＜br><br />
　　 ＜input name=&#8221;upload_file&#8221; type=&#8221;file&#8221;>＜br><br />
　　 ＜input type=&#8221;submit&#8221; value=&#8221;上传文件&#8221;><br />
　　 ＜/form><br />
　　 ＜/body><br />
　　 ＜/html><br />
＜?<br />
　　 $upload_file=$_FILES['upload_file']['tmp_name'];<br />
　　 $upload_file_name=$_FILES['upload_file']['name']; </p>
<p>　　 if($upload_file){<br />
　　 $file_size_max = 1000*1000;// 1M限制文件上传最大容量(bytes)<br />
　　 $store_dir = &#8220;d:/&#8221;;// 上传文件的储存位置<br />
　　 $accept_overwrite = 1;//是否允许覆盖相同文件<br />
　　 // 检查文件大小<br />
　　 if ($upload_file_size > $file_size_max) {<br />
　　 echo &#8220;对不起，你的文件容量大于规定&#8221;;<br />
　　 exit;<br />
　　 } </p>
<p>　　 // 检查读写文件<br />
　　 if (file_exists($store_dir . $upload_file_name) &#038;&#038; !$accept_overwrite) {<br />
　　 Echo &#8220;存在相同文件名的文件&#8221;;<br />
　　 exit;<br />
　　 } </p>
<p>　　 //复制文件到指定目录<br />
　　 if (!move_uploaded_file($upload_file,$store_dir.$upload_file_name)) {<br />
　　 echo &#8220;复制文件失败&#8221;;<br />
　　 exit;<br />
　　 } </p>
<p>　　 } </p>
<p>　　 Echo &#8220;＜p>你上传了文件:&#8221;;<br />
　　 echo $_FILES['upload_file']['name'];<br />
　　 echo &#8220;＜br>&#8221;;<br />
　　 //客户端机器文件的原名称。 </p>
<p>　　 Echo &#8220;文件的 MIME 类型为:&#8221;;<br />
　　 echo $_FILES['upload_file']['type'];<br />
　　 //文件的 MIME 类型，需要浏览器提供该信息的支持，例如“image/gif”。<br />
　　 echo &#8220;＜br>&#8221;; </p>
<p>　　 Echo &#8220;上传文件大小:&#8221;;<br />
　　 echo $_FILES['upload_file']['size'];<br />
　　 //已上传文件的大小，单位为字节。<br />
　　 echo &#8220;＜br>&#8221;; </p>
<p>　　 Echo &#8220;文件上传后被临时储存为:&#8221;;<br />
　　 echo $_FILES['upload_file']['tmp_name'];<br />
　　 //文件被上传后在服务端储存的临时文件名。<br />
　　 echo &#8220;＜br>&#8221;;<br />
　　 $Erroe=$_FILES['upload_file']['error'];<br />
　　 switch($Erroe){<br />
　　 case 0:<br />
　 Echo &#8220;上传成功&#8221;; break;<br />
　　 case 1:<br />
　 Echo &#8220;上传的文件超过了 PHP.ini 中 upload_max_filesize 选项限制的值.&#8221;; break;<br />
　　 case 2:<br />
　 Echo &#8220;上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。&#8221;; break;<br />
　　 case 3:<br />
　 Echo &#8220;文件只有部分被上传&#8221;;break;<br />
　　 case 4:<br />
　 Echo &#8220;没有文件被上传&#8221;;break;<br />
　　 }<br />
　　 ?> </p>
<p>　　 10:如何配置GD库 </p>
<p>　　 下面是我的配置过程<br />
　　 1:用dos命令(也可以手动操作,拷贝dlls文件夹里所有dll文件到system32目录下) copy c:\php\dlls\*.dll c:\Windows\system32\<br />
　　 2:打开php.ini<br />
　　 设置extension_dir = &#8220;c:/php/extensions/&#8221;;<br />
　　 3:<br />
　　 extension=php_gd2.dll;把extension前面的逗号去掉，如果没有php_gd2.dll，php_gd.dll也一样,保证确实存在这一文件c:/php/extensions/php_gd2.dll<br />
　　 4:运行下面程序进行测试 </p>
<p>　　 PHP代码:<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　 ＜?php<br />
　　 Ob_end_flush();<br />
　　 //注意,在此之前不能向浏览器输出任何信息,要注意是否设置了 auto_prepend_file.<br />
　　 header (&#8220;Content-type: image/png&#8221;);<br />
　　 $im = @imagecreate (200, 100)<br />
　 or die (&#8220;无法创建图像&#8221;);<br />
　　 $background_color = imagecolorallocate ($im, 0,0, 0);<br />
　　 $text_color = imagecolorallocate ($im, 230, 140, 150);<br />
　　 imagestring ($im, 3, 30, 50, &#8220;A Simple Text String&#8221;, $text_color);<br />
　　 imagepng ($im);<br />
　　 ?> </p>
<p>　　 11:什么是UBB代码 </p>
<p>　　 UBB代码是HTML的一个变种,是Ultimate Bulletin Board (国外一个BBS程序，国内也有不少地方使用这个程序)采用的一种特殊的TAG. </p>
<p>　　 即使禁止使用 HTML，你也可以用 UBBCode? 来实现.也许你更希望使用 UBBCode? 而不是 HTML, 即使论坛允许使用 HTML, 因为使用起来代码较少也更安全.<br />
5:如何截取指定长度汉字而不会出现以&#8221;?>&#8221;结尾,超出部分以&#8221;&#8230;&#8221;代替 </p>
<p>　　 一般来说,要截取的变量来自MySQL,首先要保证那个字段长度要足够长,一般为char(200),可以保持100个汉字，包括标点. </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 $str=&#8221;这个字符好长呀,^_^&#8221;;<br />
　　 $Short_Str=showShort($str,4);//截取前面4个汉字,结果为:这个字符&#8230;<br />
　　 Echo &#8220;$Short_Str&#8221;;<br />
　　 Function csubstr($str,$start,$len)<br />
　　 {<br />
　　 $strlen=strlen($str);<br />
　　 $clen=0;<br />
　　 for($i=0;$i＜$strlen;$i++,$clen++)<br />
　　 {<br />
　　 if ($clen>=$start+$len)<br />
　　 break;<br />
　　 if(ord(substr($str,$i,1))>0xa0)<br />
　　 {<br />
　　 if ($clen>=$start)<br />
　　 $tmpstr.=substr($str,$i,2);<br />
　　 $i++;<br />
　　 }<br />
　　 else<br />
　　 {<br />
　　 if ($clen>=$start)<br />
　　 $tmpstr.=substr($str,$i,1);<br />
　　 }<br />
　　 } </p>
<p>　　 return $tmpstr;<br />
　　 }<br />
　　 Function showShort($str,$len)<br />
　　 {<br />
　　 $tempstr = csubstr($str,0,$len);<br />
　　 if ($str＜>$tempstr)<br />
　　 $tempstr .= &#8220;&#8230;&#8221;; //要以什么结尾,修改这里就可以. </p>
<p>　　 return $tempstr;<br />
　　 } </p>
<p>　　 12:规范你的SQL语句 </p>
<p>　　 在表格，字段前面加上&#8221;`&#8221;,这样就不会因为误用关键字而出现错误，当然我并不推荐你使用关键字. </p>
<p>　　 例如<br />
　　 $Sql=&#8221;INSERT INTO `xltxlm` (`author`, `title`, `id`, `content`, `date`) VALUES (&#8216;xltxlm&#8217;, &#8216;use`&#8217;, 1, &#8216;criterion your sql string &#8216;, &#8217;2003-07-11 00:00:00&#8242;)&#8221; </p>
<p>　　 &#8220;`&#8221;怎么输入? 在TAB键上面. </p>
<p>　　 13:如何使Html/PHP格式的字符串不被解释,而是照原样显示 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 $str=&#8221;＜h1>PHP＜/h1>&#8221;;<br />
　　 Echo &#8220;被解释过的: &#8220;.$str.&#8221;＜br>经过处理的:&#8221;;<br />
　　 Echo htmlentities(nl2br($str));<br />
　　 ?> </p>
<p>　　 14怎么在函数里取得函数外的变量值 </p>
<p>　　 PHP代码: </p>
<p>　　 ＜?PHP<br />
　　 $a=&#8221;PHP&#8221;;<br />
　　 foo();<br />
　　 Function foo()<br />
　　 {<br />
　　 global $a;//删除这里看看是什么结果<br />
　　 Echo &#8220;$a&#8221;;<br />
　　 }<br />
　　 ?><br />
之前，俺一直疑惑如何在funtion里调用function以外的变量，也查过书，也问过网友。也查过手册，得回来的反馈就是要使用全局变量。但刚开始不知道如何使用全局变量。一直迷迷糊糊。。。现在终于见到实际例程。原来是这样调用function以年的变量的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1039.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>网上收集到php 的ftp function 大全</title>
		<link>http://www.evanjiang.net.cn/archives/1036.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1036.html#comments</comments>
		<pubDate>Thu, 14 May 2009 03:04:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1036</guid>
		<description><![CDATA[<p>这段时间正在研究一个基于PHP网站开发语言编的开源商城程序，并且考虑在其基础加以完善与改造。所以，就对PHP研究多些，刚好要考虑利用php 的ftp类Function作些事，就从网上收集这些ftp  function大全。并且收录下来。。。</p>
<p>FTP 的全称是 File Transfer Protocol，也就是文件传输协议。利用本函数库可以让 PHP 也能处理 FTP 的相关功能。本函数库需要 PHP 3.0.13 版之后才支持。</p>
<p>　　ftp_connect： 打开 FTP 链接。
　　ftp_login： 登入 FTP 服务器。
　　ftp_pwd： 取得目前所在路径。
　　ftp_cdup： 回上层目录。
　　ftp_chdir： 改变路径。
　　ftp_mkdir： 建新目录。
　　ftp_rmdir： 删除目录。
　　ftp_nlist： 列出指定目录中所有文件。
　　ftp_rawlist： 详细列出指定目录中所有文件。
　　ftp_systype： 显示服务器系统。
　　ftp_pasv： 切换主被动传输模式。
　　ftp_get： 下载文件。
　　ftp_fget： 下载文件，并存在已开的档中。
　　ftp_put： 上传文件。
　　ftp_fput： 上传已打开文件。
　　ftp_size： 获得指定文件的大小。
　　ftp_mdtm： 获得指定文件的最后修改时间。
　　ftp_rename： 将文件改名。
　　ftp_delete： 将文件删除。
　　ftp_quit： 关闭 FTP 连接。</p>
<p>　　ftp_connect　打开 FTP 链接。
　　语法： int ftp_connect(string host, int [port]);
　　返回值： 整数
　　函数种类： 网络系统
　　内容说明： 本函数可打开 FTP 服务器的链接。参数 host 为 [...]]]></description>
			<content:encoded><![CDATA[<p>这段时间正在研究一个基于PHP网站开发语言编的开源商城程序，并且考虑在其基础加以完善与改造。所以，就对PHP研究多些，刚好要考虑利用php 的ftp类Function作些事，就从网上收集这些ftp  function大全。并且收录下来。。。</p>
<p>FTP 的全称是 File Transfer Protocol，也就是文件传输协议。利用本函数库可以让 PHP 也能处理 FTP 的相关功能。本函数库需要 PHP 3.0.13 版之后才支持。</p>
<p>　　ftp_connect： 打开 FTP 链接。<br />
　　ftp_login： 登入 FTP 服务器。<br />
　　ftp_pwd： 取得目前所在路径。<br />
　　ftp_cdup： 回上层目录。<br />
　　ftp_chdir： 改变路径。<br />
　　ftp_mkdir： 建新目录。<br />
　　ftp_rmdir： 删除目录。<br />
　　ftp_nlist： 列出指定目录中所有文件。<br />
　　ftp_rawlist： 详细列出指定目录中所有文件。<br />
　　ftp_systype： 显示服务器系统。<br />
　　ftp_pasv： 切换主被动传输模式。<br />
　　ftp_get： 下载文件。<br />
　　ftp_fget： 下载文件，并存在已开的档中。<br />
　　ftp_put： 上传文件。<br />
　　ftp_fput： 上传已打开文件。<br />
　　ftp_size： 获得指定文件的大小。<br />
　　ftp_mdtm： 获得指定文件的最后修改时间。<br />
　　ftp_rename： 将文件改名。<br />
　　ftp_delete： 将文件删除。<br />
　　ftp_quit： 关闭 FTP 连接。</p>
<p>　　ftp_connect　打开 FTP 链接。<br />
　　语法： int ftp_connect(string host, int [port]);<br />
　　返回值： 整数<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可打开 FTP 服务器的链接。参数 host 为 FTP 服务器的网址。参数 port 通常省略，若 FTP 服务器的埠号 (port) 不是 21 时才需要加本参数。若无错误则返回连接代码，失败则返回 false 值。<br />
　　参考： ftp_quit()<br />
<span id="more-1036"></span><br />
　　ftp_login　登入 FTP 服务器。<br />
　　语法： boolean ftp_login(int ftp_stream, string username, string password);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
内 容说明： 本函数可登入已链接的 FTP 服务器。参数 ftp_stream 为 FTP 的连接代码。参数 username 及 password 分别为服务器的使用者帐号及密码，通常 anonymous 为公开的使用帐号，密码则为 Email。成功则返回 true 值。</p>
<p>　　ftp_pwd　取得目前所在路径。<br />
　　语法： string ftp_pwd(int ftp_stream);<br />
　　返回值： 字符串<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来取得目前在 FTP 服务器中的路径。参数 ftp_stream 为 FTP 的连接代码。若有错误则返回 NULL 值。</p>
<p>　　ftp_cdup　回上层目录。<br />
　　语法： boolean ftp_cdup(int ftp_stream);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来回到上层目录，也就是目前目录的父目录。参数 ftp_stream 为 FTP 的连接代码。成功则返回 true 值。</p>
<p>　　ftp_chdir　改变路径。<br />
　　语法： boolean ftp_chdir(int ftp_stream, string directory);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
内容说明： 本函数用来改变路径。参数 ftp_stream 为 FTP 的连接代码。参数 directory 为欲前往的目录。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_mkdir　建新目录。<br />
　　语法： string ftp_mkdir(int ftp_stream, string directory);<br />
　　返回值： 字符串<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来建立新的目录。参数 ftp_stream 为 FTP 的连接代码。参数 directory 为欲建立的新目录。成功则返回已建立的目录名，失败则返回 false 值。</p>
<p>　　ftp_rmdir　删除目录。<br />
　　语法： boolean ftp_chdir(int ftp_stream, string directory);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来删除空目录。参数 ftp_stream 为 FTP 的连接代码。参数 directory 为欲删除的目录。成功则返回 true 值，失败则返回 false 值。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　ftp_nlist　列出指定目录中所有文件。<br />
　　语法： array ftp_nlist(int ftp_stream, string directory);<br />
　　返回值： 数组<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来列出指定路径中的所有文件名称。参数 ftp_stream 为 FTP 的连接代码。参数 directory 为指定的目录。成功则返回文件名称的数组，失败则返回 false 值。</p>
<p>　　ftp_rawlist　详细列出指定目录中所有文件。<br />
　　语法： array ftp_rawlist(int ftp_stream, string directory);<br />
　　返回值： 数组<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可详细列出指定路径中的所有文件名称。参数 ftp_stream 为 FTP 的连接代码。参数 directory 为指定的目录。成功则返回文件名称的数组，失败则返回 false 值。</p>
<p>　　ftp_systype　显示服务器系统。<br />
　　语法： string ftp_systype(int ftp_stream);<br />
　　返回值： 字符串<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可显示远端 FTP 服务器的系统，也就等于对 FTP 服务器下 system 或 syst 指令。参数 ftp_stream 为 FTP 的连接代码。成功则返回字符串，如： &#8220;215 UNIX Type： L8&#8243;，失败则返回 false 值。</p>
<p>　　ftp_pasv　切换主被动传输模式。<br />
　　语法： boolean ftp_systype(int ftp_stream);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可以切换成主动传输或者被动传输模式，也就等于对 FTP 服务器下 passive 或 pass 指令。参数 ftp_stream 为 FTP 的连接代码。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_get　下载文件。<br />
　　语法： boolean ftp_get(int ftp_stream, string local_file, string remote_file, int mode);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来下载指定的文件。参数 ftp_stream 为 FTP 的连接代码。参数 local_file 为欲存成本地端的文件名。参数 remote_file 为欲下载的文件名。参数 mode 的值有 FTP_ASCII 及 FTP_BINARY 二种，分别表示文字档宁或者是二进位文件。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_fget　下载文件，并存在已开的文件中。<br />
　　语法： boolean ftp_fget(int ftp_stream, int fp, string remote_file, int mode);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来下载指定的文件。参数 ftp_stream 为 FTP 的连接代码。参数 fp 为本地端的已开文件的文件指针。参数 remote_file 为欲下载的文件名。参数 mode 的值有 FTP_ASCII 及 FTP_BINARY 二种，分别表示文字档宁或者是二进位文件。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_put　上传文件。<br />
　　语法： boolean ftp_put(int ftp_stream, string remote_file, string local_file, int mode);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来上传指定的文件。参数 ftp_stream 为 FTP 的连接代码。参数 remote_file 为欲存在远端的文件名。参数 local_file 为欲上传文件的文件名。参数 mode 的值有 FTP_ASCII 及 FTP_BINARY 二种，分别表示文字档宁或者是二进位文件。成功则返回 true 值，失败则返回 false 值。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　ftp_fput　上传已打开文件。<br />
　　语法： boolean ftp_fput(int ftp_stream, string remote_file, int fp, int mode);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来上传指定的文件。参数 ftp_stream 为 FTP 的连接代码。参数 remote_file 为欲存在远端的文件名。参数 fp 为欲上传的已开文件文件指针。参数 mode 的值有 FTP_ASCII 及 FTP_BINARY 二种，分别表示文字档宁或者是二进位文件。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_size　获得指定文件的大小。<br />
　　语法： int ftp_size(int ftp_stream, string remote_file);<br />
　　返回值： 整数<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来获取 FTP 服务器上指定文件的大小。参数 ftp_stream 为 FTP 的连接代码。参数 remote_file 为欲获取大小文件名。返回值为文件大小，失败则返回 -1 值。</p>
<p>　　ftp_mdtm　获得指定文件的最后修改时间。<br />
　　语法： int ftp_mdtm(int ftp_stream, string remote_file);<br />
　　返回值： 整数<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来获取 FTP 服务器上指定文件的最后修改时间。参数 ftp_stream 为 FTP 的连接代码。参数 remote_file 为欲获取修改时间的文件名。返回值为 UNIX 的时间格式 (timestamp)，失败则返回 -1 值。</p>
<p>　　ftp_rename　将文件改名。<br />
　　语法： boolean ftp_rename(int ftp_stream, string from, string to);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可将远端 FTP 服务器的文件改名字，值的注意的是权限不符时无法改动。参数 ftp_stream 为 FTP 的连接代码。参数 from 为原来的文件名。参数 to 为欲改的新文件名。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_delete　将文件删除。<br />
　　语法： boolean ftp_delete(int ftp_stream, string remote_file);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数可将远端 FTP 服务器的文件删除，若是权限不符则无法删除。参数 ftp_stream 为 FTP 的连接代码。参数 remote_file 为欲删除的文件名。成功则返回 true 值，失败则返回 false 值。</p>
<p>　　ftp_quit　关闭 FTP 连接。<br />
　　语法： boolean ftp_quit(int ftp_stream);<br />
　　返回值： 布尔值<br />
　　函数种类： 网络系统<br />
　　内容说明： 本函数用来将远端 FTP 服务器连接关闭。参数 ftp_stream 为 FTP 的连接代码。成功则返回 true 值，失败则返回 false 值。<br />
　　参考： ftp_connect()</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1036.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>收集的几个有用php function</title>
		<link>http://www.evanjiang.net.cn/archives/1030.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1030.html#comments</comments>
		<pubDate>Wed, 13 May 2009 07:35:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1030</guid>
		<description><![CDATA[<p>很有用的一些函数，你可以作为源码保存，然后以后避免重复编写。</p>
<p>文件读取函数 </p>
<p>   //文件读取函数
   function PHP_Read($file_name) {
   $fd=fopen($file_name,r);
   while($bufline=fgets($fd, 4096)){
   $buf.=$bufline;
    }
   fclose($fd);
   return $buf;
    }
   ?></p>
<p>文件写入函数 </p>
<p>   //文件写入函数
   function PHP_Write($file_name,$data,$method=&#8221;w&#8221;) {
   $filenum=@fopen($file_name,$method);
   flock($filenum,LOCK_EX);
   [...]]]></description>
			<content:encoded><![CDATA[<p>很有用的一些函数，你可以作为源码保存，然后以后避免重复编写。</p>
<p>文件读取函数 </p>
<p>   //文件读取函数<br />
   function PHP_Read($file_name) {<br />
   $fd=fopen($file_name,r);<br />
   while($bufline=fgets($fd, 4096)){<br />
   $buf.=$bufline;<br />
    }<br />
   fclose($fd);<br />
   return $buf;<br />
    }<br />
   ?></p>
<p>文件写入函数 </p>
<p>   //文件写入函数<br />
   function PHP_Write($file_name,$data,$method=&#8221;w&#8221;) {<br />
   $filenum=@fopen($file_name,$method);<br />
   flock($filenum,LOCK_EX);<br />
   $file_data=fwrite($filenum,$data);<br />
   fclose($filenum);<br />
   return $file_data;<br />
    }<br />
   ?></p>
<p>静态页面生成函数<br />
<span id="more-1030"></span><br />
   //静态页面生成函数<br />
   function phptohtm($filefrom,$fileto,$u2u=1){<br />
   if($u2u==1){<br />
   $data=PHP_Read($filefrom);<br />
    }else{<br />
   $data=$filefrom;<br />
    }<br />
   PHP_Write($fileto,$data);<br />
   return true;<br />
    }<br />
   ?></p>
<p>指定条件信息数量检索函数 </p>
<p>    //指定条件信息数量检索函数<br />
   function rec_exist($table,$where){<br />
   $query=&#8221;select count(*) as num from $table &#8220;.$where;<br />
   $result=mysql_query($query) or die(nerror(1));<br />
   $rowcount=mysql_fetch_array($result);<br />
   $num=$rowcount["num"];<br />
   if ($num==0){<br />
   return false;<br />
    }<br />
   return $num;<br />
    }<br />
   ?></p>
<p>目录删除函数 </p>
<p>   //目录删除函数<br />
   function del_DIR($directory){<br />
   $mydir=dir($directory);<br />
   while($file=$mydir->read()){<br />
   if((is_dir(&#8220;$directory/$file&#8221;)) AND ($file!=&#8221;.&#8221;) AND ($file!=&#8221;..&#8221;)){<br />
   del_DIR(&#8220;$directory/$file&#8221;);<br />
    }else{<br />
   if(($file!=&#8221;.&#8221;) AND ($file!=&#8221;..&#8221;)){<br />
   unlink(&#8220;$directory/$file&#8221;);<br />
   //echo &#8220;unlink $directory/$file ok &#8220;;<br />
    }<br />
    }<br />
    }<br />
   $mydir->close();<br />
   rmdir($directory);<br />
   //echo &#8220;rmdir $directory ok &#8220;;<br />
    }<br />
   ?></p>
<p>目录名称合法性检测函数 </p>
<p>   //目录名称合法性检测<br />
   function isen($str){<br />
   $ret=&#8221;";<br />
   for($i=0;$i   $p=ord(substr($str,$i,1));<br />
   if(($p<48 &#038; $p!=45 &#038; $p!=46) || ($p>57 &#038; $p<65) || ($p>90 &#038; $p<97 &#038; $p!=95) || $p>122){<br />
   nerror(&#8220;不符合规范！&#8221;);<br />
    }<br />
   $ret.=chr($p);<br />
    }<br />
   return $ret;<br />
    }<br />
   ?><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
分页函数 </p>
<p>   //分页函数<br />
   function splitlist($HALT,$LRLIST,$ECHOCNT,$paper,$table,$where,$page_id,$userid){<br />
   global $splitstr,$sumcnt;<br />
   if($paper==&#8221;" || $sumcnt==&#8221;"){<br />
   $query = &#8220;select count(*) as num from $table $where&#8221;;<br />
   $result = mysql_query($query);<br />
   $row = mysql_fetch_array($result);<br />
   $sumcnt=$row["num"];<br />
   if($sumcnt==0){<br />
   nerror(&#8220;该版内还没有选择发布新闻 ！&#8221;);<br />
    }<br />
   $paper=1;<br />
    }<br />
   $sumpaper=($sumcnt-$sumcnt%$ECHOCNT)/$ECHOCNT;<br />
   if(($sumcnt%$ECHOCNT)!=0) $sumpaper+=1;<br />
   if($sumpaper==1 &#038;&#038; $HALT==0) return($where);<br />
   $enwhere=base64_encode(base64_encode($where));<br />
   if(($LRLIST*2+1) < $sumpaper){<br />
   if(($paper-$LRLIST) < 2){<br />
   $tract=1;<br />
   $sub=$LRLIST*2+1;<br />
    }else if(($paper+$LRLIST) >= $sumpaper){<br />
   $tract=$sumpaper-($LRLIST*2);<br />
   $sub=$sumpaper;<br />
    }else{<br />
   $tract=$paper-$LRLIST;<br />
   $sub=$paper+$LRLIST;<br />
    }<br />
    }else{<br />
   $tract=1;<br />
   $sub=$sumpaper;<br />
    }<br />
   $uppaper=$paper-1;<br />
   $downpaper=$paper+1;<br />
   $startcnt=($paper-1)*$ECHOCNT;<br />
   $where.=&#8221; limit ${ startcnt },${ ECHOCNT }&#8221;;<br />
   if($tract > 1) { $splitstr=&#8221;【 << "; }<br />
   else $splitstr="【 << ";<br />
   for($i=$tract;$i<=$sub;$i++){<br />
   if ($i!=$paper) $splitstr.="".$i." ";<br />
   else $splitstr.="".$i." ";<br />
    }<br />
   if ($sub!=$sumpaper) $splitstr.=">> 】&#8221;;<br />
   else $splitstr.=&#8221;>> 】&#8221;;<br />
   return($where);<br />
    }<br />
   ?></p>
<p>关于分页函数的使用说明  </p>
<p>    /*<br />
   #### 检索分页函数 ####<br />
   Int $HALT &#8211; 检索结果仅分1页时是否(1/0)显示页码条<br />
   Int $LRLIST &#8211; (页码条显示页码数-1)/2<br />
   Int $ECHOCNT &#8211; 检索时每页显示记录的数量<br />
   Int $paper &#8211; 页数，预提取：$paper=$HTTP_GET_VARS[paper];<br />
   Varchar $table &#8211; 数据表名,预附值：$table=&#8221;db.table&#8221;;<br />
   Varchar $where &#8211; 检索条件，预附值：$where=&#8221;where field=&#8217;value&#8217;&#8221;;<br />
   Varchar $enwhere &#8211; 将原$where进行两次base64_encode()编码后以GET的方式提交<br />
   Varchar $splitstr &#8211; 页码条输出字串，执行函数后在相应的位置执行 echo $splitstr;<br />
   函数调用前需获取变量 &#8211;<br />
   $paper=$HTTP_GET_VARS[paper];<br />
   $sumcnt=$HTTP_GET_VARS[sumcnt];<br />
   $enwhere=$HTTP_GET_VARS[enwhere];<br />
   Return (Varchar $where) &#8211; 分页后检索语句的检索条件<br />
   注意：本函数需调用出错处理函数 nerror($error);<br />
   */<br />
   ?><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
图片文件上传函数</p>
<p>   //图片文件上传函数<br />
   function upload_img($UploadFile,$UploadFile_name,$UploadFile_size,$UploadPath,$max_size=64){<br />
   //$TimeLimit=60; //设置超时限制时间 缺省时间为 30秒 设置为0时为不限时<br />
   //set_time_limit($TimeLimit);<br />
   if(($UploadFile!= &#8220;none&#8221; )&#038;&#038;($UploadFile != &#8220;&#8221; )){<br />
   $FileName=$UploadPath.$UploadFile_name;<br />
   if($UploadFile_size <1024){<br />
   $FileSize="(string)$UploadFile_size" . "字节";<br />
    }elseif($UploadFile_size <(1024 * $max_size)){<br />
   $FileSize=number_format((double)($UploadFile_size / 1024), 1) . " KB";<br />
    }else{<br />
   nerror("文件超过限制大小！");<br />
    }<br />
   //{<br />
   //$FileSize="number_format((double)($UploadFile_size" / (1024 * 1024)), 1) . " MB";<br />
   // }<br />
   if(!file_exists($FileName)){<br />
   if(copy($UploadFile,$FileName)){<br />
   return "$UploadFile_name ($FileSize)";<br />
    }else{<br />
   nerror("文件 $UploadFile_name 上载失败！");<br />
    }<br />
   unlink($UploadFile);<br />
    }else{<br />
   nerror("文件 $UploadFile_name 已经存在！");<br />
    }<br />
   //set_time_limit(30); //恢复缺省超时设置<br />
    }<br />
    }<br />
   ?></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1030.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>编写安全PHP应用程序的七个习惯</title>
		<link>http://www.evanjiang.net.cn/archives/1027.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1027.html#comments</comments>
		<pubDate>Wed, 13 May 2009 05:43:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1027</guid>
		<description><![CDATA[<p>PHP 应用程序中的安全性包括远程安全性和本地安全性。本文将揭示 PHP 开发人员在实现具有这两种安全性的 Web 应用程序时应该养成的习惯。</p>
<p>在提及安全性问题时，需要注意，除了实际的平台和操作系统安全性问题之外，您还需要确保编写安全的应用程序。在编写 PHP 应用程序时，请应用下面的七个习惯以确保应用程序具有最好的安全性：</p>
<p>验证输入
保护文件系统
保护数据库
保护会话数据
保护跨站点脚本（Cross-site scripting，XSS）漏洞
检验表单 post
针对跨站点请求伪造（Cross-Site Request Forgeries，CSRF）进行保护
在提及安全性问题时，验证数据是您可能采用的最重要的习惯。而在提及输入时，十分简单：不要相信用户。您的用户可能十分优秀，并且大多数用户可能完全按照期望来使用应用程序。但是，只要提供了输入的机会，也就极有可能存在非常糟糕的输入。作为一名应用程序开发人员，您必须阻止应用程序接受错误的输入。仔细考虑用户输入的位置及正确值将使您可以构建一个健壮、安全的应用程序。</p>
<p>虽然后文将介绍文件系统与数据库交互，但是下面列出了适用于各种验证的一般验证提示：</p>
<p>使用白名单中的值
始终重新验证有限的选项
使用内置转义函数
验证正确的数据类型（如数字）
白名单中的值（White-listed value）是正确的值，与无效的黑名单值（Black-listed value）相对。两者之间的区别是，通常在进行验证时，可能值的列表或范围小于无效值的列表或范围，其中许多值可能是未知值或意外值。</p>
<p>在进行验证时，记住设计并验证应用程序允许使用的值通常比防止所有未知值更容易。例如，要把字段值限定为所有数字，需要编写一个确保输入全都是数字的例程。不要编写用于搜索非数字值并在找到非数字值时标记为无效的例程。</p>
<p>保护文件系统</p>
<p>2000 年 7 月，一个 Web 站点泄露了保存在 Web 服务器的文件中的客户数据。该 Web 站点的一个访问者使用 URL 查看了包含数据的文件。虽然文件被放错了位置，但是这个例子强调了针对攻击者保护文件系统的重要性。</p>
<p>如果 PHP 应用程序对文件进行了任意处理并且含有用户可以输入的变量数据，请仔细检查用户输入以确保用户无法对文件系统执行任何不恰当的操作。清单 1 显示了下载具有指定名的图像的 PHP 站点示例。
</p>
<p>清单 1. 下载文件</p>
<p>]]></description>
			<content:encoded><![CDATA[<p>PHP 应用程序中的安全性包括远程安全性和本地安全性。本文将揭示 PHP 开发人员在实现具有这两种安全性的 Web 应用程序时应该养成的习惯。</p>
<p>在提及安全性问题时，需要注意，除了实际的平台和操作系统安全性问题之外，您还需要确保编写安全的应用程序。在编写 PHP 应用程序时，请应用下面的七个习惯以确保应用程序具有最好的安全性：</p>
<p>验证输入<br />
保护文件系统<br />
保护数据库<br />
保护会话数据<br />
保护跨站点脚本（Cross-site scripting，XSS）漏洞<br />
检验表单 post<br />
针对跨站点请求伪造（Cross-Site Request Forgeries，CSRF）进行保护<br />
在提及安全性问题时，验证数据是您可能采用的最重要的习惯。而在提及输入时，十分简单：不要相信用户。您的用户可能十分优秀，并且大多数用户可能完全按照期望来使用应用程序。但是，只要提供了输入的机会，也就极有可能存在非常糟糕的输入。作为一名应用程序开发人员，您必须阻止应用程序接受错误的输入。仔细考虑用户输入的位置及正确值将使您可以构建一个健壮、安全的应用程序。</p>
<p>虽然后文将介绍文件系统与数据库交互，但是下面列出了适用于各种验证的一般验证提示：</p>
<p>使用白名单中的值<br />
始终重新验证有限的选项<br />
使用内置转义函数<br />
验证正确的数据类型（如数字）<br />
白名单中的值（White-listed value）是正确的值，与无效的黑名单值（Black-listed value）相对。两者之间的区别是，通常在进行验证时，可能值的列表或范围小于无效值的列表或范围，其中许多值可能是未知值或意外值。</p>
<p>在进行验证时，记住设计并验证应用程序允许使用的值通常比防止所有未知值更容易。例如，要把字段值限定为所有数字，需要编写一个确保输入全都是数字的例程。不要编写用于搜索非数字值并在找到非数字值时标记为无效的例程。</p>
<p>保护文件系统</p>
<p>2000 年 7 月，一个 Web 站点泄露了保存在 Web 服务器的文件中的客户数据。该 Web 站点的一个访问者使用 URL 查看了包含数据的文件。虽然文件被放错了位置，但是这个例子强调了针对攻击者保护文件系统的重要性。</p>
<p>如果 PHP 应用程序对文件进行了任意处理并且含有用户可以输入的变量数据，请仔细检查用户输入以确保用户无法对文件系统执行任何不恰当的操作。清单 1 显示了下载具有指定名的图像的 PHP 站点示例。<br />
<span id="more-1027"></span></p>
<p>清单 1. 下载文件</p>
<p><?php<br />
if ($_POST['submit'] == 'Download') {<br />
    $file = $_POST['fileName'];<br />
    header("Content-Type: application/x-octet-stream");<br />
    header("Content-Transfer-Encoding: binary");<br />
    header("Content-Disposition: attachment; filename=\"" . $file . "\";" );<br />
    $fh = fopen($file, 'r');<br />
    while (! feof($fh))<br />
    {<br />
        echo(fread($fh, 1024));<br />
    }<br />
    fclose($fh);<br />
} else {<br />
    echo("<html><head><");<br />
        echo("title>Guard your filesystem</title></head>&#8220;);<br />
    echo(&#8220;<body><br />
<form id=\"myFrom\" action=\"" . $_SERVER['PHP_SELF'] .<br />
        "\" method=\"post\">&#8220;);<br />
    echo(&#8220;
<div>
<input type=\"text\" name=\"fileName\" value=\"");<br />
    echo(isset($_REQUEST['fileName']) ? $_REQUEST['fileName'] : '');<br />
    echo("\" />&#8220;);<br />
    echo(&#8220;<br />
<input type=\"submit\" value=\"Download\" name=\"submit\" /></div>
<p>&#8220;);<br />
    echo(&#8220;</p></form>
<p></body></html>&#8220;);<br />
}<br />
正如您所见，清单 1 中比较危险的脚本将处理 Web 服务器拥有读取权限的所有文件，包括会话目录中的文件（请参阅 “保护会话数据”），甚至还包括一些系统文件（例如 /etc/passwd）。为了进行演示，这个示例使用了一个可供用户键入文件名的文本框，但是可以在查询字符串中轻松地提供文件名。</p>
<p>同时配置用户输入和文件系统访问权十分危险，因此最好把应用程序设计为使用数据库和隐藏生成的文件名来避免同时配置。但是，这样做并不总是有效。清单 2 提供了验证文件名的示例例程。它将使用正则表达式以确保文件名中仅使用有效字符，并且特别检查圆点字符：..。</p>
<p>清单 2. 检查有效的文件名字符</p>
<p>function isValidFileName($file) {<br />
    /* don&#8217;t allow .. and allow any &#8220;word&#8221; character \ / */<br />
    return preg_match(&#8216;/^(((?:\.)(?!\.))|\w)+$/&#8217;, $file);<br />
}</p>
<p>保护数据库</p>
<p>2008 年 4 月，美国某个州的狱政局在查询字符串中使用了 SQL 列名，因此泄露了保密数据。这次泄露允许恶意用户选择需要显示的列、提交页面并获得数据。这次泄露显示了用户如何能够以应用程序开发人员无法预料的方法执行输入，并表明了防御 SQL 注入攻击的必要性。</p>
<p>清单 3 显示了运行 SQL 语句的示例脚本。在本例中，SQL 语句是允许相同攻击的动态语句。此表单的所有者可能认为表单是安全的，因为他们已经把列名限定为选择列表。但是，代码疏忽了关于表单欺骗的最后一个习惯 — 代码将选项限定为下拉框并不意味着其他人不能够发布含有所需内容的表单（包括星号 [*]）。</p>
<p>清单 3. 执行 SQL 语句</p>
<p><html><br />
<head></p>
<p></head><br />
<body></p>
<form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>&#8221;<br />
    method=&#8221;post&#8221;></p>
<div>
<input type="text" name="account_number"<br />
    value="<?php echo(isset($_POST['account_number']) ?<br />
        $_POST['account_number'] : ''); ?>&#8221; /></p>
<select name="col">
<option value="account_number">Account Number</option>
<option value="name">Name</option>
<option value="address">Address</option>
</select>
<input type="submit" value="Save" name="submit" /></div>
</form>
<p><?php<br />
if ($_POST['submit'] == 'Save') {<br />
    /* do the form processing */<br />
    $link = mysql_connect('hostname', 'user', 'password') or<br />
        die ('Could not connect' . mysql_error());<br />
    mysql_select_db('test', $link);</p>
<p>  $col = $_POST['col'];</p>
<p>    $select = "SELECT " . $col . " FROM account_data WHERE account_number = "<br />
        . $_POST['account_number'] . ";" ;<br />
    echo '
<p>&#8216; . $select . &#8216;</p>
<p>&#8216;;</p>
<p>    $result = mysql_query($select) or die(&#8216;
<p>&#8216; . mysql_error() . &#8216;</p>
<p>&#8216;);</p>
<p>    echo &#8216;<br />
<table>&#8216;;<br />
    while ($row = mysql_fetch_assoc($result)) {<br />
        echo &#8216;<br />
<tr>&#8216;;<br />
        echo &#8216;
<td>&#8216; . $row[$col] . &#8216;</td>
<p>&#8216;;<br />
        echo &#8216;</tr>
<p>&#8216;;<br />
    }<br />
    echo &#8216;</table>
<p>&#8216;;</p>
<p>    mysql_close($link);<br />
}<br />
?><br />
</body><br />
</html><br />
因此，要形成保护数据库的习惯，请尽可能避免使用动态 SQL 代码。如果无法避免动态 SQL 代码，请不要对列直接使用输入。清单 4 显示了除使用静态列外，还可以向帐户编号字段添加简单验证例程以确保输入值不是非数字值。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>清单 4. 通过验证和 mysql_real_escape_string() 提供保护</p>
<p><html><br />
<head></p>
<p></head><br />
<body></p>
<form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>&#8221;<br />
    method=&#8221;post&#8221;></p>
<div>
<input type="text" name="account_number"<br />
    value="<?php echo(isset($_POST['account_number']) ?<br />
        $_POST['account_number'] : ''); ?>&#8221; /><br />
<input type="submit"<br />
    value="Save" name="submit" /></div>
</form>
<p><?php<br />
function isValidAccountNumber($number)<br />
{<br />
    return is_numeric($number);<br />
}</p>
<p>if ($_POST['submit'] == 'Save') {</p>
<p>    /* Remember habit #1--validate your data! */<br />
    if (isset($_POST['account_number']) &#038;&#038;<br />
    isValidAccountNumber($_POST['account_number'])) {</p>
<p>        /* do the form processing */<br />
        $link = mysql_connect('hostname', 'user', 'password') or<br />
        die ('Could not connect' . mysql_error());<br />
        mysql_select_db('test', $link);</p>
<p>        $select = sprintf("SELECT account_number, name, address " .<br />
  " FROM account_data WHERE account_number = %s;",<br />
        mysql_real_escape_string($_POST['account_number']));<br />
        echo '
<p>&#8216; . $select . &#8216;</p>
<p>&#8216;;</p>
<p>        $result = mysql_query($select) or die(&#8216;
<p>&#8216; . mysql_error() . &#8216;</p>
<p>&#8216;);</p>
<p>        echo &#8216;<br />
<table>&#8216;;<br />
        while ($row = mysql_fetch_assoc($result)) {<br />
            echo &#8216;<br />
<tr>&#8216;;<br />
            echo &#8216;
<td>&#8216; . $row['account_number'] . &#8216;</td>
<p>&#8216;;<br />
            echo &#8216;
<td>&#8216; . $row['name'] . &#8216;</td>
<p>&#8216;;<br />
            echo &#8216;
<td>&#8216; . $row['address'] . &#8216;</td>
<p>&#8216;;<br />
            echo &#8216;</tr>
<p>&#8216;;<br />
        }<br />
        echo &#8216;</table>
<p>&#8216;;</p>
<p>        mysql_close($link);<br />
    } else {<br />
        echo &#8220;<span style=\"font-color:red\">&#8221; .<br />
    &#8220;Please supply a valid account number!</span>&#8220;;</p>
<p>    }<br />
}<br />
?><br />
</body><br />
</html><br />
本例还展示了 mysql_real_escape_string() 函数的用法。此函数将正确地过滤您的输入，因此它不包括无效字符。如果您一直依赖于 magic_quotes_gpc，那么需要注意它已被弃用并且将在 PHP V6 中删除。从现在开始应避免使用它并在此情况下编写安全的 PHP 应用程序。此外，如果使用的是 ISP，则有可能您的 ISP 没有启用 magic_quotes_gpc。</p>
<p>最后，在改进的示例中，您可以看到该 SQL 语句和输出没有包括动态列选项。使用这种方法，如果把列添加到稍后含有不同信息的表中，则可以输出这些列。如果要使用框架以与数据库结合使用，则您的框架可能已经为您执行了 SQL 验证。确保查阅文档以保证框架的安全性；如果仍然不确定，请进行验证以确保稳妥。即使使用框架进行数据库交互，仍然需要执行其他验证。</p>
<p>保护会话</p>
<p>默认情况下，PHP 中的会话信息将被写入临时目录。考虑清单 5 中的表单，该表单将显示如何存储会话中的用户 ID 和帐户编号。</p>
<p>清单 5. 存储会话中的数据</p>
<p><?php<br />
session_start();<br />
?><br />
<html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
if ($_POST['submit'] == 'Save') {<br />
    $_SESSION['userName'] = $_POST['userName'];<br />
    $_SESSION['accountNumber'] = $_POST['accountNumber'];<br />
}<br />
?></p>
<form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>&#8221;<br />
    method=&#8221;post&#8221;></p>
<div>
<input type="hidden" name="token" value="<?php echo $token; ?>&#8221; /></p>
<input type="text" name="userName"<br />
    value="<?php echo(isset($_POST['userName']) ? $_POST['userName'] : ''); ?>&#8221; /><br />
</p>
<input type="text" name="accountNumber"<br />
    value="<?php echo(isset($_POST['accountNumber']) ?<br />
    $_POST['accountNumber'] : ''); ?>&#8221; /><br />
</p>
<input type="submit" value="Save" name="submit" /></div>
</form>
<p></body><br />
</html></p>
<p>清单 6 显示了 /tmp 目录的内容。<br />
清单 6. /tmp 目录中的会话文件</p>
<p>-rw&#8212;&#8212;-  1 _www    wheel       97 Aug 18 20:00 sess_9e4233f2cd7cae35866cd8b61d9fa42b</p>
<p>正如您所见，在输出时（参见清单 7），会话文件以非常易读的格式包含信息。由于该文件必须可由 Web 服务器用户读写，因此会话文件可能为共享服务器中的所有用户带来严重的问题。除您之外的某个人可以编写脚本来读取这些文件，因此可以尝试从会话中取出值。</p>
<p>清单 7. 会话文件的内容</p>
<p>userName|s:5:&#8221;ngood&#8221;;accountNumber|s:9:&#8221;123456789&#8243;;</p>
<p> 存储密码</p>
<p>不管是在数据库、会话、文件系统中，还是在任何其他表单中，无论如何密码都决不能存储为纯文本。处理密码的最佳方法是将其加密存储并相互比较加密的密码。虽然如此，在实践中人们仍然把密码存储到纯文本中。只要使用可以发送密码而非重置密码的 Web 站点，就意味着密码是存储在纯文本中或者可以获得用于解密的代码（如果加密的话）。即使是后者，也可以找到并使用解密代码。</p>
<p>您可以采取两项操作来保护会话数据。第一是把您放入会话中的所有内容加密。但是正因为加密数据并不意味着绝对安全，因此请慎重采用这种方法作为保护会话的惟一方式。备选方法是把会话数据存储在其他位置中，比方说数据库。您仍然必须确保锁定数据库，但是这种方法将解决两个问题：第一，它将把数据放到比共享文件系统更加安全的位置；第二，它将使您的应用程序可以更轻松地跨越多个 Web 服务器，同时共享会话可以跨越多个主机。</p>
<p>要实现自己的会话持久性，请参阅 PHP 中的 session_set_save_handler() 函数。使用它，您可以将会话信息存储在数据库中，也可以实现一个用于加密和解密所有数据的处理程序。清单 8 提供了实现的函数用法和函数骨架示例。您还可以在 参考资料 小节中查看如何使用数据库。</p>
<p>清单 8. session_set_save_handler() 函数示例</p>
<p>function open($save_path, $session_name)<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>function close()<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>function read($id)<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>function write($id, $sess_data)<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>function destroy($id)<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>function gc($maxlifetime)<br />
{<br />
    /* custom code */<br />
    return (true);<br />
}</p>
<p>session_set_save_handler(&#8220;open&#8221;, &#8220;close&#8221;, &#8220;read&#8221;, &#8220;write&#8221;, &#8220;destroy&#8221;, &#8220;gc&#8221;);</p>
<p>针对 XSS 漏洞进行保护</p>
<p>XSS 漏洞代表 2007 年所有归档的 Web 站点的大部分漏洞（请参阅 参考资料）。当用户能够把 HTML 代码注入到您的 Web 页面中时，就是出现了 XSS 漏洞。HTML 代码可以在脚本标记中携带 JavaScript 代码，因而只要提取页面就允许运行 JavaScript。清单 9 中的表单可以表示论坛、维基、社会网络或任何可以输入文本的其他站点。</p>
<p>清单 9. 输入文本的表单</p>
<p><html><br />
<head></p>
<p></head><br />
<body></p>
<form id="myFrom" action="showResults.php" method="post">
<div><textarea name="myText" rows="4" cols="30"></textarea></p>
<input type="submit" value="Delete" name="submit" /></div>
</form>
<p></body><br />
</html></p>
<p>清单 10 演示了允许 XSS 攻击的表单如何输出结果。</p>
<p>清单 10. showResults.php</p>
<p><html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
echo("
<p>You typed this:</p>
<p>&#8220;);<br />
echo(&#8220;
<p>&#8220;);<br />
echo($_POST['myText']);<br />
echo(&#8220;</p>
<p>&#8220;);<br />
?><br />
</body><br />
</html><br />
清单 11 提供了一个基本示例，在该示例中将弹出一个新窗口并打开 Google 的主页。如果您的 Web 应用程序不针对 XSS 攻击进行保护，则会造成严重的破坏。例如，某个人可以添加模仿站点样式的链接以达到欺骗（phishing）目的（请参阅 参考资料）。</p>
<p>清单 11. 恶意输入文本样例</p>
<p><script type="text/javascript">myRef = window.open('http://www.google.com','mywin',
'left=20,top=20,width=500,height=500,toolbar=1,resizable=0');</script></p>
<p>要防止受到 XSS 攻击，只要变量的值将被打印到输出中，就需要通过 htmlentities() 函数过滤输入。记住要遵循第一个习惯：在 Web 应用程序的名称、电子邮件地址、电话号码和帐单信息的输入中用白名单中的值验证输入数据。</p>
<p>下面显示了更安全的显示文本输入的页面。</p>
<p>清单 12. 更安全的表单</p>
<p><html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
echo("
<p>You typed this:</p>
<p>&#8220;);<br />
echo(&#8220;
<p>&#8220;);<br />
echo(htmlentities($_POST['myText']));<br />
echo(&#8220;</p>
<p>&#8220;);<br />
?><br />
</body><br />
</html></p>
<p>针对无效 post 进行保护</p>
<p>表单欺骗 是指有人把 post 从某个不恰当的位置发到您的表单中。欺骗表单的最简单方法就是创建一个通过提交至表单来传递所有值的 Web 页面。由于 Web 应用程序是没有状态的，因此没有一种绝对可行的方法可以确保所发布数据来自指定位置。从 IP 地址到主机名，所有内容都是可以欺骗的。清单 13 显示了允许输入信息的典型表单。</p>
<p>清单 13. 处理文本的表单</p>
<p><html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
if ($_POST['submit'] == 'Save') {<br />
    echo("
<p>I am processing your text: &#8220;);<br />
    echo($_POST['myText']);<br />
    echo(&#8220;</p>
<p>&#8220;);<br />
}<br />
?><br />
</body><br />
</html></p>
<p>清单 14 显示了将发布到清单 13 所示表单中的表单。要尝试此操作，您可以把该表单放到 Web 站点中，然后把清单 14 中的代码另存为桌面上的 HTML 文档。在保存表单后，在浏览器中打开该表单。然后可以填写数据并提交表单，从而观察如何处理数据。</p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
清单 14. 收集数据的表单</p>
<p><html><br />
<head></p>
<p></head><br />
<body></p>
<form action="processStuff.php" method="post">
<select name="answer">
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
<input type="submit" value="Save" name="submit" />
</form>
<p></body><br />
</html><br />
表单欺骗的潜在影响是，如果拥有含下拉框、单选按钮、复选框或其他限制输入的表单，则当表单被欺骗时这些限制没有任何意义。考虑清单 15 中的代码，其中包含带有无效数据的表单。</p>
<p>清单 15. 带有无效数据的表单</p>
<p><html><br />
<head></p>
<p></head><br />
<body></p>
<form action="http://path.example.com/processStuff.php"<br />
    method="post"><br />
<input type="text" name="answer"<br />
    value="There is no way this is a valid response to a yes/no answer..." /><br />
<input type="submit" value="Save" name="submit" />
</form>
<p></body><br />
</html><br />
思考一下：如果拥有限制用户输入量的下拉框或单选按钮，您可能会认为不用担心验证输入的问题。毕竟，输入表单将确保用户只能输入某些数据，对吧？要限制表单欺骗，需要进行验证以确保发布者的身份是真实的。您可以使用一种一次性使用标记，虽然这种技术仍然不能确保表单绝对安全，但是会使表单欺骗更加困难。由于在每次调用表单时都会更改标记，因此想要成为攻击者就必须获得发送表单的实例，去掉标记，并把它放到假表单中。使用这项技术可以阻止恶意用户构建持久的 Web 表单来向应用程序发布不适当的请求。清单 16 提供了一种表单标记示例。</p>
<p>清单 16. 使用一次性表单标记</p>
<p><?php<br />
session_start();<br />
?><br />
<html><br />
<head></p>
<p></head><br />
<body><br />
<?php</p>
<p>echo 'Session token=' . $_SESSION['token'];<br />
echo '<br />&#8216;;<br />
echo &#8216;Token from form=&#8217; . $_POST['token'];<br />
echo &#8216;<br />&#8216;;</p>
<p>if ($_SESSION['token'] == $_POST['token']) {<br />
    /* cool, it&#8217;s all good&#8230; create another one */</p>
<p>} else {<br />
    echo &#8216;<br />
<h1>Go away!</h1>
<p>&#8216;;<br />
}<br />
$token = md5(uniqid(rand(), true));<br />
$_SESSION['token'] = $token;<br />
?></p>
<form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>&#8221;<br />
    method=&#8221;post&#8221;></p>
<div>
<input type="hidden" name="token" value="<?php echo $token; ?>&#8221; /></p>
<input type="text" name="myText"<br />
    value="<?php echo(isset($_POST['myText']) ? $_POST['myText'] : ''); ?>&#8221; /></p>
<input type="submit" value="Save" name="submit" /></div>
</form>
<p></body><br />
</html></p>
<p>针对 CSRF 进行保护</p>
<p>跨站点请求伪造（CSRF 攻击）是利用用户权限执行攻击的结果。在 CSRF 攻击中，您的用户可以轻易地成为预料不到的帮凶。清单 17 提供了执行特定操作的页面示例。此页面将从 cookie 中查找用户登录信息。只要 cookie 有效，Web 页面就会处理请求。</p>
<p>清单 17. CSRF 示例</p>
<p><img src="http://www.example.com/processSomething?id=123456789" /><br />
CSRF 攻击通常是以 <img> 标记的形式出现的，因为浏览器将在不知情的情况下调用该 URL 以获得图像。但是，图像来源可以是根据传入参数进行处理的同一个站点中的页面 URL。当此 <img> 标记与 XSS 攻击结合在一起时 — 在已归档的攻击中最常见 — 用户可以在不知情的情况下轻松地对其凭证执行一些操作 — 因此是伪造的。</p>
<p>为了保护您免受 CSRF 攻击，需要使用在检验表单 post 时使用的一次性标记方法。此外，使用显式的 $_POST 变量而非 $_REQUEST。清单 18 演示了处理相同 Web 页面的糟糕示例 — 无论是通过 GET 请求调用页面还是通过把表单发布到页面中。</p>
<p>清单 18. 从 $_REQUEST 中获得数据</p>
<p><html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
if ($_REQUEST['submit'] == 'Save') {<br />
    echo("
<p>I am processing your text: &#8220;);<br />
    echo(htmlentities($_REQUEST['text']));<br />
    echo(&#8220;</p>
<p>&#8220;);<br />
}<br />
?><br />
</body><br />
</html></p>
<p>清单 19 显示了只使用表单 POST 的干净页面。</p>
<p>清单 19. 仅从 $_POST 中获得数据</p>
<p><html><br />
<head></p>
<p></head><br />
<body><br />
<?php<br />
if ($_POST['submit'] == 'Save') {<br />
    echo("
<p>I am processing your text: &#8220;);<br />
    echo(htmlentities($_POST['text']));<br />
    echo(&#8220;</p>
<p>&#8220;);<br />
}<br />
?><br />
</body><br />
</html></p>
<p>结束语</p>
<p>从这七个习惯开始尝试编写更安全的 PHP Web 应用程序，可以帮助您避免成为恶意攻击的受害者。和许多其他习惯一样，这些习惯最开始可能很难适应，但是随着时间的推移遵循这些习惯会变得越来越自然。</p>
<p>记住第一个习惯是关键：验证输入。在确保输入不包括无效值之后，可以继续保护文件系统、数据库和会话。最后，确保 PHP 代码可以抵抗 XSS 攻击、表单欺骗和 CSRF 攻击。形成这些习惯后可以帮助您抵御一些简单的攻击。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1027.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP上传、生成缩略图、生成文字水印和图片水印的程序代码</title>
		<link>http://www.evanjiang.net.cn/archives/1021.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1021.html#comments</comments>
		<pubDate>Mon, 11 May 2009 05:41:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/archives/1021.html</guid>
		<description><![CDATA[<p>]]></description>
			<content:encoded><![CDATA[<p><?php<br />
/*<br />
'-##########################################      |<br />
'|    结合自己以前做的上传和生成缩略和改编一个<br />
'|    老前辈的生成图片水印做成这个                |<br />
'|    上传+生成缩略图+生成文字水印和图片水印      |<br />
'|    可以直接引用                            |<br />
'-##########################################-|<br />
*/<br />
//审明图片文件夹<br />
$bigfolder="img";<br />
$smallfolder="smallimg";<br />
//审明文件夹名称 以年月日来建议文件夹<br />
$fdate=date("Ymd");<br />
//echo $fdate;<br />
//审明文件名称。以年月日时分秒命名<br />
$fname=date("YmdHis");<br />
$bigname="0724e_com_".$fname;<br />
$smallname="0724e_com_".$fname."_s";<br />
//echo $fname."<br/>&#8220;.$bigname.&#8221;<br/>&#8220;.$smallname;<br />
//确定大小文件夹的名称和路经<br />
$bigaddrname=$bigfolder.&#8221;/&#8221;.$fdate.&#8221;/&#8221;.$bigname;<br />
$smalladdrname=$smallfolder.&#8221;/&#8221;.$fdate.&#8221;/&#8221;.$smallname;<br />
//审明小图片的高度和宽度<br />
$RESIZEWIDTH=180;<br />
$RESIZEHEIGHT=150;<br />
//审明水印的文字或图片的地址及字体的地址<br />
$imgaddr=&#8221;img.jpg&#8221;;    //图片水印<br />
$fontname=&#8221;www.0724e.com&#8221;;  //文字水印<br />
//充许上传的文件扩展名<br />
$exit_name=array(&#8220;.jpg&#8221;,&#8221;.gif&#8221;,&#8221;.png&#8221;);<br />
if (isset($_POST['Submit'])){<br />
//上传部分&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
//定议上传名称和上传错误<br />
$upfile=$_FILES['image']['name'];<br />
$uperror=$_FILES['image']['error'];<br />
//最简表单验证</p>
<p>switch ($uperror) {<br />
  case 1:<br />
      die(&#8220;
<div align=\"center\">上传真过PHP设置充许的最大值<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);<br />
  break;<br />
  case 2:<br />
  die(&#8220;
<div align=\"center\">上传超过了表单充许的最大值<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);<br />
  break;<br />
  case 3:<br />
  die(&#8220;
<div align=\"center\">文件只有部分被上传了<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);<br />
    break;<br />
  case 4:<br />
  die(&#8220;
<div align=\"center\">文件不有被上传<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);<br />
    break;<br />
}<br />
<span id="more-1021"></span><br />
//检测扩展是否是充许上传的文件类型<br />
//取得文件扩展名<br />
$exname=strrchr($upfile,&#8221;.&#8221;);<br />
//判断取得扩展名是否在要求的扩展名内<br />
if(!in_array($exname,$exit_name))<br />
die(&#8220;
<div align=\"center\">文件扩展名不对。只允许上传jpg gif png的图片<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);</p>
<p>//检测存放图片的目录和子目录是否存在，如果不存在则建目录和子目录，并给目录最大权限777 对LINUX或unix对WINDOWS没必要<br />
//大图<br />
if (!file_exists($bigfolder)){<br />
  mkdir($bigfolder,0777);<br />
  mkdir($bigfolder.&#8221;/&#8221;.$fdate,0777);<br />
}else{<br />
  if (!file_exists($bigfolder.&#8221;/&#8221;.$fdate)){<br />
  mkdir($bigfolder.&#8221;/&#8221;.$fdate,0777);<br />
  }<br />
}<br />
//缩略图<br />
if (!file_exists($smallfolder)){<br />
  mkdir($smallfolder,0777);<br />
  mkdir($smallfolder.&#8221;/&#8221;.$fdate,0777);<br />
}else{<br />
  if (!file_exists($smallfolder.&#8221;/&#8221;.$fdate)){<br />
  mkdir($smallfolder.&#8221;/&#8221;.$fdate,0777);<br />
  }<br />
}<br />
//创建目录结束</p>
<p>//得到临时上传的文件<br />
$upfiletmp=$_FILES['image']['tmp_name'];<br />
//判断临时文件是否存在<br />
if ($uperror==6)<br />
die(&#8220;
<div align=\"center\">找不到临时上传文件，上传失败<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);</p>
<p>//水印部分==========================================<br />
//水印函数开始============<br />
/**      $groundImage    背景图片，即需要加水印的图片，暂只支持GIF,JPG,PNG格式；<br />
*      $waterPos      水印位置，有10种状态，0为随机位置；<br />
*                      1为顶端居左，2为顶端居中，3为顶端居右；<br />
*                      4为中部居左，5为中部居中，6为中部居右；<br />
*                      7为底端居左，8为底端居中，9为底端居右；<br />
*      $waterImage    图片水印，即作为水印的图片，暂只支持GIF,JPG,PNG格式；<br />
*      $waterText      文字水印，即把文字作为为水印，支持ASCII码，不支持中文；<br />
*      $textFont      文字大小，值为1、2、3、4或5，默认为5；<br />
*      $textColor      文字颜色，值为十六进制颜色值，默认为#FF0000(红色)；<br />
* */</p>
<p>function imageWaterMark($groundImage,$waterPos=0,$waterImage=&#8221;",$waterText=&#8221;", $textFont=5,$textColor=&#8221;#FF0000&#8243;)<br />
{<br />
    $isWaterImage = FALSE;<br />
    $formatMsg = &#8220;暂不支持该文件格式，请用图片处理软件将图片转换为GIF、JPG、PNG格式。&#8221;; </p>
<p>    //读取水印文件<br />
    if(!empty($waterImage) &#038;&#038; file_exists($waterImage)) {<br />
        $isWaterImage = TRUE;<br />
        $water_info = getimagesize($waterImage);<br />
        $water_w    = $water_info[0];//取得水印图片的宽<br />
        $water_h    = $water_info[1];//取得水印图片的高 </p>
<p>        switch($water_info[2])  {  //取得水印图片的格式<br />
            case 1:$water_im = imagecreatefromgif($waterImage);break;<br />
            case 2:$water_im = imagecreatefromjpeg($waterImage);break;<br />
            case 3:$water_im = imagecreatefrompng($waterImage);break;<br />
            default:die($formatMsg);<br />
        }<br />
    } </p>
<p>    //读取背景图片<br />
    if(!empty($groundImage) &#038;&#038; file_exists($groundImage)) {<br />
        $ground_info = getimagesize($groundImage);<br />
        $ground_w    = $ground_info[0];//取得背景图片的宽<br />
        $ground_h    = $ground_info[1];//取得背景图片的高 </p>
<p>        switch($ground_info[2]) {  //取得背景图片的格式<br />
            case 1:$ground_im = imagecreatefromgif($groundImage);break;<br />
            case 2:$ground_im = imagecreatefromjpeg($groundImage);break;<br />
            case 3:$ground_im = imagecreatefrompng($groundImage);break;<br />
            default:die($formatMsg);<br />
        }<br />
    } else {<br />
        die(&#8220;需要加水印的图片不存在！&#8221;);<br />
    } </p>
<p>    //水印位置<br />
    if($isWaterImage) { //图片水印<br />
        $w = $water_w;<br />
        $h = $water_h;<br />
        $label = &#8220;图片的&#8221;;<br />
    } else {  //文字水印<br />
        $temp = imagettfbbox(ceil($textFont*2.5),0,&#8221;./cour.ttf&#8221;,$waterText);//取得使用 TrueType 字体的文本的范围<br />
        $w = $temp[2] &#8211; $temp[6];<br />
        $h = $temp[3] &#8211; $temp[7];<br />
        unset($temp);<br />
        $label = &#8220;文字区域&#8221;;<br />
    }<br />
    if( ($ground_w<$w) || ($ground_h<$h) ) {<br />
        echo "需要加水印的图片的长度或宽度比水印".$label."还小，无法生成水印！";<br />
        return;<br />
    } </p>
<p>    switch($waterPos) {<br />
        case 0://随机<br />
            $posX = rand(0,($ground_w - $w));<br />
            $posY = rand(0,($ground_h - $h));<br />
            break;<br />
        case 1://1为顶端居左<br />
            $posX = 0;<br />
            $posY = 0;<br />
            break;<br />
        case 2://2为顶端居中<br />
            $posX = ($ground_w - $w) / 2;<br />
            $posY = 0;<br />
            break;<br />
        case 3://3为顶端居右<br />
            $posX = $ground_w - $w;<br />
            $posY = 0;<br />
            break;<br />
        case 4://4为中部居左<br />
            $posX = 0;<br />
            $posY = ($ground_h - $h) / 2;<br />
            break;<br />
        case 5://5为中部居中<br />
            $posX = ($ground_w - $w) / 2;<br />
            $posY = ($ground_h - $h) / 2;<br />
            break;<br />
        case 6://6为中部居右<br />
            $posX = $ground_w - $w;<br />
            $posY = ($ground_h - $h) / 2;<br />
            break;<br />
        case 7://7为底端居左<br />
            $posX = 0;<br />
            $posY = $ground_h - $h;<br />
            break;<br />
        case 8://8为底端居中<br />
            $posX = ($ground_w - $w) / 2;<br />
            $posY = $ground_h - $h;<br />
            break;<br />
        case 9://9为底端居右<br />
            $posX = $ground_w - $w;<br />
            $posY = $ground_h - $h;<br />
            break;<br />
        default://随机<br />
            $posX = rand(0,($ground_w - $w));<br />
            $posY = rand(0,($ground_h - $h));<br />
            break;<br />
    }<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    //设定图像的混色模式<br />
    imagealphablending($ground_im, true); </p>
<p>    if($isWaterImage) { //图片水印<br />
        imagecopy($ground_im, $water_im, $posX, $posY, 0, 0, $water_w,$water_h);//拷贝水印到目标文件<br />
    } else {//文字水印<br />
        if( !empty($textColor) &#038;&#038; (strlen($textColor)==7) ) {<br />
            $R = hexdec(substr($textColor,1,2));<br />
            $G = hexdec(substr($textColor,3,2));<br />
            $B = hexdec(substr($textColor,5));<br />
        } else {<br />
            die(&#8220;水印文字颜色格式不正确！&#8221;);<br />
        }<br />
        imagestring ( $ground_im, $textFont, $posX, $posY, $waterText, imagecolorallocate($ground_im, $R, $G, $B));<br />
    } </p>
<p>    //生成水印后的图片<br />
    @unlink($groundImage);<br />
    switch($ground_info[2]) {//取得背景图片的格式<br />
        case 1:imagegif($ground_im,$groundImage);break;<br />
        case 2:imagejpeg($ground_im,$groundImage);break;<br />
        case 3:imagepng($ground_im,$groundImage);break;<br />
        default:die($errorMsg);<br />
    } </p>
<p>    //释放内存<br />
    if(isset($water_info)) unset($water_info);<br />
    if(isset($water_im)) imagedestroy($water_im);<br />
    unset($ground_info);<br />
    imagedestroy($ground_im);<br />
}<br />
//水印函数完</p>
<p>//存在则移动完在上传<br />
$goodupfile=@move_uploaded_file($upfiletmp,$bigaddrname.$exname);<br />
if (!$goodupfile){<br />
die(&#8220;
<div align=\"center\">上传图片失败<a href=\"javascript:history.back();\">点击返回</a></div>
<p>&#8220;);<br />
}else{ </p>
<p>//文字水印<br />
    imageWaterMark($bigaddrname.$exname,5,&#8221;",$fontname,5,&#8221;#FF0000&#8243;); </p>
<p>    //图片水印<br />
    //imageWaterMark($bigaddrname.$exname,5,$imgaddr);<br />
//结束水印部分===================================</p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
//缩略图部分&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
//判断缩略图大小函数&#8212;&#8211;<br />
    function ResizeImage($im,$maxwidth,$maxheight,$name){<br />
    $width = imagesx($im);<br />
    $height = imagesy($im);<br />
    if(($maxwidth &#038;&#038; $width > $maxwidth) || ($maxheight &#038;&#038; $height > $maxheight)){<br />
        if($maxwidth &#038;&#038; $width > $maxwidth){<br />
            $widthratio = $maxwidth/$width;<br />
            $RESIZEWIDTH=true;<br />
        }<br />
        if($maxheight &#038;&#038; $height > $maxheight){<br />
            $heightratio = $maxheight/$height;<br />
            $RESIZEHEIGHT=true;<br />
        }<br />
        if($RESIZEWIDTH &#038;&#038; $RESIZEHEIGHT){<br />
            if($widthratio < $heightratio){<br />
                $ratio = $widthratio;<br />
            }else{<br />
                $ratio = $heightratio;<br />
            }<br />
        }elseif($RESIZEWIDTH){<br />
            $ratio = $widthratio;<br />
        }elseif($RESIZEHEIGHT){<br />
            $ratio = $heightratio;<br />
        }<br />
        $newwidth = $width * $ratio;<br />
        $newheight = $height * $ratio;<br />
        if(function_exists("imagecopyresampled")){<br />
              $newim = imagecreatetruecolor($newwidth, $newheight);<br />
              imagecopyresampled($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);<br />
        }else{<br />
            $newim = imagecreate($newwidth, $newheight);<br />
              imagecopyresized($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);<br />
        }<br />
        ImageJpeg ($newim,$smalladdrname.$name.".jpg");<br />
        ImageDestroy ($newim);<br />
    }else{<br />
        ImageJpeg ($im,$smalladdrname.$name.".jpg");<br />
    }<br />
    }<br />
    //生成部分<br />
    if($_FILES['image']['size']){<br />
    if($_FILES['image']['type'] == "image/pjpeg"){<br />
        $im = imagecreatefromjpeg($bigaddrname.$exname);<br />
    }elseif($_FILES['image']['type'] == "image/x-png"){<br />
        $im = imagecreatefrompng($bigaddrname.$exname);<br />
    }elseif($_FILES['image']['type'] == "image/gif"){<br />
        $im = imagecreatefromgif($bigaddrname.$exname);<br />
    }<br />
    if($im){<br />
        if(file_exists($smalladdrname.".jpg")){<br />
            unlink($smalladdrname.".jpg");<br />
        }<br />
        ResizeImage($im,$RESIZEWIDTH,$RESIZEHEIGHT,$smalladdrname);<br />
        ImageDestroy ($im);<br />
    }<br />
    }<br />
    echo "
<div align='center'><a href='javascript:window.history.back()'>上传成功</a></div>
<p>&#8220;;<br />
}<br />
//缩略图结束&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; </p>
<p>}<br />
?></p>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input type="file" name="image" />
<input type="hidden" name="MAX_FILE_SIZE" value="<?=1024*100?>&#8220;></p>
<input type="submit" name="Submit" value="上传图片" />
</form>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1021.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php如何打开远程的目录</title>
		<link>http://www.evanjiang.net.cn/archives/1019.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1019.html#comments</comments>
		<pubDate>Mon, 11 May 2009 05:40:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1019</guid>
		<description><![CDATA[<p>php如何打开远程的目录</p>
<p>要打开一个远程的ftp目录，然后读取目录下的文件名显示在页面上，请问要怎么做？我用opendir(&#8220;ftp://XXXXX&#8221;)不行啊。看好是打开远程目录，不是文件</p>
<p></p>
<p>具体格式呢，根据自己的需要调整一下就可以</p>
]]></description>
			<content:encoded><![CDATA[<p>php如何打开远程的目录</p>
<p>要打开一个远程的ftp目录，然后读取目录下的文件名显示在页面上，请问要怎么做？我用opendir(&#8220;ftp://XXXXX&#8221;)不行啊。看好是打开远程目录，不是文件</p>
<p><?php</p>
<p>// 创建一个基本的ftp连接<br />
$conn_id = ftp_connect($ftp_server);</p>
<p>// 用正确的用户名跟密码登陆到ftp<br />
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);</p>
<p>// 取得当前目录的内容<br />
$contents = ftp_nlist($conn_id, ".");</p>
<p>// 输出目录的内容<br />
var_dump($contents);</p>
<p>?></p>
<p>具体格式呢，根据自己的需要调整一下就可以</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1019.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php类的使用</title>
		<link>http://www.evanjiang.net.cn/archives/1016.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1016.html#comments</comments>
		<pubDate>Mon, 11 May 2009 05:38:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1016</guid>
		<description><![CDATA[<p>以我的观点来说说PHP中的Class，用于表达的语言都是非正式的语言，也不能确定是否正确。</p>
<p>建立一个类很简单：</p>
<p>class my_class {}</p>
<p>　　类到底干什么呢？很多人都说是什么黑匣子，我在这里称它为一个独立的整体。我们只知道类名，而不知道里面有什么东西。那么，该如何使用这个类呢？
　　首先：要知道它里面是否定义公共的变量－－专业术语上称它为“属性”。
　　其次：要知道它里面定义什么函数－－专业术语中称它为“方法”。
　　我都被这些专业术语搞糊涂，所以干脆不理它。</p>
<p>　　类中的如何定义公共变量，它有什么作用呢？</p>
<p>　　很简单，我们来扩充 my_class 类：</p>
<p>class my_class
{
    var $username;
}</p>
<p>　　看上面很简单，我们定义一个公共的变量，只是用 var+空格+普通变量名 构成。它有什么用呢？考虑一下函数中，如果我们要访问函数外的变量，是不是要先 global 一下呢？这个想实现的效果也是如此，它是想让这个类中的所有函数都能访问它，而它区别于函数的一个地方，是类的外部也可以随时访问和控制这个变量，我随后再讲外部如何访问它。还有一个区别，不能用复杂的语句给这个变量赋值（具体的等理解类以后自己去看规则）。</p>
<p>　　给它一个默认值：</p>
<p>class my_class
{
    var $username = &#8220;小花&#8221;;
}
</p>
<p>　　OK，定义一个公共的变量，接下来定义一个函数（也就是所谓的“方法”）：</p>
<p>class my_class
{
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username()
    {
    }
}</p>
<p>　　这个定义函数跟普通的定义函数形式上没什么区别。简单就好，定义一个打印 $username 的函数：</p>
<p>class my_class
{
    var $username = &#8220;小花&#8221;;</p>
<p>  [...]]]></description>
			<content:encoded><![CDATA[<p>以我的观点来说说PHP中的Class，用于表达的语言都是非正式的语言，也不能确定是否正确。</p>
<p>建立一个类很简单：</p>
<p>class my_class {}</p>
<p>　　类到底干什么呢？很多人都说是什么黑匣子，我在这里称它为一个独立的整体。我们只知道类名，而不知道里面有什么东西。那么，该如何使用这个类呢？<br />
　　首先：要知道它里面是否定义公共的变量－－专业术语上称它为“属性”。<br />
　　其次：要知道它里面定义什么函数－－专业术语中称它为“方法”。<br />
　　我都被这些专业术语搞糊涂，所以干脆不理它。</p>
<p>　　类中的如何定义公共变量，它有什么作用呢？</p>
<p>　　很简单，我们来扩充 my_class 类：</p>
<p>class my_class<br />
{<br />
    var $username;<br />
}</p>
<p>　　看上面很简单，我们定义一个公共的变量，只是用 var+空格+普通变量名 构成。它有什么用呢？考虑一下函数中，如果我们要访问函数外的变量，是不是要先 global 一下呢？这个想实现的效果也是如此，它是想让这个类中的所有函数都能访问它，而它区别于函数的一个地方，是类的外部也可以随时访问和控制这个变量，我随后再讲外部如何访问它。还有一个区别，不能用复杂的语句给这个变量赋值（具体的等理解类以后自己去看规则）。</p>
<p>　　给它一个默认值：</p>
<p>class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;<br />
}<br />
<span id="more-1016"></span></p>
<p>　　OK，定义一个公共的变量，接下来定义一个函数（也就是所谓的“方法”）：</p>
<p>class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username()<br />
    {<br />
    }<br />
}</p>
<p>　　这个定义函数跟普通的定义函数形式上没什么区别。简单就好，定义一个打印 $username 的函数：</p>
<p>class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username($username)<br />
    {<br />
        echo $username;<br />
    }<br />
}</p>
<p>　　到这里可能某些人开始迷糊，呵呵，最关键的就是这里，看清楚。现在有三个 $username 。到底哪个是哪个啊～～</p>
<p>　　函数所带的形参，不用解释吧？这个函数功能就是打印形参所接收的值，也就是如果：</p>
<p>show_username(&#8220;温室小花&#8221;);</p>
<p>　　那么它将打印 “温室小花” ，就这么简单。</p>
<p>　　怎么样访问这个函数？肯定不是我上面说的那样直接 show_username(&#8220;温室小花&#8221;); ，别急，类有类的一套。如下：</p>
<p>$Name = new my_class();</p>
<p>　　这样就初始化上面的那个 my_class 的类，并把这个对象赋给变量 $Name ，你可以这样理解，这个变量就代表整个类，呵呵。</p>
<p>　　使用类中的函数：</p>
<p>$Name->show_username(&#8220;温室小花&#8221;);</p>
<p>　　晕，为什么这么复杂？还要箭头？其实很形象的。本来已经把类给变量 $Name 是吧？也就是 $Name 代表这个类，然后用一个箭头指向类中的 show_username 这个函数。就是这么简单，也就是说，这个函数是这个类中的，而不是其他的函数－－你就理解为表示一个区别吧，呵呵。</p>
<p>　　试试看哦，打印出 “温室小花” 这四个字。你说为什么要这么复杂？用函数不是也能实现么？我说，这么简单的你当然看不出好处，我们继续扩充。</p>
<p>　　还有一个疑问是：刚才说的“公共的变量”怎么一点用处都没有呢？为什么这个函数不会自动接收这个公共变量 var $username 中的默认值？也就是如果我使用：</p>
<p>$Name->show_username($username);</p>
<p>　　会有什么结果呢?答案是没有任何输出。因为你没有给形参 $username 一个值。</p>
<p>　　那么该怎么使用这个公共的变量？我们来修改一下这个类:<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username()<br />
    {<br />
        echo $this->username;<br />
    }<br />
}</p>
<p>　　哇靠，不是吧，这回连形参都没有？还多一个$this->，晕不是，呵呵。其实这也是类的一个最大的方便之处。<br />
　　$this 的作用：访问一个公共的变量，或者类里面的函数。<br />
　　访问？这么专业？其实就是用 $this->username 来代替 var $username 而已拉，$this 用来说明它是公共的、可以访问的、函数外部的东西（比如其他变量或函数）。</p>
<p>试试看：</p>
<p>$Name->show_username();</p>
<p>　　看到吧，终于打印 “小花” 这两个字，娃哈哈。</p>
<p>　　我不打印“小花”这两个字，我要打印“温室小花”，怎么办？很简单，我们给这个公共变量重新赋值拉。服你。</p>
<p>$Name->username = &#8220;温室小花&#8221;;</p>
<p>　　这个能明白意思么？$Name->username 表示的是类里面的这个公共变量。等号赋值不用我解释。</p>
<p>　　我们再来打印看看：</p>
<p>$Name->show_username();</p>
<p>　　哈哈，终于打印“温室小花”。不错吧，很方便吧，不用形参也能任意修改打印值哦～～。</p>
<p>　　不过单单打印一个名称也太没意思，我们说点欢迎的话吧，来扩充一下这个类，创建一个名叫 Welcome 的函数：</p>
<p>class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username()<br />
    {<br />
        echo $this->username;<br />
    }</p>
<p>    function Welcome()<br />
    {<br />
    }<br />
}</p>
<p>　　恩，实现什么功能好呢？简单点吧，就实现在名字前面有 “欢迎” 两个字好</p>
<p>class my_class<br />
{<br />
    var $username = &#8220;小花&#8221;;</p>
<p>    function show_username()<br />
    {<br />
        echo $this->username;<br />
    }</p>
<p>    function Welcome()<br />
    {<br />
        echo &#8220;欢迎&#8221;;<br />
        $this->show_username();<br />
    }<br />
}</p>
<p>　　第二次看到 $this 吧？和上次有点不同，$this->show_username(); 干什么用呢？指向类中的一个函数，其实它就是调用 show_username 这个函数，用 $this 来表示这个函数在类中并且和 Welcome 函数平行，而不是在其他地方（比如Welcome函数中）。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　Welcome 函数实现的功能很简单，首先打印两个字&#8221;欢迎&#8221;，然后接下去执行 show_username 函数，打印名字。</p>
<p>　　来试试这个函数吧：</p>
<p>$Name->Welcome();</p>
<p>　　看到吧，打印出“欢迎小花”这四个字。</p>
<p>　　可是我要打印“欢迎温室小花”，怎么办？我服你，我们给公共变量 var $username 一个值吧：</p>
<p>$Name->username = &#8220;温室小花&#8221;;</p>
<p>　　接下去打印欢迎语：</p>
<p>$Name->Welcome();</p>
<p>　　嘿嘿，终于打印“欢迎温室小花”。</p>
<p>　　怎么样？明白类的用法么？好处在于能够调用类中的任意函数，只要用 $this 指出来，可以改变一个公共变量的值，可以在类中的函数中使用这个公共变量。………多去，它的应用等待你去发现。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1016.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php class的申明与使用方法</title>
		<link>http://www.evanjiang.net.cn/archives/992.html</link>
		<comments>http://www.evanjiang.net.cn/archives/992.html#comments</comments>
		<pubDate>Tue, 05 May 2009 06:55:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/archives/992.html</guid>
		<description><![CDATA[<p>下面来看看在很多程序语言中会使用到的class吧，现在会举个简单的实例来实现php class,类申明,class使用方法.</p>
<p></p>
]]></description>
			<content:encoded><![CDATA[<p>下面来看看在很多程序语言中会使用到的class吧，现在会举个简单的实例来实现php class,类申明,class使用方法.</p>
<p><?php<br />
/*</p>
<p> */<br />
class System{//系统部分<br />
 function usr_level($name){<br />
  $SQL = new MySQL();<br />
  $SQL->Query(&#8220;SELECT `level` FROM `members` WHERE `username` = &#8216;$name&#8217;;&#8221;);<br />
  $SQL->NextRecord();<br />
  $TMP = $SQL->GetRecord(&#8216;level&#8217;);<br />
  $SQL->Free();<br />
  return $TMP;<br />
 }<br />
 function channel_level($cid){<br />
  $SQL = new MySQL();<br />
  $SQL->Query(&#8220;SELECT `level` FROM `channels` WHERE `id` = $id;&#8221;);<br />
  $SQL->NextRecord();<br />
  $TMP = $SQL->GetRecord(&#8216;id&#8217;);<br />
  $SQL->Free();<br />
  return $TMP;<br />
 }<br />
 function uid2name($uid){<br />
  $SQL = new MySQL();<br />
  if($SQL->Query(&#8220;SELECT `username` FROM `members` WHERE `uid` = $uid;&#8221;)){<br />
   $SQL->NextRecord();<br />
   $TMP = $SQL->GetRecord(&#8216;username&#8217;);<br />
   $SQL->Free();<br />
   return $TMP;<br />
  }else{<br />
   return 0;<br />
  }<br />
 }<br />
<span id="more-992"></span><br />
 function name2uid($name){<br />
  $SQL = new MySQL();<br />
  if($SQL->Query(&#8220;SELECT `uid` FROM `members` WHERE `username` = &#8216;$name&#8217;;&#8221;)){<br />
   $SQL->NextRecord();<br />
   $TMP = $SQL->GetRecord(&#8216;uid&#8217;);<br />
   $SQL->Free();<br />
   return $TMP;<br />
  }else{<br />
   return 0;<br />
  }<br />
 }<br />
 function sysinfo($Name){//获取系统信息<br />
  $SQL = new MySQL();<br />
  $SQL->Query(&#8220;SELECT * FROM `sysinfo`;&#8221;);<br />
  $SQL->NextRecord();<br />
  $TMP = $SQL->GetRecord($Name);<br />
  $SQL->Free();<br />
  return $TMP;<br />
 }<br />
 function find_member($name){//查找该用户（注册时需要）<br />
  $SQL = New MySQL();<br />
  $SQL->Query(&#8220;SELECT * FROM `members` WHERE `username` = &#8216;$name&#8217;;&#8221;);<br />
  $RS = $SQL->RowS();<br />
  $SQL->Free();<br />
  if($RS)<br />
   return 1;<br />
  else<br />
   return 0;<br />
 }<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
 function str_safe($str){//字符串安全过滤<br />
  $str = str_replace($str,&#8221;;&#8221;,&#8221;；&#8221;);<br />
  $str = str_replace($str,&#8221;&#8216;&#8221;,&#8221;‘&#8221;);<br />
  $str = str_replace($str,&#8221;/&#8221;,&#8221;／&#8221;);<br />
  $str = str_replace($str,&#8221;`&#8221;,&#8221;｀&#8221;);<br />
  $str = str_replace($str,&#8221;\&#8221;,&#8221;＼&#8221;);<br />
  return $str;<br />
 }<br />
 function GetMyIP()<br />
 {<br />
  if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"])<br />
   $ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];<br />
  elseif ($HTTP_SERVER_VARS["HTTP_CLIENT_IP"])<br />
   $ip = $HTTP_SERVER_VARS["HTTP_CLIENT_IP"];<br />
  elseif ($HTTP_SERVER_VARS["REMOTE_ADDR"])<br />
   $ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];<br />
  elseif (getenv(&#8220;HTTP_X_FORWARDED_FOR&#8221;))<br />
   $ip = getenv(&#8220;HTTP_X_FORWARDED_FOR&#8221;);<br />
  elseif (getenv(&#8220;HTTP_CLIENT_IP&#8221;))<br />
   $ip = getenv(&#8220;HTTP_CLIENT_IP&#8221;);<br />
  elseif (getenv(&#8220;REMOTE_ADDR&#8221;))<br />
   $ip = getenv(&#8220;REMOTE_ADDR&#8221;);<br />
  else<br />
   $ip = &#8220;127.0.0.1&#8243;;<br />
  return $ip;<br />
 }<br />
 function Version(){<br />
  return &#8220;1.0.9&#8243;;<br />
 }<br />
}<br />
class MySQL{//数据库部分<br />
 var $DBServer = &#8216;localhost&#8217;;//服务器<br />
 var $DBName = &#8221;;//数据库名称<br />
 var $DBUser = &#8221;;//数据库用户<br />
 var $DBPass = &#8221;;//数据库密码<br />
 var $OnErrorResume = 1;//错误提示关闭<br />
 var $LinkID = 0;//连接句柄<br />
 var $QueryID = 0;//查询句柄<br />
 var $ResultS = array();//查询结果集<br />
 var $Error = &#8221;;//错误信息<br />
 function Connect($Srv = &#8220;&#8221;,$Usr = &#8220;&#8221;,$Pass = &#8220;&#8221;,$DB = &#8220;&#8221;){//连接数据库<br />
  if($Srv == &#8220;&#8221;) $Srv = $this->DBServer;<br />
  if($Usr == &#8220;&#8221;) $Usr = $this->DBUser;<br />
  if($Pass == &#8220;&#8221;) $Pass = $this->DBPass;<br />
  if($DB == &#8220;&#8221;) $DB = $this->DBName;<br />
  if($this->LinkID == 0){<br />
   $this->LinkID = @mysql_connect($Srv,$Usr,$Pass) or die(&#8220;数据库连接失败，请联系管理员修复此问题。&#8221;);<br />
  }<br />
  @mysql_select_db($DB,$this->LinkID) or die(&#8220;数据库选择失败，请联系管理员修复此问题。&#8221;);<br />
  return $this->LinkID;<br />
 }<br />
 function Free(){//释放查询结果<br />
  @mysql_free_result($this->QueryID);<br />
  $this->QueryID = 0;<br />
 }<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
 function RowS(){//查询到的记录总数<br />
  if(!$this->QueryID) return 0;<br />
  return @mysql_num_rows($this->QueryID);<br />
 }<br />
 function NextRecord(){//下一条记录<br />
  if(!$this->QueryID) return 0;<br />
  $this->ResultS = @mysql_fetch_array($this->QueryID);<br />
 }<br />
 function Seek($seek){<br />
  if(!$this->QueryID) return 0;<br />
  @mysql_data_seek($this->QueryID,$seek);<br />
 }<br />
 function Query($Sql){//执行查询<br />
  if($Sql == &#8220;&#8221;) return 0;<br />
  if($this->LinkID == 0) $this->Connect();<br />
  if($this->QueryID) $this->Free();//释放原来查询结果<br />
  $this->QueryID = @mysql_query($Sql,$this->LinkID);<br />
  $this->Error = mysql_error($this->LinkID);<br />
  if(!$this->QueryID) exit(&#8220;$Sql执行失败.&#8221;);<br />
  return $this->QueryID;<br />
 }<br />
 function GetRecord($Name){<br />
  if(!$this->QueryID) return 0;<br />
  return $this->ResultS[$Name];<br />
 }<br />
}<br />
?></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/992.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php 类的写法</title>
		<link>http://www.evanjiang.net.cn/archives/989.html</link>
		<comments>http://www.evanjiang.net.cn/archives/989.html#comments</comments>
		<pubDate>Tue, 05 May 2009 06:40:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=989</guid>
		<description><![CDATA[<p>php 类的写法//Db.class.php
class Db {
    private $_dblink;
    public $result;
    public function __construct($host, $user, $password, $dbname, $charset = &#8216;utf8&#8242;) {
        try{
            if($this->_dblink = mysql_connect($host, $user, $password)) {
    [...]]]></description>
			<content:encoded><![CDATA[<p>php 类的写法//Db.class.php<br />
class Db {<br />
    private $_dblink;<br />
    public $result;<br />
    public function __construct($host, $user, $password, $dbname, $charset = &#8216;utf8&#8242;) {<br />
        try{<br />
            if($this->_dblink = mysql_connect($host, $user, $password)) {<br />
                if(mysql_select_db($dbname)) {<br />
                    $this->query(&#8220;SET NAMES &#8221; . $charset . &#8221; ;&#8221;);<br />
                } else {<br />
                    throw new Exception(mysql_error());<br />
                }<br />
            } else {<br />
                throw new Exception(mysql_error());<br />
            }<br />
        } catch (Exception $e) {<br />
            die($e->getMessage());<br />
        }<br />
    }</p>
<p>    public function query($sql) {<br />
        return $this->result = mysql_query($sql);<br />
    }<br />
<span id="more-989"></span><br />
    public function fetch() {<br />
        return mysql_fetch_array($this->result);<br />
    }</p>
<p>    public function fetchAll() {<br />
        $rs = array();<br />
        $rsAll = array();<br />
        while($rs = mysql_fetch_array($this->result)) {<br />
            $rsAll[] = $rs;<br />
        }<br />
        return $rsAll;<br />
    }<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    public function __destruct() {<br />
        mysql_close($this->_dblink);<br />
    }<br />
}<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>复制PHP内容到剪贴板PHP代码:<br />
//test.php<br />
$db = new Db(&#8216;localhost&#8217;, &#8216;root&#8217;, &#8221;, &#8216;hent_qxoa&#8217;);<br />
$db->query(&#8220;SELECT * FROM qx_user ;&#8221;);<br />
var_dump($db->fetchAll());</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/989.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>unix常用指令及参数</title>
		<link>http://www.evanjiang.net.cn/archives/893.html</link>
		<comments>http://www.evanjiang.net.cn/archives/893.html#comments</comments>
		<pubDate>Wed, 08 Apr 2009 13:48:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[freebsd unix]]></category>
		<category><![CDATA[netbsd unix]]></category>
		<category><![CDATA[openbsd unix]]></category>
		<category><![CDATA[other linux]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[sco unix]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[sun unix]]></category>
		<category><![CDATA[suse linux]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[unix 常用命令 及参数]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=893</guid>
		<description><![CDATA[<p>常用组合键
ctrl+h,backspace :删除前面的字符.
ctrl+u:删除一整行.
ctrl+c,del,break: 强行终止正在运行的程序.
ctrl+d:
常用指令
1.date:查看当前时间.
2.cal:查看某一个月的月历.
3.Finger 命令:显示一个用户的详细信息.
4.who命令:显示所有登陆用户.who an i
5.clear 命令:执行清屏动作.
6.echo 命令:将命令名后跟随的参数显示在屏幕echo hello </p>
<p>world
7.banner 命令:将命令名后跟的ACSSII字符串以大字的方式显</p>
<p>示在屏幕上banner hello
8.wc 命令:用于计算一个指定的文件中的行数单词及字符数:
   格式wc[-c(计算字符的数目)] [-l(计算行的数目)] [-w(计算</p>
<p>单词的数目)] filename
9.passwd 命令,用于修改口令.
10.man 命令:联机手册
六.shell的基本功能:命令解释器,程序设计语言.
shell的退出命令.
1.exit 主要用于退出B_shell
2.logout 主要用于退出C_shell
3.ctrl+d 用于退出各类shell
第三章 通信
内部通信
外部通信





下.
mail命令模式常用命令
 如有下页则显示,否则退出mail.
p      显示本邮件信息
d      删除当前邮件
n      显示下一个邮件
q      退出 mail,把末删除的邮件保存到个人邮箱中.
R     [...]]]></description>
			<content:encoded><![CDATA[<p>常用组合键<br />
ctrl+h,backspace :删除前面的字符.<br />
ctrl+u:删除一整行.<br />
ctrl+c,del,break: 强行终止正在运行的程序.<br />
ctrl+d:<br />
常用指令<br />
1.date:查看当前时间.<br />
2.cal:查看某一个月的月历.<br />
3.Finger 命令:显示一个用户的详细信息.<br />
4.who命令:显示所有登陆用户.who an i<br />
5.clear 命令:执行清屏动作.<br />
6.echo 命令:将命令名后跟随的参数显示在屏幕echo hello </p>
<p>world<br />
7.banner 命令:将命令名后跟的ACSSII字符串以大字的方式显</p>
<p>示在屏幕上banner hello<br />
8.wc 命令:用于计算一个指定的文件中的行数单词及字符数:<br />
   格式wc[-c(计算字符的数目)] [-l(计算行的数目)] [-w(计算</p>
<p>单词的数目)] filename<br />
9.passwd 命令,用于修改口令.<br />
10.man 命令:联机手册<br />
六.shell的基本功能:命令解释器,程序设计语言.<br />
shell的退出命令.<br />
1.exit 主要用于退出B_shell<br />
2.logout 主要用于退出C_shell<br />
3.ctrl+d 用于退出各类shell<br />
第三章 通信<br />
内部通信<br />
外部通信<1,电子邮件,2.即时通信<br />
一.即时通讯<br />
1.write 交谈命令 (半双工通信)<br />
格式 write student1<br />
ctrl+d 退出write<br />
Write协议:消息发送结束用O(结束)<br />
结束谈话用OO(结束并退出)<br />
2.mesg 消息开关命令.用于查询和开关本终端的消息接收状态.<br />
格式:mesg [-y] [-n]<br />
$ mesg 查询本终端当前的消息接收状态<br />
is y 可以接收消息<br />
is n 拒绝接收消息<br />
$ mesg n 设置关闭状态<br />
$ mesg y 设置打开状态<br />
3.talk 双向通信命令 (全双工方式)<br />
4.wall 广播信息命令<br />
二,电子邮件<br />
$ mail username  发送邮件<br />
$ mail                 接收邮件<br />
系统邮箱:在/usr/mail或/var/mail下,每个用户都有一个以其名字</p>
<p>命名的邮箱.例如:student8的系统邮箱可能为:/var/mail/student8<br />
个人邮箱:个人邮箱通常为用户自己的主目录(home)下的mbox<br />
<span id="more-893"></span><br />
文件.用户读过的邮件如果末删除或转存,则存放在个人邮箱中</p>
<p>.例如:student8的个人邮箱可能是:/home/student8/mbox<br />
1.发送邮件:<br />
$ mail student8<br />
给多个用户发送邮件<br />
a.$ mail student1 student2 student3 把用户列出来.<br />
b.$ mail TEACHER TEACHER为用户组名,即向属于TEACHER</p>
<p>组所有用记发邮件.<br />
c.$ alias usr_list student1 student2 student3给student1 student2 </p>
<p>student3等多个名字建立一个部的别名usr_list,该别名只在本</p>
<p>shell中起作用,退出shell后无效.<br />
$ mail usr_list<br />
把已有的文件作为邮件发送给用户:<br />
$ mail student8 < my_letter<br />
发邮件给不存在的用户:<br />
$ mail meizhegeren<br />
mail命令本身能正常执行,由于无有效的接收方,所以系统把邮</p>
<p>件退回到用户主目录下dead.letter中.<br />
2.接收邮件<br />
不带参数输入mial表示读取邮件.此时已进入出境mail命令模式<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
下.<br />
mail命令模式常用命令<br />
<cr> 如有下页则显示,否则退出mail.<br />
p      显示本邮件信息<br />
d      删除当前邮件<br />
n      显示下一个邮件<br />
q      退出 mail,把末删除的邮件保存到个人邮箱中.<br />
R     回复邮件<br />
!      执行shell命令.<br />
?      显示mail的内部命令.<br />
第四章 文件系统<br />
与目录相关的命令(pwd,cd,mkdir,rmdir,ls)<br />
与文件相关的命令(cp,mv,ln,more,rm)<br />
1.pwd 显示当前工作目录<br />
2.cd  改变当前目录<br />
3.mkdir 创建目录<br />
格式 mkdir dir_name<br />
4.rmdir 删除目录<br />
格式 rmdir dir_name<br />
     a.只能是空目录.<br />
      b.有写的权限<br />
一次操作多个目录<br />
- p 选项.在当前目录下逐级创建目录,也可以逐级删除目录.<br />
5.ls 显示目录<br />
$ ls -a 显示所有文件(以点开头的文件名是隐藏文件)<br />
$ ls -R 显示所有子目录的内容<br />
$ ls &#8211; l  能得到目录中的文件的详细信息.<br />
-:普通 d: 目录 c: 字符设备 b: 块设备 p:管道<br />
$ ls &#8211; C 以多列的格式列表,按列排序.<br />
$ ls &#8211; F 如果是目录,文件名后加/,如果是可执行文件,加*表示.<br />
$ ls &#8211; m 按页宽列文件,以逗号分隔.<br />
$ ls &#8211; p 如果是目录,文件名后加/<br />
$ ls &#8211; r 以字母反序列表<br />
$ ls &#8211; s 以文件块为单位显示文件大小<br />
$ ls &#8211; x 以多列的格式列表,按行排序.<br />
$ ls -G 以不同的颜色显示.<br />
$ ls -lc 显示更新时间<br />
$ ls -i   inode序号将列在第一列<br />
$ ls -lu 显示访问时间<br />
$ ls -I   显示更改时间<br />
6.touch 命令:作用是用来修改文件访问时间更改时间的.并可以</p>
<p>用来创建0字节长度的文件.<br />
格式 touch 命令参数<br />
7.cp 命令:复制文件<br />
格式 cp source target<br />
         $ cp file1 file2 &#8230; Target-dir<br />
$ cp -i 如果目标文件存在,请求确认<br />
$ cp -r 复制目录到新的目录<br />
8.mv 命令:移动文件或命名文件<br />
格式:mv source target<br />
9.ln 命令:ln命令的主要功能是给一个已经存在的文件再取一个</p>
<p>名字.新的文件名与原文件名可以在同一个目录下,也可以以在</p>
<p>不同的目录下,新老文件名代表同一个文件.<br />
格式ln source-file target-file<br />
作用:在现有的文件与新文件之间建立新链接,使一个文件具有</p>
<p>一个以上的名字.<br />
显示文件内容命令<br />
10.cat 命令:用来显示.创建或者合并文件<br />
格式cat filename<br />
11.more 命令:逐屏显示文件内容.翻屏时用<space>键.<br />
格式:$ more filename<br />
12.rm 命令:删除文件(删除后无法恢复)<br />
格式:$ rm file<br />
         $ rm file1 file2<br />
$ rm -i 删除文件前,给出确认<br />
$ rm -r 删除指定的目录及目录中的所有文件和子目录.即删除</p>
<p>整个目录结构.<br />
13.lp 命令:打印命令<br />
14.cut 命令:切取文件内容,用于切取文件中的列或字段.它把文</p>
<p>本文件中每一行的一部分显示输出.运行时必须指定功能选项.<br />
- f 指定字段的位置<br />
-c 指定列的位置<br />
-d 指定字段分隔符,缺省的字段分隔符是制表符tab<br />
15.paste 命令:连接文件.<br />
作用:把文件一行接一行地连接在一起,或者把两个或多个文件</p>
<p>的域连到一个新文件里.<br />
格式: $paste 选项 参数<br />
选项:-d 指定分隔符.默认是制表符<br />
第五章 文件权限<br />
16.chmod 命令:修改文件权限,常用chmod命令修改文件(包括普</p>
<p>通,目录和设备)的访问权限,<br />
格式: chmod pattern filename &#8230;<br />
finename 为要修改的权限文件名.可以有多个.<br />
pattern 为将改变成的权限,可以用两种形式表示:字母式和数字</p>
<p>形式.<br />
a,字母形式(符号模式)<br />
字母形式由用户类别(u,g,o). 如何改变(+,-)和权限(r,w,x)三部分</p>
<p>组成.<br />
u:本用户g:同组用户o:其它用户. + :增加权限 -:删除权限<br />
r:读w:写x:执行<br />
例如:chmod u+x file1<br />
         chmod o-w file2 file3<br />
          chmod go+r file4<br />
b,    数值形式<br />
格式: chmod 777 file1<br />
*新建文件或目录最大权限=状态掩码+新建文件或目录缺省</p>
<p>权限.此时unask为000<br />
对一个新建的文件,umask值为022则指定该文件的权限为644:<br />
对一个新建的目录,umask值为022则指定该目录的权限为755<br />
17.sort 命令:作用在于将指定的文件中的文件进行排序,并把排</p>
<p>序的结果输出到指定的标准输出中.<br />
格式:$srot [-t delimiter] [+field] [.column]][option]<br />
选项: -d 以字典顺序进行排序<br />
          -<br />
18.head 命令:用于查看一个文件.或多个文件的前面几行的内</p>
<p>容.<br />
格式:$ head [-number_of_lines] file(s)<br />
19.tail 命令:用于显示从指定行开始直到文件末尾的文件内容<br />
格式;tail [-number_of_lines | +number_of_lines]file<br />
20.tee 命令:在获得输入后,将把该输入数据送到两个地点:标准<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
输出和文件.<br />
21.grep 命令: 用于选项定包含特定模式的文本行.<br />
21.find 命令:在目录中递归地搜索包括有特定字符的文件名.<br />
22.df 命令:磁盘空间监测命令.显示当前系统中各个逻辑磁盘</p>
<p>中空闲的磁盘块数和空闲的索引节点(即可建立的新文件数)<br />
23.du 命令:查看磁盘使用情况统计,统计指定的目录及所有子</p>
<p>目录的磁盘使用情况,统计单位是磁盘块数.<br />
选项:-a 显示所有文件及子目录<br />
24.fsck 命令:文件系统管理:用于检测和修复文件文件的错误,<br />
25.tar命令:文件存储与备份.该命令可以把文件系统中的一个</p>
<p>或一组文件打成一个文件包.存放到外存上或硬盘上文件系统</p>
<p>的其它地方.常用于多个文件(包括目录)的备份或转移.<br />
格式: tar -cvf target file1 file2 file3 &#8230;把file1 file2 file3等文件备份到</p>
<p>档案文件target中.<br />
         tar -tvf target 检查档案文件target中包含的文件信息.<br />
         tar -xvf targer [file1] 从档案文件target中提取全部或file指定</p>
<p>的文件.<br />
26.shutdown 命令:系统关机<br />
选项:-h 完全关机<br />
         -r 关机并重新启动系统<br />
         time 关机时间,如17:30<br />
         message 关机前向所有已登陆用户发送消息<br />
例如: shutdown -r now 现在关机重启.<br />
27.crypt 文件加密命令:用于对文本文件进行加密和解密.以防</p>
<p>止文件内容泄密.<br />
例如:$ crypt < file > file.cry 对file加密,结果保存在file.cry中.key:加</p>
<p>密口令<br />
        $ crypt <aaa.cry > aaa 对aaa.cry解密,结果保存到aaa中. key:</p>
<p>解密口令<br />
附:$ vi -x file.cry 编辑一个加密后的文件<br />
28.compress/uncompress 文件压缩和解压命令<br />
格式:compress data_file 加压后自动在文件名后加一个.Z<br />
         umcompress abc.Z<br />
29.at 定时执行任务:在指定的时间一次性执行规定的任务.<br />
at 15:30 在15:30分执行<br />
who >> userlist 把上机用户清单发到userlist<br />
30,cron 系统定量执行任务:<br />
31,crontab 任务描述文件的管理命令.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/893.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to install LAMP (Apache, PHP and MySQL in Linux) using Yum</title>
		<link>http://www.evanjiang.net.cn/archives/868.html</link>
		<comments>http://www.evanjiang.net.cn/archives/868.html#comments</comments>
		<pubDate>Sun, 05 Apr 2009 13:19:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[lamp yum install]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=868</guid>
		<description><![CDATA[<p>Many friends ask me how to install LAMP (Linux, apache, php, mysql). There are many ways to install LAMP. Here i teach you the most easiest way to install LAMP using yum program in CentOS.
Below are the steps to install LAMP (Apache, PHP and MySQL in Linux) using Yum:-</p>
<p>•	Go to CentOS and download a copy [...]]]></description>
			<content:encoded><![CDATA[<p>Many friends ask me how to install LAMP (Linux, apache, php, mysql). There are many ways to install LAMP. Here i teach you the most easiest way to install LAMP using yum program in CentOS.<br />
Below are the steps to install LAMP (Apache, PHP and MySQL in Linux) using Yum:-</p>
<p>•	Go to CentOS and download a copy of CentOS Linux and install it (i’ll not go thru the how to install CentOS with you here)<br />
•	Once your CentOS is installed. Open a terminal (if you are using X-Window), and type yum install httpd and follow on screen instruction to install apache web server<br />
•	Once apache web server has been installed, type yum install php<br />
•	Once PHP installed successfully, type yum install mysql-servermysql<br />
•	Once everything finish, type service httpd start to start your apache web server, screen will show you if web server service successfully started<br />
•	type service mysqld start to start your mysql server<br />
•	Once both services is running, you can point your browser to http://localhost and you should see a welcome page from CentOS<br />
•	If you see that welcome page, you just installed everything successfull.<br />
•	To test if php is running, go to /var/www/html and create anindex.php file with the content below<br />
<?php phpinfo(); ?><br />
and refresh your browser again. If you see a purple PHP information page showing all the php configuration variables, then php is running now.<br />
•	Congratulation, you just successfully installed LAMP in your machine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/868.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>网站恢复时，Lighttpd+php环境搭建文档笔记</title>
		<link>http://www.evanjiang.net.cn/archives/866.html</link>
		<comments>http://www.evanjiang.net.cn/archives/866.html#comments</comments>
		<pubDate>Fri, 03 Apr 2009 03:20:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[lighttpd php 环境 搭建 文档笔记]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=866</guid>
		<description><![CDATA[<p>早前。网站要迁移。要从apache+php环境迁移到Lighttpd +php环境，如下为lighttpd+php环境搭建文档笔记。有点乱。有空再详细整理。</p>
<p>fetch ftp://ftp.freebsd.org/pub/FreeBS &#8230; Latest/lighttpd.tgz
tar -zxvf lighttpd.tgz
cd lighttpd
./configure &#8211;prefix=/home/tiger/evan/lighttpd &#8211;with-pcre &#8211;with-gdbm &#8211;with-memcache make
make install
安装PHP
tar -zxvf php-5.0.4.tgz
cd php-5.0.4
./configure &#8211;prefix=/home/tiger/evan/php5-fastcgi &#8211;enable-fastcgi &#8211;without-pear &#8211;with-mysql=/usr/local/mysql  &#8211;enable-discard-path &#8211;enable-force-cgi-redirect -with-iconv
./configure &#8211;prefix=/home/tiger/evan/php5-fastcgi &#8211;with-mysql=/usr/local/mysql &#8211;enable-gd-native-ttf &#8211;with-gd &#8211;enable-ftp &#8211;with-iconv &#8211;with-gettext &#8211;enable-fastcgi &#8211;enable-zend-multibyte &#8211;without-pear &#8211;enable-force-cgi-redirect &#8211;enable-discard-path
Make
Make test
Make clean
Make install</p>
<p>配置Lighttpd
vi lighttpd.confserver.port=5678
server.modules=(&#8220;mod_access&#8221;,&#8221;mod_fastcgi&#8221;,&#8221;mod_accesslog&#8221;)
server.document-root=&#8221;/home/tiger/evan/lighttpd/htdocs&#8221;
server.pid-file=&#8221;/home/tiger/evan//lighttpd/lighttpd.pid&#8221;
server.errorlog=&#8221;/home/tiger/evan//lighttpd/lighttpd.error.log&#8221;
server.indexfiles=(&#8220;index.php&#8221;,&#8221;index.html&#8221;)
fastcgi.server=(&#8220;.php&#8221;=>(&#8220;localhost&#8221;=>(&#8220;socket&#8221; =>&#8221;/tmp/php-fastcgi.socket&#8221;,&#8221;bin-path&#8221;
=>&#8221;/home/tiger/evan/php5-fastcgi/bin/php&#8221;)))</p>
<p>启动Lighttpd
/home/tiger/evan/lighttpd/sbin/lighttpd -f  /home/tiger/evan/lighttpd/conf/lighttpd.conf
</p>
<p>安装环境: Linux Fedora Core 3 上安装 php-5.2.0</p>
<p>在安装 PHP 到系统中时要是发生「undefined reference to [...]]]></description>
			<content:encoded><![CDATA[<p>早前。网站要迁移。要从apache+php环境迁移到Lighttpd +php环境，如下为lighttpd+php环境搭建文档笔记。有点乱。有空再详细整理。</p>
<p>fetch ftp://ftp.freebsd.org/pub/FreeBS &#8230; Latest/lighttpd.tgz<br />
tar -zxvf lighttpd.tgz<br />
cd lighttpd<br />
./configure &#8211;prefix=/home/tiger/evan/lighttpd &#8211;with-pcre &#8211;with-gdbm &#8211;with-memcache make<br />
make install<br />
安装PHP<br />
tar -zxvf php-5.0.4.tgz<br />
cd php-5.0.4<br />
./configure &#8211;prefix=/home/tiger/evan/php5-fastcgi &#8211;enable-fastcgi &#8211;without-pear &#8211;with-mysql=/usr/local/mysql  &#8211;enable-discard-path &#8211;enable-force-cgi-redirect -with-iconv<br />
./configure &#8211;prefix=/home/tiger/evan/php5-fastcgi &#8211;with-mysql=/usr/local/mysql &#8211;enable-gd-native-ttf &#8211;with-gd &#8211;enable-ftp &#8211;with-iconv &#8211;with-gettext &#8211;enable-fastcgi &#8211;enable-zend-multibyte &#8211;without-pear &#8211;enable-force-cgi-redirect &#8211;enable-discard-path<br />
Make<br />
Make test<br />
Make clean<br />
Make install</p>
<p>配置Lighttpd<br />
vi lighttpd.confserver.port=5678<br />
server.modules=(&#8220;mod_access&#8221;,&#8221;mod_fastcgi&#8221;,&#8221;mod_accesslog&#8221;)<br />
server.document-root=&#8221;/home/tiger/evan/lighttpd/htdocs&#8221;<br />
server.pid-file=&#8221;/home/tiger/evan//lighttpd/lighttpd.pid&#8221;<br />
server.errorlog=&#8221;/home/tiger/evan//lighttpd/lighttpd.error.log&#8221;<br />
server.indexfiles=(&#8220;index.php&#8221;,&#8221;index.html&#8221;)<br />
fastcgi.server=(&#8220;.php&#8221;=>(&#8220;localhost&#8221;=>(&#8220;socket&#8221; =>&#8221;/tmp/php-fastcgi.socket&#8221;,&#8221;bin-path&#8221;<br />
=>&#8221;/home/tiger/evan/php5-fastcgi/bin/php&#8221;)))</p>
<p>启动Lighttpd<br />
/home/tiger/evan/lighttpd/sbin/lighttpd -f  /home/tiger/evan/lighttpd/conf/lighttpd.conf<br />
<span id="more-866"></span></p>
<p>安装环境: Linux Fedora Core 3 上安装 php-5.2.0</p>
<p>在安装 PHP 到系统中时要是发生「undefined reference to `libiconv_open&#8217;」之类的错误讯息，那表示在「./configure 」没抓好一些环境变量值。错误发生点在建立「-o sapi/cli/php」时出错，没给到要 link 的 iconv 函式库参数。</p>
<p>快速的解法是：<br />
编辑 Makefile 大约 70 行左右的地方:</p>
<p>EXTRA_LIBS = &#8230;.. -lcrypt</p>
<p>在最后加上 -liconv，例如:</p>
<p>EXTRA_LIBS = &#8230;.. -lcrypt -liconv</p>
<p>然后重新再次 make 即可。<br />
________________________________________</p>
<p>如果要安装 iconv 函式库的话：<br />
其首页是: http://www.gnu.org/software/libiconv/<br />
下载点是: http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.2.tar.gz</p>
<p>安装步骤:</p>
<p># ./configure &#8211;prefix=/usr/local<br />
# make<br />
# make install</p>
<p>________________________________________</p>
<p>make 时的错误讯息范例：</p>
<p>[jjdai@zhupiter php-5.2.0]$ make<br />
/bin/sh /home/jjdai/work/zhupiter/php-5.2.0/libtool &#8211;silent &#8211;preserve-dup-deps &#8211;mode=link gcc -export-dynamic -I/usr/local/include -g -O2 -L/usr/kerberos/lib -L/usr/local/lib -L/usr/lib/mysql -R /usr/kerberos/lib -R /usr/local/lib -R /usr/lib/mysql ext/libxml/libxml.lo ext/openssl/openssl.lo ext/openssl/xp_ssl.lo ext/pcre/pcrelib/pcre_chartables.lo ext/pcre/pcrelib/pcre_ucp_searchfuncs.lo ext/pcre/pcrelib/pcre_compile.lo ext/pcre/pcrelib/pcre_config.lo ext/pcre/pcrelib/pcre_exec.lo ext/pcre/pcrelib/pcre_fullinfo.lo ext/pcre/pcrelib/pcre_get.lo ext/pcre/pcrelib/pcre_globals.lo ext/pcre/pcrelib/pcre_info.lo ext/pcre/pcrelib/pcre_maketables.lo ext/pcre/pcrelib/pcre_ord2utf8.lo ext/pcre/pcrelib/pcre_refcount.lo ext/pcre/pcrelib/pcre_study.lo ext/pcre/pcrelib/pcre_tables.lo ext/pcre/pcrelib/pcre_try_flipped.lo ext/pcre/pcrelib/pcre_valid_utf8.lo ext/pcre/pcrelib/pcre_version.lo ext/pcre/pcrelib/pcre_xclass.lo ext/pcre/php_pcre.lo ext/zlib/zlib.lo ext/zlib/zlib_fopen_wrapper.lo ext/zlib/zlib_filter.lo ext/bz2/bz2.lo ext/bz2/bz2_filter.lo ext/ctype/ctype.lo ext/curl/interface.lo ext/curl/multi.lo ext/curl/streams.lo ext/date/php_date.lo ext/date/lib/astro.lo ext/date/lib/dow.lo ext/date/lib/parse_date.lo ext/date/lib/parse_tz.lo ext/date/lib/timelib.lo ext/date/lib/tm2unixtime.lo ext/date/lib/unixtime2tm.lo ext/dom/php_dom.lo ext/dom/attr.lo ext/dom/document.lo ext/dom/domerrorhandler.lo ext/dom/domstringlist.lo ext/dom/domexception.lo ext/dom/namelist.lo ext/dom/processinginstruction.lo ext/dom/cdatasection.lo ext/dom/documentfragment.lo ext/dom/domimplementation.lo ext/dom/element.lo ext/dom/node.lo ext/dom/string_extend.lo ext/dom/characterdata.lo ext/dom/documenttype.lo ext/dom/domimplementationlist.lo ext/dom/entity.lo ext/dom/nodelist.lo ext/dom/text.lo ext/dom/comment.lo ext/dom/domconfiguration.lo ext/dom/domimplementationsource.lo ext/dom/entityreference.lo ext/dom/notation.lo ext/dom/xpath.lo ext/dom/dom_iterators.lo ext/dom/typeinfo.lo ext/dom/domerror.lo ext/dom/domlocator.lo ext/dom/namednodemap.lo ext/dom/userdatahandler.lo ext/filter/filter.lo ext/filter/sanitizing_filters.lo ext/filter/logical_filters.lo ext/filter/callback_filter.lo ext/gd/gd.lo ext/gd/gdttf.lo ext/gd/libgd/gd.lo ext/gd/libgd/gd_gd.lo ext/gd/libgd/gd_gd2.lo ext/gd/libgd/gd_io.lo ext/gd/libgd/gd_io_dp.lo ext/gd/libgd/gd_io_file.lo ext/gd/libgd/gd_ss.lo ext/gd/libgd/gd_io_ss.lo ext/gd/libgd/gd_png.lo ext/gd/libgd/gd_jpeg.lo ext/gd/libgd/gdxpm.lo ext/gd/libgd/gdfontt.lo ext/gd/libgd/gdfonts.lo ext/gd/libgd/gdfontmb.lo ext/gd/libgd/gdfontl.lo ext/gd/libgd/gdfontg.lo ext/gd/libgd/gdtables.lo ext/gd/libgd/gdft.lo ext/gd/libgd/gdcache.lo ext/gd/libgd/gdkanji.lo ext/gd/libgd/wbmp.lo ext/gd/libgd/gd_wbmp.lo ext/gd/libgd/gdhelpers.lo ext/gd/libgd/gd_topal.lo ext/gd/libgd/gd_gif_in.lo ext/gd/libgd/xbm.lo ext/gd/libgd/gd_gif_out.lo ext/hash/hash.lo ext/hash/hash_md.lo ext/hash/hash_sha.lo ext/hash/hash_ripemd.lo ext/hash/hash_haval.lo ext/hash/hash_tiger.lo ext/hash/hash_gost.lo ext/hash/hash_snefru.lo ext/hash/hash_whirlpool.lo ext/hash/hash_adler32.lo ext/hash/hash_crc32.lo ext/iconv/iconv.lo ext/json/json.lo ext/json/utf8_to_utf16.lo ext/json/utf8_decode.lo ext/json/JSON_parser.lo ext/mysql/php_mysql.lo ext/pdo/pdo.lo ext/pdo/pdo_dbh.lo ext/pdo/pdo_stmt.lo ext/pdo/pdo_sql_parser.lo ext/pdo/pdo_sqlstate.lo ext/pdo_sqlite/pdo_sqlite.lo ext/pdo_sqlite/sqlite_driver.lo ext/pdo_sqlite/sqlite_statement.lo ext/pdo_sqlite/sqlite/src/attach.lo ext/pdo_sqlite/sqlite/src/auth.lo ext/pdo_sqlite/sqlite/src/btree.lo ext/pdo_sqlite/sqlite/src/build.lo ext/pdo_sqlite/sqlite/src/callback.lo ext/pdo_sqlite/sqlite/src/date.lo ext/pdo_sqlite/sqlite/src/delete.lo ext/pdo_sqlite/sqlite/src/expr.lo ext/pdo_sqlite/sqlite/src/func.lo ext/pdo_sqlite/sqlite/src/hash.lo ext/pdo_sqlite/sqlite/src/insert.lo ext/pdo_sqlite/sqlite/src/legacy.lo ext/pdo_sqlite/sqlite/src/main.lo ext/pdo_sqlite/sqlite/src/os_unix.lo ext/pdo_sqlite/sqlite/src/os_win.lo ext/pdo_sqlite/sqlite/src/os.lo ext/pdo_sqlite/sqlite/src/pager.lo ext/pdo_sqlite/sqlite/src/pragma.lo ext/pdo_sqlite/sqlite/src/prepare.lo ext/pdo_sqlite/sqlite/src/printf.lo ext/pdo_sqlite/sqlite/src/random.lo ext/pdo_sqlite/sqlite/src/select.lo ext/pdo_sqlite/sqlite/src/table.lo ext/pdo_sqlite/sqlite/src/tokenize.lo ext/pdo_sqlite/sqlite/src/analyze.lo ext/pdo_sqlite/sqlite/src/complete.lo ext/pdo_sqlite/sqlite/src/trigger.lo ext/pdo_sqlite/sqlite/src/update.lo ext/pdo_sqlite/sqlite/src/utf.lo ext/pdo_sqlite/sqlite/src/util.lo ext/pdo_sqlite/sqlite/src/vacuum.lo ext/pdo_sqlite/sqlite/src/vdbeapi.lo ext/pdo_sqlite/sqlite/src/vdbeaux.lo ext/pdo_sqlite/sqlite/src/vdbe.lo ext/pdo_sqlite/sqlite/src/vdbemem.lo ext/pdo_sqlite/sqlite/src/where.lo ext/pdo_sqlite/sqlite/src/parse.lo ext/pdo_sqlite/sqlite/src/opcodes.lo ext/pdo_sqlite/sqlite/src/alter.lo ext/pdo_sqlite/sqlite/src/vdbefifo.lo ext/pdo_sqlite/sqlite/src/vtab.lo ext/pdo_sqlite/sqlite/src/loadext.lo ext/posix/posix.lo ext/reflection/php_reflection.lo ext/session/session.lo ext/session/mod_files.lo ext/session/mod_mm.lo ext/session/mod_user.lo ext/simplexml/simplexml.lo ext/spl/php_spl.lo ext/spl/spl_functions.lo ext/spl/spl_engine.lo ext/spl/spl_iterators.lo ext/spl/spl_array.lo ext/spl/spl_directory.lo ext/spl/spl_sxe.lo ext/spl/spl_exceptions.lo ext/spl/spl_observer.lo ext/sqlite/sqlite.lo ext/sqlite/sess_sqlite.lo ext/sqlite/pdo_sqlite2.lo ext/sqlite/libsqlite/src/opcodes.lo ext/sqlite/libsqlite/src/parse.lo ext/sqlite/libsqlite/src/encode.lo ext/sqlite/libsqlite/src/auth.lo ext/sqlite/libsqlite/src/btree.lo ext/sqlite/libsqlite/src/build.lo ext/sqlite/libsqlite/src/delete.lo ext/sqlite/libsqlite/src/expr.lo ext/sqlite/libsqlite/src/func.lo ext/sqlite/libsqlite/src/hash.lo ext/sqlite/libsqlite/src/insert.lo ext/sqlite/libsqlite/src/main.lo ext/sqlite/libsqlite/src/os.lo ext/sqlite/libsqlite/src/pager.lo ext/sqlite/libsqlite/src/printf.lo ext/sqlite/libsqlite/src/random.lo ext/sqlite/libsqlite/src/select.lo ext/sqlite/libsqlite/src/table.lo ext/sqlite/libsqlite/src/tokenize.lo ext/sqlite/libsqlite/src/update.lo ext/sqlite/libsqlite/src/util.lo ext/sqlite/libsqlite/src/vdbe.lo ext/sqlite/libsqlite/src/attach.lo ext/sqlite/libsqlite/src/btree_rb.lo ext/sqlite/libsqlite/src/pragma.lo ext/sqlite/libsqlite/src/vacuum.lo ext/sqlite/libsqlite/src/copy.lo ext/sqlite/libsqlite/src/vdbeaux.lo ext/sqlite/libsqlite/src/date.lo ext/sqlite/libsqlite/src/where.lo ext/sqlite/libsqlite/src/trigger.lo regex/regcomp.lo regex/regexec.lo regex/regerror.lo regex/regfree.lo ext/standard/array.lo ext/standard/base64.lo ext/standard/basic_functions.lo ext/standard/browscap.lo ext/standard/crc32.lo ext/standard/crypt.lo ext/standard/cyr_convert.lo ext/standard/datetime.lo ext/standard/dir.lo ext/standard/dl.lo ext/standard/dns.lo ext/standard/exec.lo ext/standard/file.lo ext/standard/filestat.lo ext/standard/flock_compat.lo ext/standard/formatted_print.lo ext/standard/fsock.lo ext/standard/head.lo ext/standard/html.lo ext/standard/image.lo ext/standard/info.lo ext/standard/iptc.lo ext/standard/lcg.lo ext/standard/link.lo ext/standard/mail.lo ext/standard/math.lo ext/standard/md5.lo ext/standard/metaphone.lo ext/standard/microtime.lo ext/standard/pack.lo ext/standard/pageinfo.lo ext/standard/quot_print.lo ext/standard/rand.lo ext/standard/reg.lo ext/standard/soundex.lo ext/standard/string.lo ext/standard/scanf.lo ext/standard/syslog.lo ext/standard/type.lo ext/standard/uniqid.lo ext/standard/url.lo ext/standard/url_scanner.lo ext/standard/var.lo ext/standard/versioning.lo ext/standard/assert.lo ext/standard/strnatcmp.lo ext/standard/levenshtein.lo ext/standard/incomplete_class.lo ext/standard/url_scanner_ex.lo ext/standard/ftp_fopen_wrapper.lo ext/standard/http_fopen_wrapper.lo ext/standard/php_fopen_wrapper.lo ext/standard/credits.lo ext/standard/css.lo ext/standard/var_unserializer.lo ext/standard/ftok.lo ext/standard/sha1.lo ext/standard/user_filters.lo ext/standard/uuencode.lo ext/standard/filters.lo ext/standard/proc_open.lo ext/standard/streamsfuncs.lo ext/standard/http.lo ext/tokenizer/tokenizer.lo ext/xml/xml.lo ext/xml/compat.lo ext/xmlreader/php_xmlreader.lo ext/xmlwriter/php_xmlwriter.lo TSRM/TSRM.lo TSRM/tsrm_strtok_r.lo TSRM/tsrm_virtual_cwd.lo main/main.lo main/snprintf.lo main/spprintf.lo main/php_sprintf.lo main/safe_mode.lo main/fopen_wrappers.lo main/alloca.lo main/php_scandir.lo main/php_ini.lo main/SAPI.lo main/rfc1867.lo main/php_content_types.lo main/strlcpy.lo main/strlcat.lo main/mergesort.lo main/reentrancy.lo main/php_variables.lo main/php_ticks.lo main/network.lo main/php_open_temporary_file.lo main/php_logos.lo main/output.lo main/streams/streams.lo main/streams/cast.lo main/streams/memory.lo main/streams/filter.lo main/streams/plain_wrapper.lo main/streams/userspace.lo main/streams/transports.lo main/streams/xp_socket.lo main/streams/mmap.lo Zend/zend_language_parser.lo Zend/zend_language_scanner.lo Zend/zend_ini_parser.lo Zend/zend_ini_scanner.lo Zend/zend_alloc.lo Zend/zend_compile.lo Zend/zend_constants.lo Zend/zend_dynamic_array.lo Zend/zend_execute_API.lo Zend/zend_highlight.lo Zend/zend_llist.lo Zend/zend_opcode.lo Zend/zend_operators.lo Zend/zend_ptr_stack.lo Zend/zend_stack.lo Zend/zend_variables.lo Zend/zend.lo Zend/zend_API.lo Zend/zend_extensions.lo Zend/zend_hash.lo Zend/zend_list.lo Zend/zend_indent.lo Zend/zend_builtin_functions.lo Zend/zend_sprintf.lo Zend/zend_ini.lo Zend/zend_qsort.lo Zend/zend_multibyte.lo Zend/zend_ts_hash.lo Zend/zend_stream.lo Zend/zend_iterators.lo Zend/zend_interfaces.lo Zend/zend_exceptions.lo Zend/zend_strtod.lo Zend/zend_objects.lo Zend/zend_object_handlers.lo Zend/zend_objects_API.lo Zend/zend_mm.lo Zend/zend_default_classes.lo Zend/zend_execute.lo sapi/cli/php_cli.lo sapi/cli/php_cli_readline.lo sapi/cli/getopt.lo main/internal_functions_cli.lo -lcrypt -lcrypt -lrt -lmysqlclient -lt1 -lpng -lz -ljpeg -lcurl -lbz2 -lz -lresolv -lm -ldl -lnsl -lxml2 -lz -lm -lssl -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto -lresolv -ldl -lz -lcurl -lssl -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto -lresolv -ldl -lz -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv -lidn -lssl -lcrypto -lssl -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto -lresolv -ldl -lz -lz -lxml2 -lz -lm -lxml2 -lz -lm -lcrypt -lxml2 -lz -lm -lxml2 -lz -lm -lxml2 -lz -lm -lcrypt -o sapi/cli/php<br />
ext/gd/libgd/.libs/gdkanji.o(.text+0x5b): In function `do_convert&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/gd/libgd/gdkanji.c:350: undefined reference to `libiconv_open&#8217;<br />
ext/gd/libgd/.libs/gdkanji.o(.text+0xa1):/home/jjdai/work/zhupiter/php-5.2.0/ext/gd/libgd/gdkanji.c:365: undefined reference to `libiconv&#8217;<br />
ext/gd/libgd/.libs/gdkanji.o(.text+0xb0):/home/jjdai/work/zhupiter/php-5.2.0/ext/gd/libgd/gdkanji.c:381: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;155): In function `_php_iconv_appendl&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:335: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;219):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:372: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x2b0): In function `php_iconv_string&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:428: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x2e8):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:437: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;309):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:450: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x32c):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:461: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x37d): In function `_php_iconv_strlen&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:586: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x3d8):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:609: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;402):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:643: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x47e): In function `_php_iconv_strpos&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:828: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x4e4):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:853: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;574):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:967: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x6fd): In function `_php_iconv_mime_decode&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1328: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x7a9):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1797: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x7bd):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1800: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0xa67):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1439: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0xa79):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1442: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;1025): In function `zif_iconv_substr&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:699: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x10c1):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:722: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;1108):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:779: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x111d):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:783: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x123e):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:730: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;1738): In function `zif_iconv_mime_encode&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1017: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;1756):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1031: undefined reference to `libiconv_open&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0&#215;1993):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1290: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x19ad):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1293: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x1b01):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1102: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x1b33):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1134: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x1b5e):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1150: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x1e10):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1202: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x1e3c):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1233: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x207f):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:1277: more undefined references to `libiconv&#8217; follow<br />
ext/iconv/.libs/iconv.o(.text+0x2c08): In function `php_iconv_stream_filter_dtor&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:2393: undefined reference to `libiconv_close&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x2cf2): In function `php_iconv_stream_filter_append_bucket&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:2543: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x2d34):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:2543: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x2de7):/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:2465: undefined reference to `libiconv&#8217;<br />
ext/iconv/.libs/iconv.o(.text+0x30e2): In function `php_iconv_stream_filter_factory_create&#8217;:<br />
/home/jjdai/work/zhupiter/php-5.2.0/ext/iconv/iconv.c:2419: undefined reference to `libiconv_open&#8217;<br />
collect2: ld returned 1 exit status<br />
make: *** [sapi/cli/php] Error 1<br />
[错误]error while loading shared libraries: libiconv.so.2:<br />
Tags:error Posted in webserver:-)抢沙发<br />
error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory<br />
安装好apache后apache无法启动<br />
问题是找不到共享库，查看apache的出错文件，查找的位置是/usr/lib，但实际上find / -name libiconv.so.2是可以找到了，位置在/usr/local/lib/<br />
只要加一个链接就行<br />
ln -s /usr/local/lib/libiconv.so.2 /usr/lib/libiconv.so.2<br />
其它有关库类找不着的都应该可以查看一下是否默认库的位置和实际位置不符</p>
<p>Php5.2.9下面安装pear<br />
访问 http://pear.php.net/go-pear  将这个页面的内容全选，复制 并保存成一个go-pear.php文件，然后将这个文件放到某个目录下面，然后 php –q go-pear.php 然后，按照提示进行安装。<br />
/home/tiger/evan/php5-fastcgi/bin/php -q go-pear.php</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/866.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Step-by-Step Guide to Building an OpenBSD PPPoE Gateway, with Firewall</title>
		<link>http://www.evanjiang.net.cn/archives/845.html</link>
		<comments>http://www.evanjiang.net.cn/archives/845.html#comments</comments>
		<pubDate>Mon, 23 Mar 2009 14:21:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[dns]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[openbsd unix]]></category>
		<category><![CDATA[pf]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[Building  OpenBSD PPPoE Gateway]]></category>
		<category><![CDATA[with Firewall]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=845</guid>
		<description><![CDATA[<p>Introduction
Why would one install his own personal gateway to the Internet? Because it is quite easy to do. And also because it simply is the most reliable, safest way to connect machines to a dedicated xDSL modem. Moreover, we can stash a whole bunch of useful features in such a little box. Here is a [...]]]></description>
			<content:encoded><![CDATA[<p>Introduction<br />
Why would one install his own personal gateway to the Internet? Because it is quite easy to do. And also because it simply is the most reliable, safest way to connect machines to a dedicated xDSL modem. Moreover, we can stash a whole bunch of useful features in such a little box. Here is a list: </p>
<p>PPPoE Gateway<br />
PPPoE is a curious beast forced down our throats by some DSL providers. On one side, it does not really break anything, has low overhead and allows you to change IP adresses very easily &#038; quickly. On the other side, it sucks big time because it does add overhead to the IP packets, is proprietary, non-standard, forces you to change IP adresses unpredictably, and is unsupported in most operating systems. A good PPPoE gateway simply hides PPPoE from the machines on your internal network. It makes life much easier because you don&#8217;t have to install any special &#8220;access manager&#8221; software on your windoze boxen. They will just work (provided you set their IP address correctly). </p>
<p>Firewall<br />
A firewall is quite mandatory for any machine directly connected to the Big Bad Internet. We want an industrial-strength stateful inspection firewall and this is what we&#8217;ll get. </p>
<p>NAT (Network Adress Translation)<br />
The name seems complex, but it is really quite simple: this allows the gateway machine to act on the internet on behalf of all the machines located on the intranet (your internal home network). Even though you might have two, three or even ten computers on your local network, a NAT equipped gateway will hide them to outside observers. They will only see a single very busy machine, with a single IP address. </p>
<p>DNS (Domain Name Service) cache<br />
Having your own DNS server will lower the latency of getting DNS translations for all the machines on your intranet. This will not really decrease the traffic on your DSL modem by a large percentage, but it will improve the quality of the &#8220;internet experience&#8221; on your local network. </p>
<p>Dynamic DNS tracker<br />
Free dynamic DNS services are extremely useful to xDSL customers. They allow you to have your very own domain name, free of charge, which will follow in real-time your IP address changes. The catch is that the top-level part of your domain must be one of their supplied choices. They are not that bad, really&#8230; Personally, I use DYNDNS but any of the multiple free dynamic DNS providers out there will do just fine. Simply make sure they have a client &#8220;updater&#8221; which can compile and run under OpenBSD. </p>
<p>WEB server<br />
Most ISP&#8217;s only allow a few megabytes of disk for web service. Moreover, they never give you direct access to the web logs. Having your own web server allows you the luxury of using all the disk space you want, plus the added advantage of complete control over the web service (cgi-bin) and its logs. Moreover, OpenBSD comes with a crypto-enabled version of Apache and all the tools you need to create RSA-keyed certificates. </p>
<p>Mail server<br />
Have you ever wanted to create a temporary email address just to receive some password? Or simply wanted addresses tailored for specific domains of interest? These are only a few of the many advantages of having your own mail server. </p>
<p>NTP server<br />
The Network Time Protocol allow you to synchronize the gateway&#8217;s clock to one of the numerous atomic time references available on the internet. Moreover, the same program is also used as a local time server, so that all your intranet machines can themselves synchronize their clocks to the gateway&#8217;s clock. NTP synchronizations are made in tiers, like this, in order to lower the burden on the public time servers. </p>
<p>This page is for all those of you who have are lucky enough to enjoy a dedicated xDSL connection and would like to have a small firewall installation. In my search for the holy grail, i found the answer to most of my wishes in the OpenBSD package. This step-by-step guide is a collection of notes taken while I was installing the thing. They are intended to help my friends do their own setups very quickly and easily, without having to bug me too much <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  They should help you too.</p>
<p>Constructive comments can be sent there &#8230; Have fun and GOOD LUCK!</p>
<p><span id="more-845"></span><br />
Getting some hardware<br />
The first thing to think about when one embarks on the firewalling adventure is to establish on what hardware you are going to install the thing. This seems unimportant at first, but don&#8217;t forget that this box will be turned on 24/7, so the components you use must be reliable.</p>
<p>What are the minimum requirements? My system uses about 50% of its CPU to support Sympatico&#8217;s ADSL rate (around 900 kbps). It is built with the following components:</p>
<p>An ancient 486 motherboard (with an ISA bus) given to me by a friend (thanks Christian!). It runs at 66 MHz.<br />
32 MB of brand new RAM i bought for it.<br />
A 200 MB hard disk, which was dying after about 1 year of faithful use (it came with the motherboard). This disk was recently replaced with the cheapest brand new drive i could find. I didn&#8217;t know they still made those slow 3600 RPM drives <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Anyway, the old drive is kept as a kind of extreme emergency backup.<br />
Two ISA-bus ethernet cards. I&#8217;ll talk more about this later.<br />
A CD-ROM drive. Very optional, but can make life easier.<br />
A &#8220;home&#8221; grade hub &#038; cat5 cabling. This is not strictly necessary if you&#8217;ll have only one machine connected to your firewall: you can make do with a special &#8220;crossover&#8221; cat5 cable instead. The cable that comes with xDSL modems is usually (always?) a crossover cable. Anyway, for two or more machines, the hub is mandatory. Small hubs can be bought for a very reasonable price (~40$ cdn).<br />
or<br />
Alternatively, many older ethernet cards come with a BNC female connector. This can be used to connect the machines on your network with coax cables, without any hub. However, be warned that a 10base-2 network must follow certain rules if you want it to work flawlessly. Follow them.<br />
This gives a good approximation of what you need. The MOST important part is the RAM. Make absolutely sure that whatever RAM you use is reliable. Old boxen were usually setup to run Windoze, and it was not a big deal if the machine had flaky RAM because of the way Windoze works&#8230;</p>
<p>OpenBSD (like any real OS out there) is much less tolerant of flaky RAM, because it actually uses all of it. It will crash quite quickly if your RAM is marginal, probably within 5-10 minutes. You have been warned.</p>
<p>Finally, the OpenBSD hardware list is there. Try to make sure that whatever hardware you use in your gateway box figures on that list. It&#8217;s a long list <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>The ethernet cards<br />
There is a boring thing of which we must talk about here. You see, there are many kinds of ethernet cards, and you must make sure you have the right ones for your machine. If you have a PCI-based machine, then all is well. Whatever ethernet card you put in there will probably be supported by OpenBSD. However, you must be a bit more careful if you have an ISA-based machine.</p>
<p>It is most likely that your box will not have any ethernet cards to start with since most people did not have networks at home in the pre-historic era of 4 years ago. You need two cards. One will be connected to the DSL modem (the big, bad outerworld), while the other is connected to your internal network hub (your intranet). The gateway&#8217;s job will be to pass (or block) packets between those two network cards. For security, its very important that the outside world packets cannot reach directly any of the intranet machines. This is the reason why we use two ethernet cards: complete logical and electrical isolation. Why so much isolation? For example, if someone(s) were launching a full (distributed or not) denial of service attack on your gateway box, its internet-connected ethernet card would be extremely busy, but your intranet would see nothing of this. While any communication with the outside world would probably fail, at least your intranet machines would still be able to talk to each other.</p>
<p>ISA cards use dedicated I/O ports and IRQ&#8217;s in your machine. Those must be setup either with jumpers directly on the card, or with a special DOS program if the card is of the more recent &#8220;Plug &#038; Play&#8221; type. This DOS program is always supplied with the card, when purchased brand new.</p>
<p>If your card is Plug&#038;Play, you must disable the Plug&#038;Play, and program specific I/O port and IRQ values with the setup software that comes with the card. Make sure that you program both cards with different sets of I/O ports and IRQs! Otherwise they will battle each other for cycles on the bus and the result will not be pretty. Once you have set the parameters on the card it will remember them and you don&#8217;t have to reprogram anything later on, even if the computer is turned off.</p>
<p>It is good at this point to know a few magic numbers:</p>
<p>Card Type I/O #1 IRQ #1 Mem #1 I/O #2 IRQ #2 Mem #2<br />
NE2000 (ne) 0&#215;240 9 &#8212; 0&#215;300 10 &#8212;<br />
SMC WD-8003 (we) 0&#215;280 9 0xd0000 0&#215;300 10 0xcc000 </p>
<p>For example, i use two cards made by AOpen: the model ALN-101. They are Plug&#038;Play and use the NE2000 chip. The first one is setup at I/O port 0&#215;240, IRQ 9. It is known as &#8220;ne0&#8243; in the GENERIC openBSD kernel. The second one is set at I/O port 0&#215;300, IRQ 10. It is known as &#8220;ne1&#8243;. If the cards were programmed differently, the GENERIC kernel would not recognize them &#8220;out of the box&#8221; and you would have to re-configure the kernel. It can be done, but its much easier to setup the hardware once than re-configure the kernel every time it gets upgraded.</p>
<p>Some of you might have problems setting the card to an arbitrary combination of IO port and IRQ number. This is allright, just let the card decide what it wants and simply reconfigure your kernel to accomodate that. What is important is that both ethernet cards are not set to conflicting values. Otherwise, any combination that the cards like will be programmable in the kernel.</p>
<p>Last but not least: some cards can be used in the so-called &#8220;full-duplex&#8221; mode. Be aware that if you want to use an ethernet card in full-duplex, your hub must also be full-duplex, as well as the other ethernet cards in the system. A full-duplex hub is much more expensive and not necessary at all. Unless you know what you are doing, program your ethernet cards to use the half-duplex mode, otherwise it won&#8217;t play nice with the other components in your local network, including the xDSL modem <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
(注，这里需要说NE2000等旧款的基于486机的网卡也可以用，但现在这些网卡，其本难找，所以至少要用8139系列芯片的10-100M自适应的网卡来做应用）</p>
<p>The hard disk<br />
The most secure storage medium is one which can&#8217;t be erased. Some firewalls actually use setups like this (with CD-ROMS) but we&#8217;ll build our firewall with a classic, writeable hard drive because:</p>
<p>We don&#8217;t need &#8220;Absolute Security&#8221;, do we? We can&#8217;t have it anyway <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
We want to use an &#8220;out-of-the-box&#8221; OpenBSD distro. This will make maintenance (security, patches, etc&#8230;) much easier.<br />
Almost any hard disk out there will work OK, since 200 MB is a safe minimum size. The only thing you must remember is that this disk will run 24/7, so if you use an old drive, it will likely die relatively soon. The venerable drive my friend gave me lasted 6 months before i had to change it, YMMV.</p>
<p>No keyboard?<br />
Of course you&#8217;ll need a keyboard&#8230; and a monitor too, but just for the installation. After the firewall is successfully installed, you will be able to talk to it through encrypted ssh connections over your internal network, so a keyboard &#038; monitor will not be really useful at that point.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Getting the software<br />
We will be using OpenBSD. Why? Because it is the most secure freely available operating system out there. All the source code included in the mainstream distribution CD&#8217;s has been audited for years by the OpenBSD team, which is why sometimes an exploit published on BugTraq is found not to work on OpenBSD simply because the faulty code was already fixed months ago.</p>
<p>I strongly suggest you buy their CD-ROM kit as it comes with a set of very cool stickers&#8230; You can also download their stuff for free, of course, but you won&#8217;t have the stickers then <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>This Guide is written for OpenBSD 3.0.</p>
<p>The easiest way to install the software is to use a CD-ROM drive on your firewall box. If you don&#8217;t have that, you can do a network install with the &#8220;ftp&#8221; protocol, either directly to an outside OpenBSD mirror, or to one of your own internal machines equipped with an ftp server. Be aware that if your DSL provider forces you to use PPPoE (boooo!), then of course your link to the outside world will not be functional yet at installation time, which is one more reason to use the CD-ROM. If your machine can boot a CD-ROM, great! It will gladly boot the OpenBSD disc. Otherwise, simply create a boot diskette according to the README and boot that. This diskette is also your rescue disk, so don&#8217;t lose it.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Installing OpenBSD<br />
The installation of OpenBSD is very easy, once you have the right hardware, and the right answers to some of the questions. In the following steps, i&#8217;ll assume you can follow the instructions of the install program and focus only on the tricky little things you should know to make your life easier.</p>
<p>fdisk &#038; disklabel<br />
After you boot the installer, one of the very first things you&#8217;ll have to do is partition your disk. This is done with the &#8220;fdisk&#8221; and &#8220;disklabel&#8221; programs. The installer will ask you if you want to use the entire hard disk for OpenBSD. Answer No, even if it is not entirely true. If you say yes, the whole fdisk step will be bypassed, and you will not be able to change the default cylinder/head/sector configuration in order to boot off the hard disk without resorting to the silly &#8220;FDISK /MBR&#8221; DOS command which is a stupid solution to a stupid problem.<br />
The default OpenBSD fdisk partition setup choice is in slot #3. If you want, you can move your OpenBSD partition in slot #0 with no ill effect.</p>
<p>Important: On some systems, to make sure your system boots off the hard disk, you must set the starting CHS (cylinder/head/sector) to C=0, H=0, S=1, because fdisk suggested an incorrect value for H in OpenBSD 2.7, and still does in 2.8 &#8230; If you use &#8220;1&#8243;, as it suggests, your system will not be able to boot from the hard disk.</p>
<p>After the disk is partitioned with fdisk, you use disklabel to further organize the partition. A label behaves like a traditional partition (as used in Linux, for example), except that you can put as many labels as you want in the single OpenBSD partition. This is useful.</p>
<p>On a fully partitioned system, the disk labels might look like this: </p>
<p>  a:  2097648        0    4.2BSD     1024  8192    16   # /               1 GB<br />
  b:   262080  2097648      swap                        # SWAP          128 MB<br />
  c: 20015856        0    unused        0     0         # (whole disk)   10 GB<br />
  d:  2097648  2359728    4.2BSD     1024  8192    16   # /usr            1 GB<br />
  e:  2097648  4457376    4.2BSD     1024  8192    16   # /tmp            1 GB<br />
  f:  2097648  6555024    4.2BSD     1024  8192    16   # /var            1 GB<br />
  g:  4194288  8652672    4.2BSD     1024  8192    16   # /usr/local      2 GB<br />
  h:  7168896 12846960    4.2BSD     1024  8192    16   # /home           3 GB<br />
On my firewall, i like to keep things simpler, so it goes like this: </p>
<p>#        size   offset    fstype   [fsize bsize   cpg]<br />
  a: 18874800        0    4.2BSD     1024  8192    16   # (Cyl.    0 &#8211; 18724)<br />
  b:  1141056 18874800      swap                        # (Cyl. 18725 &#8211; 19856)<br />
  c: 20015856        0    unused        0     0         # (Cyl.    0 &#8211; 19856)As you see, the &#8216;c&#8217; label is a placeholder for the whole disk, in all cases. Don&#8217;t delete or otherwise change this, or you&#8217;ll be in trouble. </p>
<p>One of the main disadvantages of having a single partition is that one could do bad things in such quantity that the log files would simply fill up the whole drive. OpenBSD doesn&#8217;t like it when all its disk space is full. You can guess the rest of the story. In practice, this is not an issue, since i monitor my log files daily, but it could be an issue for someone out there. </p>
<p>On a fully partitioned system, the &#8220;df&#8221; command says this, after the OS is installed, with its complete source trees: </p>
<p>Filesystem      1K-blocks     Used    Avail Capacity  Mounted on<br />
/dev/wd0a         1015269    25985   938521     3%    /<br />
/dev/wd0d         1015269   480284   484222    50%    /usr<br />
/dev/wd0e         1015269        1   964505     0%    /tmp<br />
/dev/wd0f         1015269     5141   959365     1%    /var<br />
/dev/wd0g         2030307     8698  1920094     0%    /usr/local<br />
/dev/wd0h         3470505       27  3296953     0%    /home</p>
<p>On my system i have this:</p>
<p>Filesystem                           1K-blocks     Used    Avail Capacity  Mounted on<br />
/dev/wd0a                              9137589   503054  8177656     6%    /</p>
<p>In this example, the full OpenBSD source tree is installed, which explains why the thing uses up about 500 MB. Without the source tree, you only need about 120 MB in there, but having the source tree allows you to make security patches as they are published. This is important and i&#8217;ll talk about it more later.</p>
<p>Active FTP<br />
If you do an FTP install to a private FTP server, it might be necessary to use active FTP. </p>
<p>Crypto, SSL, etc&#8230;<br />
The crytographic packages are included in the CD&#8217;s since release 2.9 of OpenBSD. They will be automatically installed. </p>
<p>UTC time zone<br />
Keep your server in the UTC time zone. This way, your firewall logs will be timestamped in UTC time and it will be simpler to have them interpreted by the abuse@&#8230; services of ISP&#8217;s. Also, it is important to make sure the gateway is time-synchronized to one of the numerous public NTP servers out there, because having only an IP address is not enough to pin down internet abusers. In this age of dynamic IP allocations you need both IP address and exact time in order to positively identify the origin of an IP packet. Keep your gateway synchronized.<br />
Why not GMT instead? Read all about it there.</p>
<p>Normally, the installer will ask you for a time zone at install time. If you want to change it later, simply make /etc/localtime point to /usr/share/zoneinfo/UTC with a soft link: </p>
<p>ln -s /usr/share/zoneinfo/UTC /etc/localtime</p>
<p>First Boot<br />
reboot &#8230; did your machine boot correctly? If not, please consult the numerous FAQ&#8217;s available at the OpenBSD site. Are you sure you set H=0 in fdisk? By the way, if it doesn&#8217;t boot from hard disk, you can probably still force it by first booting the install diskette, and entering &#8220;boot wd0a:/bsd&#8221; at the initial prompt. You have about 5 seconds to make your mind, when you see this prompt, act swiftly.<br />
On first boot, you will probably get a message like &#8220;ssh-keygen: generating new DSA host key&#8230;&#8221;, followed with an equivalent message for the RSA host key. They might take quite a long time on a 486 (5-10 minutes), so Don&#8217;t Panic! &#8482; , the machine is not crashed, and the boot process will eventually follow its course, given time. This will happen only on the first boot.</p>
<p>Kernel extra configuration<br />
If, at this point, the kernel sees all you devices (including both ethernet cards), congratulations. If not, you can reconfigure the kernel without having to recompile it by simply using the config utility. Typically, you would copy your current kernel (the &#8220;/bsd&#8221; file) to an appropriate backup name (e.g. &#8220;/bsd.ORIGINAL&#8221;), and issue this command: </p>
<p>config -e -f /bsd<br />
and make whatever changes you need. You should know what you&#8217;re doing in order to use this command without blowing your system up into tiny bits &#038; pieces. Don&#8217;t forget to save your changes. If this modified kernel doesn&#8217;t work OK, just boot the &#8220;/bsd.ORIGINAL&#8221; kernel instead, and you will have another chance. </p>
<p>Sys control files<br />
The services allowed by OpenBSD are configured by a couple of files in the /etc directory. Actually, this directory contains all the configuration files of OpenBSD, for your convenience, but this is something you&#8217;ll only appreciate later, when you become an experienced BSD maintainer&#8230; We&#8217;ll come back to that /etc directory quite often.<br />
For now, just make sure that the following are enabled:</p>
<p>In the file /etc/sysctl.conf:<br />
net.inet.ip.forwarding=1</p>
<p>and in /etc/rc.conf:<br />
sendmail_flags=&#8221;-L sm-mta -bd -q30m&#8221;<br />
named_flags=&#8221;"<br />
httpd_flags=&#8221;-DSSL&#8221;</p>
<p>Important: If you plan to use PPPoE, don&#8217;t enable pf here because you want to start it in a controlled manner, after PPPoE is started. Enabling &#8220;pf&#8221; here would make it start at the very beginning of the boot process and this would not work. </p>
<p>PPP &#038; PPPoE<br />
Ahhhh&#8230; the Evil Beast. Installing a good, working PPP and PPPoE can be quite a tricky task. In OpenBSD 3.0, it is included and works well, once properly configured. This version of PPP supports the &#8220;mssfixup&#8221; instruction which magically allows you to avoid setting MTU&#8217;s at 1492 or less on all of your intranet&#8217;s machines. This is very recommended as it avoids a whole bunch of problems with Windows machines, internet appliances, etc&#8230;<br />
Notice that there is an excellent Network FAQ available from the OpenBSD site. It contains a lot of information on what to do with those ethernet adapters. </p>
<p>The configuration file for ppp is in /etc/ppp/ppp.conf. Mine contains exactly this:</p>
<p>default:<br />
 set log Phase Chat IPCP CCP tun command<br />
 set redial 15 0<br />
 set reconnect 15 10000</p>
<p>pppoe:<br />
 set device &#8220;!/usr/sbin/pppoe -i ne0&#8243;<br />
 disable acfcomp protocomp<br />
 deny acfcomp<br />
 set mtu max 1492<br />
 set speed sync<br />
 enable lqr<br />
 set lqrperiod 5<br />
 set cd 5<br />
 set dial<br />
 set login<br />
 set timeout 0<br />
 set authname xxxxxxx<br />
 set authkey xxxxxx<br />
 add! default HISADDR<br />
 enable dns<br />
 enable mssfixupNotice how we specify the real network interface ne0 to pppoe (with double quotes), and that i use &#8220;max 1492&#8243; for the MTU value, as suggested by many people. Also, no value is specified for the MRU, the PPP network address translation is not enabled, the magic &#8220;mssfixup&#8221; is enabled and i use the &#8220;add!&#8221; command instead of plain &#8220;add&#8221; (suggested by Chris Pockele).</p>
<p>Also notice that the authname and authkey fields don&#8217;t contain double-quote characters. You should put in there your own ISP identification and password. Some ISPs require authname to have a full identification (e.g. &#8220;username@sympatico.ca&#8221;), while other ISPs will want to have only &#8220;username&#8221; in the authname field. Experiment.</p>
<p>Robert Jameson (thanks Robert!) reports that some ISPs require you to specify the pppoe service you want. This is done on the &#8220;set device&#8221; line. For example: </p>
<p>      set device &#8220;!/usr/sbin/pppoe -n Shasta_1 -i ne0&#8243;</p>
<p>VERY IMPORTANT!</p>
<p>For some reason, the routes setup automatically by ppp at linkup time were not correctly defined prior to OpenBSD version 3.0. The MTU&#8217;s were wrong, leading to all sorts of subtle problems. This is now fixed, and we can safely use the &#8220;add default HISADDR&#8221; command in the ppp config file, with no special route commands at all in the ppp.linkup file. The MTUs will be properly set to 1492 on all the routes which go through the external interface. </p>
<p>The command &#8220;netstat -rn&#8221; confirms this:</p>
<p>pcreal# netstat -rn<br />
Routing tables</p>
<p>Internet:<br />
Destination        Gateway            Flags     Refs     Use    Mtu  Interface<br />
default            65.92.185.1        UGS         3    13423   1492   tun0<br />
65.92.185.1        65.92.185.97       UH          1        0   1492   tun0<br />
127.0.0.1          127.0.0.1          UH          1     1045  33224   lo0<br />
192.168.1/24       link#2             UC          0        0   1500   ne1<br />
192.168.1.1        0:e0:18:90:a7:c7   UHL         3    10475   1500   ne1<br />
&#8230;</p>
<p>A friend from Australia (thanks Doug!) suggested i clarify the following points:</p>
<p>(1) The 64.229.x.x adresses will NOT be the same in your setup! Those are the adress blocks of my PPPoE service provider (Sympatico). Your own setup will use, most likely, different address blocks.</p>
<p>(2) The ppp daemon creates a virtual network interface (&#8220;tun0&#8243;) out of thin air. This virtual network interface is internally linked to the actual physical interface (&#8220;ne0&#8243; in my system), but you will never have to deal directly with &#8220;ne0&#8243; in your configuration files. For example, the firewall rules are written with the virtual &#8220;tun0&#8243; interface, not the physical &#8220;ne0&#8243; interface. In my setup, the internal interface is &#8220;ne1&#8243;, and the external interface is &#8220;tun0&#8243;. Here is Doug&#8217;s analogy with the Windows world:</p>
<p>&#8220;&#8230; think of the PPPoE adaptor like the dialup adaptor in a Windows<br />
control panel. it doesn&#8217;t really exist but you gotta have it&#8230;&#8221;(3) The ppp daemon takes care of automatically assigning the name servers and the routes. Consequently, make sure there is no file &#8220;/etc/mygate&#8221;, and bear in mind that &#8220;/etc/resolv.conf&#8221; will be automatically generated as well, at connection time. This has the advantage that you don&#8217;t need to know anything about the details of your connection (name server adresses, etc&#8230;) to your ISP. Your user ID and password are sufficient, as the ppp daemon will negociate with the server and obtain the information it needs to open the connection.</p>
<p>(4) Since the ppp daemon will take are of the external network interface, you don&#8217;t need a &#8220;/etc/hostname.ne0&#8243; file. However, you do need a file to describe your internal network interface (in my case, &#8220;ne1&#8243;):</p>
<p>pcreal# cat /etc/hostname.ne1<br />
inet 192.168.1.2 255.255.255.0 NONENormally, this file should have been built by the setup program of OpenBSD, but if not, you must manually put it there and replace the &#8220;192.168.1.2&#8243; with whatever address you want your gateway to have as seen from your internal network.</p>
<p>Another friend, from France (thanks Xavier!), sent me this ascii picture of the network connections:</p>
<p>           |                                      |<br />
   internet| ====> |DSL Modem| ====>|server|=====>|LAN (HUB)<br />
           |                   tun0           ne1 |<br />
           |                   =ne0               |</p>
<p>Note: I consider this PPP/PPPoE setup to be a work in progress. I continually discover new things about it&#8230; so, please bear with me and do send me your feedback about your own experience regarding PPP/PPPoE. It really is a pain, but apparently we will be stuck with it for a long long time, so we might as well learn how to tame the thing!</p>
<p>Second Boot<br />
reboot &#8230; your machine should boot correctly. You won&#8217;t have internet access yet because the ppp program is not activated. If you want to try it out, just issue </p>
<p>ifconfig ne0 up<br />
ppp -ddial pppoeand ping/telnet away. Don&#8217;t worry if you get &#8220;carrier settings ignored&#8221;, or &#8220;change route failed&#8221; messages. Be careful because at this point you have no firewall rules set, so you are very vulnerable. Also, make sure your xDSL modem is plugged in the correct ethernet card&#8230;</p>
<p>If all works well, then you should kill the &#8220;ppp&#8221; process. Only restart it when the firewall rules are in place.</p>
<p>The afterboot phase<br />
Follow the instructions obtained by issuing the &#8220;man afterboot&#8221; command. Actually, quoting FAQ section 2.3, here is a list of the most useful man pages for new users: </p>
<p>     * [15]afterboot(8) &#8211; things to check after the first complete boot<br />
     * [16]boot(8) &#8211; system boot strapping procedures<br />
     * [17]passwd.conf(5) &#8211; format of the password configuration file<br />
     * [18]adduser_proc(8) &#8211; procedure for adding new users<br />
     * [19]adduser(8) &#8211; command for adding new users<br />
     * [20]vipw(8) &#8211; edit the pass word file<br />
     * [21]man(1) &#8211; display the on-line manual pages<br />
     * [22]sendbug(1) &#8211; send a problem report (PR) about OpenBSD to a<br />
       central support site.<br />
     * [23]disklabel(8) &#8211; Read and write disk pack label.<br />
     * [24]ifconfig(8) &#8211; configure network interface parameters.<br />
     * [25]route(8) &#8211; manually manipulate the routing tables.<br />
     * [26]netstat(1) &#8211; show network status.<br />
     * [27]reboot, halt(8) &#8211; Stopping and restarting the system.<br />
     * [28]shutdown(8) &#8211; close down the system at a given time.<br />
     * [29]boot_config(8) &#8211; how to change kernel configuration at boot</p>
<p>One of the first things you should do at this point is to add an unprivileged user and make him member of the wheel group. This is because, for security reasons, it is never a good idea to log in directly as root. The preferred way to gain root privileges is to login as a wheel member, and then use the &#8220;su -&#8221; command to gain root privileges.</p>
<p>OpenBSD will not prevent you from logging in directly as root, but will warn you every time against doing it.</p>
<p>Have fun!</p>
<p>Firewall and NAT rule sets<br />
This is a tricky one. Many people earn a good living just by knowing how to write firewall rule sets! Moreover, the whole packet filter and NAT code was completely rewritten from scratch in OpenBSD 3.0. It is now called &#8220;pf&#8221;, and is completely free of any external licensing strings so we will always have the latest, fully audited versions in future OpenBSD releases.<br />
Here are my own pf rules, in all their glory. They were heavily influenced by the various man pages and HOW-TO&#8217;s pertaining to &#8220;pf&#8221;. Be aware that they might be either too restrictive, or not enough, depending on your context. My philosophy about this is to disallow everything by default, and only open whatever is known to be useful. This restrictive ruleset will prevent ftp from working correctly, from the firewall itself. However, the ftp proxy currently available will work correctly for client machines located on the intranet. </p>
<p>Don&#8217;t forget to send me your tips for better rules&#8230; Thanks!</p>
<p>/etc/nat.conf<br />
nat on tun0 from 192.168.1.0/24 to any -> tun0<br />
rdr on ne1 proto tcp from any to any port 21 -> 127.0.0.1 port 8081</p>
<p>/etc/pf.conf<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# PF ruleset, 11 dec. 2001<br />
#<br />
# Liberally adapted from the pf man page, the OpenBSD &#8220;Network How-To&#8221;,<br />
# and my own rulesets.<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# Definitions<br />
Ext = &#8220;tun0&#8243;            # External interface<br />
Int = &#8220;ne1&#8243;             # Internal interface<br />
Loop = &#8220;lo0&#8243;            # Loopback interface<br />
IntNet=&#8221;192.168.1.0/24&#8243; # Internal network</p>
<p>NoRoute = &#8220;{ 127.0.0.1/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 255.255.255.255/32 }&#8221;</p>
<p>InServicesTCP = &#8220;{ ssh, smtp, auth, http, https, pop3 }&#8221;<br />
#InServicesUDP = &#8220;{ domain }&#8221;<br />
OutServicesTCP = &#8220;{ http, https, smtp, pop3, whois, domain, ssh, telnet, ftp, ftp-data, nntp, auth, ntp }&#8221;<br />
OutServicesUDP = &#8220;{ ntp, domain }&#8221;</p>
<p>XMMS = &#8220;{ 6000, 7500, 8000, 8004, 8044, 8034, 8052, 8038, 8010, 8400, 8014, 8026, 8048, \<br />
          8002, 8024, 8028, 8080 }&#8221;<br />
RealAudio = &#8220;{ 554, 7070, 8080 }&#8221;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# Clean up fragmented and abnormal packets<br />
# By default in pf, packets which contain IP options are blocked. Good.<br />
scrub in on { $Ext, $Int } all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# Defaults<br />
# block and log everything<br />
block             out log on $Ext           all<br />
block             in  log on $Ext           all<br />
block return-rst  out log on $Ext proto tcp all<br />
block return-rst  in  log on $Ext proto tcp all<br />
block return-icmp out log on $Ext proto udp all<br />
block return-icmp in  log on $Ext proto udp all</p>
<p>block in  quick inet6 all<br />
block out quick inet6 all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# loopback packets left unmolested<br />
pass in quick on $Loop all<br />
pass out quick on $Loop all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# Immediate blocks<br />
# fuzz any &#8216;nmap&#8217; attempt<br />
block in log quick on $Ext inet proto tcp from any to any flags FUP/FUP<br />
block in log quick on $Ext inet proto tcp from any to any flags SF/SFRA<br />
block in log quick on $Ext inet proto tcp from any to any flags /SFRA</p>
<p># don&#8217;t allow anyone to spoof non-routeable addresses<br />
block in log quick on $Ext from $NoRoute to any<br />
block out log quick on $Ext from any to $NoRoute</p>
<p># silently drop broadcasts (cable modem noise)<br />
block in quick on $Ext from any to 255.255.255.255<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# PASS rules</p>
<p># ALL  &#8212; we don&#8217;t normally do that. For debugging only.<br />
#pass out quick on $Ext all keep state</p>
<p># pass in data mode connections for ftp-proxy running on this host.<br />
pass in quick on $Ext inet proto tcp from any to any port > 49151 flags S/SA keep state</p>
<p># ICMP<br />
pass out     quick on $Ext inet proto icmp all icmp-type 8 code 0 keep state<br />
pass in  log quick on $Ext inet proto icmp all icmp-type 8 code 0 keep state</p>
<p># Services we provide to the outside world<br />
#pass in quick on $Ext inet proto udp from any to any port $InServicesUDP keep state<br />
pass in quick on $Ext inet proto tcp from any to any port $InServicesTCP flags S/SA keep state</p>
<p># Standard services we want to access in the world<br />
pass out quick on $Ext inet proto udp from any to any port $OutServicesUDP keep state<br />
pass out quick on $Ext inet proto tcp from any to any port $OutServicesTCP flags S/SA modulate state</p>
<p># Special services<br />
pass out quick on $Ext inet proto tcp from any to any port $XMMS flags S/SA modulate state<br />
pass out quick on $Ext inet proto tcp from any to any port $RealAudio flags S/SA modulate state<br />
IMPORTANT: Note that the &#8220;rdr&#8221; rule in the NAT file refers to the INTERNAL network interface. Its purpose is to redirect all ftp-data requests from the intranet to be redirected to the ftp-proxy on the firewall. Then the ftp-proxy channels those into ports 49152-65535, and outputs them on the internet. This is why we have this hole in the firewall starting at port 49152. I know, it is in the IN direction, but that is how passive ftp works&#8230; It is quite a broken protocol.<br />
That&#8217;s it! Nothing too painful, as you see. Since pf is a stateful inspection firewall, we can keep our ingress rules to a strict minimum. Notice the sheer elegance of the ruleset, with all services defined at once in a single IN or OUT rule. </p>
<p>One last thing: in order to automagically enable your firewall when the link comes up, you can put the following lines in the /etc/ppp/ppp.linkup file. Notice the extra space in front of each &#8220;!&#8221; character:</p>
<p>MYADDR:<br />
 ! sh -c &#8220;/sbin/ifconfig pflog0 up&#8221;<br />
 ! sh -c &#8220;/sbin/pfctl -e -l tun0 -F all -O aggressive -R /etc/pf.conf -N /etc/nat.conf&#8221;</p>
<p>The FTP proxy<br />
If you want tight security, and no FTP available on your intranet, simply remove the hole at 49152, and the &#8220;rdr&#8221; command in the file &#8220;nat.conf&#8221;. However, if you want to be able to use FTP from the intranet, then you must keep those, as well as enable the &#8220;ftp-proxy&#8221; service in inetd. Simply add this line to inetd.conf : </p>
<p>8081            stream  tcp     nowait  root    /usr/libexec/ftp-proxy  ftp-proxyDon&#8217;t forget that you still won&#8217;t be able to do FTP&#8217;ing from the firewall itself, when the packet filtering is enabled. Hopefully, it is very easy to temporarily disable pf with the command &#8220;pfctl -d&#8221;, and later re-enable it with the command &#8220;pfctl -e&#8221;. This comes in handy when we install packages from ftp.openbsd.org with the command &#8220;pkg_add&#8221;. </p>
<p>We are confident that ftp-proxy will improve with time and eventually dynamically manipulate the state tables of the firewall in order to open/close needed connections on-the-fly. </p>
<p>Addinc stuff to /etc/rc.local<br />
This is where our custom startup instructions go. Those things are started while the kernel is in secure level 1. If you need anything started in a lower security level, modify /etc/rc.securelevel instead. In order to start up PPPoE correctly, I added this at the end of my /etc/rc.local : </p>
<p>ifconfig ne0 up<br />
route flush<br />
ppp -ddial pppoe</p>
<p>This starts PPP, PPPoE, the firewall and the NAT translator (because the firewall and the NAT are started automatically in the ppp.linkup file). If you&#8217;re curious, you can reboot at this point, and confirm that you have a fully firewalled internet access:</p>
<p>pcreal# ifconfig -a<br />
lo0: flags=8009 mtu 33224<br />
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0&#215;5<br />
        inet6 ::1 prefixlen 128<br />
        inet 127.0.0.1 netmask 0xff000000<br />
lo1: flags=8008 mtu 33224<br />
ne0: flags=8863 mtu 1500<br />
        media: Ethernet autoselect (10baseT)<br />
        inet6 fe80::240:f4ff:fe2b:190d%ne0 prefixlen 64 scopeid 0&#215;1<br />
ne1: flags=8863 mtu 1500<br />
        media: Ethernet autoselect (10baseT)<br />
        inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255<br />
        inet6 fe80::240:f4ff:fe2b:16b1%ne1 prefixlen 64 scopeid 0&#215;2<br />
pflog0: flags=141 mtu 33224<br />
sl0: flags=c010 mtu 296<br />
sl1: flags=c010 mtu 296<br />
ppp0: flags=8010 mtu 1500<br />
ppp1: flags=8010 mtu 1500<br />
tun0: flags=8011 mtu 1492<br />
        inet 65.92.185.97 &#8211;> 65.92.185.1 netmask 0xffffffff<br />
tun1: flags=10 mtu 3000<br />
enc0: flags=0<> mtu 1536<br />
bridge0: flags=0<> mtu 1500<br />
bridge1: flags=0<> mtu 1500<br />
vlan0: flags=0<> mtu 1500<br />
vlan1: flags=0<> mtu 1500<br />
gre0: flags=8010 mtu 1450<br />
gif0: flags=8010 mtu 1280<br />
gif1: flags=8010 mtu 1280<br />
gif2: flags=8010 mtu 1280<br />
gif3: flags=8010 mtu 1280</p>
<p>pcreal# pfctl -sr<br />
@0 scrub in on ne1 all<br />
@1 scrub in on tun0 all<br />
@2 block out log on tun0 all<br />
@3 block in log on tun0 all<br />
@4 block return-rst out log on tun0 proto tcp all<br />
@5 block return-rst in log on tun0 proto tcp all<br />
@6 block return-icmp out log on tun0 proto udp all<br />
@7 block return-icmp in log on tun0 proto udp all<br />
@8 block in quick inet6 all<br />
@9 block out quick inet6 all<br />
@10 pass in quick on lo0 all<br />
@11 pass out quick on lo0 all<br />
@12 block in log quick on tun0 inet proto tcp all flags FPU/FPU<br />
@13 block in log quick on tun0 inet proto tcp all flags FS/FSRA<br />
@14 block in log quick on tun0 inet proto tcp all flags /FSRA<br />
@15 block in log quick on tun0 inet from 255.255.255.255/32 to any<br />
@16 block in log quick on tun0 inet from 10.0.0.0/8 to any<br />
@17 block in log quick on tun0 inet from 172.16.0.0/12 to any<br />
@18 block in log quick on tun0 inet from 192.168.0.0/16 to any<br />
@19 block in log quick on tun0 inet from 127.0.0.1/8 to any<br />
@20 block out log quick on tun0 inet from any to 255.255.255.255/32<br />
@21 block out log quick on tun0 inet from any to 10.0.0.0/8<br />
@22 block out log quick on tun0 inet from any to 172.16.0.0/12<br />
@23 block out log quick on tun0 inet from any to 192.168.0.0/16<br />
@24 block out log quick on tun0 inet from any to 127.0.0.1/8<br />
@25 block in quick on tun0 inet from any to 255.255.255.255/32<br />
@26 pass in quick on tun0 inet proto tcp from any to any port > 49151 flags S/SA keep state<br />
@27 pass out quick on tun0 inet proto icmp all icmp-type echoreq code 0 keep state<br />
@28 pass in log quick on tun0 inet proto icmp all icmp-type echoreq code 0 keep state<br />
@29 pass in quick on tun0 inet proto tcp from any to any port = pop3 flags S/SA keep state<br />
@30 pass in quick on tun0 inet proto tcp from any to any port = https flags S/SA keep state<br />
@31 pass in quick on tun0 inet proto tcp from any to any port = www flags S/SA keep state<br />
@32 pass in quick on tun0 inet proto tcp from any to any port = auth flags S/SA keep state<br />
@33 pass in quick on tun0 inet proto tcp from any to any port = smtp flags S/SA keep state<br />
@34 pass in quick on tun0 inet proto tcp from any to any port = ssh flags S/SA keep state<br />
@35 pass out quick on tun0 inet proto udp from any to any port = domain keep state<br />
@36 pass out quick on tun0 inet proto udp from any to any port = ntp keep state<br />
@37 pass out quick on tun0 inet proto tcp from any to any port = ntp flags S/SA modulate state<br />
@38 pass out quick on tun0 inet proto tcp from any to any port = auth flags S/SA modulate state<br />
@39 pass out quick on tun0 inet proto tcp from any to any port = nntp flags S/SA modulate state<br />
@40 pass out quick on tun0 inet proto tcp from any to any port = ftp-data flags S/SA modulate state<br />
@41 pass out quick on tun0 inet proto tcp from any to any port = ftp flags S/SA modulate state<br />
@42 pass out quick on tun0 inet proto tcp from any to any port = telnet flags S/SA modulate state<br />
@43 pass out quick on tun0 inet proto tcp from any to any port = ssh flags S/SA modulate state<br />
@44 pass out quick on tun0 inet proto tcp from any to any port = domain flags S/SA modulate state<br />
@45 pass out quick on tun0 inet proto tcp from any to any port = whois flags S/SA modulate state<br />
@46 pass out quick on tun0 inet proto tcp from any to any port = pop3 flags S/SA modulate state<br />
@47 pass out quick on tun0 inet proto tcp from any to any port = smtp flags S/SA modulate state<br />
@48 pass out quick on tun0 inet proto tcp from any to any port = https flags S/SA modulate state<br />
@49 pass out quick on tun0 inet proto tcp from any to any port = www flags S/SA modulate state<br />
&#8230;<br />
@72 pass out quick on tun0 inet proto tcp from any to any port = 6000 flags S/SA modulate state<br />
@73 pass out quick on tun0 inet proto tcp from any to any port = 8080 flags S/SA modulate state<br />
@74 pass out quick on tun0 inet proto tcp from any to any port = 7070 flags S/SA modulate state<br />
@75 pass out quick on tun0 inet proto tcp from any to any port = 554 flags S/SA modulate state</p>
<p>pflogd and tcpdump<br />
With the new pf firewall code comes a new way to log firewalled packets and look at them. The log is actually taken care of by a separate daemon ( pflogd ) which should be started in &#8220;ppp.linkup&#8221; and killed in &#8220;ppp.linkdown&#8221;. This daemon puts its data in a special log file ( /var/log/pflog ) which is not directly human readable, for performance reasons. To get a dump of the file, simply issue the command &#8220;tcpdump -n -e -ttt -r /var/log/pflog&#8221;, or , if you want a real-time display of the logs, simply issue &#8220;tcpdump -n -e -ttt -i pflog0&#8243;. </p>
<p>The Dynamic DNS<br />
Dynamic DNS is a wonderful thing. Basically, you just go to a dyndns provider like those nice people and 10 minutes later you have your very own domain, for free. In order to make that domain dynamically follow your IP address changes, you must use a special client program which must be called whenever your IP changes. </p>
<p>Until recently I liked ddup, but now i use ipcheck. The latter is truly compliant with all of dyndns&#8217;s client specification, and maintains its state automatically in system files. You will have to install the python package if you use &#8220;ipcheck&#8221;. Also, you&#8217;ll need your user ID and password from the dyndns provider.</p>
<p>One more advice: it is perfectly acceptable to have more than one domain pointing at the same IP address. Remember this when choosing one or more domain names&#8230;</p>
<p>Keeping your xDSL link alive 24/7<br />
xDSL connections are very reliable, but ISP&#8217;s are not <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  For many reasons unfathomable, you will sometimes lose your connection. There are many methods of re-establishing that connection automatically, and i&#8217;ll describe here the one i use. </p>
<p>The Method<br />
Make sure you initialise ppp with the &#8220;-ddial&#8221; command, and NOT the &#8220;-background&#8221; command&#8230;</p>
<p>The automatic restart of the ppp link is handled by ppp itself (using the &#8220;-ddial&#8221; command), which is quite handy. This leaves us with the dyndns updates, which are performed intelligently by ipcheck.py . An easy way of doing it is to create an executable file named &#8220;do_ipcheck&#8221; which contains this:</p>
<p>#!/bin/sh<br />
/usr/local/sbin/ipcheck.py -q -d /etc/ipcheck -i tun0  -w Username Password DomainName1,DomainName2with your own Username, Password and Domain names, of course. Then, all you have to do is to add the following line to crontab:</p>
<p>*/5     *       *       *       *       /usr/local/sbin/do_ipcheckAlso, don&#8217;t forget to create the directory /etc/ipcheck and make sure your /etc/ppp/ppp.linkup file looks like this:</p>
<p>MYADDR:<br />
 ! sh -c &#8220;/sbin/ifconfig pflog0 up&#8221;<br />
 ! sh -c &#8220;/sbin/pfctl -e -l tun0 -F all -O aggressive -R /etc/pf.conf -N /etc/nat.conf&#8221;<br />
 ! sh -c &#8220;/usr/local/sbin/ResetNTP.sh&#8221;<br />
 !bg sh -c &#8220;/usr/local/sbin/do_ipcheck&#8221;<br />
You can call &#8220;do_ipcheck&#8221; from &#8220;ppp.linkup&#8221; &#8230; however, you must use the special &#8220;!bg&#8221; construct, in order to instruct ppp to fork it in the background. Nasty stuff happens if you don&#8217;t use &#8220;!bg&#8221; here. Big thanks to Dan for this update!</p>
<p>This setup should garantee the proper restart of the firewall &#038; ipnat each time the ppp link is brought up again.</p>
<p>Apache<br />
Now would be a good time to install your htdocs directory. The way i like to do this is to mount a read-only NFS file system over the current htdocs. This is easily accomplished by adding a line like this to your /etc/fstab : </p>
<p>192.168.1.1:/usr/local/Apache/htdocs /var/www/htdocs nfs ro  Moreover, the web logs are kept in /var/www/logs. Interesting stuff.</p>
<p>We are in full virus season and i&#8217;m sure your log files will fill up as fast as mine with useless garbage, once your Apache is up. In order to remove some clutter, you can filter out the virus attacks and channel them to a specialized attack_log file. Simply insert the following lines into your /var/www/conf/httpd.conf file: </p>
<p>SetEnvIf Request_URI &#8220;^/default.ida&#8221; attacks # For Code Red<br />
SetEnvIf Request_URI &#8220;^/scripts&#8221; attacks # For nimda<br />
SetEnvIf Request_URI &#8220;^/c/winnt&#8221; attacks # &#8230; ditto all the way down<br />
SetEnvIf Request_URI &#8220;^/_mem_bin&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/_vti_bin&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/MSADC&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/msadc&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/d/winnt&#8221; attacks</p>
<p>CustomLog /var/www/logs/access_log combined env=!attacks<br />
CustomLog /var/www/logs/attack_log combined env=attacks<br />
This will send all virus-related requests to &#8220;attack_log&#8221;, while still logging other activities normally in access_log.</p>
<p>Named<br />
Someone (Chavous P. Camp, thanks!) sent me advice on optimizing &#8220;named&#8221; for faster throughput. He recommends to add two lines to the &#8220;/var/named/named.boot&#8221; file:</p>
<p>options forward-only<br />
forwarders ip.addresses.of.ISPs.nameservers.separated.by.spacesThis forces named to always use the same servers for dns. If your ISP&#8217;s servers are always on fixed IP adresses, then it works well. However, ISP&#8217;s who force you to use PPPoE will also sometimes change dynamically the DNS servers allocated to you (in &#8220;/etc/resolv.conf&#8221;, automatically created by ppp at startup). In that case, there is no garantee that the name servers you hardwire as forwarders will always be available.</p>
<p>Removing IPv6 related errors<br />
The GENERIC OpenBSD kernel comes precompiled with IP v6 support. This is the reason why you might see many &#8220;/bsd: tun0: not multicast capable, IPv6 not enabled&#8221; error messages in your logs. Those messages are completely harmless and do not alter the performance of your system. However, should you want to get rid of them, you can simply remove IPv6 support from your kernel by modifying &#8220;/usr/src/sys/conf/GENERIC&#8221; and removing the &#8220;option INET6&#8243; line. Then recompile your kernel in the usual way. Thanks Chavous for this info!</p>
<p>Setting permissions of scripts &#038; config files<br />
Another excellent suggestion from Chavous. Scripts and config files with passwords should have their permissions changed to 500 (for scripts) or 400 (for config files), for greater security. This includes &#8220;ppp.conf&#8221;, &#8220;do_ipcheck&#8221;, etc&#8230;</p>
<p>The NTP daemon<br />
The ntpd daemon is not installed by default. However, you can download it as a package, and install it with the pkg_add command. Since you have internet connectivity by now, you can download &#038; install it in a single command:</p>
<p>pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/3.0/packages/i386/ntp-4.1.71.tgz Moreover, you will need a valid /etc/ntp.conf file:</p>
<p>pcreal# cat /etc/ntp.conf<br />
server 128.100.102.201<br />
driftfile /etc/ntp.driftFeel free to use any other atomic time server if you want. Also, the drift file will be created &#038; maintained automagically.</p>
<p>Important tip from Chavous:<br />
=========================================<br />
I found my ntp server would refuse to synchronize after a reboot because it<br />
had no route to the time server.  This was, of course, because PPPoE is<br />
loaded AFTER ntp, and sometimes the PPPoE negotiation after a reboot takes a<br />
few seconds.</p>
<p>Anyway, here is something you might want to add as a suggestion:</p>
<p>Turn ntpd OFF in the rc.conf file<br />
add this line to your ppp.linkup file &#8211; AFTER the firewall initialization</p>
<p> ! sh -c &#8220;/etc/ppp/ResetNTP.sh&#8221;</p>
<p>That script should then contain:</p>
<p>#!/bin/sh<br />
if [ -f /var/run/ntpd.pid ]; then<br />
        kill `cat /var/run/ntpd.pid`<br />
        rm -f /var/run/ntpd.pid<br />
fi<br />
/usr/local/sbin/ntpd -p /var/run/ntpd.pid</p>
<p>(as I have said before, remind your readers that this script is executed as<br />
root and should therefore be chmod 444 or less)</p>
<p>This kills the NTP daemon (if it exists) and restarts it.  On boot, it would<br />
not be restarted, but what if the link went down for a while? The ntp daemon<br />
would give up and stop sending queries because it couldn&#8217;t get a route to<br />
host.</p>
<p>REALLY, the ntp daemon SHOULD NOT stop querying the server just because it<br />
can&#8217;t get a route to the host, but it seems to be written as such now<br />
anyway.  I haven&#8217;t tested the ntp daemon over a long period of time (more<br />
than about a day) so I don&#8217;t know if it just gives up for some arbitrarily<br />
long period (MORE than a day) and then tries again. I seriously doubt it<br />
does, because a day is a LONG time.  This workaround isn&#8217;t ideal, because<br />
for time consistency, one would want the time server to stay running at all<br />
times.  According to the ntpd documentation, ntpd tends to become more<br />
accurate the longer it runs.</p>
<p>Chavous<br />
=========================================</p>
<p>Sendmail<br />
If you have followed all the steps of the recipe so far, your sendmail should be configured &#038; ready to receive mail from the internet, however you should know a few more things about this. First, if you want your gateway to receive mail for more than one domain, you must make sure the all fully qualified domains are setup as aliases for your host in the file /etc/hosts.</p>
<p>The mail popper<br />
All ingress mail is received &#038; kept on the gateway untill some POP client on the intranet gets it. I use the &#8220;popa3d&#8221; server package because it is written with security in mind. It is now part of the main OpenBSD 3.0 distribution, so you don&#8217;t have to download it as a separate package. Simply enable it in the file /etc/inetd.conf and you should be up &#038; running. </p>
<p>The installed packages<br />
Just to do a quick check, here are the packages i have installed on my system:</p>
<p>pcreal# pkg_info<br />
gmp-3.1.1          library for arbitrary precision arithmetic<br />
python-2.1.1       interpreted object-oriented programming language<br />
ntp-4.1.71         network time protocol implementation<br />
libiconv-1.7       character set conversion library<br />
gettext-0.10.40    GNU gettext<br />
mhash-0.8.9        strong hash library<br />
libtool-1.3.5p3    generic shared library support script<br />
postgresql-7.1.3   PostgreSQL RDBMS<br />
libmcrypt-2.4.15   interface to access block/stream encryption algorithms<br />
c-client-4.40p1    University of Washington&#8217;s c-client mail access routines<br />
php4-4.0.6p1-gettext-imap-mhash-no_x11-mcrypt-postgresql server-side HTML-embedded scripting language</p>
<p>The Secure Shell<br />
The secure shell looks &#038; feels exactly like telnet, except that all communication between the client and the server is encrypted. It is the only possible way to access your gateway, because the telnet daemon is disabled by default. Usage is very simple: just like telnet! </p>
<p>[real@pcreal Projects]$ ssh 192.168.1.2<br />
real@192.168.1.2&#8242;s password:<br />
Warning: Remote host denied X11 forwarding.<br />
Last login: Sun Nov  5 12:58:08 2000 from 192.168.1.1<br />
OpenBSD 2.7 (GENERIC) #1: Thu Nov  2 16:05:11 GMT 2000</p>
<p>pcreal:real {39}</p>
<p>Once you are logged in as an unprivileged user, member of the wheel group, you can use su to gain superuser privileges:</p>
<p>pcreal:real {39} su -<br />
Password:<br />
Terminal type? [nxterm]<br />
pcreal#</p>
<p>The log files<br />
There are many log files of high interest maintained automatically by your gateway. It is usually convenient to look at them with the &#8220;tail -f&#8221; command. The files i look at often are: </p>
<p>/var/log/messages<br />
/var/log/maillog<br />
/var/log/secure<br />
/var/www/logs/access_log</p>
<p>Moreover, you can grab interesting info about the blocked packets on your firewall with the &#8220;ipmon&#8221; utility.</p>
<p>There are many other log files available for all kinds of things. Dig around to find more about them.</p>
<p>Installing IPSEC<br />
Dave Cook has kindly provided us with a good description of how to install IPSEC on your OpenBSD boxen: file:///H:/OPENBSD/ipsec.pdf, in PDF (Acrobat) format. Be aware that it is a largish file (440K), and it might take some time for your Acrobat reader to load afterwards, so don&#8217;t hit the link repeatedly, it won&#8217;t make things load faster&#8230; <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Apply the security patches!<br />
Security patches are published there. APPLY THEM RELIGIOUSLY!<br />
It is not really difficult, but you will need a copy of the complete, original source tree of the distribution. The compressed source archives are to be found with the distribution files. These are the 3.0 source files:</p>
<p>      src.tar.gz      64447 Kb    Tue May  1 16:18:00 2001 Unix Tape Archive<br />
      srcsys.tar.gz   13837 Kb    Tue May  1 16:18:00 2001 Unix Tape ArchiveThey total about 80 MB. Once you have them, simply unpack them to &#8216;/usr/src&#8217; and &#8216;/usr/src/sys&#8217;. The latter is the kernel proper.</p>
<p>Once you have your source tree, you can start downloading the patches, and apply them. Usually, all the currently published patches are availble in a single file. For 3.0, it is there. After that, simply watch the patch page from time to time, to keep updated.</p>
<p>Patches are either applied to an application (in &#8216;/usr/src&#8217;), or to the kernel ( in &#8216;/usr/src/sys&#8217;). Since all kernel patches should be installed, the thing i do is to apply all the kernel patches in one session, then i recompile my kernel once.</p>
<p>The applications you don&#8217;t use (e.g. &#8216;X11&#8242;, for example) don&#8217;t have to be patched &#038; recompiled.</p>
<p>Reboot and enjoy!<br />
You should be able to ssh into your new gateway from any machine on the intranet. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/845.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>centos下安装jdk15+ MySQL5+Apache22(worker+ssl)+PHP5+Resin3</title>
		<link>http://www.evanjiang.net.cn/archives/759.html</link>
		<comments>http://www.evanjiang.net.cn/archives/759.html#comments</comments>
		<pubDate>Fri, 06 Mar 2009 11:02:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[It Tips]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[resin]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[centos下安装jdk15+ MySQL5+Apache22(worker+ssl)+PHP5+Resin3]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=759</guid>
		<description><![CDATA[<p>系统：CentOS4.3</p>
<p>1、安装jdk1.5
修改jdk-1_5_0_07-linux-i586.bin为可执行：
#./jdk-1_5_0_07-linux-i586.bin进行安装，然后会在当前目录下解压，生成一个名为 jdk-1_5_0_07的目录
#mv jdk-1_5_0_07 /usr/local/jdk
安装ok后设置环境变量：
修改/etc/profile
增加如下内容：
JAVA_HOME=/usr/local/jdk
RESIN_HOME=/usr/local/resin
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$RESIN_HOME/lib:/usr/local/jdbc
export RESIN_HOME JAVA_HOME CLASSPATH
存盘退出。。。
source /etc/profile</p>
<p>2、安装openssl
解压openssl-0.9.8b.tar.gz
#tar zxvf openssl-0.9.8b.tar.gz
#cd openssl-0.9.8b
#./Configure
#make install

接下来安装相关应用软件：
1.MySQL5 </p>
<p>2.安装mysql5.0.18（源码包）
源码包可以在这个网址获得：</p>
<p>http://download.mysql.cn/src/2006/0208/62.html</p>
<p>所有这些操作需要root权限
安装开始：
1&#62;cd /home/ftpsite
2&#62;groupadd mysql&#8212;&#8212;&#8212;-添加mysql用户组,如果提示该组存在,则不用再加
3&#62;useradd -g mysql mysql&#8212;&#8211;加mysql用户,并把它归到mysql组,如果提示用户存在,则不用再加
4&#62;tar zxvf mysql-5.0.18.tar.tar
5&#62;cd mysql-5.0.18
6&#62;./configure &#8211;prefix=/usr/local/mysql
7&#62;make
8&#62;make install
9&#62;cp support-files/my-medium.cnf /etc/my.cnf
10&#62;cd /usr/local/mysql
11&#62;./bin/mysql_install_db
12&#62;chown -R root /usr/local/mysql
13&#62;chown -R mysql /usr/local/mysql/var
14&#62;chgrp -R root /usr/local/mysql
15&#62;./bin/mysqld_saft &#8211;user=mysql &#38;
16&#62;./bin/mysql
17&#62;mysql&#62;&#8212;&#8212;&#8212;&#8212;&#8212;经过第16步,你应该能看到mysql&#62;提示符,那么恭喜你安装初步成功</p>
<p>2.Apache22








下载httpd-2.0.55.tar.gz, php-5.0.5.tar.gz等二进制源码包
执行下列命令解压源码包
# tar -zxvf httpd-2.0.55.tar.gz
进入安装目录
# cd httpd-2.0.55
配置apache安装信息：
#./configure &#8211;enable-layout=Apache &#8211;enable-so &#8211;enable-ssl=shared &#8211;with-mpm=worker &#8211;with-ssl=/usr/share/ssl
执行make安装：
# make; make install
使用/usr/local/apache/bin/apachectl start 启动apache</p>
<p>#/usr/local/sbin/httpd -l
看看是否存在以下几个模块
core.c
worker.c
http_core.c
mod_so.c
现在是使用worker方式运行的apache。</p>
<p>OK，完成。</p>
<p>3.PHP5
安装php
tar -zxvf [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #000000;">系统：CentOS4.3</span></p>
<p><span style="color: #000000;">1、安装jdk1.5<br />
修改jdk-1_5_0_07-linux-i586.bin为可执行：<br />
#./jdk-1_5_0_07-linux-i586.bin进行安装，然后会在当前目录下解压，生成一个名为 jdk-1_5_0_07的目录<br />
#mv jdk-1_5_0_07 /usr/local/jdk<br />
安装ok后设置环境变量：<br />
修改/etc/profile<br />
增加如下内容：<br />
JAVA_HOME=/usr/local/jdk<br />
RESIN_HOME=/usr/local/resin<br />
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$RESIN_HOME/lib:/usr/local/jdbc<br />
export RESIN_HOME JAVA_HOME CLASSPATH<br />
存盘退出。。。<br />
source /etc/profile</span></p>
<p><span style="color: #000000;">2、安装openssl<br />
解压openssl-0.9.8b.tar.gz<br />
#tar zxvf openssl-0.9.8b.tar.gz<br />
#cd openssl-0.9.8b<br />
#./Configure<br />
#make install<br />
<span id="more-759"></span><br />
接下来安装相关应用软件：<br />
1.MySQL5 </span></p>
<p><span style="color: #000000;">2.安装mysql5.0.18（源码包）<br />
源码包可以在这个网址获得：</p>
<p>http://download.mysql.cn/src/2006/0208/62.html</p>
<p>所有这些操作需要root权限<br />
安装开始：<br />
1&gt;cd /home/ftpsite<br />
2&gt;groupadd mysql&#8212;&#8212;&#8212;-添加mysql用户组,如果提示该组存在,则不用再加<br />
3&gt;useradd -g mysql mysql&#8212;&#8211;加mysql用户,并把它归到mysql组,如果提示用户存在,则不用再加<br />
4&gt;tar zxvf mysql-5.0.18.tar.tar<br />
5&gt;cd mysql-5.0.18<br />
6&gt;./configure &#8211;prefix=/usr/local/mysql<br />
7&gt;make<br />
8&gt;make install<br />
9&gt;cp support-files/my-medium.cnf /etc/my.cnf<br />
10&gt;cd /usr/local/mysql<br />
11&gt;./bin/mysql_install_db<br />
12&gt;chown -R root /usr/local/mysql<br />
13&gt;chown -R mysql /usr/local/mysql/var<br />
14&gt;chgrp -R root /usr/local/mysql<br />
15&gt;./bin/mysqld_saft &#8211;user=mysql &amp;<br />
16&gt;./bin/mysql<br />
17&gt;mysql&gt;&#8212;&#8212;&#8212;&#8212;&#8212;经过第16步,你应该能看到mysql&gt;提示符,那么恭喜你安装初步成功</span></p>
<p><span style="color: #000000;">2.Apache22<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
下载httpd-2.0.55.tar.gz, php-5.0.5.tar.gz等二进制源码包<br />
执行下列命令解压源码包<br />
# tar -zxvf httpd-2.0.55.tar.gz<br />
进入安装目录<br />
# cd httpd-2.0.55<br />
配置apache安装信息：<br />
#./configure &#8211;enable-layout=Apache &#8211;enable-so &#8211;enable-ssl=shared &#8211;with-mpm=worker &#8211;with-ssl=/usr/share/ssl<br />
执行make安装：<br />
# make; make install<br />
使用/usr/local/apache/bin/apachectl start 启动apache</span></p>
<p><span style="color: #000000;">#/usr/local/sbin/httpd -l<br />
看看是否存在以下几个模块<br />
core.c<br />
worker.c<br />
http_core.c<br />
mod_so.c<br />
现在是使用worker方式运行的apache。</span></p>
<p><span style="color: #000000;">OK，完成。</span></p>
<p><span style="color: #000000;">3.PHP5<br />
安装php<br />
tar -zxvf php-5.1.4.tar.gz<br />
cd php-5.1.4<br />
./configure &#8211;prefix=/usr/local/php5 (配置php的参数)<br />
&#8211;with-apxs2=/usr/local/apache2/bin/apxs<br />
&#8211;with-libxml-dir=/usr/local/lib<br />
&#8211;enable-sockets<br />
&#8211;with-mysql=/usr/local/mysql (mysql 的安装目录 就是那个解压后的目录)<br />
# make<br />
# make install<br />
将安装目录下的php.ini-dist文件改为php.ini存放的/usr/local/lib下。 </span></p>
<p><span style="color: #000000;">安装后修改httpd.conf文件：<br />
将httpd.conf中的loadmodule 最后一个刚加进去的php的#去掉<br />
在AddType application/x-gzip .gz .tgz后面加：<br />
AddType application/x-httpd-php .php<br />
AddType application/x-httpd-php-source .phps<br />
随后设置网站默认启动页允许为index.php，找到 DirectoryIndex这行，改为：<br />
DirectoryIndex index.html index.htm index.php</span></p>
<p><span style="color: #000000;">写一个phpinfo()测试一下就可以。 </span></p>
<p><span style="color: #000000;">4.安装phpMyAdmin</span></p>
<p><span style="color: #000000;">下面我们开始安装phpMyAdmin2.8.0.1! 这个文件应该从网上找的到！<br />
把下载好的源码放在/usr/local/www/data下面，解压！<br />
#tar xvzf phpMyAdmin.tar.gz<br />
进入phpmyadmin下的libraries 目录！<br />
修改 config.default.php:<br />
找到$cfg['PmaAbsoluteUri'] = &#8221;;<br />
修改成 $cfg['PmaAbsoluteUri'] = &#8216;http://你的IP/phpmyadmin&#8217;;<br />
找到$cfg['Servers'][$i]['auth_type'] = &#8216;config&#8217;; // Authentication method (config, http or cookie based)?<br />
$cfg['Servers'][$i]['user'] = &#8216;root&#8217;; // MySQL user<br />
$cfg['Servers'][$i]['password'] = &#8221;;<br />
写上你的Mysql用户名and密码！<br />
保存退出！<br />
然后用http://your/ IP/phpmyadmin访问！如果出现mysql管理页面，则安装成功，如果没有出现，请检查配制文件！</span></p>
<p><span style="color: #000000;">5．安装resin<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
安装resin：<br />
1）到http://www.caucho.com/下载resin-3.0.18.tar.gz，这个是目前的最新版本<br />
2）解压 生成目录 resin-3.0.18<br />
3）执行 mv resin-3.0.18 /usr/local/resin<br />
4）重新编译resin：<br />
./configure &#8211;with-apxs=/usr/local/apache2/bin/apxs &#8211;with-java-home=/usr/local/jdk/ &#8211;prefix=/usr/local/resin<br />
make &amp;&amp; make install &amp;&amp; make clean<br />
如果/etc/profile设置没有问题的话，该步骤能够正常运行</span></p>
<p><span style="color: #000000;">6．整合Apache和Resin<br />
1）修改/usr/local/apache/conf/httpd.conf<br />
增加：<br />
LoadModule caucho_module /usr/local/apache/libexec/mod_caucho.so<br />
ResinConfigServer localhost 6802<br />
CauchoStatus yes</p>
<p>SetHandler caucho-status</p>
<p>2）修改/usr/local/resin/conf/resin.conf<br />
修改以下片断：</p>
<p>3）<br />
重新启动 apache,<br />
/usr/local/apache/bin/apachectl start<br />
启动 resin<br />
/usr/local/resin/bin/httpd.sh start<br />
写一个简单的脚本可以测试，jsp执行是否成功。</span></p>
<p><span style="color: #000000;">7．Resin连接MySQL数据库</span></p>
<p><span style="color: #000000;">下载相相应的jbdc 驱动，俺下载的是:mysql-connector-java-3.1.12-bin.jar，将此文件放<br />
到/usr/local/resin/lib下!<br />
然后再写一个jsp连接mysql的jsp文件测试一下!</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/759.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache PHP MySQL Zend GD OpenSSL vsftpd For Debian  完全编译</title>
		<link>http://www.evanjiang.net.cn/archives/720.html</link>
		<comments>http://www.evanjiang.net.cn/archives/720.html#comments</comments>
		<pubDate>Thu, 05 Mar 2009 07:28:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[Apache PHP MySQL Zend GD OpenSSL vsftpd For Debian  完全编译]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=720</guid>
		<description><![CDATA[<p>系统 Debian Linux v3.1r0 (Sarge) Kernel v2.6.11 i686</p>
<p>安装方式：源码编译</p>
<p>################
##### 软件 #####
################</p>
<p>Apache v2.0.54 官方主页： http://www.apache.org
http://www.apache.org/dist/httpd/httpd-2.0.54.tar.gz  [7.16MB]</p>
<p>PHP v4.3.11 官方主页： http://www.php.net
http://cn.php.net/distributions/php-4.3.11.tar.gz  [4.64MB]</p>
<p>Zend Optimizer v2.5.10 官方主页： http://www.zend.com
http://downloads.zend.com/optimizer/2.5.10/ZendOptimizer-2.5.10-linux-glibc21-i386.tar.gz  [3.36MB]</p>
<p>MySQL v4.0.24 官方主页： http://www.mysql.com
http://ftp.stu.edu.tw/pub/Unix/Database/Mysql/Downloads/MySQL-4.0/mysql-4.0.24.tar.gz  [16.1MB]</p>
<p>GD Library v2.0.33 官方主页： http://www.boutell.com/gd/
http://www.boutell.com/gd/http/gd-2.0.33.tar.gz  [573KB]</p>
<p>FreeType v2.1.10 官方主页： http://www.freetype.org
http://savannah.nongnu.org/download/freetype/freetype-2.1.10.tar.gz  [1.31MB]</p>
<p>Jpeg v6b 官方主页： http://www.ijg.org
ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz  [598KB]</p>
<p>LibPNG v1.2.8 官方主页： http://www.libpng.org/pub/png/
http://switch.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.8.tar.gz  [498KB]</p>
<p>OpenSSL v0.9.7g 官方主页： http://www.openssl.org
http://www.openssl.org/source/openssl-0.9.7g.tar.gz [...]]]></description>
			<content:encoded><![CDATA[<p>系统 Debian Linux v3.1r0 (Sarge) Kernel v2.6.11 i686</p>
<p>安装方式：源码编译</p>
<p>################<br />
##### 软件 #####<br />
################</p>
<p>Apache v2.0.54 官方主页： http://www.apache.org<br />
http://www.apache.org/dist/httpd/httpd-2.0.54.tar.gz  [7.16MB]</p>
<p>PHP v4.3.11 官方主页： http://www.php.net<br />
http://cn.php.net/distributions/php-4.3.11.tar.gz  [4.64MB]</p>
<p>Zend Optimizer v2.5.10 官方主页： http://www.zend.com<br />
http://downloads.zend.com/optimizer/2.5.10/ZendOptimizer-2.5.10-linux-glibc21-i386.tar.gz  [3.36MB]</p>
<p>MySQL v4.0.24 官方主页： http://www.mysql.com<br />
http://ftp.stu.edu.tw/pub/Unix/Database/Mysql/Downloads/MySQL-4.0/mysql-4.0.24.tar.gz  [16.1MB]</p>
<p>GD Library v2.0.33 官方主页： http://www.boutell.com/gd/<br />
http://www.boutell.com/gd/http/gd-2.0.33.tar.gz  [573KB]</p>
<p>FreeType v2.1.10 官方主页： http://www.freetype.org<br />
http://savannah.nongnu.org/download/freetype/freetype-2.1.10.tar.gz  [1.31MB]</p>
<p>Jpeg v6b 官方主页： http://www.ijg.org<br />
ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz  [598KB]</p>
<p>LibPNG v1.2.8 官方主页： http://www.libpng.org/pub/png/<br />
http://switch.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.8.tar.gz  [498KB]</p>
<p>OpenSSL v0.9.7g 官方主页： http://www.openssl.org<br />
http://www.openssl.org/source/openssl-0.9.7g.tar.gz  [2.98MB]</p>
<p>vsftpd v2.0.3 官方主页： http://vsftpd.beasts.org<br />
ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.0.3.tar.gz  [149KB]</p>
<p>zlib v1.2.2 官方主页： http://www.gzip.org/zlib/<br />
http://www.zlib.net/zlib-1.2.2.tar.gz  [420KB]</p>
<p>ClibPDF v2.02-r1-1 官方网站： http://www.fastio.com<br />
http://www.fastio.com/clibpdf202r1.tar.gz  [836KB]</p>
<p>mod_limitipconn v0.22 官方网站： http://dominia.org/djao/<br />
http://dominia.org/djao/limit/mod_limitipconn-0.22.tar.gz  [6.18KB]</p>
<p>Bandwidth Module v0.6 官方网站： http://www.ivn.cl/apache/<br />
http://www.ivn.cl/apache/bw_mod-0.6.tgz  [28.5KB]</p>
<p>Apache DoS Evasive Maneuvers Module v1.10 官方网站： http://www.nuclearelephant.com/projects/dosevasive/<br />
http://www.nuclearelephant.com/projects/dosevasive/mod_dosevasive_1.10.tar.gz  [19.1KB]<br />
<span id="more-720"></span><br />
################<br />
##### 安装 #####<br />
################</p>
<p>1、解压缩，把所有源码压缩包放在一个目录中，解压缩所有 .tar.gz 压缩包<br />
for i in `ls *.gz`;do tar zxvf $i; done;</p>
<p>2、开始安装</p>
<p>##### zlib #####</p>
<p>cd zlib-1.2.2<br />
./configure<br />
make<br />
make install<br />
cd ..</p>
<p>##### OpenSSL #####</p>
<p>cd openssl-0.9.7g<br />
./config &#8211;prefix=/usr/local/ssl \<br />
&#8211;openssldir=/usr/local/ssl \<br />
shared \<br />
zlib</p>
<p>make<br />
make install<br />
ln -s /usr/local/ssl /usr/lib/ssl<br />
cd ..</p>
<p>##### MySQL #####</p>
<p>cd mysql-4.0.24</p>
<p>编辑 sql/mysqld.cc ：<br />
搜索：&#038;max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1,<br />
修改：&#038;max_connections, 0, GET_ULONG, REQUIRED_ARG, 1000, 1, 16384, 0, 1,</p>
<p>groupadd mysql<br />
useradd -g mysql mysql</p>
<p>./configure \<br />
&#8211;prefix=/server/mysql \<br />
&#8211;sysconfdir=/server/mysql \<br />
&#8211;without-isam \<br />
&#8211;without-debug \<br />
&#8211;enable-assembler \<br />
&#8211;with-unix-socket-path=/tmp/mysql.sock \<br />
&#8211;with-mysqld-user=mysql \<br />
&#8211;with-extra-charset=all \<br />
&#8211;with-client-ldflags=-all-static \<br />
&#8211;with-mysqld-ldflags=-all-static \<br />
&#8211;localstatedir=/data/mysql/data</p>
<p>如果出现以下错误：<br />
checking for tgetent in -ltermcap&#8230; no<br />
checking for termcap functions library&#8230; configure: error: No curses/termcap library found<br />
说明 curses/termcap 库没有安装<br />
apt-cache search curses | grep lib<br />
安装 libncurses5-dev ，然后重新运行配置</p>
<p>mkdir /data<br />
mkdir /data/mysql<br />
mkdir /data/mysql/data</p>
<p>make<br />
make install</p>
<p>/server/mysql/bin/mysql_install_db &#8211;user=mysql</p>
<p>chown -R mysql /data/mysql<br />
chgrp -R mysql /data/mysql<br />
chown -R root /server/mysql<br />
chgrp -R mysql /server/mysql<br />
cp /server/mysql/share/mysql/my-medium.cnf /server/mysql/my.cnf</p>
<p>/server/mysql/share/mysql/mysql.server start<br />
/server/mysql/bin/mysqladmin -u root password 123456789<br />
cd ..<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>##### Apache2 #####</p>
<p>cd httpd-2.0.54</p>
<p>./configure &#8211;prefix=/server/httpd \<br />
&#8211;enable-so \<br />
&#8211;with-mysql=/server/mysqld \<br />
&#8211;enable-cgi \<br />
&#8211;with-config-file-path=/server/httpd/conf \<br />
&#8211;enable-track-vars \<br />
&#8211;enable-mods-shared=all \<br />
&#8211;enable-cache \<br />
&#8211;enable-disk-cache \<br />
&#8211;enable-mem-cache \<br />
&#8211;enable-rewrite \<br />
&#8211;with-mpm=worker \<br />
&#8211;with-ssl=/usr/local/ssl \<br />
&#8211;enable-ssl</p>
<p>make<br />
make install<br />
cd ..</p>
<p>##### mod_deflate #####</p>
<p>cd httpd-2.0.54/modules/filters</p>
<p>/server/httpd/bin/apxs -i -c -a mod_deflate.c</p>
<p>修改 Apache 配置文件 /server/httpd/conf/httpd.conf ：<br />
添加：<br />
<Location />;<br />
# Insert filter<br />
SetOutputFilter DEFLATE</p>
<p># Netscape 4.x has some problems&#8230;<br />
BrowserMatch ^Mozilla/4 gzip-only-text/html</p>
<p># Netscape 4.06-4.08 have some more problems<br />
BrowserMatch ^Mozilla/4\.0[678] no-gzip</p>
<p># MSIE masquerades as Netscape, but it is fine<br />
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html</p>
<p># NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48<br />
# the above regex won&#8217;t work. You can use the following<br />
# workaround to get the desired effect:<br />
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html</p>
<p># Don&#8217;t compress images<br />
SetEnvIfNoCase Request_URI \<br />
\.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary</p>
<p># Make sure proxies don&#8217;t deliver the wrong content<br />
#Header append Vary User-Agent env=!dont-vary<br />
</Location>;</p>
<p>DeflateFilterNote ratio<br />
LogFormat &#8216;&#8221;%v %h %l %u %t &#8220;%r&#8221; %>;s %b &#8220;%{Referer}i&#8221; &#8220;%{User-Agent}i&#8221;" (%{ratio}n)&#8217; deflate</p>
<p>CustomLog logs/deflate_log deflate</p>
<p>然后<br />
cd ../../../</p>
<p>##### FreeType #####</p>
<p>cd freetype-2.1.10</p>
<p>./configure &#8211;prefix=/usr/local/freetype</p>
<p>make<br />
make install<br />
cd ..</p>
<p>##### LibPNG #####</p>
<p>cd libpng-1.2.8</p>
<p>cp scripts/makefile.linux makefile</p>
<p>make test<br />
make install<br />
cd ..</p>
<p>##### Jpeg #####</p>
<p>cd jpeg-6b</p>
<p>mkdir /usr/local/jpeg<br />
mkdir /usr/local/jpeg/bin<br />
mkdir /usr/local/jpeg/lib<br />
mkdir /usr/local/jpeg/include<br />
mkdir /usr/local/jpeg/man<br />
mkdir /usr/local/jpeg/man/man1<br />
./configure &#8211;prefix=/usr/local/jpeg &#8211;enable-shared &#8211;enable-static</p>
<p>make<br />
make install<br />
cd ..</p>
<p>##### GD Library #####</p>
<p>cd gd-2.0.33</p>
<p>./configure &#8211;prefix=/usr/local/gd \<br />
&#8211;with-jpeg=/usr/local/jpeg \<br />
&#8211;with-freetype=/usr/local/freetype \<br />
&#8211;with-png \<br />
&#8211;with-zlib</p>
<p>make<br />
make install<br />
cd ..</p>
<p>##### ClibPDF #####</p>
<p>cd ClibPDF/source<br />
cp Makefile.Linux makefile<br />
make<br />
make install<br />
cd ..</p>
<p>##### PHP #####</p>
<p>cd php-4.3.11</p>
<p>./configure &#8211;prefix=/server/php \<br />
&#8211;with-apxs2=/server/httpd/bin/apxs \<br />
&#8211;with-gd=/usr/local/gd \<br />
&#8211;enable-gd \<br />
&#8211;enable-gd-native-ttf \<br />
&#8211;with-jpeg-dir=/usr/local/jpeg \<br />
&#8211;with-png \<br />
&#8211;with-ttf \<br />
&#8211;with-zlib \<br />
&#8211;with-freetype-dir=/usr/local/freetype \<br />
&#8211;enable-magic-quotes \<br />
&#8211;with-mysql=/server/mysql \<br />
&#8211;with-mysql-sock=/tmp/mysql.sock \<br />
&#8211;with-iconv \<br />
&#8211;with-mbstring \<br />
&#8211;enable-mbstring \<br />
&#8211;enable-track-vars \<br />
&#8211;enable-force-cgi-redirect \<br />
&#8211;enable-ftp \<br />
&#8211;with-config-file-path=/server/httpd/conf \<br />
&#8211;with-openssl=/usr/local/ssl \<br />
&#8211;with-openssl-dir=/usr/local/ssl \<br />
&#8211;with-cpdflib=/usr/local \<br />
&#8211;with-pear=/server/php/pear</p>
<p>make<br />
make install</p>
<p>cp php.ini-dist /server/httpd/conf/php.ini<br />
cd ..</p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
##### Zend Optimizer #####</p>
<p>cd ZendOptimizer-2.5.10-linux-glibc21-i386</p>
<p>./install</p>
<p>操作 [OK] [EXIT] [YES] [/server/zend] [/server/httpd/conf] [YES] [/server/httpd/bin/apachectl] [OK] [OK] [NO]</p>
<p>cd ..</p>
<p>##### mod_limitipconn #####</p>
<p>cd mod_limitipconn-0.22</p>
<p>/server/httpd/bin/apxs -i -c -a mod_limitipconn.c</p>
<p>修改 Apache 配置文件 /server/httpd/conf/httpd.conf：<br />
查找：#ExtendedStatus On ，去掉注释&#8221;#&#8221;<br />
查找：CustomLog logs/access_log common ，修改成 CustomLog logs/access_log common env=!LIMITIP<br />
添加：<br />
<IfModule mod_limitipconn.c>;<br />
    <Location />;<br />
        MaxConnPerIP 5<br />
        NoIPLimit image/*<br />
    </Location>;</p>
<p>    <Location /mp3>;<br />
        MaxConnPerIP 2<br />
        OnlyIPLimit audio/mpeg video<br />
    </Location>;<br />
</IfModule>;</p>
<p>然后<br />
cd ..</p>
<p>##### Bandwidth Module #####</p>
<p>cd bw_mod-0.6</p>
<p>/server/httpd/bin/apxs -i -c -a bw_mod-0.6.c</p>
<p>cd ..</p>
<p>带宽限制在虚拟主机中设置</p>
<p>##### Apache DoS Evasive Maneuvers Module #####</p>
<p>cd mod_dosevasive</p>
<p>/server/httpd/bin/apxs -i -c -a mod_dosevasive20.c</p>
<p>cd ..</p>
<p>等一下启动 Apache2 后可以测试<br />
perl test.pl</p>
<p>###############################################################################################</p>
<p>现在，WEB 服务已经安装完毕！<br />
测试 WEB 服务：</p>
<p>mkdir /data/vhosts<br />
mkdir /data/vhosts/localhost</p>
<p>启动 Apache2<br />
/server/httpd/bin/apachectl start<br />
如果出错请参考下一贴中的 httpd.conf 和 虚拟主机配置文件示例</p>
<p>MySQL 服务前面已经启动，密码是：123456789</p>
<p>编辑一个 info.php 放在 /data/vhosts/localhost 下面，内容如下：</p>
<p><?php<br />
phpinfo();<br />
?>;</p>
<p>测试： http://localhost/info.php<br />
OK，看到 PHP 信息吧 </p>
<p>##### 开机自动启动服务 #####</p>
<p>cp /server/httpd/bin/apachectl /etc/init.d/httpd<br />
cp /server/mysql/share/mysql/mysql.server /etc/init.d/mysql<br />
recconf<br />
配置，已经有 httpd 和 mysql 选项，选中，OK</p>
<p>如果没有 rcconf ，用 apt-get install rcconf 安装</p>
<p>#######################<br />
##### 使 SSL 工作 #####<br />
#######################</p>
<p>mkdir /server/ssl<br />
cd /server/ssl</p>
<p>##### 手工签署证书 #####<br />
/usr/local/ssl/bin/openssl genrsa -des3 \<br />
-rand 任意大文件1:任意大文件2 \<br />
-out server.key 1024</p>
<p>输入密码<br />
重复密码</p>
<p>/usr/local/ssl/bin/openssl req -new -key server.key -out server.csr</p>
<p>Enter pass phrase for localhost.key:  #<&#8211;## 输入密码<br />
You are about to be asked to enter information that will be incorporated<br />
into your certificate request.<br />
What you are about to enter is what is called a Distinguished Name or a DN.<br />
There are quite a few fields but you can leave some blank<br />
For some fields there will be a default value,<br />
If you enter &#8216;.&#8217;, the field will be left blank.<br />
&#8212;&#8211;<br />
Country Name (2 letter code) [AU]:CN  #<&#8211;## 国家代码<br />
State or Province Name (full name) [Some-State]N  #<&#8211;## 省或州<br />
Locality Name (eg, city) []:SY  #<&#8211;## 城市<br />
Organization Name (eg, company) [Internet Widgits Pty Ltd]:micronsky.net  #<&#8211;## 组织名称<br />
Organizational Unit Name (eg, section) []:root  #<&#8211;## 部门<br />
Common Name (eg, YOUR name) []:keelort  #<&#8211;## 名字<br />
Email Address []:keelort@gmail.com  #<&#8211;## 电子邮件</p>
<p>Please enter the following &#8216;extra&#8217; attributes<br />
to be sent with your certificate request<br />
A challenge password []:  #<&#8211;## 直接回车就可以<br />
An optional company name []:  #<&#8211;## 直接回车就可以</p>
<p>/usr/local/ssl/bin/openssl x509 -req \<br />
-days 3650 \<br />
-in server.csr \<br />
-signkey server.key \<br />
-out server.crt</p>
<p>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..</p>
<p>注意：SSL 部分目前还不是很明白，apachectl startssl 启动后 http:// 不能用，只能用 https:// 连接，<br />
不知道怎么回事请高手指教，暂时没有写全</p>
<p>###############################################################################################</p>
<p>##### vsftpd #####</p>
<p>cd vsftpd-2.0.3</p>
<p>编辑 builddefs.h ：<br />
#define VSF_BUILD_PAM<br />
修改为<br />
#undef VSF_BUILD_PAM</p>
<p>编辑 defs.h ：<br />
#define VSFTP_DEFAULT_CONFIG    &#8220;/etc/vsftpd.conf&#8221;<br />
修改为<br />
#define VSFTP_DEFAULT_CONFIG    &#8220;/server/vsftpd/conf/vsftpd.conf&#8221;</p>
<p>make</p>
<p>useradd nobody<br />
mkdir /usr/share/empty<br />
mkdir /data/ftp<br />
useradd -d /data/ftp ftp<br />
chown root:root /data/ftp<br />
chmod og-w /data/ftp</p>
<p>install -m 755 vsftpd /server/vsftpd/vsftpd<br />
install -m 644 vsftpd.8 /usr/share/man/man8<br />
install -m 644 vsftpd.conf.5 /usr/share/man/man5<br />
mkdir /server/vsftpd/conf<br />
install -m 644 vsftpd.conf /server/vsftpd/conf/vsftpd.conf</p>
<p>使 vsftpd 以 standalone 方式启动：<br />
编写名为 vsftpd 的启动脚本：</p>
<p>CODE:<br />
[Copy to clipboard]<br />
#!/bin/sh<br />
# /etc/init.d/vsftpd<br />
#</p>
<p>set -e</p>
<p># Exit if vsftpd.conf doesn&#8217;t have listen=yes or listen_ipv6=yes<br />
# (mandatory for standalone operation)<br />
if [ -f /server/vsftpd/conf/vsftpd.conf ] &#038;&#038; ! egrep -iq &#8220;^ *listen(_ipv6)? *= *yes&#8221; </p>
<p>/server/vsftpd/conf/vsftpd.conf; then<br />
    exit 0<br />
fi</p>
<p>DAEMON=/server/vsftpd/vsftpd<br />
NAME=vsftpd</p>
<p>test -x $DAEMON || exit 0</p>
<p>case &#8220;$1&#8243; in<br />
  start)<br />
    echo -n &#8220;Starting FTP server: $NAME&#8221;<br />
    start-stop-daemon &#8211;start &#8211;background -m &#8211;pidfile /tmp/vsftpd.pid &#8211;exec $DAEMON<br />
    echo &#8220;.&#8221;<br />
    ;;<br />
  stop)<br />
    echo -n &#8220;Stopping FTP server: $NAME&#8221;<br />
    start-stop-daemon &#8211;stop &#8211;pidfile /tmp/vsftpd.pid &#8211;oknodo &#8211;exec $DAEMON<br />
    echo &#8220;.&#8221;<br />
      ;;<br />
  restart)<br />
    echo -n &#8220;Restarting FTP server: $NAME&#8221;<br />
    start-stop-daemon &#8211;stop &#8211;pidfile /tmp/vsftpd.pid &#8211;oknodo &#8211;exec $DAEMON<br />
    start-stop-daemon &#8211;start &#8211;background -m &#8211;pidfile /tmp/vsftpd.pid &#8211;exec $DAEMON<br />
    echo &#8220;.&#8221;<br />
    ;;<br />
  reload|force-reload)<br />
    echo &#8220;Reloading $NAME configuration files&#8221;<br />
    start-stop-daemon &#8211;stop &#8211;pidfile /tmp/vsftpd.pid &#8211;signal 1 &#8211;exec $DAEMON<br />
    echo &#8220;.&#8221;<br />
    ;;<br />
  *)<br />
    echo &#8220;Usage: /etc/init.d/$NAME {start|stop|restart|reload}&#8221;<br />
    exit 1<br />
    ;;<br />
esac</p>
<p>exit 0<br />
运行 rcconf 选中 vsftpd ，确定</p>
<p>重新启动，试试试不是所有的服务都启动，呵呵&#8230;</p>
<p>全文完</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/720.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redhat  tar 自动备份和恢复脚本 （RHEL4）</title>
		<link>http://www.evanjiang.net.cn/archives/684.html</link>
		<comments>http://www.evanjiang.net.cn/archives/684.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 10:14:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[redhat  备份脚本]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=684</guid>
		<description><![CDATA[<p>自动备份脚本
#!/bin/bash
# df -k
#Filesystem           1K-blocks      Used Available Use% Mounted on
#/dev/sda2            113852040  10113912  97954732  10% /
#/dev/sda1             [...]]]></description>
			<content:encoded><![CDATA[<p>自动备份脚本<br />
#!/bin/bash<br />
# df -k<br />
#Filesystem           1K-blocks      Used Available Use% Mounted on<br />
#/dev/sda2            113852040  10113912  97954732  10% /<br />
#/dev/sda1               790588     24680    725748   4% /boot<br />
#none                   1028008         0   1028008   0% /dev/shm<br />
#/dev/sda5             19362784  10617104   7762104  58% /export/home<br />
#<br />
# to show how to set crontab<br />
# [root@ad12 log]# crontab -l<br />
# SHELL=/bin/bash<br />
# 30 18 * * *       /usr/local/william.w/backup-1.sh >> /usr/local/william.w/backup.log 2>&#038;1<br />
#<br />
# to avoid the error: TERM environment variable not set.<br />
TERM=linux<br />
export TERM<br />
cd /<br />
clear<br />
echo<br />
echo<br />
echo =====================================<br />
echo this tool is used to backup the MMSC<br />
echo =====================================<br />
# to get the IP<br />
IP1=`ifconfig | grep &#8220;inet addr:&#8221; | grep -v &#8220;inet addr:127.0.0.1&#8243; | awk -F: &#8216;{printf $2}&#8217;`<br />
IP2=${IP1%% *}<br />
echo the server IP is $IP2<br />
# to get the date<br />
DATE=`date +%Y-%m-%d-%H`-tar<br />
echo today is ${DATE%-*}<br />
# to make a file folder to store the backp files, but if it was already exsit, just to overwirite it.<br />
mkdir /export/home/$DATE 2> /dev/null<br />
echo /export/home/$DATE has already exsited or been made.<br />
echo and backup file will be backuped in this folder.<br />
echo<br />
# all backup files using tar file have been located in /export/home, and below command just sum the backup files and show them in the list.<br />
NUM=`ls /export/home/ | grep tar | wc -l`<br />
echo now we have $NUM tar folder, they are all under /export/home/<br />
echo =================<br />
ls -tr /export/home/ | grep tar<br />
echo =================<br />
# to caculate the used disk space for /export/home<br />
USEDISK=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
        if [ $USEDISK -gt 85 ]<br />
        then<br />
        echo USEDISK is $USEDISK%<br />
        echo WARNNIG: have no enough space to backup!<br />
        exit;<br />
        fi<br />
<span id="more-684"></span><br />
echo USEDISK is $USEDISK%<br />
        if [ $USEDISK -gt 65 ]<br />
                then<br />
                echo &#8220;***************************&#8221;<br />
                echo &#8216;USEDISK is lager than 65!!!&#8217;<br />
                if [ $NUM -gt 2 ]<br />
                        then<br />
                        echo &#8220;***************************&#8221;<br />
                        echo there are $NUM tar folders:<br />
                        ls -tr /export/home/ | grep tar<br />
                        echo &#8220;*****************************************&#8221;<br />
                        # if the used disk space is beyond 65% and the number of tar-format-backup-file-folder is bigger than 2, we would delete these folders to keep the number to be less or equate 2<br />
                        DIFF=`expr $NUM &#8211; 2`<br />
                        # the number of file folders that would be deleted is $DIFF, and they would be deleted in below circle.<br />
                        for dir in `ls -tr /export/home/ | grep tar | head -n $DIFF`<br />
                                do<br />
                                        DISKSPACE=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
                                        if [ $DISKSPACE -le 65 ]<br />
                                        then<br />
                                                echo now USEDISK is $DISKSPACE%, and it is OK<br />
                                                break;<br />
                                        fi<br />
#                                        line = $dir;<br />
                                        echo &#8220;`ls -tr /export/home/ | grep tar | head -n 1` will be deleted soon&#8230;&#8221;<br />
                                        echo &#8230;<br />
                                        rm -fr /export/home/$dir;<br />
                                        echo &#8220;$dir has been deleted successfully&#8221;<br />
                                echo &#8220;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&#8221;<br />
                                done<br />
                        echo &#8220;********************************&#8221;<br />
                fi<br />
        fi<br />
echo<br />
echo &#8220;==========Begin to tar==============&#8221;<br />
echo now below file folder would be tared:<br />
# just show the list of file folder that would be backuped, and folder name has been add with &#8220;/&#8221; becuase this RHEL4.0 X86-64 does not show the root path.<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
ls / | grep -v -e proc -e mnt -e media -e lost+found -e export| sed &#8216;s/\([ ]\{1,\}\)/\1\//g;s/^./\/&#038;/g&#8217;<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo tar is working now&#8230;<br />
echo please waiting&#8230;&#8230;.<br />
# prepare to show the file name, and the backup file name is $DATE/$RNAME-$IP3-$DAY.tar.gz locating at /export/home/$DATE/<br />
# to backup all root file folders,  but donot include /proc, /mnt, /media/, and /export<br />
# all the display infomation would not show by  >&#038; /dev/null<br />
# all error information would not show by 2> /dev/null<br />
IP3=`echo $IP2 | awk -F. &#8216;{printf $3&#8243;.&#8221;$4}&#8217;`<br />
DAY=`echo $DATE| awk -F- &#8216;{printf $2$3$4}&#8217;`<br />
RNAME=`hostname | awk -F. &#8216;{printf $1}&#8217;`<br />
tar -zcvPf /export/home/$DATE/$RNAME-$IP3-$DAY.tar.gz 2> /dev/null $(ls / | grep -v -e proc -e mnt -e media -e lost+found -e export)  >&#038; /dev/null<br />
echo now backup is successful.<br />
echo the file is /export/home/$DATE/$RNAME-$IP3-$DAY.tar.gz<br />
echo &#8220;==================================End to tar=========================&#8221;<br />
echo<br />
# to list the backup folders<br />
echo Summary of backup files:<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
echo the img backup:<br />
ls -t /export/home/ | grep img<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo the tar backup:<br />
ls -t /export/home/ | grep tar<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo other files:<br />
ls -t /export/home/ | grep -v tar |grep -v img<br />
echo =================================<br />
USEDISK1=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
echo before backup the USEDISK is $USEDISK%<br />
echo at last the USEDISK is $USEDISK1%<br />
echo =================================</p>
<p>自动恢复脚本<br />
#!/bin/bash<br />
cd /<br />
clear<br />
echo<br />
echo<br />
echo<br />
echo =====================================<br />
echo this tool is used to restore the MMSC<br />
echo =====================================<br />
echo<br />
echo this restore command must be like   &#8220;#/export/home/restore.sh   backup-file-folder&#8221;<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
echo for example:<br />
echo &#8220;#/export/home/restore.sh 2008-04-01-00-tar&#8221;<br />
echo<br />
# to get the date<br />
DATE=`date +%Y-%m-%d-%H`-tar<br />
echo today is ${DATE%-*}<br />
# to get the IP<br />
IP1=`ifconfig | grep &#8220;inet addr:&#8221; | grep -v &#8220;inet addr:127.0.0.1&#8243; | awk -F: &#8216;{printf $2}&#8217;`<br />
IP2=${IP1%% *}<br />
IP3=`echo $IP2 | awk -F. &#8216;{printf $3&#8243;.&#8221;$4}&#8217;`<br />
echo the server IP is $IP2<br />
RNAME=`hostname | awk -F. &#8216;{printf $1}&#8217;`<br />
echo the server name is $RNAME<br />
# to get the path of the backup file, and it is /export/home/$1/<br />
# to get the name of the backup file, and it is $RNAME-$IP3-$DAY.tar.gz<br />
echo the restored folder and file are:<br />
DAY=`echo $1| awk -F- &#8216;{printf $2$3$4}&#8217;`<br />
echo /export/home/$1/$RNAME-$IP3-$DAY.tar.gz<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo please wait&#8230;&#8230;<br />
# to restore the backup files under root path<br />
cd /<br />
tar -zxvPf /export/home/$1/$RNAME-$IP3-*.tar.gz  2> /dev/null -C / >&#038; /dev/null<br />
echo backup is successful<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
echo</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/684.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysql备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/682.html</link>
		<comments>http://www.evanjiang.net.cn/archives/682.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 10:10:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=682</guid>
		<description><![CDATA[<p>#!/bin/sh
#
# Copyright (C), 2008 bug All Rights Reserved
# Title       : Database Backup Script
# Author      : BUG
# File        : db_bak.sh
# Version     : 1.1.0
# Date        :
# Email  [...]]]></description>
			<content:encoded><![CDATA[<p>#!/bin/sh<br />
#<br />
# Copyright (C), 2008 bug All Rights Reserved<br />
# Title       : Database Backup Script<br />
# Author      : BUG<br />
# File        : db_bak.sh<br />
# Version     : 1.1.0<br />
# Date        :<br />
# Email       :<br />
# License     : General Public License (GPL) v2<br />
# Description : Database Backup Script<br />
#</p>
<p>initial() {<br />
    echo -en &#8220;\33[2J"<br />
    echo -en "\33[0;0H"<br />
    echo -en "\33[32m"<br />
    echo "------------------------------------------------------------"<br />
    echo "---                Database Backup Script                ---"<br />
    echo "------------------------------------------------------------"<br />
    echo -en "\33[37m"<br />
    stty -echo<br />
    umask 077<br />
    mysqln=`echo 'show databases;' | /usr/local/mysql/bin/mysql -psjldafhkg | sed -n '3,$p'`<br />
    mysqlu="root"<br />
    mysqlp="********"<br />
    binpath="/usr/local/mysql/bin"<br />
    dstpath="/pri/bak/sql_bak/"<br />
    runuser=`ps aux | grep $$ | sed -n "1p" | awk '{ print $1 }'`<br />
    mkdir -p $dstpath/`date +%y%m%d`<br />
    exec 3>>$dstpath/`date +%y%m%d`/db_bak.log<br />
}</p>
<p>initial</p>
<p>echo -e "\n[`date +%y/%m/%d\ %H:%M:%S`] Database Backup Script start by $runuser PID:$$&#8221; >&#038;3</p>
<p>if [ -f "$dstpath/`date +%y%m%d`/lock" ]<br />
then<br />
    echo -e &#8220;\33[33mIt's has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!\33[37m"<br />
    echo "[`date +%y/%m/%d\ %H:%M:%S`] It&#8217;s has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!&#8221; >&#038;3<br />
else<br />
    echo -e &#8220;Database\tExport\tCompress\tSql\tTgz\tRate&#8221;<br />
    echo -e &#8220;\33[32m------------------------------------------------------------\33[37m"<br />
    cd $dstpath/`date +%y%m%d`<br />
    for db in $mysqln<br />
    do<br />
    echo -n "$db"<br />
    $binpath/mysqldump --opt -u$mysqlu -p$mysqlp $db > $dstpath/`date +%y%m%d`/$db.sql 2> /dev/null<br />
    RETVAL1=$?<br />
    if [ $RETVAL1 -eq 0 ]<br />
    then<br />
    sqlsize=`du -k $db.sql | cut -f1`<br />
    echo -n &#8220;[`date +%y/%m/%d\ %H:%M:%S`]&#8221; >&#038;3<br />
    echo -n &#8220;$db&#8221; | awk &#8216;{printf &#8221; %-17s&#8221;, $1}&#8217; >&#038;3<br />
    echo -n &#8220;OK  &#8221; >&#038;3<br />
    echo -en &#8220;\r\t\t  \33[32mOK\33[37m\t"<br />
    tar -czvf $db.tgz $db.sql > /dev/null 2>&#038;1<br />
        RETVAL2=$?<br />
        if [ $RETVAL2 -eq 0 ]<br />
        then<br />
        tgzsize=`du -k $db.tgz | cut -f1`<br />
        echo &#8220;OK&#8221; >&#038;3<br />
        rm -f $dstpath/`date +%y%m%d`/$db.sql<br />
        echo -en &#8221;   \33[32mOK\33[37m"<br />
        echo -en "\33[33m"<br />
        echo -en "$sqlsize" | awk '{printf "%12sKB", $1}'<br />
        echo -en "$tgzsize" | awk '{printf "%6sKB", $1}'<br />
        echo "$sqlsize $tgzsize" | awk '{printf "%8.0f%",$2/$1*100}'<br />
        echo -e "\33[37m"<br />
        else<br />
        echo "Compress fail return $RETVAL2" >&#038;3<br />
        echo -e "  \33[31mfail\33[37m"<br />
        fi<br />
    else<br />
    echo -n "[`date +%y/%m/%d\ %H:%M:%S`]&#8221; >&#038;3<br />
    echo -n &#8220;$db&#8221; | awk &#8216;{printf &#8221; %-17s &#8220;, $1}&#8217; >&#038;3<br />
    echo &#8220;Export fail return $RETVAL1&#8243; >&#038;3<br />
    echo -en &#8220;\r\t\t   \33[31mfail\33[37m&#8221;<br />
    fi<br />
    done<br />
    echo &#8220;`date +%H:%M:%S`&#8221;>$dstpath/`date +%y%m%d`/lock<br />
fi</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/682.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux下的bash与sh 详解以及实例</title>
		<link>http://www.evanjiang.net.cn/archives/668.html</link>
		<comments>http://www.evanjiang.net.cn/archives/668.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 09:45:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[suse linux]]></category>
		<category><![CDATA[linux下的bash与sh]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=668</guid>
		<description><![CDATA[<p>关于bash与sh的话题（限于一般linux），以下个人的一些总结及理解，有理解错误的地方还望指点</p>
<p>1、bash的POSIX标准</p>
<p>在一般的linux系统当中（如redhat），
使用sh调用执行脚本相当于打开了bash的POSIX标准模式
（等效于bash的 &#8211;posix 参数）</p>
<p>一般的，sh是bash的“子集”
（不是子集的部分，具体区别见下的“Things sh has that bash does not”）</p>
<p>例子：</p>
<p>[wwy@sf-watch test]$ cat t2.sh
#!/bin/bash
diff 




</p>
<p>2、调用相关：</p>
<p>在脚本的调用方面（interactive、login相关），bash与sh也是存在差异
以下是详细说明（假如被调用执行的脚本名字叫xxx.sh）</p>
<p>BASH：</p>
<p>1、交互式的登录shell （bash –il xxx.sh）
载入的信息：
/etc/profile
~/.bash_profile（ ->  ~/.bashrc  ->  /etc/bashrc）
~/.bash_login
~/.profile</p>
<p>2、非交互式的登录shell （bash –l xxx.sh）
载入的信息：
/etc/profile
~/.bash_profile （ ->  ~/.bashrc  ->  /etc/bashrc）
~/.bash_login
~/.profile
$BASH_ENV</p>
<p>3、交互式的非登录shell （bash –i xxx.sh）
载入的信息：
~/.bashrc （ ->  /etc/bashrc）</p>
<p>4、非交互式的非登录shell （bash xxx.sh）
载入的信息：
$BASH_ENV</p>
<p>SH：</p>
<p>1、交互式的登录shell
载入的信息：
/etc/profile
~/.profile</p>
<p>2、非交互式的登录shell
载入的信息：
/etc/profile
~/.profile</p>
<p>3、交互式的非登录shell
载入的信息：
$ENV</p>
<p>4、非交互式的非登录shell
载入的信息：
nothing</p>
<p>由此可以看出，最主要的区别在于相关配置文件的是否载入，
而这些配置的是否载入，也就导致了很多默认选项的差异
（具体请仔细查看~/.bash_profile 等文件）</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ grep ulimit /etc/profile
ulimit -S -c unlimited > /dev/null 2>&#038;1</p>
<p>即，如果/etc/profile没有被载入，则不会产生core dump</p>
<p>3、关于ssh</p>
<p>非常值得一提的是，使用ssh远程执行命令，
远端sshd进程通过“bash [...]]]></description>
			<content:encoded><![CDATA[<p>关于bash与sh的话题（限于一般linux），以下个人的一些总结及理解，有理解错误的地方还望指点</p>
<p>1、bash的POSIX标准</p>
<p>在一般的linux系统当中（如redhat），<br />
使用sh调用执行脚本相当于打开了bash的POSIX标准模式<br />
（等效于bash的 &#8211;posix 参数）</p>
<p>一般的，sh是bash的“子集”<br />
（不是子集的部分，具体区别见下的“Things sh has that bash does not”）</p>
<p>例子：</p>
<p>[wwy@sf-watch test]$ cat t2.sh<br />
#!/bin/bash<br />
diff <(echo xxx) <(echo yyy) </p>
<p>[wwy@sf-watch test]$ bash -x ./t2.sh # 使用bash 调用，不会出问题<br />
+ diff /dev/fd/63 /dev/fd/62<br />
++ echo xxx<br />
++ echo yyy<br />
1c1<br />
< xxx<br />
---<br />
> yyy<br />
[wwy@sf-watch test]$ sh ./t2.sh    # 而用sh调用，报错如下<br />
./t2.sh: line 3: syntax error near unexpected token `(&#8216;<br />
./t2.sh: line 3: `diff <(echo xxx) <(echo yyy)'<br />
[wwy@sf-watch test]$ echo $?<br />
2<br />
<span id="more-668"></span></p>
<p>但是，在我们的linux系统中，sh是bash的一个软链接：</p>
<p>[wangweiyu@ComSeOp mon]$ which sh<br />
/bin/sh<br />
[wangweiyu@ComSeOp mon]$ ls -l /bin/sh<br />
lrwxrwxrwx  1 root root 4 Mar 21  2007 /bin/sh -> bash</p>
<p>那为什么上面的例子中还会出现问题呢？原因在于：<br />
bash程序执行，当“$0”是“sh”的时候，<br />
则要求下面的代码遵循一定的规范，当不符合规范的语法存在时，则会报错，<br />
所以可以这样理解，<br />
“sh”并不是一个程序，而是一种标准（POSIX），<br />
这种标准，在一定程度上（具体区别见下面的“Things bash has that sh does not”）保证了脚本的跨系统性（跨UNIX系统）</p>
<p>下面的内容详细的说明了bash与sh在语法等方面的具体差异（引自Bash FAQ）：</p>
<p>Things bash has that sh does not:</p>
<p>        long invocation options<br />
        [+-]O invocation option<br />
        -l invocation option<br />
        `!&#8217; reserved word to invert pipeline return value<br />
        `time&#8217; reserved word to time pipelines and shell builtins<br />
        the `function&#8217; reserved word<br />
        the `select&#8217; compound command and reserved word<br />
        arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done<br />
        new $&#8217;&#8230;&#8217; and $&#8221;&#8230;&#8221; quoting<br />
        the $(&#8230;) form of command substitution<br />
        the $(<filename) form of command substitution, equivalent to<br />
                $(cat filename)<br />
        the ${#param} parameter value length operator<br />
        the ${!param} indirect parameter expansion operator<br />
        the ${!param*} prefix expansion operator<br />
        the ${param:offset[:length]} parameter substring operator<br />
        the ${param/pat[/string]} parameter pattern substitution operator<br />
        expansions to perform substring removal (${p%[%]w}, ${p#[#]w})<br />
        expansion of positional parameters beyond $9 with ${num}<br />
        variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, REPLY,<br />
                   TIMEFORMAT, PPID, PWD, OLDPWD, SHLVL, RANDOM, SECONDS,<br />
                   LINENO, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HOSTNAME,<br />
                   ENV, PS3, PS4, DIRSTACK, PIPESTATUS, HISTSIZE, HISTFILE,<br />
                   HISTFILESIZE, HISTCONTROL, HISTIGNORE, GLOBIGNORE, GROUPS,<br />
                   PROMPT_COMMAND, FCEDIT, FIGNORE, IGNOREEOF, INPUTRC,<br />
                   SHELLOPTS, OPTERR, HOSTFILE, TMOUT, FUNCNAME, histchars,<br />
                   auto_resume<br />
        DEBUG trap<br />
        ERR trap<br />
        variable arrays with new compound assignment syntax<br />
        redirections: <>, &#038;>, >|, <<<, [n]<&#038;word-, [n]>&#038;word-<br />
        prompt string special char translation and variable expansion<br />
        auto-export of variables in initial environment<br />
        command search finds functions before builtins<br />
        bash return builtin will exit a file sourced with `.&#8217;<br />
        builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t.<br />
                  export -n/-f/-p/name=value, pwd -L/-P,<br />
                  read -e/-p/-a/-t/-n/-d/-s/-u,<br />
                  readonly -a/-f/name=value, trap -l, set +o,<br />
                  set -b/-m/-o option/-h/-p/-B/-C/-H/-P,<br />
                  unset -f/-v, ulimit -i/-m/-p/-q/-u/-x,<br />
                  type -a/-p/-t/-f/-P, suspend -f, kill -n,<br />
                  test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S<br />
        bash reads ~/.bashrc for interactive shells, $ENV for non-interactive<br />
        bash restricted shell mode is more extensive<br />
        bash allows functions and variables with the same name<br />
        brace expansion<br />
        tilde expansion<br />
        arithmetic expansion with $((&#8230;)) and `let&#8217; builtin<br />
        the `[[...]]&#8217; extended conditional command<br />
        process substitution<br />
        aliases and alias/unalias builtins<br />
        local variables in functions and `local&#8217; builtin<br />
        readline and command-line editing with programmable completion<br />
        command history and history/fc builtins<br />
        csh-like history expansion<br />
        other new bash builtins: bind, command, compgen, complete, builtin,<br />
                                 declare/typeset, dirs, enable, fc, help,<br />
                                 history, logout, popd, pushd, disown, shopt,<br />
                                 printf<br />
        exported functions<br />
        filename generation when using output redirection (command >a*)<br />
        POSIX.2-style globbing character classes<br />
        POSIX.2-style globbing equivalence classes<br />
        POSIX.2-style globbing collating symbols<br />
        egrep-like extended pattern matching operators<br />
        case-insensitive pattern matching and globbing<br />
        variable assignments preceding commands affect only that command,<br />
                even for builtins and functions<br />
        posix mode and strict posix conformance<br />
        redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,<br />
                /dev/tcp/host/port, /dev/udp/host/port<br />
        debugger support, including `caller&#8217; builtin and new variables<br />
        RETURN trap<br />
        the `+=&#8217; assignment operator</p>
<p>Things sh has that bash does not:<br />
        uses variable SHACCT to do shell accounting<br />
        includes `stop&#8217; builtin (bash can use alias stop=&#8217;kill -s STOP&#8217;)<br />
        `newgrp&#8217; builtin<br />
        turns on job control if called as `jsh&#8217;<br />
        $TIMEOUT (like bash $TMOUT)<br />
        `^&#8217; is a synonym for `|&#8217;<br />
        new SVR4.2 sh builtins: mldmode, priv</p>
<p>Implementation differences:<br />
        redirection to/from compound commands causes sh to create a subshell<br />
        bash does not allow unbalanced quotes; sh silently inserts them at EOF<br />
        bash does not mess with signal 11<br />
        sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100<br />
        bash splits only the results of expansions on IFS, using POSIX.2<br />
                field splitting rules; sh splits all words on IFS<br />
        sh does not allow MAILCHECK to be unset (?)<br />
        sh does not allow traps on SIGALRM or SIGCHLD<br />
        bash allows multiple option arguments when invoked (e.g. -x -v);<br />
                sh allows only a single option argument (`sh -x -v' attempts<br />
                to open a file named `-v', and, on SunOS 4.1.4, dumps core.<br />
                On Solaris 2.4 and earlier versions, sh goes into an infinite<br />
                loop.)<br />
        sh exits a script if any builtin fails; bash exits only if one of<br />
                the POSIX.2 `special' builtins fails</p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>2、调用相关：</p>
<p>在脚本的调用方面（interactive、login相关），bash与sh也是存在差异<br />
以下是详细说明（假如被调用执行的脚本名字叫xxx.sh）</p>
<p>BASH：</p>
<p>1、交互式的登录shell （bash –il xxx.sh）<br />
载入的信息：<br />
/etc/profile<br />
~/.bash_profile（ ->  ~/.bashrc  ->  /etc/bashrc）<br />
~/.bash_login<br />
~/.profile</p>
<p>2、非交互式的登录shell （bash –l xxx.sh）<br />
载入的信息：<br />
/etc/profile<br />
~/.bash_profile （ ->  ~/.bashrc  ->  /etc/bashrc）<br />
~/.bash_login<br />
~/.profile<br />
$BASH_ENV</p>
<p>3、交互式的非登录shell （bash –i xxx.sh）<br />
载入的信息：<br />
~/.bashrc （ ->  /etc/bashrc）</p>
<p>4、非交互式的非登录shell （bash xxx.sh）<br />
载入的信息：<br />
$BASH_ENV</p>
<p>SH：</p>
<p>1、交互式的登录shell<br />
载入的信息：<br />
/etc/profile<br />
~/.profile</p>
<p>2、非交互式的登录shell<br />
载入的信息：<br />
/etc/profile<br />
~/.profile</p>
<p>3、交互式的非登录shell<br />
载入的信息：<br />
$ENV</p>
<p>4、非交互式的非登录shell<br />
载入的信息：<br />
nothing</p>
<p>由此可以看出，最主要的区别在于相关配置文件的是否载入，<br />
而这些配置的是否载入，也就导致了很多默认选项的差异<br />
（具体请仔细查看~/.bash_profile 等文件）</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ grep ulimit /etc/profile<br />
ulimit -S -c unlimited > /dev/null 2>&#038;1</p>
<p>即，如果/etc/profile没有被载入，则不会产生core dump</p>
<p>3、关于ssh</p>
<p>非常值得一提的是，使用ssh远程执行命令，<br />
远端sshd进程通过“bash –c”的方式来执行命令（即“非交互式的非登录shell”）<br />
所以这一点，和登录之后再在本地执行执行命令，就存在了一定的差异</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $-&#8217;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
hBc<br />
[wangweiyu@ComSeOp ~]$ echo $-<br />
himBH<br />
[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $0&#8242;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
bash<br />
[wangweiyu@ComSeOp ~]$ echo $0<br />
-bash</p>
<p>注：<br />
“$-” 中含有“i”代表“交互式shell”<br />
“$0”的显示结果为“-bash”，bash前面多个“-”，代表“登录shell”<br />
没有“i“和“-”的，是“非交互式的非登录shell”</p>
<p>另外还有一点，虽然ssh远程执行的命令是“非交互式的非登录shell”，<br />
但在执行命令之前，ssh的那一次登录本身是“交互式的登录shell”，所以其会先载入“~/.bash_profile”</p>
<p>如：<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
[wangweiyu@ComSeOp ~]$ cat .bashrc<br />
# .bashrc<br />
# User specific aliases and functions<br />
# Source global definitions<br />
if [ -f /etc/bashrc ]; then<br />
        . /etc/bashrc<br />
fi<br />
echo &#8216;xxx&#8217; # 随便输出一些字符</p>
<p>[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $-&#8217;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
xxx # .bashrc 被执行<br />
hBc </p>
<p>这一点，衍生出一个关于scp的问题，scp在传输数据之前，会先进行一次ssh登录，<br />
而当.bashrc文件有输出的时候，则会导致scp失败！原因是解析返回的数据包出现混乱</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ cat .bashrc<br />
# .bashrc<br />
# User specific aliases and functions<br />
# Source global definitions<br />
if [ -f /etc/bashrc ]; then<br />
        . /etc/bashrc<br />
fi<br />
echo &#8216;xxx&#8217; # 随便输出一些字符<br />
[wangweiyu@ComSeOp ~]$ scp file wangweiyu@127.0.0.1:/tmp<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
xxx # 输出xxx，随后scp失败<br />
[wangweiyu@ComSeOp ~]$ echo $?<br />
1<br />
[wangweiyu@ComSeOp ~]$ ls /tmp/<br />
[wangweiyu@ComSeOp ~]$</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/668.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>apache2+php+oracle9的安装</title>
		<link>http://www.evanjiang.net.cn/archives/650.html</link>
		<comments>http://www.evanjiang.net.cn/archives/650.html#comments</comments>
		<pubDate>Mon, 02 Mar 2009 10:46:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[oracle]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[apache2 php oracle9  安装]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=650</guid>
		<description><![CDATA[<p>1、前言：
   对于unix(linux)来说，apache＋php是个不错的选择。对于小型的网站，比较通用的是apache+php+mysql，优点不比说。但是，对于大型的网站，需要对数据库检索和连接请求高的站点，mysql还是出现他的局限性。很多门户网站，例如：sina、tom、sohu、china等，都是用新闻发稿器的生成静态页面。但是这个新闻发稿器，很多都是通过apache＋php来完成，大量的资料放在数据库中，用户访问的时候，在由程序生成静态页面。所以，apache+php+oracle是比较合理的选择。</p>
<p>由于平时都是用的sun的sparc机器，这个环境是临时搭建，用的是redhat9，如果有喜欢用redhat ad的朋友，需要自己先测试一下。</p>
<p>2、结构：
主机两台：
odb &#8211;安装oracle server，作为数据存储。
webapp &#8212;安装oracle client和apache+php，php通过oracle client来访问oracle。
odb ip:192.168.1.2
webapp ip: 192.168.1.3  211.11.11.11
优点：安全，odb可以用内网ip，还能实现降低webapp的负载。</p>
<p>3、主机系统相关软件：
redhat9
oacle9 for liunx
httpd2.0.50
php-4.32</p>
<p>4、安装软件：
4.1、odb的安装：
这里关于oracle9的redhat9上的安装，大家查看论坛响应的其他文章，这里就不过多写。为上下文，这里建立库为odb。</p>
<p>4.2、apache2的安装：

# tar zxvf httpd-2.0.49.tar.gz
# cd httpd-2.0.49
# ./configure &#8211;prefix=/opt/apache &#8211;enable-so &#8211;with-mpm=worker
# make
# make install</p>
<p>4.3、webapp主机上的oracle client安装：</p>
<p>4.3.1 安装好RedHat9.0操作系统，确保安装以下的RPM开发包
gcc
cpp
glibc-devel
compat-libstdc++
glibc-kernheaders
binutils
可以使用命令来查看是否已安装这些包
rpm –q gcc cpp compat-libstdc++ glibc-devel glibc-kernheaders binutils</p>
<p>4.3.2、从Oracle官方网站下载Oracle9i安装文件并使用如下命令解包








# zcat lnx_920_disk1.cpio.gz &#124; cpio –idmv
# zcat lnx_920_disk2.cpio.gz &#124; cpio –idmv
# zcat lnx_920_disk3.cpio.gz &#124; cpio –idmv
然后会有Disk1 Disk2 Disk3三个子目录。</p>
<p>4.3.3、设置内核参数
# [...]]]></description>
			<content:encoded><![CDATA[<p>1、前言：<br />
   对于unix(linux)来说，apache＋php是个不错的选择。对于小型的网站，比较通用的是apache+php+mysql，优点不比说。但是，对于大型的网站，需要对数据库检索和连接请求高的站点，mysql还是出现他的局限性。很多门户网站，例如：sina、tom、sohu、china等，都是用新闻发稿器的生成静态页面。但是这个新闻发稿器，很多都是通过apache＋php来完成，大量的资料放在数据库中，用户访问的时候，在由程序生成静态页面。所以，apache+php+oracle是比较合理的选择。</p>
<p>由于平时都是用的sun的sparc机器，这个环境是临时搭建，用的是redhat9，如果有喜欢用redhat ad的朋友，需要自己先测试一下。</p>
<p>2、结构：<br />
主机两台：<br />
odb &#8211;安装oracle server，作为数据存储。<br />
webapp &#8212;安装oracle client和apache+php，php通过oracle client来访问oracle。<br />
odb ip:192.168.1.2<br />
webapp ip: 192.168.1.3  211.11.11.11<br />
优点：安全，odb可以用内网ip，还能实现降低webapp的负载。</p>
<p>3、主机系统相关软件：<br />
redhat9<br />
oacle9 for liunx<br />
httpd2.0.50<br />
php-4.32</p>
<p>4、安装软件：<br />
4.1、odb的安装：<br />
这里关于oracle9的redhat9上的安装，大家查看论坛响应的其他文章，这里就不过多写。为上下文，这里建立库为odb。</p>
<p>4.2、apache2的安装：<br />
<span id="more-650"></span><br />
# tar zxvf httpd-2.0.49.tar.gz<br />
# cd httpd-2.0.49<br />
# ./configure &#8211;prefix=/opt/apache &#8211;enable-so &#8211;with-mpm=worker<br />
# make<br />
# make install</p>
<p>4.3、webapp主机上的oracle client安装：</p>
<p>4.3.1 安装好RedHat9.0操作系统，确保安装以下的RPM开发包<br />
gcc<br />
cpp<br />
glibc-devel<br />
compat-libstdc++<br />
glibc-kernheaders<br />
binutils<br />
可以使用命令来查看是否已安装这些包<br />
rpm –q gcc cpp compat-libstdc++ glibc-devel glibc-kernheaders binutils</p>
<p>4.3.2、从Oracle官方网站下载Oracle9i安装文件并使用如下命令解包<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
# zcat lnx_920_disk1.cpio.gz | cpio –idmv<br />
# zcat lnx_920_disk2.cpio.gz | cpio –idmv<br />
# zcat lnx_920_disk3.cpio.gz | cpio –idmv<br />
然后会有Disk1 Disk2 Disk3三个子目录。</p>
<p>4.3.3、设置内核参数<br />
# echo 4294967295 >; /proc/sys/kernel/shmmax，建议放到/etc/rc.local文件里。<br />
或编辑/etc/sysctl.conf<br />
kernel.shmmax=4294967295<br />
我有512MB内存，所以设置这个数值。可根据实际情况设置。</p>
<p>4.3.4、创建Oracle用户帐号和安装目录<br />
在shell下,作为root<br />
# groupadd dba<br />
# groupadd oinstall<br />
# useradd –g oinstall –G dba oracle<br />
# passwd oracle</p>
<p># mkdir /opt/oracle<br />
# mkdir /opt/oracle/product<br />
# mkdir /opt/oracle/product/9.2.0<br />
# chown –R oracle.oinstall /opt/oracle<br />
# mkdir /var/oracle<br />
# chown oracle.dba /var/oracle<br />
# chmod 755 /var/oracle</p>
<p>4.3.5、设置环境变量</p>
<p># vi /home/oracle/.bash_profile文件，添加下列行<br />
－－－－－－－－－－<br />
export LD_ASSUME_KERNEL=2.4.1<br />
export ORACLE_BASE=/opt/oracle<br />
export ORACLE_HOME=/opt/oracle/product/9.2.0<br />
NLS_LANG=&#8221;SIMPLIFIED CHINESE_CHINA.ZHS16GBK&#8221;;export NLS_LANG<br />
ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data; export ORA_NLS33<br />
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib;export LD_LIBRARY_PATH<br />
PATH=$PATH ORACLE_HOME/bin;export PATH</p>
<p>－－－－－－－－－－－－－－</p>
<p>4.3.6、安装<br />
可以重新启动机器，让设置的参数生效，让后用oracle用户登陆，安装oracle。</p>
<p># ~Disk1<br />
# ./runInstaller</p>
<p>安装的时候，选择安装client。<br />
有提示你用root用户执行几个脚本，按照提示做就可以。</p>
<p>4.4、 php安装<br />
在安装php的时候，php调用oracle9（9.0.2 &#8211;10 )的时候需要安装一个patch，不然会出现问题。但是oracle8的版本没有问题。oracle的官方网站上有下载，地址如下：</p>
<p>http://otn.oracle.com/products/ias/ohs/htdocs/ociheaders.tar</p>
<p># cp ociheaders.tar  /opt/oracle/product/9.2.0/rdbms/demo/<br />
# cd cd /opt/oracle/product/9.2.0/rdbms/demo<br />
# tar xvf ociheaders.tar</p>
<p># tar zxvf php-4.3.2.tar.gz<br />
# cd php-4.3.2<br />
#  ./configure &#8211;prefix=/opt/php &#8211;with-zlib<br />
   &#8211;with-apxs2=/opt/apache/bin/apxs &#8211;disable-xml &#8211;without-mysql<br />
   &#8211;with-oci8=/opt/oracle/product/9.2.0<br />
   &#8211;with-config-file-path=/opt/php/etc/php.ini<br />
   &#8211;disable-rpath &#8211;without-pear<br />
# make<br />
# make install<br />
# mkdir /usr/local/php/etc<br />
# cp /home/peng/php-4.3.2/etc/php.ini-disk /usr/local/php/etc/php.ini/php.ini<br />
# vi /usr/local/php/etc/php.ini/php.ini</p>
<p>5 配置软件：</p>
<p>5.1、启动odb主机上的oracle：<br />
以oracle用户登陆：</p>
<p>启动数据库<br />
$ Sqlplus “ / as sysdba”<br />
  SQL>;startup</p>
<p>启动监听程序<br />
$ lsnrctl</p>
<p>5.2、配置apache2：</p>
<p># vi /opt/apache/conf/httpd.conf</p>
<p>添加：AddType application/x-httpd-php .php<br />
更改下列选项如下：<br />
Listen 211.11.11.11:80  &#8211;你的发布主机ip<br />
User nobody<br />
Group nobody<br />
DirectoryIndex index.html index.php<br />
AddDefaultCharset Off</p>
<p>5.3 配置php：<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
# vi /usr/local/php/etc/php.ini/php.ini<br />
  更改：<br />
  register_global =Off 为 register_global =On</p>
<p>5.4 配置oracle client：<br />
# vi /opt/oracle/product/9.2.0/network/admin/tnsnames.ora</p>
<p>&#8212;&#8212;&#8212;&#8212;-<br />
odb =<br />
  (DESCRIPTION =<br />
    (ADDRESS_LIST =<br />
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521))<br />
    )<br />
    (CONNECT_DATA =<br />
      (SERVICE_NAME = odb)<br />
    )<br />
  )</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>到这里，系统已经全部安装成功，需要根据自己情况，配置apache的具体主机设置。</p>
<p>总结：<br />
apche+php+oracle一般的应用情况都是针对数据库访问量比较大，或者经常用到数据库检索的应用。很多都是为应用服务器而搭建的环境。</p>
<p>这里注意一点就是，这个环境的搭建，同样适合oracle10的版本。如果用oracle817以下的版本，是不需要安装ociheaders这个补丁的。对于oracle7，php要用&#8211;with-oracle＝的参数。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/650.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>apache2.0.x+mysql4.0.x+php5.0.x+solaris 9.0+proftpd1.2.x</title>
		<link>http://www.evanjiang.net.cn/archives/646.html</link>
		<comments>http://www.evanjiang.net.cn/archives/646.html#comments</comments>
		<pubDate>Mon, 02 Mar 2009 10:39:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ftp]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sun unix]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[soaris 安装 apache mysql php proftpd]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=646</guid>
		<description><![CDATA[<p>solaris下提供一个pkgadd的工具，它特别容易安装，对菜鸟来说非常方便，所谓AMPSP就是apache2.0.x+mysql4.0.x+php5.0.x+solaris 9.0+proftpd1.2.x.
首先当然有一个solaris9.0的系统，安装solaris就不用说吧，我装的是u7，安装时候用root安装，我用的是SUN的默认sh.
# uname -a
SunOS bad.com 5.9 Generic_117171-07 sun4u sparc SUNW,Ultra-5_10
看一下root的环境变量，如果不是下面的，可以在/etc/profile下面进行修改
# env
HOME=/
HZ=100
LOGNAME=root
MAIL=/var/mail/root
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/etc:/usr/local/bin:/usr/local/sbin
SHELL=/sbin/sh
TERM=ansi
TZ=PRC
在安装AMPSP前，必须安装一些EIS，下面的软件可以在www.sunfreeware.com的网站上可以下到，按你的系统下载安装包，我的系统是sparc的，所以下的也是for sparc的安装包，我们先建一个backup的目录，将下来的软件放到这个目录下，软件列表如下：
gcc-3.4.2-sol9-sparc-local.gz
db-4.2.52.NC-sol9-sparc-local.gz
expat-1.95.5-sol9-sparc-local.gz
libgcc-3.3-sol9-sparc-local.gz
libiconv-1.8-sol9-sparc-local.gz
libxml2-2.6.16-sol9-sparc-local.gz
libxslt-1.1.2-sol9-sparc-local.gz
ncurses-5.4-sol9-sparc-local.gz
zlib-1.2.2-sol9-sparc-local.gz
pcre-4.5-sol9-sparc-local.gz
在安装AMPSP前先安装这些，一点要注意的，gcc和libgcc这两个包的版本号不要太高，我在安装的时候，版本太高装不，用pkgadd命令安装：
#gunzip gcc-3.4.2-sol9-sparc-local.gz
#pkgadd –d gcc-3.4.2-sol9-sparc-local
安完以上的，接下来就可以安装AMPSP，下载并CP到/backup下：
apache-2.0.53-sol9-sparc-local.gz
mysql-4.0.21-sol9-sparc-local.gz
php-5.0.2-sol9-sparc-local.gz
proftpd-1.2.10rc1-sol9-sparc-local.gz

MYSQL的安装
创建运行mysql的用户
#cd /backup
# groupadd mysql
# useradd -g mysql mysql
安装mysql的安装包
#gunzip mysql-4.0.21-sol9-sparc-local.gz
#pkgadd –d mysql-4.0.21-sol9-sparc-local
安装完后，在/usr/local/下多一个mysql的目录，我们对它进行设置
#cd /usr/local/mysql
#cd scripts
#./mysql_install_db –user=mysql
#chown –R root /usr/local/mysql
#chgrp –R mysql /usr/local/mysql
#cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf
试运行一个mysql服务；
#cd /usr/local/mysql/bin
#./mysqld_safe –user=mysql&#038;
如果没出错误错的话，就说明成功，如果出现：
Starting mysqld daemon with databases from /usr/local/mysql/var
STOPPING server from pid file /usr/local/mysql/var/bad.com.pid
050407 01:44:15 mysqld ended
说明没有成功，看/usr/local/mysql/var/bad.com.err,这个错误可以用
#chown mysql:mysql /usr/local/mysql/var/mysql解决（我刚开的时候就是因为这个，弄半天没装好。








试一个mysql是不是可用
# ./mysql [...]]]></description>
			<content:encoded><![CDATA[<p>solaris下提供一个pkgadd的工具，它特别容易安装，对菜鸟来说非常方便，所谓AMPSP就是apache2.0.x+mysql4.0.x+php5.0.x+solaris 9.0+proftpd1.2.x.<br />
首先当然有一个solaris9.0的系统，安装solaris就不用说吧，我装的是u7，安装时候用root安装，我用的是SUN的默认sh.<br />
# uname -a<br />
SunOS bad.com 5.9 Generic_117171-07 sun4u sparc SUNW,Ultra-5_10<br />
看一下root的环境变量，如果不是下面的，可以在/etc/profile下面进行修改<br />
# env<br />
HOME=/<br />
HZ=100<br />
LOGNAME=root<br />
MAIL=/var/mail/root<br />
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/etc:/usr/local/bin:/usr/local/sbin<br />
SHELL=/sbin/sh<br />
TERM=ansi<br />
TZ=PRC<br />
在安装AMPSP前，必须安装一些EIS，下面的软件可以在www.sunfreeware.com的网站上可以下到，按你的系统下载安装包，我的系统是sparc的，所以下的也是for sparc的安装包，我们先建一个backup的目录，将下来的软件放到这个目录下，软件列表如下：<br />
gcc-3.4.2-sol9-sparc-local.gz<br />
db-4.2.52.NC-sol9-sparc-local.gz<br />
expat-1.95.5-sol9-sparc-local.gz<br />
libgcc-3.3-sol9-sparc-local.gz<br />
libiconv-1.8-sol9-sparc-local.gz<br />
libxml2-2.6.16-sol9-sparc-local.gz<br />
libxslt-1.1.2-sol9-sparc-local.gz<br />
ncurses-5.4-sol9-sparc-local.gz<br />
zlib-1.2.2-sol9-sparc-local.gz<br />
pcre-4.5-sol9-sparc-local.gz<br />
在安装AMPSP前先安装这些，一点要注意的，gcc和libgcc这两个包的版本号不要太高，我在安装的时候，版本太高装不，用pkgadd命令安装：<br />
#gunzip gcc-3.4.2-sol9-sparc-local.gz<br />
#pkgadd –d gcc-3.4.2-sol9-sparc-local<br />
安完以上的，接下来就可以安装AMPSP，下载并CP到/backup下：<br />
apache-2.0.53-sol9-sparc-local.gz<br />
mysql-4.0.21-sol9-sparc-local.gz<br />
php-5.0.2-sol9-sparc-local.gz<br />
proftpd-1.2.10rc1-sol9-sparc-local.gz<br />
<span id="more-646"></span><br />
MYSQL的安装<br />
创建运行mysql的用户<br />
#cd /backup<br />
# groupadd mysql<br />
# useradd -g mysql mysql<br />
安装mysql的安装包<br />
#gunzip mysql-4.0.21-sol9-sparc-local.gz<br />
#pkgadd –d mysql-4.0.21-sol9-sparc-local<br />
安装完后，在/usr/local/下多一个mysql的目录，我们对它进行设置<br />
#cd /usr/local/mysql<br />
#cd scripts<br />
#./mysql_install_db –user=mysql<br />
#chown –R root /usr/local/mysql<br />
#chgrp –R mysql /usr/local/mysql<br />
#cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf<br />
试运行一个mysql服务；<br />
#cd /usr/local/mysql/bin<br />
#./mysqld_safe –user=mysql&#038;<br />
如果没出错误错的话，就说明成功，如果出现：<br />
Starting mysqld daemon with databases from /usr/local/mysql/var<br />
STOPPING server from pid file /usr/local/mysql/var/bad.com.pid<br />
050407 01:44:15 mysqld ended<br />
说明没有成功，看/usr/local/mysql/var/bad.com.err,这个错误可以用<br />
#chown mysql:mysql /usr/local/mysql/var/mysql解决（我刚开的时候就是因为这个，弄半天没装好。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
试一个mysql是不是可用<br />
# ./mysql -u root -p<br />
Enter password 密码为空)<br />
Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
Your MySQL connection id is 1 to server version: 4.0.21-log</p>
<p>Type &#8216;help;&#8217; or &#8216;\h&#8217; for help. Type &#8216;\c&#8217; to clear the buffer.</p>
<p>mysql>; show databases;<br />
+&#8212;&#8212;&#8212;-+<br />
| Database |<br />
+&#8212;&#8212;&#8212;-+<br />
| mysql    |<br />
| test     |<br />
+&#8212;&#8212;&#8212;-+<br />
2 rows in set (0.06 sec)</p>
<p>mysql>;quit<br />
Bye<br />
#<br />
如果想让mysql开机自动运行，可以如下设置：<br />
#cp /usr/local/mysql/share/mysql/mysql.server  /etc/init.d/mysql<br />
#ln /etc/init.d/mysql /etc/rc3.d/S99mysql<br />
#ln /etc/init.d/mysql /etc/rc3.d/K01mysql</p>
<p>APACHE的安装</p>
<p>Apache的安装<br />
#cd /backup<br />
#gunzip apache-2.0.53-sol9-sparc-local.gz<br />
#pkgadd –d apache-2.0.53-sol9-sparc-local<br />
这样就安装好，接下来修改apache的配置文件<br />
#cd /usr/local/apache2<br />
#cd conf<br />
#vi httpd.conf<br />
这里没有什么改的，，只要将：<br />
Group #-1<br />
改成：<br />
Group nobody</p>
<p>测试服务器<br />
#/usr/local/apache2/bin/apachectl start<br />
这个你就可以在IE里防问，http://IP</p>
<p>设置自起动，和mysql差不多：<br />
#cp /usr/local/apache2/bin/apachectl /etc/init.d/httpd<br />
#ln /etc/init.d/httpd /etc/rc3.d/S99httpd<br />
#ln /etc/init.d/httpd /etc/rc3.d/K01httpd</p>
<p>安装PHP</p>
<p>安装PHP<br />
#cd /backup<br />
#gunzip php-5.0.2-sol9-sparc-local.gz<br />
#pkgadd –d php-5.0.2-sol9-sparc-local<br />
#cp /usr/local/php/doc/php/php.ini-dist /usr/local/lib/php.ini</p>
<p>修改apache，使它支持php<br />
#cd /usr/local/apache2/conf<br />
#vi httpd.conf<br />
在AddType后面加入：<br />
AddType application/x-httpd-php .php<br />
在loadModule后面加入：<br />
LoadModule php5_module modules/libphp5.so<br />
然后保存关退出其不意<br />
再测试一个apache是否可用<br />
#/usr/local/apache2/bin/apachectl restart</p>
<p>PROFTPD安装</p>
<p>因为solaris自带的ftp不怎么好用，，所以改用proftp来代替，proftp安装；<br />
#cd /backup<br />
#gunzip proftpd-1.2.10rc1-sol9-sparc-local.gz<br />
#pkgadd –d proftpd-1.2.10rc1-sol9-sparc-local</p>
<p>配置proftp</p>
<p>新建用户和用户组，给proftp使用<br />
#groupadd –g 100 webmaster<br />
#useradd –u 1234 –g webmaster –d /usr/local/apache2/htdocs –s /bin/false webmaster<br />
#cd /usr/local/etc<br />
#vi proftpd.conf<br />
我们去掉一些不必要，，然后就行，我将我的FTP设置给大家看看，<br />
# cat proftpd.conf<br />
ServerName      &#8220;bad&#8217;s server!&#8221;   //ftp的名字<br />
ServerType      standalone   //ftp是独立运行，<br />
DefaultServer   on<br />
Port    21<br />
Umask   022<br />
MaxInstances    30<br />
User    webmaster                //只允许webmaster<br />
Group   webmaster<br />
MaxLoginAttempts       10<br />
MaxClientsPerHost       2<br />
MaxClients      20             //最大用户数<br />
DirFakeUser On webmaster<br />
DirFakeGroup On webmaster<br />
DisplayLogin welcome.msg<br />
DeferWelcome On<br />
SystemLog /var/log/proftpd.log     //proftpd的目志文件<br />
ServerIdent OFF<br />
RequireValidShell off    //没用shell的用户可以进入<br />
AllowRetrieveRestart on   //支持继传功能<br />
AllowStoreRestart on<br />
TimeoutIdle 300</p>
<p>DefaultRoot ~ webmaster</p>
<p><Directory /usr/local/apache2/htdocs >;   //webmaster对/usr/local/apache2/htdocs有管理权限<br />
  <Limit WRITE>;<br />
  Order deny,allow<br />
  AllowUser webmaster<br />
  </Limit>;<br />
</Directory>;</p>
<p>Proftp自起动<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
Proftp没有自带的起动文件，，可以自己写一个，内空如下：<br />
# cat proftpd</p>
<p>#!/sbin/sh<br />
#<br />
#Copyringht badb0y<br />
#All rights reserved.<br />
#<br />
if [ -x /usr/local/sbin/proftpd ]; then<br />
/usr/local/sbin/proftpd<br />
echo &#8220;proftpd startup..&#8221;<br />
fi</p>
<p>#cp proftpd /etc/init.d/proftpd<br />
#chmod 777 /etc/init.d/proftpd<br />
#ln /etc/init.d/proftpd /etc/rc3.d/S99proftdd<br />
#ln /etc/init.d/proftpd /etc/rc3.d/K01proftpd</p>
<p>到这里AMPSP就安装完成，，mysql的管理可以用phpMyAdmin实现.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/646.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php常用安全技术,原理浅谈</title>
		<link>http://www.evanjiang.net.cn/archives/614.html</link>
		<comments>http://www.evanjiang.net.cn/archives/614.html#comments</comments>
		<pubDate>Thu, 26 Feb 2009 14:15:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[php 常用安全技术]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=614</guid>
		<description><![CDATA[<p>PHP是一种服务器端的，嵌入HTML的脚本语言。PHP区别其他语言的地方是它的代码在服务器端执行，例如收集表格数据,生成动态页面内容,或者收发cookies等，今天我们来了解一下它的漏洞问题。</p>
<p>一  全局变量
全局变量，就是能够在整个程序执行的过程中都存在的变量。基于PHP的应用程序的主函数一般都是接受用户的输入，然后对输入数据进行处理，然后把结果返回到客户端浏览器。为了使PHP代码访问用户的输入尽可能容易，实际上PHP是把这些输入数据看作全局变量来处理的。 </p>




<p>这段代码会显示一个文本框和提交按钮。当用户点击提交按钮时，页面就会将用户输入的数据传递到“get.php”，当“get.php”运行时，“$test”就会自动创建，包含了用户在文本框输入的数据。我们可以看出，攻击者可以按照自己的意愿创建任意的全局变量。下面的认证代码暴露了PHP的全局变量所导致的安全问题：

上面的代码首先检查用户的密码是否为“monster”，如果匹配的话，则设置“$pass”为“1”，之后如果“$pass”的值为“1”的话，就会认证通过。
从表面看起来，这是正确的，但是这段代码犯了想当然的错误，它假定“$pass”在没有设置值的时候是空的，却没有想到,攻击者可以创建任何全局变量并赋值，通过提交“http://server/get.php?pass=1”的方法，我们完全可以欺骗这段代码，使它相信我们是已经认证过的。

二  过滤输入/输出转义
过滤是Web应用安全的基础。它是你验证数据合法性的过程。通过在输入时确认对所有的数据进行过滤，你可以避免未过滤数据在你的程序中被误信及误用。大多数流行的PHP应用的漏洞最终都是因为没有对输入进行恰当过滤造成的。最好的方法是把过滤看成是一个检查的过程。
    另外一个Web应用安全的基础是对输出进行转义或对特殊字符进行编码，以保证原意不变。例如，O&#8217;Reilly在传送给MySQL数据库前需要转义成O\&#8217;Reilly。单引号前的反斜杠代表单引号是数据本身的一部分，而不是并不是它的本义。
    为了区分数据是否已转义，还是建议定义一个命名机制。对于输出到客户机的转义数据，使$html数组进行存储，该数据首先初始化成一个空数组，对所有已过滤和已转义数据进行保存。
]]></description>
			<content:encoded><![CDATA[<p>PHP是一种服务器端的，嵌入HTML的脚本语言。PHP区别其他语言的地方是它的代码在服务器端执行，例如收集表格数据,生成动态页面内容,或者收发cookies等，今天我们来了解一下它的漏洞问题。</p>
<p>一  全局变量<br />
全局变量，就是能够在整个程序执行的过程中都存在的变量。基于PHP的应用程序的主函数一般都是接受用户的输入，然后对输入数据进行处理，然后把结果返回到客户端浏览器。为了使PHP代码访问用户的输入尽可能容易，实际上PHP是把这些输入数据看作全局变量来处理的。 </p>
<form method="get" action="get.php">
<input type="text" name="test">
<input type="submit">
</form>
<p>这段代码会显示一个文本框和提交按钮。当用户点击提交按钮时，页面就会将用户输入的数据传递到“get.php”，当“get.php”运行时，“$test”就会自动创建，包含了用户在文本框输入的数据。我们可以看出，攻击者可以按照自己的意愿创建任意的全局变量。下面的认证代码暴露了PHP的全局变量所导致的安全问题：<br />
<?php<br />
if ($password == "monster")<br />
$pass = 1;<br />
……………<br />
if ($pass == 1)<br />
echo "认证通过";<br />
?><br />
上面的代码首先检查用户的密码是否为“monster”，如果匹配的话，则设置“$pass”为“1”，之后如果“$pass”的值为“1”的话，就会认证通过。<br />
从表面看起来，这是正确的，但是这段代码犯了想当然的错误，它假定“$pass”在没有设置值的时候是空的，却没有想到,攻击者可以创建任何全局变量并赋值，通过提交“http://server/get.php?pass=1”的方法，我们完全可以欺骗这段代码，使它相信我们是已经认证过的。<br />
<span id="more-614"></span><br />
二  过滤输入/输出转义<br />
过滤是Web应用安全的基础。它是你验证数据合法性的过程。通过在输入时确认对所有的数据进行过滤，你可以避免未过滤数据在你的程序中被误信及误用。大多数流行的PHP应用的漏洞最终都是因为没有对输入进行恰当过滤造成的。最好的方法是把过滤看成是一个检查的过程。<br />
    另外一个Web应用安全的基础是对输出进行转义或对特殊字符进行编码，以保证原意不变。例如，O&#8217;Reilly在传送给MySQL数据库前需要转义成O\&#8217;Reilly。单引号前的反斜杠代表单引号是数据本身的一部分，而不是并不是它的本义。<br />
    为了区分数据是否已转义，还是建议定义一个命名机制。对于输出到客户机的转义数据，使$html数组进行存储，该数据首先初始化成一个空数组，对所有已过滤和已转义数据进行保存。<br />
<?php<br />
  $html = array(  );<br />
  $html['username'] = htmlentities($clean['username'], ENT_QUOTES, 'UTF-8');<br />
  echo "
<p>Welcome, {$html['username']}.</p>
<p>&#8220;;<br />
?><br />
htmlspecialchars( )函数与htmlentities( )函数基本相同，它们的参数定义完全相同，只不过是htmlentities( )的转义更为彻底。<br />
通过$html['username']把username输出到客户端，你就可以确保其中的特殊字符不会被浏览器所错误解释。如果username只包含字母和数字的话，实际上转义是没有必要的，但是这体现了深度防范的原则。<br />
SQL 注入是PHP应用中最常见的漏洞之一，事实上，开发者需要同时犯以上两个错误才会引发一个SQL注入漏洞。</p>
<p>三  远程文件<br />
PHP是一种具有丰富特性的语言，提供了大量的函数，使编程者实现某个功能很容易。但是从安全的角度来看，功能越多，要保证它的安全性就越难，远程文件就是说明这个问题的一个很好的例子：<br />
<?php<br />
if (!($fo = fopen("$file", "s"))<br />
echo("文件$file打开错误 ");<br />
?><br />
上面的脚本试图打开文件“$filename”，如果失败就显示错误信息。那么如果我们能够指定“$file”的话，就能利用这个脚本浏览任何文件。但是，这个脚本还存在一个不太明显的特性，那就是它可以从任何其它WEB或FTP站点读取文件。实际上，PHP的大多数文件处理函数对远程文件的处理是透明的。<br />
例如：<br />
如果指定“$file”为“http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir”,则上面的代码实际上是利用主机target上的unicode漏洞，执行了dir命令。<br />
这使得支持远程文件的include()，require()，include_once()和require_once()在上下文环境中变得更有趣。这些函数主要功能是包含指定文件的内容，并且把它们按照PHP代码解释。<br />
例如：<br />
<?php<br />
include($dir."/ attack.php");<br />
?><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
上例中“$dir”一般是一个在执行代码前已经设置好的路径，如果攻击者能够使得“$dir”没有被设置的话，那么他就可以改变这个路径。但是攻击者并不能做任何事情，因为他们只能在他们指定的路径中访问文件“attack.php”。但是由于有了对远程文件的支持，攻击者就可以做任何事情。例如，攻击者可以在某台服务器上放一个文件“attack.php”，里面包含了恶意代码<br />
然后把“$dir”设置为“http://evilhost/”，这样我们就可以在目标主机上执行上面的恶意代码，将结果返回到客户的浏览器中。<br />
需要注意的是，攻击服务器（也就是evilhost）应该不能执行PHP代码，否则攻击代码会在攻击服务器，而不是目标服务器执行。 </p>
<p>四  文件上载<br />
PHP自动支持基于RFC 1867的文件上载，我们看下面的例子： </p>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="hidden" name="maxfilesize" value="1024">
<input type="submit">
</form>
<p>上面的代码让用户从本地机器选择一个文件，当点击提交后，文件就会被上载到服务器。这显然是很有用的功能，但是PHP的响应方式会使这项功能变的不安全。当 PHP在它开始解析被调用的PHP代码之前，它会先接受远程用户的文件，检查文件的长度是否超过 “$ maxfilesizevariable”定义的值，如果通过这些测试的话，文件就会被存在服务器的一个临时目录中。<br />
因此，攻击者可以发送任意文件给运行PHP的主机，在PHP程序还没有决定是否接受文件上载时，文件就已经被保存在服务器上面了。<br />
现在我们看一下处理文件上载的PHP程序，正如上面所说，文件被接收并且存在服务器上（位置一般是/tmp），文件名一般是随机的。PHP程序需要上载文件的信息以便处理它，这可以通过两种方式，一种方式是在PHP 3中已经使用的，另一种是在我们对以前的方法提出安全公告后引入的。<br />
但是，我们可以肯定的说，问题还是存在的，大多数PHP程序还是使用老的方式来处理上载文件。PHP设置了四个全局变量来描述上载文件，比如说上面的例子：<br />
$file = Filename on local machine (e.g &#8220;/tmp/phpxXuoXG&#8221;)<br />
$file_size = Size in bytes of file (e.g 1024)<br />
$file_name =远程系统上的文件名(e.g &#8220;c:/file.txt&#8221;)<br />
$file_type = Mime type of uploaded file (e.g &#8220;text/plain&#8221;)<br />
然后PHP程序开始处理根据“$file”指定的文件，问题在于“$file”不一定是一个PHP设置的变量，任何远程用户都可以指定它。如果我们使用下面的方式：<br />
http://vulnhost/file.php?file=/ &#8230; file_name=file.txt<br />
就导致了下面的PHP全局变量（当然POST方式也可以（甚至是Cookie））：<br />
$file = &#8220;/etc/passwd&#8221;<br />
$file_size = 10240<br />
$file_type = &#8220;text/plain&#8221;<br />
$file_name = &#8220;file.txt&#8221;<br />
上面的表单数据正好满足了PHP程序所期望的变量，但是这时PHP程序不再处理上载的文件，而是处理“/etc/passwd”（通常会导致内容暴露）。这种攻击可以用于暴露任何敏感文件的内容。<br />
我在前面已经说了，新版本的PHP使用HTTP_POST_FILES[]来决定上载文件，同时也提供了很多函数来解决这个问题，例如有一个函数用来判断某个文件是不是实际上载的文件。这些函数很好的解决了这个问题，但是实际上肯定有很多PHP程序仍然使用旧的方法，很容易受到这种攻击。<br />
作为文件上载的攻击方法的一个变种，我们看一下下面的一段代码：<br />
<?php<br />
if (file_exists($file))<br />
include("$file");<br />
?><br />
如果攻击者可以控制“$file”的话，很显然它可以利用“$file”来读取远程系统上的任何文件。攻击者的最终目标是在远程服务器上执行任意指令，但是他无法使用远程文件，因此，他必须得在远程服务器上创建一个PHP文件。这乍看起来好象是不可能的，但是文件上载帮了我们这个忙，如果攻击者先在本地机器上创建一个包含PHP代码的文件，然后创建一个包含名为“file”的文件域的表单，最后用这个表单通过文件上载把创建的包含PHP代码的文件提交给上面的代码，PHP就会把攻击者提交的文件保存起来，并把“$file”的值设置为攻击者提交的文件，这样file_exists()函数会检查通过，攻击者的代码也将执行。 </p>
<p>五  Session文件<br />
PHP 4以上的版本提供了对sessions的支持，它的主要作用是在PHP程序中保存页与页之间的状态信息。例如，当一个用户登陆进入网站，他登陆了这个事实以及谁登陆进入这个网站都被保存在session中，当他在网站中到处浏览时，所有的PHP代码都可以获得这些状态信息。<br />
事实上， 当一个session启动时，就会生成一个随机的“session id”，如果远程浏览器总是在发送请求时提交这个“sessionid”的话，session就会一直保持。这通过Cookie很容易实现，也可以通过在每页提交一个表单变量来实现。PHP程序可以用session注册一个特殊的变量，它的值会在每个PHP脚本结束后存在session文件中，也会在每个PHP脚本开 始前加载到变量中。下面是一个简单的例子：<br />
<?php<br />
session_destroy();<br />
$session_auth = "shaun";<br />
session_register("session_auth");<br />
?><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
新版本的PHP都会自动把“$session_auth”的值设置为“shaun”，如果它们被修改的话，以后的脚本都会自动接受修改后的值，这对无状态的Web来说的确是种很不错的工具，但是我们也应该小心。<br />
一个很明显的问题就是确保变量的确来自session，例如，给定上面的代码，如果后续的脚本是下面这样的话：<br />
<?php<br />
if (!empty($session_auth))<br />
// Grant access to site here<br />
?><br />
上面的代码假定如果“$session_auth”被置位的话，就是从session，而不是从用户输入来置位的，如果攻击者通过表单输入来置位的话，他就可以获得对站点的访问权。注意攻击者必须在session注册该变量之前使用这种攻击方法，一旦变量被放进了session，就会覆盖任何表单输入。<br />
Session 数据一般是保存在文件中，目录一般是“/tmp”，文件名一般是类似 “sess_<sessionid>”的形式，这个文件包含变量名称，变量类型，变量值和一些其它的数据。在多主机系统中，因为文件是以运行Web服务器的用户身份保存的，因此恶意的站点拥有者就可以通过创建一个session文件来获得对其它站点的访问，甚至可以检查session文件中的敏感信息。<br />
常见的针对session的攻击手段就是会话劫持。它是所有攻击者可以用来访问其它人的会话的手段的总称。所有这些手段的第一步都是取得一个合法的会话标识来伪装成合法用户，因此保证会话标识不被泄露非常重要。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/614.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ubuntu8.10常用桌面应用软件以及网站开发应用环境</title>
		<link>http://www.evanjiang.net.cn/archives/584.html</link>
		<comments>http://www.evanjiang.net.cn/archives/584.html#comments</comments>
		<pubDate>Wed, 25 Feb 2009 14:05:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[utunbu8.10 常用应用软件 网站开发应用环境  开发]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=584</guid>
		<description><![CDATA[<p>一、基础系统配置</p>
<p>1.安装ubuntu8.10就不讲，网上太多资料</p>
<p>2.配置源（我在杭州当然也就用杭州的源）</p>
<p>sudo cp /etc/apt/sources.list ~</p>
<p>sudo gedit /etc/apt/sources.list</p>
<p>把你要用的源考进去，保存即可</p>
<p>3.更新软件包列表</p>
<p>sudo apt-get update</p>
<p>4.安装系统更新 </p>
<p>打开“系统->系统管理->更新管理器”，安装更新。完成后若系统提示重新启动，请重新启动系统。

5.设置中文环境</p>
<p>单击主菜单中的“系统(System) &#8211;> 系统管理(Administration) &#8211;> 语言支持(language support)”。</p>
<p>在“支持的语言”列表中找到“汉语（Chinese）”，在右端打上勾。同时将默认语言修改为“汉语 （Chinese）”并勾选“启用复杂字符输入支持（Enable support to enter complex characters）”， 点击确定按钮。</p>
<p>Ubuntu 这时会下载并安装语言包。安装完毕之后，你注销重新登录后，界面变为中文。

6.设置文档查看器 Evince 的中文支持</p>
<p>sudo apt-get install xpdf-chinese-simplified xpdf-chinese-traditional poppler-data</p>
<p>7.安装硬件驱动</p>
<p>打开 “系统->系统管理->硬件驱动”。Ubuntu 自动开始查找可用驱动程序，选中你需要启用的硬件 驱动程序（如显卡驱动），Ubuntu将自动为你安装。完装完成后，请按系统提示重启操作系统。 </p>
<p>8.多媒体应用环境设置</p>
<p>Gstreamer多媒体引擎解码器</p>
<p>sudo apt-get install gstreamer0.10-ffmpeg gstreamer0.10-pitfdll gstreamer0.10-plugins-bad gstreamer0.10-plugins-bad-multiverse gstreamer0.10-plugins-ugly gstreamer0.10-plugins-ugly-multiverse gstreamer0.10-esd</p>
<p>配置电影播放器</p>
<p>sudo apt-get remove totem-mozilla -y</p>
<p>sudo apt-get install smplayer smplayer-themes mozilla-mplayer libmatroska0</p>
<p>配置音乐播放器</p>
<p>sudo apt-get install gstreamer0.10-fluendo-mpegdemux [...]]]></description>
			<content:encoded><![CDATA[<p>一、基础系统配置</p>
<p>1.安装ubuntu8.10就不讲，网上太多资料</p>
<p>2.配置源（我在杭州当然也就用杭州的源）</p>
<p>sudo cp /etc/apt/sources.list ~</p>
<p>sudo gedit /etc/apt/sources.list</p>
<p>把你要用的源考进去，保存即可</p>
<p>3.更新软件包列表</p>
<p>sudo apt-get update</p>
<p>4.安装系统更新 </p>
<p>打开“系统->系统管理->更新管理器”，安装更新。完成后若系统提示重新启动，请重新启动系统。<br />
<span id="more-584"></span><br />
5.设置中文环境</p>
<p>单击主菜单中的“系统(System) &#8211;> 系统管理(Administration) &#8211;> 语言支持(language support)”。</p>
<p>在“支持的语言”列表中找到“汉语（Chinese）”，在右端打上勾。同时将默认语言修改为“汉语 （Chinese）”并勾选“启用复杂字符输入支持（Enable support to enter complex characters）”， 点击确定按钮。</p>
<p>Ubuntu 这时会下载并安装语言包。安装完毕之后，你注销重新登录后，界面变为中文。<br />
<!more--><br />
6.设置文档查看器 Evince 的中文支持</p>
<p>sudo apt-get install xpdf-chinese-simplified xpdf-chinese-traditional poppler-data</p>
<p>7.安装硬件驱动</p>
<p>打开 “系统->系统管理->硬件驱动”。Ubuntu 自动开始查找可用驱动程序，选中你需要启用的硬件 驱动程序（如显卡驱动），Ubuntu将自动为你安装。完装完成后，请按系统提示重启操作系统。 </p>
<p>8.多媒体应用环境设置</p>
<p>Gstreamer多媒体引擎解码器</p>
<p>sudo apt-get install gstreamer0.10-ffmpeg gstreamer0.10-pitfdll gstreamer0.10-plugins-bad gstreamer0.10-plugins-bad-multiverse gstreamer0.10-plugins-ugly gstreamer0.10-plugins-ugly-multiverse gstreamer0.10-esd</p>
<p>配置电影播放器</p>
<p>sudo apt-get remove totem-mozilla -y</p>
<p>sudo apt-get install smplayer smplayer-themes mozilla-mplayer libmatroska0</p>
<p>配置音乐播放器</p>
<p>sudo apt-get install gstreamer0.10-fluendo-mpegdemux gstreamer0.10-gnonlin libasound2-plugins</p>
<p>安装flash支持，到官方下载install_flash_player_10_linux.deb（目前的最新版本）</p>
<p>9.设置工具软件 </p>
<p>安装腾讯QQ,至腾讯官方网站下载 deb软件包，双击即可安装</p>
<p>安装压缩工具</p>
<p>sudo apt-get install unrar p7zip-full cabextract</p>
<p>安装下载工具（MultiGet），到官方下载deb包，点击安装即可</p>
<p>安装chm阅读器</p>
<p>sudo apt-get install chmsee<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
安装星际译王辞典（到官方下载你需要的词典），把下载的文件解压后拷贝到/usr/share/stardict/dic 目录下即可（也可以用此命令sudo mv 你解压的文件目录 /usr/share/stardict/dic）</p>
<p>10.安装openoffice3.0</p>
<p>1).卸载老版本的openoffice</p>
<p>sudo apt-get remove openoffice.org*</p>
<p>2).解压下载的OOo_3.0.0_LinuxIntel_install_zh-cn_deb.tar.gz包</p>
<p>3).进入解压后的文件目录</p>
<p>cd /home/yangbo/OOO300_m9_native_packed-1_zh-CN.9358/DEBS</p>
<p>4).sudo dpkg -i *.deb</p>
<p>5). 双击安装/OOO300_m9_native_packed-1_zh-CN.9358/DEBS/desktop-integration/下的deb 文件，就ok！</p>
<p>11.由于我较喜欢使用ibus输入法（所以就安装之，不需要的用户可以省去这一步），到</p>
<p>http://archive.ubuntu.org.cn/ubuntu-cn/dists/intrepid/main/binary-i386/ibus/</p>
<p>下载python-dbus_0.83.0-1_i386.deb</p>
<p>ibus_0.1.1.20081106-1_i386.deb</p>
<p>ibus-pinyin_0.1.1.20081106-1_i386.deb</p>
<p>ibus-table_0.1.1.20081106-1_i386.deb</p>
<p>按照下载的顺序安装，由于我不使用五笔，最后一个文件没有安装</p>
<p>然后使用 sudo im-switch -c 选择ibus输入法。重启系统后就可使用</p>
<p>二、开发工具配置</p>
<p>1.Java安装配置</p>
<p>sudo apt-get install sun-java6-jdk</p>
<p>如果之前你没有安装其他版本的java，就不需要设置，否则请参考（http://wiki.ubuntu.org.cn/index.php?title=Java%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE&#038;variant=zh-cn）</p>
<p>java中文支持（或乱码的解决）：java程序是跨平台的，但需要解决中文支持问题。</p>
<p>方法很简单，就是在java安装目录下放进去一个中文字体即可。</p>
<p>cd /usr/lib/jvm/java-6-sun/jre/lib/fonts</p>
<p>sudo mkdir fallback</p>
<p>cd fallback</p>
<p>sudo ln -s /usr/share/fonts/truetype/wqy/wqy-zenhei.ttf(把某个中文字体链接进 fallback 目录，我选了最新的文泉驿夸父字体)</p>
<p>sudo mkfontdir</p>
<p>sudo mkfontscale</p>
<p>2.安装NetBeans</p>
<p>到官方下载（最新版本为6.5），下载后的文件为*.sh文件</p>
<p>用如下命令安装：sudo ./(文件名).sh，按提示即可（可以选择安装目录，我选择opt目录下）</p>
<p>3.安装tomcat，eclipse都很简单，把下载后的文件解压后放到opt目录即可（建立eclipse的快捷方式不用我说了吧）</p>
<p>4.安装数据库</p>
<p>安装 MySQL（可以参考http://wiki.ubuntu.org.cn/index.php?title=MySQL%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97&#038;variant=zh-cn）</p>
<p>sudo apt-get install mysql-server mysql-client</p>
<p>配置MySQL编码</p>
<p>sudo gedit /etc/mysql/my.cnf</p>
<p>在如下位置添加</p>
<p>[client]</p>
<p>default-character-set=utf8</p>
<p>[mysqld]</p>
<p>default-character-set=utf8</p>
<p>init_connect=&#8217;SET_NAMES_utf8&#8242;<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
安装Oracle xe 10g（到官方下载oracle-xe-universal_10.2.0.1-1.0_i386.deb包，可以参考http://hi.baidu.com/colleage/blog/item/e9dc208d2e4d2115b21bba45.html安装）</p>
<p>5.安装apache2和PHP支持</p>
<p>sudo apt-get install apache2 </p>
<p>sudo apt-get install libapache2-mod-php5</p>
<p>sudo apt-get install php5 php5-gd php5-mysql</p>
<p>6.安装phpmyadmin</p>
<p>sudo apt-get install phpmyadmin</p>
<p>可能还需要安装php5-mcrypt</p>
<p>sudo apt-get install php5-mcrypt</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/584.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单的shell备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/439.html</link>
		<comments>http://www.evanjiang.net.cn/archives/439.html#comments</comments>
		<pubDate>Sat, 21 Feb 2009 04:13:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 脚本备份]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=439</guid>
		<description><![CDATA[<p>现：每周一对指定目录进行打包上传FTP，周二至周日做更新备份上传；</p>
<p>#!/bin/sh
backup_dir=&#8221;/var/tmp/shell/&#8221;
DAT=`date &#124; awk &#8216;{print $1}&#8217;`
if [ $DAT = 'Mon' ]
then
   filename=&#8221;`date +%G%m%d`.tar&#8221;
    if [ -f $backup_dir$filename ]
        then
          rm -f $backup_dir$filename &#124;&#124;  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit
    [...]]]></description>
			<content:encoded><![CDATA[<p>现：每周一对指定目录进行打包上传FTP，周二至周日做更新备份上传；</p>
<p>#!/bin/sh<br />
backup_dir=&#8221;/var/tmp/shell/&#8221;<br />
DAT=`date | awk &#8216;{print $1}&#8217;`<br />
if [ $DAT = 'Mon' ]<br />
then<br />
   filename=&#8221;`date +%G%m%d`.tar&#8221;<br />
    if [ -f $backup_dir$filename ]<br />
        then<br />
          rm -f $backup_dir$filename ||  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit<br />
       else<br />
          tar cvf $backup_dir$filename /var/tmp/tmp ||  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit<br />
          echo &#8220;Backup succeed&#8221;<br />
    fi<br />
else<br />
<span id="more-439"></span><br />
   date=`date +%w`<br />
   aa=`expr $date &#8211; 1 `<br />
   bb=&#8221;`date +%G%m%d`&#8221;<br />
   cc=`expr $bb &#8211; $aa`<br />
   filename=&#8221;$cc.tar&#8221;<br />
         t1=`date +%d`<br />
         t2=`expr $t1 &#8211; 1 `<br />
         yesterday=`date +%Y\/%m\/`$t2<br />
        tar -N &#8220;$yesterday&#8221; -cvf  $backup_dir$filename /var/tmp/tmp<br />
      echo &#8220;update&#8221;<br />
fi<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
#ftp-put<br />
host=&#8217;x.x.x.x&#8217;<br />
user=&#8217;test&#8217;<br />
passwd=&#8217;pass&#8217;<br />
mode=&#8217;bin&#8217;<br />
echo &#8220;Backup starting, please wait&#8230;&#8221;<br />
ftp -i -n <<!<br />
open $host<br />
user $user $passwd<br />
$mode<br />
mput $filename<br />
bye<br />
!<br />
echo &#8220;Backup finished&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/439.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solaris 系统管理 &#8211; 运行状态的种类和关机命令的区别</title>
		<link>http://www.evanjiang.net.cn/archives/414.html</link>
		<comments>http://www.evanjiang.net.cn/archives/414.html#comments</comments>
		<pubDate>Tue, 17 Feb 2009 06:39:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[sun unix]]></category>
		<category><![CDATA[solaris 系统管理  运行状态 关机命令]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=414</guid>
		<description><![CDATA[<p>§1    Solaris 系统管理简介</p>
<p>§1.1 系统管理员的职责</p>
<p>★熟悉shell</p>
<p>ü         常用的shell命令</p>
<p>ü         常用的Bourne shell命令</p>
<p>ü         常用的C shell命令</p>
<p>ü         常用的Korn shell命令</p>
<p>★用户和组管理</p>
<p>ü         添加用户</p>
<p>ü [...]]]></description>
			<content:encoded><![CDATA[<p>§1    Solaris 系统管理简介</p>
<p>§1.1 系统管理员的职责</p>
<p>★熟悉shell</p>
<p>ü         常用的shell命令</p>
<p>ü         常用的Bourne shell命令</p>
<p>ü         常用的C shell命令</p>
<p>ü         常用的Korn shell命令</p>
<p>★用户和组管理</p>
<p>ü         添加用户</p>
<p>ü         删除用户</p>
<p>ü         更改用户信息</p>
<p>ü         创建删除组</p>
<p> <span id="more-414"></span></p>
<p>★角色管理</p>
<p>ü         针对特殊任务授权超级用户权限</p>
<p>ü         创建修改删除角色</p>
<p>★文件系统管理</p>
<p>ü         文件系统的类型</p>
<p>ü         加载移除文件系统</p>
<p>ü         文件系统一致性检查</p>
<p>ü         备份恢复文件和文件系统</p>
<p>ü         创建cache文件系统</p>
<p>★设备管理</p>
<p>ü         理解设备自动配置</p>
<p>ü         使用DVD-ROM设备</p>
<p>ü         使用磁带</p>
<p>ü         格式化操盘</p>
<p>ü         磁盘使用监控</p>
<p>ü         服务访问技巧</p>
<p>ü         设置双向modem.</p>
<p>★管理系统</p>
<p>ü         查找系统信息</p>
<p>ü         创建本地邮件别名</p>
<p>ü         配置其他的交换空间</p>
<p>ü         管理时间和日期</p>
<p>★打印管理</p>
<p>ü         安装打印服务器和客户端</p>
<p>ü         使用打印命令</p>
<p>★认识文件访问问题</p>
<p>ü         通过查找path来坚定问题</p>
<p>ü         通过权限和所有来解决问题</p>
<p>ü         通过网络定位问题</p>
<p>本书不包含安装系统软件,安装第3方软件,配置管理网络服务,配置邮件服务,添加删除硬件,安全管理和账号,系统监控和网络性能等.</p>
<p>      §1.2 超级用户</p>
<p>超级用户的UID是0,su到超级用户的log在: /var/adm/sulog, 如果需要使用环境变量,使用su –</p>
<p>      §1.3 用户之间通信</p>
<p>ü         登陆时的信息显示: /etc/motd</p>
<p>ü         发送消息给单个用户: write ,要在线的才可以发送</p>
<p>       比如: bash-2.03# write meil</p>
<p>meil is logged on more than one place.</p>
<p>You are connected to &#8220;pts/2&#8243;.</p>
<p>Other locations are:</p>
<p>pts/3</p>
<p>good Afternoon</p>
<p>bash-2.03#</p>
<p>ü         发送消息给所有用户    wall</p>
<p>ü         发送消息给网络用户    rwall</p>
<p>ü         Email</p>
<p>      §1.4 启动关闭系统</p>
<p>需要关键的情况如下:</p>
<p>·         Turning off system power.</p>
<p>·         Installing a new release.</p>
<p>·         Preparing for a power outage.</p>
<p>·         Adding hardware to a system.</p>
<p>·         Performing maintenance on a file system.</p>
<p>§1.5选择初始状态</p>
<p>Table 1. System Init States</p>
<p>Init State</p>
<p>Function</p>
<p>0</p>
<p>Power-down state.</p>
<p>S, or s</p>
<p>Single-user state. All file systems mounted.</p>
<p>1</p>
<p>Administrative state. All file systems mounted and user logins allowed.</p>
<p>2</p>
<p>Multiuser state (resources not exported). All daemons are running except the NFS server daemons.</p>
<p>3</p>
<p>Multiuser state. NFS resource-sharing available.</p>
<p>4<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
Alternative multiuser state (currently unused).</p>
<p>5</p>
<p>Power-down state. Shut down the operating system so that it is safe to turn off power to the system. If possible, turn off power on systems that support this feature.</p>
<p>6</p>
<p>Reboot. Shut down the system to init state 0 and then reboot to the multiuser state defined in the inittab file.</p>
<p>/etc/inittab定义的重要内容如下:</p>
<p>·         The default run level for the system.</p>
<p>·         The processes to start, monitor, and restart if they terminate.</p>
<p>·         Actions to take when the system enters a new run level.</p>
<p>它的字段如下:</p>
<p>Field</p>
<p>Description</p>
<p>id</p>
<p>A unique identifier for the entry.</p>
<p>rstate</p>
<p>A list of run levels to which this entry applies.</p>
<p>action</p>
<p>How the process specified in the process field is to be run. Possible values include initdefault, sysinit, boot, bootwait, wait, and respawn.</p>
<p>process</p>
<p>The command to execute.</p>
<p>比如:</p>
<p>bash-2.03# vi /etc/inittab</p>
<p>&#8220;/etc/inittab&#8221; 17 lines, 1081 characters</p>
<p>ap::sysinit:/sbin/autopush -f /etc/iu.ap</p>
<p>ap::sysinit:/sbin/soconfig -f /etc/sock2path</p>
<p>fs::sysinit:/sbin/rcS sysinit           >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>is:3:initdefault:</p>
<p>p3:s1234:powerfail:/usr/sbin/shutdown -y -i5 -g0 >/dev/msglog 2<>/dev/msglog</p>
<p>sS:s:wait:/sbin/rcS                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s0:0:wait:/sbin/rc0                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s1:1:respawn:/sbin/rc1                  >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s2:23:wait:/sbin/rc2                    >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s3:3:wait:/sbin/rc3                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s5:5:wait:/sbin/rc5                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s6:6:wait:/sbin/rc6                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>fw:0:wait:/sbin/uadmin 2 0              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>of:5:wait:/sbin/uadmin 2 6              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>rb:6:wait:/sbin/uadmin 2 1              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>sc:234:respawn:/usr/lib/saf/sac -t 300</p>
<p>co:234:respawn:/usr/lib/saf/ttymon -g -h -p &#8220;`uname -n` console login: &#8221; -T sun -d /dev/console -l console -m ldterm,ttcompat</p>
<p>       init的执行脚本sbin中,</p>
<p>bash-2.03# ls /sbin/rc*</p>
<p>/sbin/rc0  /sbin/rc1  /sbin/rc2  /sbin/rc3  /sbin/rc5  /sbin/rc6  /sbin/rcS</p>
<p>       控制文件在/etc/init.d中,它们连接到/etc/rc*.d, 其下面的文件K开头的表示kill, S开头的表示start</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/414.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>有用的shell命令</title>
		<link>http://www.evanjiang.net.cn/archives/412.html</link>
		<comments>http://www.evanjiang.net.cn/archives/412.html#comments</comments>
		<pubDate>Tue, 17 Feb 2009 06:30:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 命令]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=412</guid>
		<description><![CDATA[<p>sort ad.txt &#124; uniq -u > ad_net.txt</p>
<p>例如，你ad.txt 有许多重重的数据，要处理一下，就可以用这个命令将多余的，重复的数据清除掉，只保持唯一的一条数据记录。。。</p>
]]></description>
			<content:encoded><![CDATA[<p>sort ad.txt | uniq -u > ad_net.txt</p>
<p>例如，你ad.txt 有许多重重的数据，要处理一下，就可以用这个命令将多余的，重复的数据清除掉，只保持唯一的一条数据记录。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/412.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ubutu8.10 安装 apache php mysql 实录</title>
		<link>http://www.evanjiang.net.cn/archives/389.html</link>
		<comments>http://www.evanjiang.net.cn/archives/389.html#comments</comments>
		<pubDate>Sun, 15 Feb 2009 11:30:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[ubutu 安装 apache php mysql]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=389</guid>
		<description><![CDATA[<p>ubuntu 安装AMP环境的笔记 Prefork方式与fast-cgi方式</p>
<p>     具体步骤如下: </p>
<p>     系统:ubuntu 8.10 的发行版本 </p>
<p>     AMP with Prefork(mod-php5) </p>
<p>      一、安装APACHE2 </p>
<p>     # sudo  apt-get  install  apache2  apache2-mpm-prefork </p>
<p>     这样APACHE部分就完成，默认目录是 /var/www </p>
<p>  [...]]]></description>
			<content:encoded><![CDATA[<p>ubuntu 安装AMP环境的笔记 Prefork方式与fast-cgi方式</p>
<p>     具体步骤如下: </p>
<p>     系统:ubuntu 8.10 的发行版本 </p>
<p>     AMP with Prefork(mod-php5) </p>
<p>      一、安装APACHE2 </p>
<p>     # sudo  apt-get  install  apache2  apache2-mpm-prefork </p>
<p>     这样APACHE部分就完成，默认目录是 /var/www </p>
<p>     二、进行PHP的环境配置： </p>
<p>     # sudo  apt-get  install  php5  libapache2-mod-php5  php5-cli  php5-dev  php5-gd  php5-imagick  php5-mcrypt  php5-xmlrpc </p>
<p>     当然，需要更多的PHP5 extension 便可以自己补完。完成后手动启动模块： </p>
<p>    # sudo  a2enmod  php5<br />
<span id="more-389"></span></p>
<p>    三、MYSQL软件的安装 </p>
<p>    # sudo  apt-get  install  mysql-server  libapache2-mod-auth-mysql  php5-mysql </p>
<p>    MYSQL安装完成之后一切就搞定，通过APT方式安装MYSQL在安装过程当中是必须为MYSQL的ROOT用户设置密码的。 </p>
<p>    AMP with Worker(fast-cgi) </p>
<p>     如果想使用 worker 方式来跑的话必须使用fast-cgi模式，步骤如下： </p>
<p>    一、首先安装 apache with mpm-worker： </p>
<p>    # sudo  apt-get  install  apache2  apache2-mpm-worker  libapache2-mod-fcgid </p>
<p>   二、安装和配置PHP部分 </p>
<p>    # sudo  apt-get  install  php5  php5-cgi  php5-cli  php5-dev  php5-gd  php5-imagick  php5-mcrypt  php5-xmlrpc<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    三、MYSQL的安装配置 </p>
<p>    # sudo  apt-get  install  mysql-server  libapache2-mod-auth-mysql  php5-mysql </p>
<p>     (MYSQL需要注意的部分同上,up!) </p>
<p>    四、配置FAST-CGI模式下的目录</p>
<p>         在<Directory …> … </Directory> 里加入一下两句话 </p>
<p>         AddHandler fcgid-script .php </p>
<p>         FCGIWrapper /usr/lib/cgi-bin/php5 .php </p>
<p>         并在本段的 Option 上多加一个参数 ExecCGI </p>
<p>     完成以上工作后，便可以重启apache2进行测试工作~~！ </p>
<p>     # sudo  /etc/init.d/apache2  force-reload </p>
<p>    在服务目录中我们放入写有 phpinfo(); 函数的PHP文件，才查看本LAMP环境的参数是否正确。 </p>
<p>    附录： </p>
<p>     一、根据需要调整APACHE的模块 </p>
<p>    在APACHE部分，首要的编辑就是/etc/apache2/mod-available的目录下的模块加载，你先看看自己需要哪些模块，里面有很多MOD_NAME.load和MOD_NAME.conf然后通过模块添加命令进行添加。 </p>
<p>    模块添加的命令： </p>
<p>    # sudo  a2enmod  [MOD_NAME] </p>
<p>    举例说明： </p>
<p>    启用页面压缩的deflate来说，方法如下： </p>
<p>    # sudo  a2enmod  deflate </p>
<p>    然后编辑 /etc/apache2/mods-available/deflate.conf  ,改为： </p>
<p>    <IfModule mod_deflate.c><br />
        DeflateCompressionLevel  6<br />
        AddOutputFilterByType   DEFLATE  text/html  text/plain  text/xml<br />
        AddOutputFilter   DEFLATE  html  htm  xml  css  js<br />
    </IfModule> </p>
<p>    之后重启 apache2 便可完成。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
   二、关于apache2-mpm-prefork模式和FAST-CGI模式的php.ini文件位置 </p>
<p>    apache2-mpm-prefork： /etc/php5/apache2/php.ini </p>
<p>    FAST-CGI：/etc/php5/cgi/php.ini </p>
<p>    特别是在使用eAccelerator或MMCache的时候需要特别注意！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/389.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vi 编辑器使用手册</title>
		<link>http://www.evanjiang.net.cn/archives/354.html</link>
		<comments>http://www.evanjiang.net.cn/archives/354.html#comments</comments>
		<pubDate>Thu, 05 Feb 2009 13:58:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[vi 使用]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=354</guid>
		<description><![CDATA[<p>&#8220;To me, vi is Zen.
To use vi is to practice zen.
Every command is a koan.
Profound to the user,
unintelligible to the uninitiated.
You discover truth every time you use it.&#8221;
&#8211;reddy@lion.austin.com
&#8220;对我来说，vi就是禅。
用vi就是坐禅。
每一个命令就是一个心印
对皈依者意义深远
对不了解者不可捉摸
每一次使用都会有新的发现&#8221;</p>
<p>VI是所有*NIX类系统都内置的一个命令行文本编辑软件，功能强大，命令繁多。初学时很难上手，但是一旦你熟悉之后，相信你不会再想使用其他的编辑软件。</p>
<p>本篇假定你已经熟悉VI的一些基本命令，如：
vi httpd.conf #打开一个名为httpd.conf的文档，如果不存在，将在当前目录下创建此文档；
输入“：wq”：存盘推出命令。
输入“：q！”：不存盘，强制推出
ESC：在命令模式与输入模式之间切换
i，I或者o等：插入文本命令&#8230;&#8230;..

VI之一：光标移动篇</p>
<p>这里我们先学习一下如何在一篇打开的文档中进行光标移动。</p>
<p>1. 方向键h,j,k,l.
h: 将光标向左移动一个字符
j: 将光标向下移动一个字符
k: 将光标向上移动一个字符
l: 将光标向右移动一个字符</p>
<p>这四个键相当于方向键,另设它们的好处是:你的手指不必离开正常的输入位置</p>
<p>2. 按字符移动的命令
fx: 移动光标至当前行下一个x字符处;使用;来重复上一次的f移动
tx: 同fx，但是移动光标至x字符前，而不是x字符上
Fx：通fx，但反方向移动








w:前移光标至下一个单词第一字符
W:前移光标至下一个长单词第一字符
e: 前移光标至下一个单词最后字符
E: 前移光标至下一个长单词最后字符
b: 前一单词第一字符
B: 前一长单词第一字符
(vi 按空格或标点符号分隔单词,按空格或新行来分隔长单词)</p>
<p>(: 到句首
): 到句尾</p>
<p>0: 到行首
^: 到行首第一字符
$: 到行尾</p>
<p>{: 到段首
}: 到段尾</p>
<p>*: 读取光标当前所在位置的字符,并将向前移动至下一个同样的字符
#: 和*功能相同,但反方向移动光标</p>
<p>Ctrl+F: 向前滚屏
Ctrl+B: 向后滚屏
H,M,L: 移动光标至屏幕的顶端,中间,底端</p>
<p>G: [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;To me, vi is Zen.<br />
To use vi is to practice zen.<br />
Every command is a koan.<br />
Profound to the user,<br />
unintelligible to the uninitiated.<br />
You discover truth every time you use it.&#8221;<br />
&#8211;reddy@lion.austin.com<br />
&#8220;对我来说，vi就是禅。<br />
用vi就是坐禅。<br />
每一个命令就是一个心印<br />
对皈依者意义深远<br />
对不了解者不可捉摸<br />
每一次使用都会有新的发现&#8221;</p>
<p>VI是所有*NIX类系统都内置的一个命令行文本编辑软件，功能强大，命令繁多。初学时很难上手，但是一旦你熟悉之后，相信你不会再想使用其他的编辑软件。</p>
<p>本篇假定你已经熟悉VI的一些基本命令，如：<br />
vi httpd.conf #打开一个名为httpd.conf的文档，如果不存在，将在当前目录下创建此文档；<br />
输入“：wq”：存盘推出命令。<br />
输入“：q！”：不存盘，强制推出<br />
ESC：在命令模式与输入模式之间切换<br />
i，I或者o等：插入文本命令&#8230;&#8230;..<br />
<span id="more-354"></span><br />
VI之一：光标移动篇</p>
<p>这里我们先学习一下如何在一篇打开的文档中进行光标移动。</p>
<p>1. 方向键h,j,k,l.<br />
h: 将光标向左移动一个字符<br />
j: 将光标向下移动一个字符<br />
k: 将光标向上移动一个字符<br />
l: 将光标向右移动一个字符</p>
<p>这四个键相当于方向键,另设它们的好处是:你的手指不必离开正常的输入位置</p>
<p>2. 按字符移动的命令<br />
fx: 移动光标至当前行下一个x字符处;使用;来重复上一次的f移动<br />
tx: 同fx，但是移动光标至x字符前，而不是x字符上<br />
Fx：通fx，但反方向移动<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
w:前移光标至下一个单词第一字符<br />
W:前移光标至下一个长单词第一字符<br />
e: 前移光标至下一个单词最后字符<br />
E: 前移光标至下一个长单词最后字符<br />
b: 前一单词第一字符<br />
B: 前一长单词第一字符<br />
(vi 按空格或标点符号分隔单词,按空格或新行来分隔长单词)</p>
<p>(: 到句首<br />
): 到句尾</p>
<p>0: 到行首<br />
^: 到行首第一字符<br />
$: 到行尾</p>
<p>{: 到段首<br />
}: 到段尾</p>
<p>*: 读取光标当前所在位置的字符,并将向前移动至下一个同样的字符<br />
#: 和*功能相同,但反方向移动光标</p>
<p>Ctrl+F: 向前滚屏<br />
Ctrl+B: 向后滚屏<br />
H,M,L: 移动光标至屏幕的顶端,中间,底端</p>
<p>G: 移动光标至文档最后一行<br />
numG: 移动光标至第num行<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
/text: 从光标处开始,向前搜索&#8221;text&#8221;字串<br />
?text: 同上,但搜索方向相反</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/354.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享mail服务器mysql数据库备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/252.html</link>
		<comments>http://www.evanjiang.net.cn/archives/252.html#comments</comments>
		<pubDate>Fri, 16 Jan 2009 07:54:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mail]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 备份脚本 mysql]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=252</guid>
		<description><![CDATA[<p>功能：备份mysql数据库中mail的数据库数据,并用gz压缩，先备份到本地，然后自动上传到指定的ftp服务器,备份日志email到指定的邮箱
</p>

?View Code SHELL[root@mail cron.daily]# cat mailmysql_backup_ftp
#!/bin/bash
#Mysql Autobackup Shell
&#160;
#DB env
dbuser=root
dbpasswd=root
dbserver=localhost
dbname=extmail
#dbopt=--opt
backupdir=/home/mysql-backup/
&#160;
#FTP 0 is disable,1 is enable
copytoftp=1
ftpserver=10.1.1.8
ftpuser=admin
ftppasswd=admin
fileprefix=extmail
dumpfilename=$backupdir`date +%F`.sql
newfile=$fileprefix-`date +%F`.gz
keepdays=16
&#160;
#Backup log
logfile=/tmp/mysqldump.log
logtmp=/tmp/mysqldump.tmp
&#160;
#mail 0 is diable,1 is enable
mailenable=1
mailaddress=ruochen0926@hotmail.com
&#160;
#Backup script
#===============================================
if [ ! -d $backupdir ]
then
        echo &#34;$backupdir is not exist, then make ...&#34; &#38;gt; $logfile
        mkdir -p $backupdir
fi
echo [...]]]></description>
			<content:encoded><![CDATA[<p>功能：备份mysql数据库中mail的数据库数据,并用gz压缩，先备份到本地，然后自动上传到指定的ftp服务器,备份日志email到指定的邮箱<br />
<span id="more-252"></span></p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p252code2'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2522"><td class="code" id="p252code2"><pre class="shell" style="font-family:monospace;">[root@mail cron.daily]# cat mailmysql_backup_ftp
#!/bin/bash
#Mysql Autobackup Shell
&nbsp;
#DB env
dbuser=root
dbpasswd=root
dbserver=localhost
dbname=extmail
#dbopt=--opt
backupdir=/home/mysql-backup/
&nbsp;
#FTP 0 is disable,1 is enable
copytoftp=1
ftpserver=10.1.1.8
ftpuser=admin
ftppasswd=admin
fileprefix=extmail
dumpfilename=$backupdir`date +%F`.sql
newfile=$fileprefix-`date +%F`.gz
keepdays=16
&nbsp;
#Backup log
logfile=/tmp/mysqldump.log
logtmp=/tmp/mysqldump.tmp
&nbsp;
#mail 0 is diable,1 is enable
mailenable=1
mailaddress=ruochen0926@hotmail.com
&nbsp;
#Backup script
#===============================================
if [ ! -d $backupdir ]
then
        echo &quot;$backupdir is not exist, then make ...&quot; &amp;gt; $logfile
        mkdir -p $backupdir
fi
echo &quot;start====================================&amp;gt;&quot;&amp;gt;$logfile
echo &quot;Beginning backup `date '+%F %T'`&quot; &amp;gt;&amp;gt;$logfile
echo &quot;Delete $keepdays days ago files ...&quot; &amp;gt;&amp;gt;$logfile
find $backupdir -name $fileprefix* -mtime +$keepdays -fls $logtmp -exec rm {} \;
echo &quot;Deleted Backup File Is :&quot;&amp;gt;&amp;gt;$logfile
cat $logtmp &amp;gt;&amp;gt;$logfile
echo &quot;Delete old file Success!&quot; &amp;gt;&amp;gt;$logfile
if [ -f $backupdir$newfile ]
then
echo &quot;$newfile backup exist, backup stop ...&quot; &amp;gt;&amp;gt;$logfile
else
        if [ -z $dbpasswd ]
        then
#        mysqldump -u$dbuser -h$dbserver $dbopt $dbname &amp;gt;$dumpfilename
        /usr/bin/mysqldump -u$dbuser -h$dbserver $dbopt $dbname &amp;gt;$dumpfilename
        else
#        /opt/lampp/bin/mysqldump -u$dbuser -p$dbpasswd -h$dbserver $dbopt $dbname | gzip &amp;gt; /opt/apache/mysqlbackup/$newfile
        /usr/bin/mysqldump -u$dbuser -p$dbpasswd -h$dbserver $dbopt $dbname | gzip &amp;gt; $backupdir/$newfile
        fi
#        tar czvf $backupdir$newfile $dumpfilename &amp;gt;&amp;gt;$logfile 2&amp;gt;&amp;amp;1
#        gzip $dumpfilename  $newfile  &amp;gt;&amp;gt;$logfile 2&amp;gt;&amp;amp;1
        echo &quot;$backupdir$newfile Backup Success!&quot; &amp;gt;&amp;gt;$logfile
        rm -fr $dumpfilename
&nbsp;
if [ $copytoftp = 1 ];  then
        if [ -z $ftpserver ];then
        echo &quot;Ftp Server not set,Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 1
        elif [ -z $ftpuser ];then
        echo &quot;Ftp user not set, Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 2
        elif [ -z $ftppasswd ]; then
        echo &quot;Ftp password not set, Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 3
        else
        echo &quot;Start copy to Ftp server ....&quot; &amp;gt;&amp;gt; $logfile
ftp -n&amp;lt;&amp;gt;$logfile
echo &quot;End=======================================|&quot;&amp;gt;&amp;gt;$logfile
fi
&nbsp;
if [ $mailenable=1 ];
    then
      mail -s &quot;Mail Server Mysql Backup Status&quot; $mailaddress&amp;lt;$logfile
fi</pre></td></tr></table></div>

<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/252.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用perl 作数据处理，数据分析。</title>
		<link>http://www.evanjiang.net.cn/archives/220.html</link>
		<comments>http://www.evanjiang.net.cn/archives/220.html#comments</comments>
		<pubDate>Thu, 08 Jan 2009 08:20:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[脚本语言]]></category>
		<category><![CDATA[perl 正则表达式]]></category>
		<category><![CDATA[数据分析]]></category>
		<category><![CDATA[数据处理]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=220</guid>
		<description><![CDATA[<p>题注：下面这些代码主要作用就是：将本地目录下面的js脚本作一些处理，然后将处理的数据入库，其实这敢是为之前curl信息采集后，用unlink清除过一些多余的2k字节的js脚本后，对剩下的有用的js脚本作一些信息处理，并且将一些信息入库，阅者可以从这些代码中知道一些正则的应用，一些fuction的编写，还有数据库连接。并入库的应用，还有一些encode解码模块的使用。
</p>

?View Code PERL1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/perl
use strict;
use warnings;
use Encode;
use Encode qw/encode decode/;
use Encode::CN;
use Win32::ODBC;
use Data::Dumper;
&#160;
 ##连结数据库
 my&#40;$DSN,$Db,$sql,$rc&#41;;
 $DSN =&#34;dsn=goopm;UID=sa;PWD=131468&#34;;
 if &#40;!&#40;$Db = new Win32::ODBC&#40;$DSN&#41;&#41;&#41;&#123; 
	print &#34;連接數據庫失敗.\n&#34;; 
	exit&#40;&#41;; 
 &#125; else&#123; 
	print &#34;連接數據庫成功 (連接號：&#34;, $Db-&#62;Connection&#40;&#41;, &#34;)\n\n&#34;; 
 &#125; 
 ##你要保存数据的表	
 my $TableName='team_scores';
 my @TablesN = $Db-&#62;TableList;
 my $CreateSQL=qq~create table $TableName&#40;ID int identity&#40;1,1&#41;,constraint pk_$&#123;TableName&#125;_ID primary key&#40;ID&#41;&#41;~;
 my &#40;$Tnull&#41;=grep&#123;/\b$TableName\b/&#125; @TablesN;
 if [...]]]></description>
			<content:encoded><![CDATA[<p>题注：下面这些代码主要作用就是：将本地目录下面的js脚本作一些处理，然后将处理的数据入库，其实这敢是为之前curl信息采集后，用unlink清除过一些多余的2k字节的js脚本后，对剩下的有用的js脚本作一些信息处理，并且将一些信息入库，阅者可以从这些代码中知道一些正则的应用，一些fuction的编写，还有数据库连接。并入库的应用，还有一些encode解码模块的使用。<br />
<span id="more-220"></span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p220code4'); return false;">View Code</a> PERL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2204"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
</pre></td><td class="code" id="p220code4"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Encode<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Encode <span style="color: #009966; font-style: italic;">qw/encode decode/</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Encode<span style="color: #339933;">::</span><span style="color: #006600;">CN</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Win32<span style="color: #339933;">::</span><span style="color: #006600;">ODBC</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Data<span style="color: #339933;">::</span><span style="color: #006600;">Dumper</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #666666; font-style: italic;">##连结数据库</span>
 <span style="color: #b1b100;">my</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$DSN</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$sql</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$rc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #0000ff;">$DSN</span> <span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;dsn=goopm;UID=sa;PWD=131468&quot;</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$Db</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Win32<span style="color: #339933;">::</span><span style="color: #006600;">ODBC</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$DSN</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
	<a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #ff0000;">&quot;連接數據庫失敗.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> 
	<a href="http://perldoc.perl.org/functions/exit.html"><span style="color: #000066;">exit</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
 <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span> 
	<a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #ff0000;">&quot;連接數據庫成功 (連接號：&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Connection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;)<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> 
 <span style="color: #009900;">&#125;</span> 
 <span style="color: #666666; font-style: italic;">##你要保存数据的表	</span>
 <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$TableName</span><span style="color: #339933;">=</span><span style="color: #ff0000;">'team_scores'</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@TablesN</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">TableList</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$CreateSQL</span><span style="color: #339933;">=</span><a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #339933;">~</span>create table <span style="color: #0000ff;">$TableName</span><span style="color: #009900;">&#40;</span>ID <a href="http://perldoc.perl.org/functions/int.html"><span style="color: #000066;">int</span></a> identity<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>constraint pk_<span style="color: #0000ff;">$</span><span style="color: #009900;">&#123;</span>TableName<span style="color: #009900;">&#125;</span>_ID primary key<span style="color: #009900;">&#40;</span>ID<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">~;</span>
 <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$Tnull</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">=</span><a href="http://perldoc.perl.org/functions/grep.html"><span style="color: #000066;">grep</span></a><span style="color: #009900;">&#123;</span><span style="color: #339933;">/</span><span style="color: #0000ff;">\b</span><span style="color: #0000ff;">$TableName</span><span style="color: #0000ff;">\b</span><span style="color: #339933;">/</span><span style="color: #009900;">&#125;</span> <span style="color: #0000ff;">@TablesN</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$Tnull</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$rc</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Sql</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$CreateSQL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
 <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dirname</span><span style="color: #339933;">=</span><span style="color: #ff0000;">'D:/7m'</span><span style="color: #339933;">;</span>
 <a href="http://perldoc.perl.org/functions/opendir.html"><span style="color: #000066;">opendir</span></a> SOMEDIR<span style="color: #339933;">,</span><span style="color: #0000ff;">$dirname</span> <span style="color: #b1b100;">or</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a><span style="color: #ff0000;">&quot; cannot open $dirname:$!&quot;</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">=</span><a href="http://perldoc.perl.org/functions/readdir.html"><span style="color: #000066;">readdir</span></a> SOMEDIR<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">next</span> <span style="color: #b1b100;">unless</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">=~/^</span><span style="color: #0000ff;">\d</span><span style="color: #339933;">+</span>_team_scores\<span style="color: #339933;">.</span>js<span style="color: #0000ff;">$/</span><span style="color: #339933;">;</span>			<span style="color: #666666; font-style: italic;">#只要数值型qt前缀的js文件</span>
   <span style="color: #0000ff;">$name</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;$dirname/$name&quot;</span><span style="color: #339933;">;</span>         			<span style="color: #666666; font-style: italic;">#补上路径名</span>
   <span style="color: #b1b100;">next</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">-</span>f <span style="color: #0000ff;">$name</span> <span style="color: #b1b100;">and</span> <span style="color: #339933;">-</span>r <span style="color: #0000ff;">$name</span><span style="color: #339933;">;</span>		<span style="color: #666666; font-style: italic;">#只要可读文件</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$JsText</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&amp;ReadFile</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$JsText</span><span style="color: #339933;">=</span>encode<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;euc-cn&quot;</span><span style="color: #339933;">,</span>decode_utf8<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$JsText</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@KN</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@KV</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$JsText</span><span style="color: #339933;">=~</span><a href="http://perldoc.perl.org/functions/m.html"><span style="color: #000066;">m</span></a><span style="color: #339933;">/</span>var <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\w</span><span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span>\<a href="http://perldoc.perl.org/functions/s.html"><span style="color: #000066;">s</span></a><span style="color: #339933;">*=</span>\<a href="http://perldoc.perl.org/functions/s.html"><span style="color: #000066;">s</span></a><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">?:</span>\<span style="color: #009900;">&#91;</span><span style="color: #339933;">|</span><span style="color: #ff0000;">')(.*?)(?:\]|'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;/</span>isg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$v1</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$1</span><span style="color: #339933;">;</span>
				<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$v2</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$2</span><span style="color: #339933;">;</span>
			    <span style="color: #0000ff;">$v2</span><span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">s/'/''/g</span><span style="color: #339933;">;</span>
                <a href="http://perldoc.perl.org/functions/push.html"><span style="color: #000066;">push</span></a> <span style="color: #0000ff;">@KN</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$v1</span><span style="color: #339933;">;</span>
                <a href="http://perldoc.perl.org/functions/push.html"><span style="color: #000066;">push</span></a> <span style="color: #0000ff;">@KV</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;'$v2'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
		<span style="color: #0000ff;">$sql</span><span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;select * from $TableName where id =object_id('table_name')&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$rc</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Sql</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@FieldNames</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">FieldNames</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%Field</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>map<span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$Field</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span> <span style="color: #0000ff;">@FieldNames</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">for</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$t</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@KN</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$Field</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$t</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<a href="http://perldoc.perl.org/functions/chomp.html"><span style="color: #000066;">chomp</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$t</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$Field</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$t</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$t</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$sql</span><span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;ALTER TABLE $TableName ADD $t TEXT NULL&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$rc</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Sql</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #0000ff;">$sql</span><span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;insert into $TableName(&quot;</span> <span style="color: #339933;">.</span> <a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">@KN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;)&quot;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">&quot; values(&quot;</span> <span style="color: #339933;">.</span><a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">','</span><span style="color: #339933;">,</span><span style="color: #0000ff;">@KV</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;);&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$rc</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Sql</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#40;</span>SQL 失敗 <span style="color: #ff0000;">&quot;$sql&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$rc</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$Db</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$Db</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> ReadFile <span style="color: #009900;">&#123;</span>
        <a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!-</span>e <span style="color: #ff0000;">&quot;$_[0]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$file_Str</span><span style="color: #339933;">;</span>
        <a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a><span style="color: #009900;">&#40;</span>QT<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;&lt;$_[0]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#123;</span><a href="http://perldoc.perl.org/functions/local.html"><span style="color: #000066;">local</span></a> <span style="color: #0000ff;">$/</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/undef.html"><span style="color: #000066;">undef</span></a><span style="color: #339933;">;</span> <span style="color: #0000ff;">$file_Str</span> <span style="color: #339933;">=</span> <span style="color: #009999;">&lt;QT&gt;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
        <a href="http://perldoc.perl.org/functions/close.html"><span style="color: #000066;">close</span></a><span style="color: #009900;">&#40;</span>QT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #0000ff;">$file_Str</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/220.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用perl来作数据处理，来作数据分析</title>
		<link>http://www.evanjiang.net.cn/archives/215.html</link>
		<comments>http://www.evanjiang.net.cn/archives/215.html#comments</comments>
		<pubDate>Thu, 08 Jan 2009 08:11:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[脚本语言]]></category>
		<category><![CDATA[perl 正则表达式]]></category>
		<category><![CDATA[数据处理]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=215</guid>
		<description><![CDATA[<p>题注：下面这些代码主要作用就是：将本地目录下面的js脚本作一些处理，然后将处理的数据入库，其实这敢是为之前curl信息采集后，用unlink清除过一些多余的2k字节的js脚本后，对剩下的有用的js脚本作一些信息处理，并且将一些