PHP发送头部消息

照彭武兴先生的《PHP BIBLE》中所述,header可以送出Status标头,如
<?php

header("Status: 404 Not Found");

?>

就可以让用户浏览器出现文件找不到的404错误,但是我试了这样是不行的。

后来我到w3.org上查了http的相关资料,终于试出来了如何Header出状态代码(Status),与大家分享。

其实应该是这样的:

<?php

header("http/1.1 403 Forbidden");

?>

第一部分为HTTP协议的版本(HTTP-Version)

第二部分为状态代码(Status)

第三部分为原因短语(Reason-Phrase)

三部分中间用一个空格分开,且中间不能有回车,第一部分和第二部分是必需的,第三部分则是给人看的,可写可不写甚至乱写。

还有,这一句的输出必须在Html文件的第一行。

下面我给出各代码所代表的意思(是从w3.org上查到的,够权威了):

  * 1xx: Informational – Request received, continuing process

  * 2xx: Success – The action was successfully received, understood,

  and accepted

  * 3xx: Redirection – Further action must be taken in order to

  complete the request

  * 4xx: Client Error – The request contains bad syntax or cannot be

  fulfilled

  * 5xx: Server Error – The server failed to fulfill an apparently

  valid request

       | "100" ; Continue

       | "101" ; Switching Protocols

       | "200" ; OK

       | "201" ; Created

       | "202" ; Accepted

       | "203" ; Non-Authoritative Information

       | "204" ; No Content

       | "205" ; Reset Content

       | "206" ; Partial Content

       | "300" ; Multiple Choices

       | "301" ; Moved Permanently

       | "302" ; Moved Temporarily

       | "303" ; See Other

       | "304" ; Not Modified

       | "305" ; Use Proxy

       | "400" ; Bad Request

       | "401" ; Unauthorized

       | "402" ; Payment Required

       | "403" ; Forbidden

       | "404" ; Not Found

       | "405" ; Method Not Allowed

       | "406" ; Not Acceptable

       | "407" ; Proxy Authentication Required

       | "408" ; Request Time-out

       | "409" ; Conflict

       | "410" ; Gone

       | "411" ; Length Required

       | "412" ; Precondition Failed

       | "413" ; Request Entity Too Large

       | "414" ; Request-URI Too Large

       | "415" ; Unsupported Media Type

       | "500" ; Internal Server Error

       | "501" ; Not Implemented

       | "502" ; Bad Gateway

       | "503" ; Service Unavailable

       | "504" ; Gateway Time-out

       | "505" ; HTTP Version not supported

Win2003中apache2分别整合tomcat5和iis6的终极教程

 

 2006年5月18日:一个值得记住的日子

    为了能在已经存在iis6的服务器上运行自己的java程序,经过历时半年的尝试,今天终于搞定了,好开心啊。
   
    最开始是用iis直接连接tomcat,找遍了网上所有的资料,可是死活也连不通,或许是iis的封闭吧,看来tomcat与iis远没有成为朋友。
     于是只好另辟蹊径,用apache监听80来做请求转发了,请求到iis的站点就转到相应目录,请求到tomcat下的站点就转发到tomcat下,于是开始到处找这方面的资料,终于经过反复试验,右克服请求servlet出错的困难,现在终于可以继续做自己的网站了。

参考文档:
1.http://weblife.blogbus.com/s1659/index.html
2.http://wiki.osportfolio.org/confluence/display/Technical/Apache+Tomcat+mod_jk+Integration

第一篇文档基本解决了所有的问题,第二篇文档解决了请求servlet发生找不到目标的问题

下面就从零开始,一步步配置三个服务器,让他们协调工作。

    1.下载安装apache2
   
    在http://bj.onlinedown.net/soft/11528.html中下载apache2.0.55 for windows
    在官方网站上我怎么也找不到,奇怪。下载到本地后双击就可以安装了,安装完成后应该在系统托盘中看到一个小图标了,是个羽毛加绿色播放箭头的图标,这表示正确安装了,如果不能正确安装,请确认80端口没有被别的服务器占有。
   
    2.下载安装tomcat5
   
    Tomcat还是到官方网站下载,地址是:http://tomcat.apache.org/download-55.cgi,选择5.5.17中core:zip,我比较习惯用这个压缩包,解压后设置环境变量就可以用了。在安装路径的bin里面运行startup.bat就可以启动tomcat了。
   
    3.安装IIS6.0
   
    将win2003的安装盘插入光驱,在添加或删除程序中选择“添加/删除windows组件”在“windows组件向导”中选择“应用程序服务器”并打上勾,按向导提示下一步进行,就可以安装了。IIS6.0安装后并不能正常启动,因为默认端口80被apache已经占了。双击打开“管理工具/internet信息服务(IIS)管理器”,在“默认网站(停止)”上右击选择“属性”,在“网站”选项卡中修改“TCP端口”的80为88或者其他端口,确定。选中“默认网站(停止)”然后单击工具栏中的播放图标,就可以启动IIS了,正常启动后“停止”字样就消失了。
   
    4.测试3个服务器
   
    修改Apache安装目录/htdocs中的index.html.en改名为index.html,在浏览器输入http://localhost回车如果看到apache的欢迎界面,说明apache正在运行。在浏览器中输入http://localhost:8080回车如果看到tomcat的欢迎界面,这表示tomcat运行正常。在浏览器中输入http://localhost:88回车如果看到“建设中”这样的提示,表示iis正在运行。
   
    5.配置apache与tomcat的连接
   
    第一步: 在http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.6
             下载mod_jk_1.2.6_2.0.50.dll文件,将其改名为mod_jk.so后放到apache2/modules目录中。
            
    第二步: 打开记事本,输入下列语句,以workers.properties为文件名保存在tomcat安装目录/conf目录下:
   
             workers.tomcat_home=C:\Program Files\jakarta-tomcat-5.0.28
             workers.java_home=C:\Program Files\Java\jdk1.5.0_06
             ps=\
             worker.list=ajp13
             worker.ajp13.port=8009
             worker.ajp13.host=localhost
             worker.ajp13.type=ajp13
             worker.ajp13.lbfactor=1
            
     第三步:用记事本打开apache/conf/httpd.conf文件末尾,添加下面一段:
    
     LoadModule jk_module modules/mod_jk.so
     JkWorkersFile "D:\Program Files\jakarta-tomcat-5.0.28\conf\workers.properties"

     <VirtualHost *:80>
       ServerAdmin rabbit69@openria.com   
       ServerName localhost
       DirectoryIndex index.html index.htm index.jsp
       JkMount /* ajp13   
       JkAutoAlias "C:\Program Files\jakarta-tomcat-5.0.28\webapps"  
       <Directory "C:\Program Files\jakarta-tomcat-5.0.28\webapps">
          Options Indexes FollowSymLinks
          allow from all
       </Directory>
     </VirtualHost>       

     保存,停止apache服务,在启动,就可以将新配置应用了。
    
     6.测试apache与tomcat的连接
     在服务器中输入http://localhost回车如果看见的是tomcat的欢迎界面,就表示apache和tomcat整合成功了,localhost后面加上jsp-examples目录或者servlet-examples目录就可以看到下面的例子,为了让servlet运行,我可是费了半天劲,修改这个httpd.conf文件。
    
     7.配置apache与IIS6的连接
    
     第一步:修改httpd.conf文件,启用proxy模块
             将文件中的LoadModule proxy_module modules/mod_proxy.so和LoadModule proxy_http_module modules/mod_proxy_http.so这两句
             的“#”去掉就可以了。
            
     第二步:增加IIS的虚拟主机
             在httpd.conf文件末尾加入以下代码:
            
             <VirtualHost *:80>
                ServerAdmin rabbit69@openria.cn
                ServerName localhost
                DocumentRoot "C:/Inetpub/wwwroot"
                DirectoryIndex index.html index.htm index.asp
                Alias /test "C:/Inetpub/wwwroot"
                <Directory "C:/Inetpub/wwwroot">
                   Options MultiViews
                   AllowOverride None
                   order allow,deny
                   Allow from all
                </Directory>
                ProxyPass / http://127.0.0.1:88/
                ProxyPassReverse / http://127.0.0.1:88
             </VirtualHost>
             保存,并重启apache就可以做测试了。
            
      8.测试apaceh与IIS的连接
     
      写一个asp页面,hello.asp:
      <HTML>
         <HEAD>
           <TITLE>Hello World Sample</TITLE>
         </HEAD>
         <BODY>
           <% Response.Write "Hello World" %>
         </BODY>
      </HTML>
      放到C:/Inetpub/wwwroot下面,在浏览器中访问http://localhost/test/hello.asp回车如果出现“hello world”字样就表示配置成功了。如果页面出现空白,在Internet信息服务(IIS)管理器中的web服务扩展里将“active server page”允许,然后清空缓存,刷新页面应该就可以看见hello world了。
     
      具体参数的含义就不多说了,上面的参考文档有介绍。
     
      后记:
     
      一直以为这个整合问题解决不了了,但是我还是不甘心,为什么别人能调通,我就调不通,苦脑啊,今天终于解决了,昨天晚上还弄到1点多,所有的辛苦没有白下,写下这个,做个纪念,也希望能对碰到此问题的网友有帮助,没有互联网就没有大家的成长。

 

基本的页面设计元素布局比例

基本的页面设计元素布局比例,给大家做个参考

标志图案

位置 统计结果
左上角 84%
右上角 6%
上方居中 6%
其他位置 4%

搜索功能

位置 统计结果
右上角 35%
左上角 30%
上方居中 14%
中间居中 12%
其他位置 12%

导航模式

位置 统计结果
左导航栅格 30%
选项卡 30%
通过页面顶端的链接 18%
页面中间的类别 12%
下拉菜单 10%
其他 ( 左边、底部、底部居中 ) 6%

帮助内容

位置 统计结果
右上角 41%
顶部居中 44%
左上角 4%
页中居左 11%
右下角 7%
下方居中 11%
左下方 19%

PHP 实现多服务器共享 SESSION 数据

 

一、问题起源

稍大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的二级域名,而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个模块中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在这个服务器登录之后,进入另一个服务器的别的模块时,仍然需要重新登录,这就是一次登录,全部通行的问题,映射到技术上,其实就是各个服务器之间如何实现共享 SESSION 数据的问题。

二、PHP SESSION 的工作原理

在解决问题之前,先来了解一下 PHP SESSION 的工作原理。在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用 session_start() 打开 SESSION,这样就会产生客户端的唯一标识 SESSION ID(此 ID 可通过函数 session_id() 获取/设置)。SESSION ID 可以通过两种方式保留在客户端,使得请求不同的页面时,PHP 程序可以获知客户端的 SESSION ID;一种是将 SESSION ID 自动加入到 GET 的 URL 中,或者 POST 的表单中,默认情况下,变量名为 PHPSESSID;另一种是通过 COOKIE,将 SESSION ID 保存在 COOKIE 中,默认情况下,这个 COOKIE 的名字为 PHPSESSID。这里我们主要以 COOKIE 方式进行说明,因为应用比较广泛。

那么 SESSION 的数据保存在哪里呢?当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。默认情况下,php.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,而 SESSION 文件保存的目录由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION 数据了。如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path="N;/save_path",N 为分级的级数,save_path 为开始目录。当写入 SESSION 数据的时候,PHP 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件。读取 SESSION 数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。

三、多服务器共享 SESSION 的主要障碍及解决办法

通过了解 SESSION 的工作原理,我们可以发现,在默认情况下,各个服务器会各自分别对同一个客户端产生 SESSION ID,如对于同一个用户浏览器,A 服务器产生的 SESSION ID 是 30de1e9de3192ba6ce2992d27a1b6a0a,而 B 服务器生成的则是 c72665af28a8b14c0fe11afe3b59b51b。另外,PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。如下图所示:

确定了问题所在之后,就可以着手进行解决了。想要共享 SESSION 数据,那就必须实现两个目标:一个是各个服务器对同一个客户端产生的 SESSION ID 必须相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的 COOKIE;另一个是 SESSION 数据的存储方式/位置必须保证各个服务器都能够访问到。简单地说就是多服务器共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。

第一个目标的实现其实很简单,只需要对 COOKIE 的域(domain)进行特殊地设置即可,默认情况下,COOKIE 的域是当前服务器的域名/IP 地址,而域不同的话,各个服务器所设置的 COOKIE 是不能相互访问的,如 www.aaa.com 的服务器是不能读写 www.bbb.com 服务器设置的 COOKIE 的。这里我们所说的同一网站的服务器有其特殊性,那就是他们同属于同一个一级域,如:aaa.infor96.com 和 www.infor96.com 都属于域 .infor96.com,那么我们就可以设置 COOKIE 的域为 .infor96.com,这样 aaa.infor96.com、www.infor96.com 等等都可以访问此 COOKIE。PHP 代码中的设置方法如下:


<?php
ini_set('session.cookie_domain''.infor96.com');
?>

这样各个服务器共享同一客户端 SESSION ID 的目的就达到了。

第二个目标的实现可以使用文件共享方式,如 NFS 方式,但设置、操作上有些复杂。我们可以参考先前所说的统一用户系统的方式,即使用数据库来保存 SESSION 数据,这样各个服务器就可以方便地访问同一个数据源,获取相同的 SESSION 数据了。

解决办法如下图所示:

四、代码实现

首先创建数据表,MySQL 的 SQL 语句如下:

   Create TABLE `sess` (
`sesskey` varchar(32) NOT NULL default '',
`expiry` bigint(20) NOT NULL default '0',
`data` longtext NOT NULL,
PRIMARY KEY  (`sesskey`),
KEY `expiry` (`expiry`)
) TYPE=MyISAM

sesskey 为 SESSION ID,expiry 为 SESSION 过期时间,data 用于保存 SESSION 数据。

默认情况下 SESSION 数据是以文件方式保存,想要使用数据库方式保存,就必须重新定义 SESSION 各个操作的处理函数。PHP 提供了session_set_save_handle() 函数,可以用此函数自定义 SESSION 的处理过程,当然首先要先将 session.save_handler 改成 user,可在 PHP 中进行设置:


<?php 
session_module_name('user');
?>

接下来着重讲一下 session_set_save_handle() 函数,此函数有六个参数:

session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )

各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,在这里我们使用 OO 的方式来实现这些操作,详细代码如下:


<?php
define('MY_SESS_TIME'3600);   //SESSION 生存时长
//类定义
class My_Sess
{
    function init()
    {
        $domain '.infor96.com';
        //不使用 GET/POST 变量方式
        ini_set('session.use_trans_sid',    0);
        //设置垃圾回收最大生存时间
        ini_set('session.gc_maxlifetime',   MY_SESS_TIME);
        //使用 COOKIE 保存 SESSION ID 的方式
        ini_set('session.use_cookies',      1);
        ini_set('session.cookie_path',      '/');
        //多主机共享保存 SESSION ID 的 COOKIE
        ini_set('session.cookie_domain',    $domain);
        //将 session.save_handler 设置为 user,而不是默认的 files
        session_module_name('user');
        //定义 SESSION 各项操作所对应的方法名:
        session_set_save_handler(
            array('My_Sess''open'),   //对应于静态方法 My_Sess::open(),下同。
            array('My_Sess''close'),
            array('My_Sess''read'),
            array('My_Sess''write'),
            array('My_Sess''destroy'),
            array('My_Sess''gc')
        );
    }   //end function
    function open($save_path$session_name) {
        return true;
    }   //end function
    function close() {
        global $MY_SESS_CONN;
        if ($MY_SESS_CONN) {    //关闭数据库连接
            $MY_SESS_CONN->Close();
        }
        return true;
    }   //end function
    function read($sesskey) {
        global $MY_SESS_CONN;
        $sql 'Select data FROM sess Where sesskey=' $MY_SESS_CONN->qstr($sesskey) . ' AND expiry>=' time();
        $rs =& $MY_SESS_CONN->Execute($sql);
        if ($rs) {
            if ($rs->EOF) {
                return ";
            } else {    //读取到对应于 SESSION ID 的 SESSION 数据
                $v $rs->fields[0];
                $rs->Close();
                return $v;
            }   //end if
        }   //end if
        return ";
    }   //end function
    function write($sesskey$data) {
        global $MY_SESS_CONN;
        
        $qkey $MY_SESS_CONN->qstr($sesskey);
        $expiry time() + My_SESS_TIME;    //设置过期时间
        
        //写入 SESSION
        $arr = array(
            'sesskey' => $qkey,
            'expiry'  => $expiry,
            'data'    => $data);
        $MY_SESS_CONN->Replace('sess'$arr'sesskey'$autoQuote true);
        return true;
    }   //end function
    function destroy($sesskey) {
        global $MY_SESS_CONN;
        $sql 'Delete FROM sess Where sesskey=' $MY_SESS_CONN->qstr($sesskey);
        $rs =& $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function
    function gc($maxlifetime null) {
        global $MY_SESS_CONN;
        $sql 'Delete FROM sess Where expiry<' time();
        $MY_SESS_CONN->Execute($sql);
        //由于经常性的对表 sess 做删除操作,容易产生碎片,
        //所以在垃圾回收中对该表进行优化操作。
        $sql 'OPTIMIZE TABLE sess';
        $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function
}   ///:~
//使用 ADOdb 作为数据库抽象层。
require_once('adodb/adodb.inc.php');
//数据库配置项,可放入配置文件中(如:config.inc.php)。
$db_type 'mysql';
$db_host '192.168.212.1';
$db_user 'sess_user';
$db_pass 'sess_pass';
$db_name 'sess_db';
//创建数据库连接,这是一个全局变量。
$GLOBALS['MY_SESS_CONN'] =& ADONewConnection($db_type);
$GLOBALS['MY_SESS_CONN']->Connect$db_host$db_user$db_pass$db_name);
//初始化 SESSION 设置,必须在 session_start() 之前运行!!
My_Sess::init();
?>

五、遗留问题

如果网站的访问量很大的话,SESSION 的读写会频繁地对数据库进行操作,这样效率就会明显降低。考虑到 SESSION 数据一般不会很大,可以尝试用 C/Java 写个多线程的程序,用 HASH 表保存 SESSION 数据,并通过 socket 通信进行数据读写,这样 SESSION 就保存在内存中,读写速度应该会快很多。另外还可以通过负载均衡来分担服务器负载。不过这些都只是我自己的一些想法和假设,并没有实践过

数据库操作类adodb类下载地址

ADOdb is a PHP & Python database class library to provide more powerful abstractions for performing queries and managing databases. ADOdb also hides the differences between the different databases so you can easily switch dbs without changing code.

以下全为zip格式,如果您需要下载其它版本的adodb库,请从官方网站下载

支持php4和php5版本的下载地址:点击下载[官方更新日期:(2007-09-27 09:29) ]

仅支持adodb-php5-only 版本的adodb库下载地址:点击下载[官方更新日期:(2007-09-26 21:16) ]

adodb-python 版本的下载地址:点击下载[官方更新日期:(2007-05-21 04:45) ]

官方下载地址:http://sourceforge.net/project/showfiles.php?group_id=42718

adodb学习基础教程

其中需要在本地文件夹里建立一个temp文件夹

adodbtest.php

 

<?php
require_once(newadodb.php);
?>
<html>
<head>
<meta httpequiv=Content-Type content=text/html; charset=gbk />
<title></title>
</head>
<body>
<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;

$query = Select * FROM library;

//$result = $db->Execute($query) or die($db->ErrorMsg());
$result = $db->SelectLimit($query, 10, 1) or die($db->ErrorMsg());//从第一个开始显示10个

while (!$result->EOF)
{
echo $result->fields[title] . . $result->fields[author] . <br />;
$result->MoveNext();
}
echo <br />[ . $result->RecordCount() . rows]<br /></b>;//行数
echo <br />[ . $result->FieldCount() . fields]<br /></b>;//字段数
$db->Close();
?>
</body>
</html>

 

adodbtest2.php

 

<?php
require_once(newadodb.php);
?>
<html>
<head>
<meta httpequiv=Content-Type content=text/html; charset=gbk />
<title></title>
</head>
<body>
<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

$title=$db->qstr(myz);
$author=123;
$query = Insert INTO library (title, author) VALUES ($title, $author);

$result = $db->Execute($query) or die($db->ErrorMsg());

if ($result)
{
echo Last inserted ID is . $db->Insert_ID();
}

$db->Close();
?>
</body>
</html>

 

adodbtest3.php

 

<?php
require_once(newadodb.php);
?>
<html>
<head>
<meta httpequiv=Content-Type content=text/html; charset=gbk />
<title></title>
</head>
<body>
<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

$title=$db->qstr(myz);
$author=123;
$query = Delete FROM library Where id = 4;

$result = $db->Execute($query) or die($db->ErrorMsg());

if ($result)
{
echo $db->Affected_Rows() . rows deleted;
}

$db->Close();
?>
</body>
</html>

 

adodbtest4.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

require_once(newadodb.php);

$query = $db->Prepare(Insert INTO library (title, author) VALUES (?, ?));

$data = file(list.txt);

foreach ($data as $l)
{
$arr = explode(,, $l);
$result = $db->Execute($query, array($arr[0], $arr[1])) or die(Error in query: $query. . $db->ErrorMsg());
}


$db->Close();
?>

 

adodbtest5.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

require_once(newadodb.php);


$db->BeginTrans();

// first query
$query = Insert INTO library (title, author) VALUES (‘Title A’, ‘Author B’);
$result = $db->Execute($query) or die(Error in query: $query. . $db->ErrorMsg());

// use ID from first query in second query
if ($result)
{
$id = $db->Insert_ID();
$query = Insert INTO library (title, author) VALUES ($id, ‘USD 39.99’);
$result = $db->Execute($query) or die(Error in query: $query. . $db->ErrorMsg());
}

if ($result)
{

$db->CommitTrans();
}

else
{
$db->RollbackTrans();
}


$db->Close();
?>

 

adodbtest6.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

require_once(newadodb.php);

$query = Select * FROM library;
$result = $db->CacheExecute(300,$query) or die($db->ErrorMsg());

while (!$result->EOF)
{
echo $result->fields[1] . . $result->fields[2] . ;
$result->MoveNext();
}
$db->Close();

?>

 

adodbtest7.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

require_once(newadodb.php);

$query = Select title, id FROM library;
$result = $db->Execute($query) or die(Error in query: $query. . $db->ErrorMsg());


print $result->GetMenu(library, , false);

$db->Close();

?>

 

adodbtest8.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/
require_once(adodb/toexport.inc.php);
require_once(adodb/tohtml.inc.php);
require_once(newadodb.php);
$query = Select title, id FROM library;
$result = $db->Execute($query) or die(Error in query: $query. . $db->ErrorMsg());
//echo rs2csv($result,false);
//echo rs2tab($result,false);

echo rs2html($result,false);
$db->Close();
?>

 

newadodb.php

 

<?php
/*
* @author 马永占
* @email mailmyz*gmail.com
*/

require_once adodb/adodb.inc.php;

$ADODB_CACHE_DIR = temp/;

$mydbtype=mysql;
$mydbhost=localhost;
$mydbname=root;
$mydbpass=myz;
$mydb=adodbtest;

$db = NewADOConnection($mydbtype);

$db->Connect($mydbhost, $mydbname, $mydbpass, $mydb) or die($db->ErrorMsg());
?>

 

list.txt

abc,bcd
sdf,dsfgg
grwetg,dfsdf

html中dl、dt、dd标记的使用

dl 标签 — 代表HTML自定义列表

  • dl标签是成对出现的,以<dl>开始,</dl>结束
  • 自定义列表的开始使用<dl>标签,列表中每个元素的标题使用<dt>(definition term)定义,后面跟随<dd>(definition description)用于描述列表中元素的内容.
  • 属性:
    • Common — 一般属性
  • dl是definition lists的英文缩写

示例

<dl>
<dt>www</dt>
<dd>World Wide Web的缩写.</dd>
<dt>dreamdu</dt>
<dd>梦之都.</dd>
<dd>www的:).</dd>
<dt>com</dt>
<dt>com.cn</dt>
<dt>cn</dt>
<dd>这都是域名的后缀.</dd>
</dl>

猴子提示: 不一定每个dt标签要对应一个dd,可以一对多或多对一(就像上面的例子)

源代码

<dl>
<dt>Coffee</dt>
<dd>Black hot drink</dd>
<dt>Milk</dt>
<dd>White cold drink</dd>
</dl> 

输出结果

Coffee
Black hot drink
Milk
White cold drink

例三:<dl>标记定义了一个定义列表,定义列表中的条目是通过使用<dt>标记(“definition title”,定义标题)和<dd>标记(“definition description”,定义描述)创建的。<dt>给出了术语名,<dd>标记给出了术语的定义。

         一个定义列表中可以有多个术语名对应同一个给出的定义,也可有多重定义对应于一个术语名。同时也可以只给出术语名称而不对应定义,反之亦然。当然,这种结构往往并无实际意义,我们可以通过样式表,很轻松的实现这3个标记所达到的效果。

下面是一个例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> New Document </title>
<style type="text/css">
<!–
dl    { background-color:#000;color:#fff;width:100px;}
dt    { cursor:pointer;width:100%;background-color:#666;}
.expand   { overflow:visible;}
.collapse   { height:16px;overflow:hidden;}
//–>
</style>
<script language="JavaScript" type="text/javascript">
<!–
function toggleDl(dt){
var dl=dt.parentNode;
if("collapse"==dl.className)dl.className="expand";
else dl.className="collapse";
}
//–>
</script>
</head>
<body>
<dl>
<dt onclick="toggleDl(this)">根结点</dt>
<dd>子结点1</dd>
<dd>子结点2</dd>
<dd>子结点3</dd>
<dd>子结点4</dd>
</dl>
</body>
</html>

另一个例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta http-equiv="Content-Language" content="zh-cn" />
</head>

<body>

<h4>A Definition List:</h4>
<dl>
   <dt>Coffee</dt>
   <dd>Black hot drink</dd>
   <dt>Milk</dt>
   <dd>White cold drink</dd>
</dl>

</body>
</html>

配置Apache增加SSI支持

什么是SSI?
SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针。SSI具有强大的功能,只要使用一条简单的SSI命令就可以实现整个网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。

如何使你的Apache服务器支持SSI?

Apache默认是不支持SSI的,需要我们更改httpd.conf来进行配置。我这里以windows平台的Apache 2.0.x为例,打开conf目录下的httpd.conf文件,搜索“AddType text/html .shtml”,搜索结果:

# AddType text/html .shtml
# AddOutputFilter INCLUDES .shtml

把这两行前面的#去掉。

然后搜索“Options Indexes FollowSymLinks”
在搜索到的那一行后面添加“ Includes”
即将该行改变为 Options Indexes FollowSymLinks Includes

保存httpd.conf,重起apache即可。

到此我们就完成了对Apache SSI的设置。

值得推荐的加载广告的javascript代码

<SPAN id=ad_src1 style="DISPLAY: none; POSITION: absolute">
<TABLE cellSpacing=4 cellPadding=0 width=370 align=left border=0>
  <TBODY>
  <TR>
    <TD><IFRAME marginWidth=0 marginHeight=0 src="/ads/ad_pic.htm" frameBorder=0 width=360 scrolling=no height=300 bordercolor="#000000"></IFRAME>
 </TD>
</TR></TBODY></TABLE>
</SPAN>

<SCRIPT>
var ids;
var idstext;
var showad = true;
idstext=$(‘mcontent’).innerHTML;               /*mconeent为文章内容应用的ID*/
c=idstext.indexOf("<noads>");                     /* 检查是否允许有画中画广告的,*/
d=idstext.indexOf("<NOADS>");
if(c!=-1||d!=-1) showad=false;
a=idstext.indexOf("</P>");
b=idstext.indexOf("</p>");
e=(a>b)?4+a:4+b;
if(e!=3){
idstext3=idstext.substring(0,e);
idstext4=idstext.substr(e);
idstext5="<span id=ad_dst1></span>";
idstext6=idstext3+idstext5+idstext4;                                /*画中画广告的位置,利用js代码定位在内容中间*/
$(‘mcontent’).innerHTML=idstext6;
}
else {showad=false;}
if(showad){
    src_ad = document.getElementById("ad_src1"); dst_ad = document.getElementById("ad_dst1"); tmp=src_ad.innerHTML; src_ad.innerHTML=""; dst_ad.innerHTML=tmp; }
</SCRIPT>
 function $(id) {
 return document.getElementById(id);
}
function $tag(t,o) {
 o = o?o:document;
 return o.getElementsByTagName(t);
}
function route() {
 str = $(‘preroute’).innerHTML;
 tmp = str.indexOf(‘&gt;’);
 tmp = str.indexOf(‘&gt;’,tmp+1);
 tmp = str.indexOf(‘&gt;’,tmp+1);
 str = str.substr(tmp+10);
 $(‘route’).innerHTML = ‘<a href="http://sunxingfang.cn">首页</a> &gt; <a href="/default.asp?cateID=16">网页设计</a> &gt; ‘+str;
}
function titlead() {
 $(‘titlead’).innerHTML = $(‘pretitlead’).innerHTML;
 $(‘pretitlead’).innerHTML = ”;
 doshowta();
}
function showta(v) {
 $(‘titleadm’).style.display=(v==0)?’none’:’block’;
}
function doshowta() {
 $(‘titlead’).style.height="118px";
 $(‘titleadm’).style.display=’block’;
 window.setTimeout("$(‘titlead’).style.height=’28px’;$(‘titleadm’).style.display=’none’",3000);
}
function wztj() {
 $(‘wztj’).innerHTML = $(‘prewztj’).innerHTML;
 $(‘prewztj’).innerHTML = ”;
}
function topad() {
 $(‘tad’).innerHTML = $(‘pretad’).innerHTML;
 $(‘pretad’).innerHTML = ”;
}
function flagad() {
 $(‘flagad’).innerHTML = $(‘preflagad’).innerHTML;
 $(‘preflagad’).innerHTML = ”;
}
function sidelogo() {
 $(‘sidelogo’).innerHTML = $(‘presidelogo’).innerHTML;
 $(‘presidelogo’).innerHTML = ”;
}
function baidu() {
 $(‘baidu’).innerHTML = $(‘prebaidu’).innerHTML;
 $(‘prebaidu’).innerHTML = "";
}
window.onload = function () {
 baidu();
}
function cmore() {
 str = $(‘preroute’).innerHTML;
 tmp = str.lastIndexOf(‘&gt;’);
 str = str.substr(tmp+10);
 $(‘cmore’).innerHTML = ‘&gt;&gt; 查看更多“’+str+’”资讯’;
}

DeDeCMS采集的问题与技巧集锦!

maxjay:
采集里怎么样过滤多个信息??

以下为引用的内容:
mizuno:
{dede:trim}1{/dede:trim}
  {dede:trim}2{/dede:trim}
  {dede:trim}3{/dede:trim}

tom111:
网易财经频道-财经要闻 的采集点分享

以下为引用的内容:
{dede:comments}
{!– 采集列表获取规则 –}
{/dede:comments}

{dede:list source=’single’ sourcetype=’list’
    varstart=’2′ varend=’9′}  
{dede:url value='[url]http://finance.163.com/special/00251OFM/cjyw_0[/url][var:分页].html’}

{/dede:url}  
{dede:need}/06/{/dede:need}
{dede:cannot}{/dede:cannot}
{/dede:list}

{dede:comments}
{!– 网页内容获取规则 –}
{/dede:comments}

{dede:art sptype=’full’}
{dede:sppage}{/dede:sppage}

{dede:note field=’title’ value='[var:内容]’
isunit=” isdown=”}

{dede:match}<title>[var:内容]</title>{/dede:match}
{dede:trim}_网易财经-中国的投资门户{/dede:trim}

{/dede:note}

{dede:note field=’body’ value='[var:内容]’
isunit=’1′ isdown=’1′}

{dede:match}<!– main –>[var:内容]<a href="javascript:reply_allReply()" target="_self"><img src="" alt="网友评论" width="34" height="18" border="0" />{/dede:match}
{dede:trim}_网易财经-中国的投资门户{/dede:trim}
  {dede:trim}<iframe src="[url]http://adclient.163.com/html.ng/site=netease&affiliate=stock&cat=article&type=tvscreen&location=1[/url]" width="360" height="300" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>{/dede:trim}
{dede:trim}<a href="[url]http://finance.163.com[/url]">{/dede:trim}

{/dede:note}
{/dede:art}

——————
5713090:
采集的时候,把文章内容里的链接去掉,过滤要怎么写

以下为引用的内容:
柏拉图:
{dede:trim}<a ([^>]*)>([^<]*)</a>{/dede:trim}

世界和平:
([^>]*)
什么意思,是不是代表任意字符!好想不是,
能不能解释一下具体的意思,

以下为引用的内容:
柏拉图:
除 ‘>’ 以外的任意字符

cooldgjk:
哪里有NC采集入DEDE V3的教程哦?

以下为引用的内容:
tomosak:
http://bbs.dedecms.com/read.php?tid=1426&keyword=%B2%C9%BC%AF

必须:
不知老大在DedeCms 3.0.1版中解决采集内分页问题了吗!

以下为引用的内容:
柏拉图:
关于采集器和会员整合的问题都会在dedecms V3.1中处理,到时候会有很大的改进

dede采集过程中最麻烦的莫过于采集的正则过滤函数的编写。说实在的,dede在这点上和很多ASP CMS系统比如说动易等,采集的时候直接选择几个选项就可以了,简单的完成想过滤的东西。不过他们只局限于对文章内容的过滤不是很好。而DEDE却能对所有采集的字段进行过滤,功能上弥补了易用性的缺陷,期待柏拉图在后续版本中加上选择性过滤功能。
下面是在综合论坛上网友的各种正则的一个全集:

以下为引用的内容:
{dede:trim}
{/dede:trim}
{dede:trim}<param([^>]*)>{/dede:trim}
{dede:trim}<embed([^>]*)>([^>]*)</embed>{/dede:trim}
{dede:trim}<embed([^>]*)>{/dede:trim}
{dede:trim}</embed>{/dede:trim}
{dede:trim}<object([^>]*)>([^>]*)</object>{/dede:trim}
{dede:trim}<object([^>]*)>{/dede:trim}
{dede:trim}</object>{/dede:trim}
{dede:trim}<OBJECT([^>]*)>([^>]*)</OBJECT>{/dede:trim}
{dede:trim}<OBJECT([^>]*)>{/dede:trim}
{dede:trim}</OBJECT>{/dede:trim}
{dede:trim}<iframe([^>]*)>([^>]*)</iframe>{/dede:trim}
{dede:trim}<iframe([^>]*)>{/dede:trim}
{dede:trim}</iframe>{/dede:trim}
{dede:trim}<IFRAME([^>]*)>([^>]*)</IFRAME>{/dede:trim}
{dede:trim}<IFRAME([^>]*)>{/dede:trim}
{dede:trim}</IFRAME>{/dede:trim}
{dede:trim}<font([^>]*)>([^<]*)</font>{/dede:trim}
{dede:trim}<font([^>]*)>{/dede:trim}
{dede:trim}</font>{/dede:trim}
{dede:trim}<a([^>]*)>([^<]*)</a>{/dede:trim}
{dede:trim}<a([^>]*)>{/dede:trim}
{dede:trim}</a>{/dede:trim}
{dede:trim}<td([^>]*)>([^>]*)</td>{/dede:trim}
{dede:trim}<td([^>]*)>{/dede:trim}
{dede:trim}</td>{/dede:trim}
{dede:trim}<tr([^>]*)>([^>]*)</tr>{/dede:trim}
{dede:trim}<tr([^>]*)>{/dede:trim}
{dede:trim}</tr>{/dede:trim}
{dede:trim}<tbody([^>]*)>([^>]*)</tbody>{/dede:trim}
{dede:trim}<tbody>{/dede:trim}
{dede:trim}</tbody>{/dede:trim}
{dede:trim}<table([^>]*)>([^>]*)</table>{/dede:trim}
{dede:trim}<table([^>]*)>{/dede:trim}
{dede:trim}</table>{/dede:trim}
{dede:trim}<img([^>]*)>{/dede:trim}
{dede:trim}<span([^>]*)>{/dede:trim}
{dede:trim}</span>{/dede:trim}
{dede:trim} {/dede:trim}
{dede:trim}<stong>{/dede:trim}
{dede:trim}</stong>{/dede:trim}

应用示例一:标题中空格的过滤
经常在采集文章的时候,标题文字里面有空格,采回来后应用很是麻烦,所以需要在过滤处添加下面正则过滤

以下为引用的内容:
{dede:trim} {/dede:trim}

应用示例二:来源作者中连接的过滤
在采集文章的时候,有的系统里面作者或者来源处都有连接,直接采集的话将连接采集回来了,然后由于这两个字段有限制,通常会造成需要采集的内容没有采集回来,所以需要在过滤处添加下面正则过滤

以下为引用的内容:
{dede:trim}<a([^>]*)>([^<]*)</a>{/dede:trim}

应用示例三:文章内容中连接以及其他广告代码的过滤
这个就不用说了,当需要对所有东西过滤的时候,直接用上面所有的代码过滤就可以,但是实际应用中,我们只需要对连接、动画、调用等进行过滤。(这个需要按照对方内容里面具体含有什么代码来具体操作)
一般的只有链接,使用二中的代码进行过滤就可以了,但是实际上一般的网站现在都在内容里面加有广告等,所以采取下面的过滤正则就可以完成过滤:

以下为引用的内容:
{dede:trim}<a([^>]*)>([^<]*)</a>{/dede:trim}
{dede:trim}<IFRAME([^>]*)>([^>]*)</IFRAME>{/dede:trim}
{dede:trim}<object([^>]*)>([^>]*)</object>{/dede:trim}
{dede:trim}<script([^>]*)>([^>]*)</script>{/dede:trim}

应用示例四:过滤GG广告代码
其实这个就是在上面的内容过滤,但是很多论坛里的网友经常问这个,所以单独作为一个应用列出来:

以下为引用的内容:
{dede:trim}<script([^>]*)>([^>]*)</script>{/dede:trim}

好了,上面四种应用基本上涵盖了采集的各种应用,掌握了这个,过滤基本上就不用求人了!