php的Snoopy的类-采集必用

Snoopy是一个php类,用来模拟浏览器的功能,可以获取网页内容,发送表单。

Snoopy 正确运行需要你的服务器的 PHP 版本在 4 以上,并且支持 PCRE(Perl Compatible Regular Expressions),基本的 LAMP 服务都支持。
下载snoopy

Snoopy的一些特点:

1抓取网页的内容 fetch
2 抓取网页的文本内容 (去除HTML标签) fetchtext
3抓取网页的链接,表单 fetchlinks fetchform
4 支持代理主机
5支持基本的用户名/密码验证
6 支持设置 user_agent, referer(来路), cookies 和 header content(头文件)
7支持浏览器重定向,并能控制重定向深度
8能把网页中的链接扩展成高质量的url(默认)
9提交数据并且获取返回值
10 支持跟踪HTML框架
11支持重定向的时候传递cookies
要求php4以上就可以了 由于本身是php一个类 无需扩支持 服务器不支持curl时候的最好选择,

类方法:

fetch($URI)
———–

这是为了抓取网页的内容而使用的方法。
$URI参数是被抓取网页的URL地址。
抓取的结果被存储在 $this->results 中。
如果你正在抓取的是一个框架,Snoopy将会将每个框架追踪后存入数组中,然后存入 $this->results。

fetchtext($URI)
—————

本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中的文字内容。

fetchform($URI)
—————

本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中表单内容(form)。

fetchlinks($URI)
—————-

本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中链接(link)。
默认情况下,相对链接将自动补全,转换成完整的URL。

submit($URI,$formvars)
———————-

本方法向$URL指定的链接地址发送确认表单。$formvars是一个存储表单参数的数组。

submittext($URI,$formvars)
————————–

本方法类似于submit(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回登陆后网页中的文字内容。

submitlinks($URI)
—————-

本方法类似于submit(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中链接(link)。
默认情况下,相对链接将自动补全,转换成完整的URL。

类属性: (缺省值在括号里)

$host 连接的主机
$port 连接的端口
$proxy_host 使用的代理主机,如果有的话
$proxy_port 使用的代理主机端口,如果有的话
$agent 用户代理伪装 (Snoopy v0.1)
$referer 来路信息,如果有的话
$cookies cookies, 如果有的话
$rawheaders 其他的头信息, 如果有的话
$maxredirs 最大重定向次数, 0=不允许 (5)
$offsiteok whether or not to allow redirects off-site. (true)
$expandlinks 是否将链接都补全为完整地址 (true)
$user 认证用户名, 如果有的话
$pass 认证用户名, 如果有的话
$accept http 接受类型 (image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*)
$error 哪里报错, 如果有的话
$response_code 从服务器返回的响应代码
$headers 从服务器返回的头信息
$maxlength 最长返回数据长度
$read_timeout 读取操作超时 (requires PHP 4 Beta 4+)
设置为0为没有超时
$timed_out 如果一次读取操作超时了,本属性返回 true (requires PHP 4 Beta 4+)
$maxframes 允许追踪的框架最大数量
$status 抓取的http的状态
$temp_dir 网页服务器能够写入的临时文件目录 (/tmp)
$curl_path cURL binary 的目录, 如果没有cURL binary就设置为 false

以下是demo

include "Snoopy.class.php";  
$snoopy = new Snoopy;   

$snoopy->proxy_host = "www.baidu.com";  
$snoopy->proxy_port = "8080";   

$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";  
$snoopy->referer = "http://www.baidu.com/";   

$snoopy->cookies["SessionID"] = 238472834723489l;  
$snoopy->cookies["favoriteColor"] = "RED";   

$snoopy->rawheaders["Pragma"] = "no-cache";   

$snoopy->maxredirs = 2;  
$snoopy->offsiteok = false;  
$snoopy->expandlinks = false;   

$snoopy->user = "joe";  
$snoopy->pass = "bloe";   

if($snoopy->fetchtext("http://www.baidu.com"))  
{  
      echo "<PRE>".htmlspecialchars($snoopy->results)."</PRE>\n";<BR>  
}<BR>  
else<BR>  
     echo "error fetching document: ".$snoopy->error."\n";

snoopy采集phpchina示例

<?php
//采集phpchina
set_time_limit(0);
require_once("Snoopy.class.php");
$snoopy=new Snoopy();
//登陆论坛
$submit_url = "http://www.phpchina.com/bbs/logging.php?action=login";
$submit_vars["loginmode"] = "normal";
$submit_vars["styleid"] = "1";
$submit_vars["cookietime"] = "315360000";
$submit_vars["loginfield"] = "username";
$submit_vars["username"] = "***"; //你的用户名
$submit_vars["password"] = "*****"; //你的密码
$submit_vars["questionid"] = "0";
$submit_vars["answer"] = "";
$submit_vars["loginsubmit"] = "提 交";
$snoopy->submit($submit_url,$submit_vars);
if ($snoopy->results)
{
    //获取连接地址
    $snoopy->fetchlinks("http://www.phpchina.com/bbs");
    $url=array();
    $url=$snoopy->results;
    //print_r($url);
    foreach ($url as $key=>$value)
    {
        //匹配http://www.phpchina.com/bbs/forumdisplay.php?fid=156&sid=VfcqTR地址即论坛板块地址
        if (!preg_match("/^(http:\/\/www\.phpchina\.com\/bbs\/forumdisplay\.php\?fid=)[0-9]*&sid=[a-zA-Z]{6}/i",$value))
        {
            unset($url[$key]);
        }
    }
    //print_r($url);
    //获取到板块数组$url,循环访问,此处获取第一个模块第一页的数据
    $i=0;
    foreach ($url as $key=>$value)
    {
      
  if ($i>=1)
        {
            //测试限制
            break;
        }
        else
        {
            //访问该模块,提取帖子的连接地址,正式访问里需要提取帖子分页的数据,然后根据分页数据提取帖子数据
            $snoopy=new Snoopy();
            $snoopy->fetchlinks($value);
            $tie=array();
            $tie[$i]=$snoopy->results;
            //print_r($tie);
            //转换数组
            foreach ($tie[$i] as $key=>$value)
            {
                //匹配http://www.phpchina.com/bbs/viewthread.php?tid=68127&amp;extra=page%3D1&amp;page=1&sid=iBLZfK
                if (!preg_match("/^(http:\/\/www\.phpchina\.com\/bbs\/viewthread\.php\?tid=)[0-9]*&amp;extra=page\%3D1&amp;page=[0-9]*&sid=[a-zA-Z]{6}/i",$value))
                {
                    unset($tie[$i][$key]);
                }
            }
            //print_r($tie[$i]);
            //归类数组,将同一个帖子不同页面的内容放一个数组里
            $left=”;//连接左边公用地址
            $j=0;
            $page=array();
            foreach ($tie[$i] as $key=>$value)
            {
                $left=substr($value,0,52);
                $m=0;
                foreach ($tie[$i] as $pkey=>$pvalue)
                {
                    //重组数组
                    if (substr($pvalue,0,52)==$left)
                    {
                        $page[$j][$m]=$pvalue;
                        $m++;
                    }
                }
                $j++;
            }
            //去除重复项开始
            //$page=array_unique($page);只能用于一维数组
            $paget[0]=$page[0];
            $nums=count($page);
            for ($n=1;$n<$nums;$n++)
            {
                $paget[$n]=array_diff($page[$n],$page[$n-1]);
            }
            //去除多维数组重复值结束
            //去除数组空值
            unset($page);
            $page=array();//重新定义page数组
            $page=array_filter($paget);
            //print_r($page);
            $u=0;
            $title=array();
            $content=array();
            $temp=”;
            $tt=array();
            foreach ($page as $key=>$value)
            {
                //外围循环,针对一个帖子
                if (is_array($value))
                {
                    foreach ($value as $k1=>$v1)
                    {
                        //页内循环,针对一个帖子的N页
                        $snoopy=new Snoopy();
                        $snoopy->fetch($v1);
                        $temp=$snoopy->results;
                        //读取标题
  &n
bsp;                     if (!preg_match_all("/<h2>(.*)<\/h2>/i",$temp,$tt))
                        {
                            echo "no title";
                            exit;
                        }
                        else
                        {
                            $title[$u]=$tt[1][1];
                        }
                        unset($tt);
                        //读取内容
                        if (!preg_match_all("/<div id=\"postmessage_[0-9]{1,8}\" class=\"t_msgfont\">(.*)<\/div>/i",$temp,$tt))
                        {
                            print_r($tt);
                            echo "no content1";
                            exit;
                        }
                        else
                        {
                            foreach ($tt[1] as $c=>$c2)
                            {
                                $content[$u].=$c2;
                            }
                        }
                    }
                }
                else
                {
                    //直接取页内容
                    $snoopy=new Snoopy();
                    $snoopy->fetch($value);
                    $temp=$snoopy->results;
                    //读取标题
                    if (!preg_match_all("/<h2>(.*)<\/h2>/i",$temp,$tt))
                    {
                        echo "no title";
                        exit;
                    }
                    else
                    {
                        $title[$u]=$tt[1][1];
                    }
                    unset($tt);
                    //读取内容
                    if (!preg_match_all("/<div id=\"postmessage_[0-9]*\" class=\"t_msgfont\">(.*)<\/div>/i",$temp,$tt))
                    {
                        echo "no content2";
                        exit;
                    }
                    else
                    {
                        foreach ($tt[1] as $c=>$c2)
         &nb
sp;              {
                            $content[$u].=$c2;
                        }
                    }
                }
                $u++;
            }
            print_r($content);
        }
        $i++;
    }
}
else
{
    echo "login failed";
    exit;
}
?>

服务器 Register_Globals 关闭 会影响什么功能

_globals使用详解
register_globals是php.ini里的一个配置,这个配置影响到php如何接收传递过来的参数,如果你的问题是:为什么我的表单无法传递数据?为什么我的程序无法得到传递过来的变量?等等,那么你需要仔细的阅读以下的内容。

register_globals的值可以设置为:On或者Off,我们举一段代码来分别描述它们的不同。

代码:

<form name="frmTest" id="frmTest" action="URL">
<input type="text" name="user_name" id="user_name">
<input type="password" name="user_pass" id="user_pass">
<input type="submit" value="login">
</form>

 

当register_globals=Off的时候,下一个程序接收的时候应该用$_GET[‘user_name’]和$_GET[‘user_pass’]来接受传递过来的值。(注:当<form>的method属性为post的时候应该用$_POST[‘user_name’]和$_POST[‘user_pass’])

当register_globals=On的时候,下一个程序可以直接使用$user_name和$user_pass来接受值。

顾名思义,register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。所以,碰到上边那些无法得到值的问题的朋友应该首先检查一下你的register_globals的设置和你获取值的方法是否匹配。(查看可以用phpinfo()函数或者直接查看php.ini)

那我们为什么要使用Off呢?原因有2:
1、php以后的新版本默认都用Off,虽然你可以设置它为On,但是当你无法控制服务器的时候,你的代码的兼容性就成为一个大问题,所以,你最好从现在就开始用Off的风格开始编程
2、这里有两篇文章介绍为什么要Off而不用On
http://www.linuxforum.net/forum/gshowflat.php?Cat=&Board=php3&Number=292803&page=0&view=collapsed&sb=5&o=all&fpart=
http://www.php.net/manual/en/security.registerglobals.php

现在还有一个问题就是,以前用On风格写的大量脚本怎么办?
如果你以前的脚本规划得好,有个公共包含文件,比如config.inc.php一类的文件,在这个文件里加上以下的代码来模拟一下(这个代码不保证100%可以解决你的问题,因为我没有大量测试,但是我觉得效果不错)。

代码:

<?php
if ( !ini_get(‘register_globals’) )
{
extract($_POST);
extract($_GET);
extract($_SERVER);
extract($_FILES);
extract($_ENV);
extract($_COOKIE);

if ( isset($_SESSION) )
{
extract($_SESSION);
}
}
?>

register_globals = Off的情况不仅仅影响到如何获取从<form>、url传递过来的数据,也影响到session、cookie,对应的,得到session、cookie的方式应该为:$_SESSION[]、$_COOKIE。同时对于session的处理也有一些改变,比如,session_register()没有必要而且失效,具体的变化,请查看php manual里的Session handling functions

$_REQUEST中间的内容实际上还是来源于$_GET $_POST $_COOKIE,缺点是无法判断变量到底来自于get post 还是cookie,对要求比较严格的场合不适用。
php manual 写到:

Variables provided to the script via the GET, POST, and COOKIE input mechanisms, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the PHP variables_order configuration directive.

在PHP 4.2中,新安装的PHP中的register_globals选项默认为关闭,因此EGPCS值(EGPCS是Environment、Get、Post、Cookies、Server的缩写 — 这是PHP中外部变量来源的全部范围)不会被作为全局变量来创建。当然,这个选项还可以通过手工来开启,但是PHP的开发者推荐你将其关闭。要贯彻他们的意图,你需要使用其它的方法来获取这些值。
从PHP 4.1开始,EGPCS值就可以从一组指定的数组中获得:
$_ENV — 包含系统环境变量
$_GET — 包含查询字符串中的变量,以及提交方法为GET的表单中的变量
$_POST — 包含提交方式为POST的表单中的变量
$_COOKIE — 包含所有cookie变量
$_SERVER — 包含服务器变量,例如HTTP_USER_AGENT
$_REQUEST — 包含$_GET、$_POST和$_COOKIE的全部内容
$_SESSION — 包含所有已注册的session变量
在PHP 4.1之前,当开发者关闭register_globals选项(这也被考虑为提高PHP性能的一种方法)后,必须使用诸如$HTTP_GET_VARS这样的令人讨厌的名字来获取这些变量。这些新的变量名不仅仅短,而且它们还有其他优点。
首先,让我们在PHP 4.2中(也就是说关闭register_globals 选项)重写上面提到的代码:
<?php
$username = $_REQUEST[‘username’];
$password = $_REQUEST[‘password’];

// 检查用户名和口令
if ($username == ‘kevin’ and $password == ‘secret’)
$authorized = true;
?>
<?php if (!$authorized): ?>
<!– 未授权的用户将在这里给予提示 –>
<p>Please enter your username and password:</p>
<form action="<?=$PHP_SELF?>" method="POST">
<p>Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" /></p>
</form>
<?php else: ?>
<!– 有安全要求的HTML内容 –>
<?php endif; ?>
正如你看到的,我所需要做的只是在代码的开始增加下面两行:
$username = $_REQUEST[‘username’];
$password = $_REQUEST[‘password’];
因为我们希望用户名和密码是由用户提交的,所以我们从$_REQUEST数组中获取这些值。使用这个数组使得用户可以自由选择传递方式:通过URL查询字符串(例如允许用户创建书签时自动输入他们的证书)、通过一个提交的表单或者是通过一个cookie。如果你想要限制只能通过表单提交证书(更精确地说,是通过HTTP POST请求),你可以使用$_POST数组:
$username = $_POST[‘username’];
$password = $_POST[‘password’];
除了“引入”这两个变量以外,程序代码没有任何改变。简单地关闭register_globals选项促使开发者更进一步了解哪些数据是来自外部的(不可信任的)资源。
请注意这里还有一个小问题:PHP中默认的error_reporting设置仍然是E_ALL & ~E_NOTICE,因此如果“username”和“password”这两个值没有被提交,试图从$_REQUEST数组或$_POST数组中获得这两个值并不会招致任何错误信息。如晨不你的PHP程序需要严格的错误检查,你还需要增加一些代码以首先检查这些变量。

但是这是不是意味着更多的输入?

是的,在象上面这样的简单程序中,使用PHP 4.2常常会增加输入量。但是,还是看看光明的一面吧 — 你的程序终究是更安全了!
不过认真的说,PHP的设计者并没有完全忽视你的痛苦。在这些新数组中有一个特殊的其它所PHP变量都不具备的特征,它们是完全的全局变量。这对你有什么帮助呢?让我们先对我们的示例进行一下扩充。
为了使得站点中的多个页面可以使用用户名/口令论证,我们将我们用户认证程序写到一个include文件(protectme.php)中:
<
?php /* protectme.php */
function authorize_user($authuser, $authpass)
{
$username = $_POST[‘username’];
$password = $_POST[‘password’];
// 检查用户名和口令
if ($username != $authuser or $password != $authpass):
?>
<!– 未授权的用户将在这里给予提示 –>
<p>Please enter your username and password:</p>
<form action="<?=$PHP_SELF?>" method="POST">
<p>Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" /></p>
</form>
<?php
exit();
endif;
}
?>
现在,我们刚才的页面看上去将是这样的:
<?php
require(‘protectme.php’);
authorize_user(‘kevin’,’secret’);
?>
<!– 有安全要求的HTML内容 –>
很简单,很清晰明了,对不对?现在是考验你的眼力和经验的时候了 — 在authorize_user 函数中少了什么?
在函数中没有申明$_POST是一个全局变量!在php 4.0中,当register_globals开启时,你需要增加一行代码以在函数中获取$username和$password变量:
function authorize_user($authuser, $authpass)
{
global $username, $password;

在PHP中,和其它具有类似语法的语言不同,函数外的变量在函数中不能自动获得,你需要象上面所说明的那样增加一行以指定其来自global范围。
在PHP 4.0中,当关闭register_globals以提供安全性时,你可以使用$HTTP_POST_VARS数组以获得你的表单提交的值,但是你还是需要从全局范围导入这个数组:
function authorize_user($authuser, $authpass)
{
global $HTTP_POST_VARS;
$username = $HTTP_POST_VARS[‘username’];
$password = $HTTP_POST_VARS[‘password’];
但是在PHP 4.1及以后的版本中,特殊的$_POST变量(以及上面提到的其它变量)可以在所有范围内使用。这就是不需要在函数中申明$_POST变量是一个全局变量的原因:
function authorize_user($authuser, $authpass)
{
$username = $_POST[‘username’];
$password = $_POST[‘password’];

这对session有什么影响?

特殊的$_SESSION数组的引入实际上有助于简化session代码。你不需要将session变量申明为全局变量,然后再去留意哪些变量被注册了,你现在可以简单地从$_SESSION[‘varname’]中引用你所有的session变量。
现在让我们来看看另一个用户认证的例子。这一次,我们使用sessions以标志一个在你的网站继续逗留的用户已经经过了用户认证。首先,我们来看看PHP 4.0版本(开启register_globals):
<?php
session_start();
if ($username == ‘kevin’ and $password == ‘secret’)
{
$authorized = true;
session_register(‘authorized’);
}
?>
<?php if (!$authorized): ?>
<!– 显示HTML表单以提示用户登录 –>
<?php else: ?>
<!– 有安全要求的HTML内容 –>
<?php endif; ?>
和刚开始的程序一样,这个程序也存在安全漏洞,在URL的最后加上?authorized=1可以绕过安全措施直接访问页面内容。开发者可以将$authorized视为一个session变量而忽视了可以很容易地通过用户输入设置同样的变量。
当我们增加了我们的特殊的数组(PHP 4.1)并关闭register_globals(PHP 4.2)后,我们的程序将是这样的:
<?php
session_start();
if ($username == ‘kevin’ and $password == ‘secret’)
$_SESSION[‘authorized’] = true;
?>
<?php if (!$_SESSION[‘authorized’]): ?>
<!– 显示HTML表单以提示用户登录 –>
<?php else: ?>
<!– 有安全要求的HTML内容 –>
<?php endif; ?>
是不是更加简单了?你不再需要再将普通的变量注册为一个session变量,你只需要直接设置session变量(在$_SESSION数组中),然后用同样的方法使用它。程序变得更短了,而且对于什么变量是session变量也不会引起混乱!

总结

在这篇文章中,我解释了PHP脚本语言作出改变的深层原因。在PHP 4.1中,添加了一组特殊数据以访问外部数据。这些数组可以在任何范围内调用,这使得外部数据的访问更方便。在PHP 4.2中,register_globals被默认关闭以鼓励使用这些数组以避免无经验的开发者编写出不安全的PHP代码。

网站的目录结构优化

除垃圾站之外,很少有网站只由单页面组成,当涉及到多个尤其是成千上万页面时,往往就需要有个清晰的网站结构,来确保搜索引擎和用户的访问,网站的目录结构就起到这样的作用,它在SEO中意义非凡。

  1,什么是网站的目录结构

  网站的目录是指你建立网站时所创建的目录,目录结构则主要是指物理结构和逻辑结构这两种。

  具体的说,网站物理结构指的是网站目录及所包含文件所存储的真实位置所表现出来的结构。对于小型网站来说,所有网页都存在网站根目录下的扁平式结构,这种单一的目录的扁平结构对搜索引擎而言是最为理想的,因为只要一次访问即可遍历。但是如果太多文件都放在根目录下的话,维护起来就显得相当麻烦;而对规模大一些的网站,往往需要二到三层甚至更多层级子目录才能保证文件内容页的正常存储,这种多层级目录也叫做树型结构,即根目录下再细分成多个频道或目录,然后在每一个目录下面再存储属于这个目录的终极内容网页,这样的好处是维护容易,但是搜索引擎的抓取将会显得困难些。

  与网站的物理结构不同,网站的逻辑结构也叫链接结构,主要是指由网页内部链接所形成的逻辑结构或者叫链接的结构。这在现在的一部分CMS建站系统中已经可以实现文件虽然存在不同的物理结构目录之中,但是访问的链接的目录层级只需要一层即可转向访问。

  2,网站的目录结构对SEO的影响

  网站的目录结构的层级对SEO的影响很大。网站的目录层级不要太深,目录结构越简单,搜索引擎访问就越容易,目录结构层级越深,搜索引擎爬虫就越不容易抓取。

  这个很简单的道理,有人说了个绝妙的比喻,就比如你急着上厕所的时候,总不会穿街走巷绕圈去,而总会优先考虑就近的厕所。囧!再举个例子,“酒香也怕巷子深”,再好的内容页,如果隐藏在太深的目录层级之下,搜索引擎也是要望洋兴叹,徒叹奈何!

  3,如何优化网站结构

  目录的结构往往容易被普通网站长所忽略,其实目录结构的好坏,对站点的SEO有着重要的影响。网站内部结构优化也是整个优化过程中非常重要的一个环节。那么,作为SEO,怎么去优化网站的结构呢?我想,优化网站结构应该主要涉及到物理结构和逻辑结构这两个方面。

  首先,优化网站的物理结构目录。一般说来,我们不提倡将将所有文件都存放在根目录下,而鼓励按栏目内容建立子目录,并且尽量使用意义明确的目录名称,比如image,css,js,post,bbs等等名称,但是注意不要使用中文名称,尤其是针对英文的SEO优化更应该使用中文目录,目录名称也不宜太过冗长,URL应该越短越好。举个例子,我们没有必要将seo这个目录改成sousuoyinqingyouhua,因为搜索引擎看得懂seo这个词。目录和文件命名可以适当使用到关键词,如果是关键词组,需要用分隔符分开的话,我们常用连字符“-”进行分隔。

  最为重要的是,网站的目录层级一般建议不要超过3层!——这是我们在SEO的过程对网站的物理结构目录最大的一个优化。这个优化如果不计SEO,其实还有很多其他的好处,比如较少层级的目录容易传播、用户体验和交换链接等等。

  当然,这并不是绝对的。不管内容页所处的目录层级有多深,只要该页有一个或者大量来自其它网站的外部链接,它同样会被搜索引擎收录;如果我们在首页上增加一个该页的链接,那么其实就相当于二次点击即可访问到该页,再深的巷子如果通了条火车,同样也会顾客盈门,因此链接是被搜索引擎收录的关键。对一个站点中包含的子目录,只要链向该层子目录的链接提供有搜索引擎能够跟进的导航配置和URL结构,那么所有的搜索引擎都会对子目录提供遍历。做好导航结构,将会有效控制多层目录结构对SEO造成的不利影响。

  其次,对网站的逻辑结构的优化也应该同样重视。一般来讲,首页的PR值最高,二级目录次之,最终内容页面再次之,因此为使这些页面更有效地展示出来,就要尽量减少PR流失,所以目录结构不要太深,三级已经足够,并且所有的链接应该能够做到相互回环,目录的逻辑结构也要尽量要做到符合“面包屑导航”效用。使得搜索引擎只要抓取了一个页面,就可以顺着这个页面抓取更多乃至整个站点的所有页面。另外,要注意,如果网站调整,网页目录结构改变,网页被移到一个新地址等改变网页目录结构的时候,我们都应该充分考虑到SEO,尽可能采用301重定向到新的页面,以免网站出现死链、断链、错链等问题。

  4,网站目录结构在SEO排名中的具体应用方法

  独孤天骄前面讲到,网站的目录结构的层级对SEO的影响很大,目录结构越简单,搜索引擎访问就越容易。对百度而言,它给予网站的域名、目录和页面的权重是不一样的。当参与关键词排名竞争的时候,域名级的链接在百度是最具排名优势的,目录级其次,页面级则最低。因此,当我们所关心的关键词,排名前十的大多数是页面级的站点在竞争,那我们就可以在网站之下建立一个目录来参与竞争;如果前十名都是目录级,那我们就需要用域名级来争取排名;如果前十名都是域名级,那你就要拼网站的权重和质量了。

  在这里,我们还要解决一个疑问:二级域名与二级目录,即子域名和子目录,二者到底那个目录结构更容易被收录呢?

  一般来说,二级目录的权重增加,可以提高主域名的权重,主域名的权重增加,也能带动二级目录的权重。二级目录是依靠着主域名权重,主域名收录完好,直接能加快二级目录收录;相比二级域名,二级域名在搜索引擎中相当独立的网站,单就URL来看,二级域名比一级目录天生的信任度稍微高一点,但是收录中可能要比二级目录稍慢些。

  如果你的网站类别不是很多,建议采用二级目录的形式,这样更有利于主打品牌的推广和提高网站权重。如果你是个类别比较多,内容比较丰富的网站,建议你采用二级域名的形式。

防止网页被框架显示

在做网页广告时,避免别人用irame嵌套后隐藏起来而白白损失广告费,可以用下面代码强制弹出。
1、把这段代码放到head之间

<SCRIPT LANGUAGE=JAVASCRIPT>
if (top.location !== self.location) {
top.location=self.location;
}
</SCRIPT>

2、这种方法比较好,一旦发现别人框架iframe了你的网页,他就自动跳转到你的网站上来了。

把下面代码放到head之间

<SCRIPT LANGUAGE=JAVASCRIPT>
var url=window.location.href;
if(window!=parent)
parent.navigate(url);
</SCRIPT>

大家伙敢快试试吧 :)

DIV+CSS命名规范

内容:content/container                                         导航:nav

侧栏:sidebar                                                          栏目:column

标志:logo                                                                页面主体:main

广告:banner                                                           热点:hot

新闻:news                                                              下载:download

子导航:subnav                                                       菜单:menu

搜索:search                                                           页脚:footer

滚动:scroll                                                             版权:copyright

友情链接:friendlink                                              子菜单:submenu

标签页:tab                                                            文章列表:list

注册:regsiter                                                        提示信息:msg

小技巧:tips                                                          加入:joinus

栏目标题:title                                                      指南:guild

服务:service                                                      状态:status

投票:vote                                                           合作伙伴:partner

登录条:loginbar

页面外围控制整全布局宽度:wrapper左右中:left right center

导航:nav                                                           主导航:mainnav

子导航:subnav                                               顶导航:topnav

边导航:sidebar                                              左导航:leftsidebar

右导航:rightsidebar                                       标题:title

摘要:summary                                              功能区:shop

当前的:current                                              注释:note

服务:service                                                  投票:vote

 

相聚2009.8.15北京草根站长大会

今天去参加了北京的草根站长大会,在左岸工社,就是中关村图书馆大厦上面,场面虽然有点小,但高手云集呀,几个推广牛人都到场了。

GJJ在讲网站推广与盈利

虚无座席呀

互动提问环节

经常丰富的前辈们,讲述他们的推广与盈利之道。

SupeSite7.0跟其他应用同步登录的设置方法

本教程讲解 UCenter 下 SupeSite7.0 和其他应用的同步登录设置。

如果您使用的是未安装 UCenter 版本的 SupeSite ,请参考:

如果通信不成功,请参考:

注意:须将 SupeSite7.0 和 Discuz!7.0 两个应用都开启该设置。

然后,更新缓存。

上述两点都设置成功后,一般实现同步登录就没问题。如果还是有问题,请看第三点:

3、设置 SupeSite7.0 和 Discuz!7.0 根目录下 config 文件的 cookie

1)$cookiepre 任意设置,各个应用中的 $cookiepre 不要相同。

2)$cookiesdomain 保持一致,如果是不同根域名,默认为空即可。

3)如果是 SupeSite7.0 和 Discuz!7.0 程序是在根目录,“$cookiepath=’/’;” 就不用改动,如果在子目录比如 supesite ,则可以设置为:"$cookiepath=’/supesite/’;" 。

来源:http://faq.comsenz.com/viewnews-589

PHP实例教程(4):构建基于PHP的微博客服务

添加其他用户?贴子

要将其他用户的贴子添加到一个用户的时间表(timeline)上,只需重用之前编写的一些代码。例如,现在已经知道如何获得当前用户正在追随的用户的列表。也知道如何获得某个用户发出的所有贴子。因此只需稍微修改后一个函数,使之能够接受一个用户列表,而不是单个用户。

现在只需在 index.php 文件中将第一个函数上移一点,以便马上使用它,然后使用通过该函数获得的用户 ID 列表,从他们的时间表中获取一定数量的贴子 — 这里不需要所有的贴子,只需 5 个左右。记住,要按日期倒序(最近的在上)排列那些用户的贴子。

首先,为 show_posts() 函数增加一个 limit 参数,将它的值默认为 0。如果 limit 大于 0,则将一个限制值添加到用于检索贴子的 SQL 语句中。另外要做的是将 $userid 参数放入到一个数组中,并将该数组解析到一个以逗号分隔的字段中,最后将该字段传递给 SQL 语句。这需要做一点额外工作,但是可以获得丰厚的回报,因为如您所见,所有贴子都将以倒序显示。

清单 18. 更新 show_posts(),以接受一个用户数组

				
function show_posts($userid,$limit=0){
$posts = array();

$user_string = implode(',', $userid);
$extra = " and id in ($user_string)";

if ($limit > 0){
$extra = "limit $limit";
}else{
$extra = '';
}

$sql = "select user_id,body, stamp from posts
where user_id in ($user_string)
order by stamp desc $extra";
echo $sql;
$result = mysql_query($sql);

while($data = mysql_fetch_object($result)){
$posts[] = array( 'stamp' => $data->stamp,
'userid' => $data->user_id,
'body' => $data->body
);
}
return $posts;

}

 

现在回到 index.php 文件,将不止一个用户 ID 传递给 show_posts(),如下面的清单所示。这其实很简单,因为已经收集到了这些用户。现在只需使用 array_keys() 取出键值,将会话变量加到数组中。这样,传递的数组最少包含一个值(已登录的当前用户的 ID),最多则包含当前用户 ID 和该用户追随的每个用户的 ID。

清单 19. 将一个用户数组传递给 show_posts() 函数

				
$users = show_users(

添加其他用户?贴子

要将其他用户的贴子添加到一个用户的时间表(timeline)上,只需重用之前编写的一些代码。例如,现在已经知道如何获得当前用户正在追随的用户的列表。也知道如何获得某个用户发出的所有贴子。因此只需稍微修改后一个函数,使之能够接受一个用户列表,而不是单个用户。

现在只需在 index.php 文件中将第一个函数上移一点,以便马上使用它,然后使用通过该函数获得的用户 ID 列表,从他们的时间表中获取一定数量的贴子 — 这里不需要所有的贴子,只需 5 个左右。记住,要按日期倒序(最近的在上)排列那些用户的贴子。

首先,为 show_posts() 函数增加一个 limit 参数,将它的值默认为 0。如果 limit 大于 0,则将一个限制值添加到用于检索贴子的 SQL 语句中。另外要做的是将 $userid 参数放入到一个数组中,并将该数组解析到一个以逗号分隔的字段中,最后将该字段传递给 SQL 语句。这需要做一点额外工作,但是可以获得丰厚的回报,因为如您所见,所有贴子都将以倒序显示。


清单 18. 更新 show_posts(),以接受一个用户数组
				
function show_posts($userid,$limit=0){
$posts = array();

$user_string = implode(',', $userid);
$extra = " and id in ($user_string)";

if ($limit > 0){
$extra = "limit $limit";
}else{
$extra = '';
}

$sql = "select user_id,body, stamp from posts
where user_id in ($user_string)
order by stamp desc $extra";
echo $sql;
$result = mysql_query($sql);

while($data = mysql_fetch_object($result)){
$posts[] = array( 'stamp' => $data->stamp,
'userid' => $data->user_id,
'body' => $data->body
);
}
return $posts;

}

现在回到 index.php 文件,将不止一个用户 ID 传递给 show_posts(),如下面的清单所示。这其实很简单,因为已经收集到了这些用户。现在只需使用 array_keys() 取出键值,将会话变量加到数组中。这样,传递的数组最少包含一个值(已登录的当前用户的 ID),最多则包含当前用户 ID 和该用户追随的每个用户的 ID。

清单 19. 将一个用户数组传递给 show_posts() 函数

___FCKpd___1

 

结束语

在本文中,您学习了如何构建一个简单的基于 PHP 的微博客服务,该服务类似于 Twitter 和 Facebook 状态更新工具。如果一切顺利的话,您就可以得到现在这样的成果,并将它添加到您的应用程序中,并根据需要加以定制。

SESSION['userid']);
if (count($users)){
$myusers = array_keys($users);
}else{
$myusers = array();
}
$myusers[] =

添加其他用户?贴子

要将其他用户的贴子添加到一个用户的时间表(timeline)上,只需重用之前编写的一些代码。例如,现在已经知道如何获得当前用户正在追随的用户的列表。也知道如何获得某个用户发出的所有贴子。因此只需稍微修改后一个函数,使之能够接受一个用户列表,而不是单个用户。

现在只需在 index
.php 文件中将第一个函数上移一点,以便马上使用它,然后使用通过该函数获得的用户 ID 列表,从他们的时间表中获取一定数量的贴子 — 这里不需要所有的贴子,只需 5 个左右。记住,要按日期倒序(最近的在上)排列那些用户的贴子。

首先,为 show_posts() 函数增加一个 limit 参数,将它的值默认为 0。如果 limit 大于 0,则将一个限制值添加到用于检索贴子的 SQL 语句中。另外要做的是将 $userid 参数放入到一个数组中,并将该数组解析到一个以逗号分隔的字段中,最后将该字段传递给 SQL 语句。这需要做一点额外工作,但是可以获得丰厚的回报,因为如您所见,所有贴子都将以倒序显示。

清单 18. 更新 show_posts(),以接受一个用户数组

				
function show_posts($userid,$limit=0){
$posts = array();

$user_string = implode(',', $userid);
$extra = " and id in ($user_string)";

if ($limit > 0){
$extra = "limit $limit";
}else{
$extra = '';
}

$sql = "select user_id,body, stamp from posts
where user_id in ($user_string)
order by stamp desc $extra";
echo $sql;
$result = mysql_query($sql);

while($data = mysql_fetch_object($result)){
$posts[] = array( 'stamp' => $data->stamp,
'userid' => $data->user_id,
'body' => $data->body
);
}
return $posts;

}

现在回到 index.php 文件,将不止一个用户 ID 传递给 show_posts(),如下面的清单所示。这其实很简单,因为已经收集到了这些用户。现在只需使用 array_keys() 取出键值,将会话变量加到数组中。这样,传递的数组最少包含一个值(已登录的当前用户的 ID),最多则包含当前用户 ID 和该用户追随的每个用户的 ID。

清单 19. 将一个用户数组传递给 show_posts() 函数

___FCKpd___1

 

结束语

在本文中,您学习了如何构建一个简单的基于 PHP 的微博客服务,该服务类似于 Twitter 和 Facebook 状态更新工具。如果一切顺利的话,您就可以得到现在这样的成果,并将它添加到您的应用程序中,并根据需要加以定制。

SESSION['userid'];

$posts = show_posts($myusers,5);


 

 

结束语

在本文中,您学习了如何构建一个简单的基于 PHP 的微博客服务,该服务类似于 Twitter 和 Facebook 状态更新工具。如果一切顺利的话,您就可以得到现在这样的成果,并将它添加到您的应用程序中,并根据需要加以定制。

PHP实例教程(1):构建基于PHP的微博客服务

如果您曾经留意过,就会知道 Twitter 是 Web 2.0 世界最大的轰动事件之一。简单来说,Twitter(Twitter.com 上提供的一个服务)是一个简单的微博客服务,用户可以发最多 140 个字符的贴子(称作 tweet),回答 “你现在在做什么?” 之类的问题。用户可以追随他们感兴趣的人,也有自己的追随者。通过这种方式,可以将信息发布给追随者或是广泛地转发。

随意浏览一下某个 Twitter 账户可以发现,用户常常发布关于很多不同话题的 tweet,从日常生活(例如 “我在吃三明治”)到更不平凡的话题。其中常常嵌入了图像、媒体文件和日志的链接。这些 URL 常常被 TinyURL 之类的服务缩短,主要是为了使贴子的总字符数不超过 140 个字符。

很多人喜欢上了 Twitter,使超短格式成了一种艺术形式,甚至将之用于与其他用户交谈(例如将他们的评论定向到 @user)。从这个简单的起点开始,涌现了大量支持 Twitter 的移动应用程序和其他工具。现在甚至还有专门为最有趣、最卓越和最详实的 tweet 而设置的奖项,另外还有跟踪不同 Twitter 应用程序的状态的在线应用程序。

很多其他站点和服务,例如 LinkedIn 和 Facebook 现在允许用户用仿照 Twitter 的方式更新他们的当前状态。换句话说,在 Facebook 更新状态需要使用短消息,当然,状态通常是回答 “你现在在干什么” 之类的问题。

为您自己的站点添加微博客或状态更新工具不需要做很多工作,但是却可以为用户带来乐趣和简单的交流方式。本文的目标是展示如何实现这个目的。但是,首先需要对您作一些假设。

首先,假设您对 PHP 和 MySQL 有所了解。同时假设您可以访问某个运行 PHP 和 MySQL 的本地 Apache Web 服务器。对于本文,我在使用 Macintosh、Apache、MySQL 和 PHP(MAMP)的 MacBook Products 上进行开发,这个免费程序将整个开发环境打包到一个包中。但是,您应该能够毫无困难地在 Microsoft® Windows® 或 Linux® 上进行开发。最后,假设您已经有一个可以立即运行的应用程序,该应用程序现在有一些用户,您打算以某种方式将微博客或 tweeting 添加到该应用程序中。为此,我简化应用程序中侧重用户的一些方面(例如登录、管理个人文件等),而侧重于贴子。

设计应用程序的后端

简言之,Twitter 服务以两个名词为中心:用户和消息。如果您已经构建了一个应用程序,并且希望将类似 Twitter 的服务添加到应用程序中,那么很可能已经有了用户管理功能。如果还没有,那么需要采用某种方式使用一个数据库表(一个主键,通常是一个整数)、一个用户名(也是惟一的)、一个电子邮件地址和密码等标识每个用户。

tweet(即贴子)存储在一个 posts 表中,每个贴子有一个主键(某种连续整数)、一个指向发出该贴的用户的外键关系、贴子本身(限制为一定数量的字符)和日期/时间戳。

最容易令人感到迷惑的是显示用户追随关系的数据库表。这里需要某种方式记录用户 ID 和追随者 ID,使应用程序能够快速建立追随者列表,并轻松地将信息转发给那些已注册为要追随某用户的其他用户。

理解这些内容后,现在就可以着手建立这 3 个数据库表。使用清单 1 中的 SQL 代码创建第一个表,即 users 表(如果已经有一个 users 表,则可以跳过这一步)。

清单 1. users 表

				
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 255 ) NOT NULL ,
`email` VARCHAR( 255 ) NOT NULL ,
`password` VARCHAR( 8 ) NOT NULL ,
`status` ENUM( 'active', 'inactive' ) NOT NULL
) ENGINE = MYISAM ;

 

下面是第二个表,即 posts 表。

清单 2. posts 表

				
CREATE TABLE `posts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`body` VARCHAR( 140 ) NOT NULL ,
`stamp` DATETIME NOT NULL
) ENGINE = MYISAM ;

 

清单 3 显示了最后一个表,即 following 表。注意这个表有两个主键。

清单 3. following 表

				
CREATE TABLE `following` (
`user_id` INT NOT NULL ,
`follower_id` INT NOT NULL ,
PRIMARY KEY ( `user_id` , `follower_id` )
) ENGINE = MYISAM ;

 

然后,先创建一个名为 header.php 的文件,将所有用于 MySQL 的连接字符串放到该文件中。如果已经有一个这样的文件,可以跳过这一步。请务必在各处都包括这个文件,因为将来需要用到它。清单 4 展示了这个文件的内容。

清单 4. 样例 header.php 文件

				
$SERVER = 'localhost';
$USER = 'username';
$PASS = 'password';
$DATABASE = 'microblogger';


if (!($mylink = mysql_connect( $SERVER, $USER, $PASS))){
echo "<h3>Sorry, could not connect to database.</h3><br/>
Please contact your system's admin for more help\n";
exit;
}

mysql_select_db( $DATABASE );

 

请记住,还可以随意将任何其他类型的安全检查添加到这个 header.php 文件中。例如,可以检查一个会话变量中是否设置了一个用户 ID(表明该用户已经登录)。如果用户没有登录,那么可以将用户重定向到登录页面。本文不会深入讨论这一点,不过需要时可以很容易地添加安全检查。

session问题集锦

session问题集锦

  对于PHP的session功能,始终找不到合适的答案,尤其是一些错误,还有一些没有错误的结果,最可怕的就是后者,一直为许多的初学者为难。就连有些老手,有时都被搞得莫名其妙。本文,将这些问题,做一个简单的汇总,以便大家查阅。

1.
错误提示
Warning: Cannot send session cookie – headers already sent
Warning: Cannot send session cache limiter – headers already sent
分析及解决办法
这一类问题,的原因是你在程序中使用session_start()时,之前已经有实际的html内容输出了。或许你说,我没有啊,我只不过是echo或print一条消息了。很抱歉,你的echo或print语句所产生的输出,就是实际的html内容输出。解决此类问题的办法是,将你的session_start()调到程序的第一行。

2.
错误提示
Warning: open(F:/689phpsessiondatasess_66a39376b873f4daecf239891edc98b5, O_RDWR) failed
分析及解决方法
出现这样的错误语句一般是因为你的php.ini中关于session.save_path一项没有设置好,解决的方法是将session.save_path和session.cookie_path 设置置为
session_save_path = c: emp
session.cookie_path = c: emp
然后在c:目录下建立一个temp目录,即可

3.
错误提示
Warning: Trying to destroy uninitialized session in
分析及解决方法
出类这样的提示,一般情况都是你直接调session_destroy()函数造成的。很多的朋友认为session_destroy()函数可以独立的运行,其实不然。解决的方法是在你调session_destroy()函数之前,要用session_start()开启session的功能。

4.问题:怎么获得当前session的id值呢?
最简单的方法是:
echo SID;
你会发现的。

5.问题:我的程序,在调用header函数之前没有任何的输出,虽然我include了一个config.php文件,但在config.php文件中也没有任何的输出,为什么session还是会报出与问题1同样的错误呢,是不是因为我在header之前用了session_start()的缘故呢?
答:或许你确实认真的检查了你的php程序,在引用header()之前确实也没有任何的输出,并且在你的include文件中也没有任何的输出!但是你是否用光标键在?>这个PHP代码结束语句后移动检查呢?那么你会发现在?>这个后面,有一个空行或几个空格,你删除了这几个空行或空格,那么问题就解决了。
注:此问题,会出PHP4.1.2中,更高版本,没有测试过。

6.问:用session做登录主页面后,其它页面怎么用session限制登录。。。
答:最简单的方法是
session_start();
if(!session_registered(&apos;login&apos;) ││ $login != true) {
echo "你没有登陆";
exit;
}

7.问:我用session_register()注册了session变量,可是当我用header或用javascript的重定向语句,那么在一下页面中,我却访问不到session所注册的变量值。请问如何解决?
问题的程序片段:
session_start();
$ok = &apos;love you&apos;;
session_register(&apos;ok&apos;);
header("location : next.php");
?>

next.php
session_start();
echo $ok;
?>

解决的方法:
当你用header函数或window.location这样的功能后,你上一个页面所注册的session变量,就会容易的丢失,关于这个问题的原因,至今仍没有一个详细的回答。
不过有解决的方法。如下所示
header("Location: next.php" ."?" . SID);
在跳转到下一页面的时候,将session的当前id做为一个参数,传到后一个页面。

8.session如何传数组
session_register(&apos;data&apos;);
$data=array(1,2,3,4);

方法是先注册后赋值

9.问题9:我是不是可以用像$HTTP_GET_VARS[&apos;**&apos;]方式来访问session值呢?

回答:可以,你可以使用如下global数组来访问session,以加强网页的安全性
$HTTP_SESSION_VARS
$_SESSION
例程:
session_start();
$username = &apos;stangly.wrong&apos;;
session_register(&apos;username&apos;);

echo $HTTP_SESSION_VARS[&apos;username&apos;];
echo &apos;
&apos;;
echo $_SESSION[&apos;username&apos;];
?>
请参照此例程修改符合您自己的程序。

问题10:session_unregister() 和 session_destroy() 有何区别?
session_unregister()函数主要作用是注消当前的一sion.(译自于php.net)

例程:
if(isset($_COOKIE[session_name()])) {
session_start();
session_destroy();
unset($_COOKIE[session_name()]);
}

以上,所述是一些新手经常遇到的问题。或许是详述不清,难免有误所在,请高手指点批评。

php中的session的配置

今天调试程序遇到了session的设置问题,网上这篇文章比较好,共拿来学习,并供大家参考。
转载自旅行论坛 http://www/lvxing.net

首先打开php.ini文件,找到session的部分:(分号后面的是注释)

[Session]
; Handler used to store/retrieve data.
session.save_handler = files   ;    这个是session的方式,默认的files就可以了,代表用文件储存

; Argument passed to save_handler.  In the case of files, this is the path  where data files are stored.
session.save_path = /tmp ;      这个是session的保存路径,比如你是c盘,那么默认就是c:/tmp, 所以如果出现“Warning: open(/tmpsess_cc8b04f146a1e0494bc464305da92ea1, O_RDWR)  failed”这样子的错误,你可以修改这个路径,或者在根目录下面建立一个tmp的文件夹

; Whether to use cookies.
session.use_cookies = 1 ;    sessionid的传递方式,默认是cookie,推荐使用

; Name of the session (used as cookie name).
session.name = PHPSESSID ;    sessionid的名称,保存在cookie里面的,要避免同名

; Initialize session on request startup.
session.auto_start = 0 ;    是否自动启动session,默认为不是,不需要修改

; Lifetime in seconds of cookie or, if 0, until browser is restarted.
session.cookie_lifetime = 0 ;    sessionid的cookie生存时间,0代表知道浏览器关闭

; The path for which the cookie is valid.
session.cookie_path = / ;    sessionid的cookie路径,不需要修改

; The domain for which the cookie is valid.
session.cookie_domain = ;    ;sessionid的cookie域名,不需要修改

; Handler used to serialize data.  php is the standard serializer of PHP.
session.serialize_handler = php ;    保存data的默认文件名后缀,不需要修改

; Percentual probability that the &apos;garbage collection&apos; process is started  on every session initialization.
session.gc_probability = 1

; After this number of seconds, stored data will be seen as &apos;garbage&apos; and  cleaned up by the garbage collection process.
session.gc_maxlifetime = 1440 ;    session文件的保存时间

; Check HTTP Referer to invalidate externally stored URLs containing ids.
session.referer_check = ; How many bytes to read from the file.
session.entropy_length = 0 ; Specified here to create the session id.
session.entropy_file = ;session.entropy_length = 16 ;session.entropy_file = /dev/urandom

; Set to {nocache,private,public} to determine HTTP caching aspects.
session.cache_limiter = nocache ; Document expires after n minutes.
sessio
n.cache_expire = 180 ; use transient sid support if enabled by compiling with –enable-trans-sid.
session.use_trans_sid = 1 url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ======================================================================
session 的生命周期是多长 

1 浏览器结束时其生命周期也同时结束,但是档案仍然存在于 /tmp/(sess_???)
2 下次重新开浏览器时会重新分配 sessionID,如果你使用 session_id() 把以前的 ID 带回来,
则会去读取残存在 /tmp 处的 sess_???, 取回你之前所有已经设定的参数
3 可以在 php.ini 里修改 session 档案残存的时间 session.gc_maxlifetime = 1440 ; after this number of seconds, stored
; data will be seen as &apos;garbage&apos; and
; cleaned up by the gc process 默认是 1440 秒,24分钟
=========================================================================

使用无限生命期Session的方法
   在PHP4.0中加入了对Session的支持,方便了我们很多程序,比如购物车等等!
   在很多论坛中,Session也用于处理用户的登陆,记录下用户名和密码,使得用户不必每次都输入自己的用户名和密码!但是一般的Session的生命期有限,如果用户关闭了浏览器,就不能保存Session的变量了!那么怎么样可以实现Session的永久生命期呢?
   大家知道,Session储存在服务器端,根据客户端提供的SessionID来得到这个用户的文件,然后读取文件,取得变量的值,SessionID可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取Session的目录……
   
   要实现Session的永久生命期,首先需要了解一下php.ini关于Session的相关设置(打开php.ini文件,在“[Session]”部分):
   1、session.use_cookies:默认的值是“1”,代表SessionID使用Cookie来传递,反之就是使用Query_String来传递;
   2、session.name:这个就是SessionID储存的变量名称,可能是Cookie,也可能是Query_String来传递,默认值“PHPSESSID”;
   3、session.cookie_lifetime:这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以Session不能永久使用!
   4、session.gc_maxlifetime:这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除!
   还有很多的设置,不过和本文相关的就是这些了,下面开始讲使用永久Session的原理和步骤。
   
   前面说过,服务器通过SessionID来读取Session的数据,但是一般浏览器传送的SessionID在浏览器关闭后就没有了,那么我们只需要人为的设置SessionID并且保存下来,不就可以……
   如果你拥有服务器的操作权限,那么设置这个非常非常的简单,只是需要进行如下的步骤:
   1、把“session.use_cookies”设置为1,打开Cookie储存SessionID,不过默认就是1,一般不用修改;
   2、把“session.cookie_lifetime”改为正无穷(当然没有正无穷的参数,不过999999999和正无穷也没有什么区别);
   3、把“session.gc_maxlifetime”设置为和“session.cookie_lifetime”一样的时间;
   设置完毕后,打开编辑器,输入如下的代码:
————————————————————————————

<?php  session_start();
session_register(&apos;count&apos;);
$count++;
echo $count;
?>
————————————————————————————
   然后保存为“session_check.php”,用浏览器打开“session_check.php”,看看显示的是不是“1”,再关闭浏览器,然后再打开浏览器访问“session_check.php”,如果显示“2”,那么恭喜了,你已经成功;如果失败的话,请检查你前面的设置。
   
   但是如果你没有服务器的操作权限,那就比较麻烦了,你需要通过PHP程序改写SessionID来实现永久的Session数据保存。查查php.net的函数手册,可以见到有“session_id”这个函数:如果没有设置参数,那么将返回当前的SessionID,如果设置了参数,就会将当前的SessionID设置为给出的值……
   只要利用永久性的Cookie加上“session_id”函数,就可以实现永久Session数据保存了!
   但是为了方便,我们需要知道服务器设置的“session.name”,但是一般用户都没有权限查看服务器的php.ini设置,不过PHP提供了一个非常好的函数“phpinfo”,利用这个可以查看几乎所有的PHP信息!
————————————————————————————

————————————————————————————
   打开编辑器,输入上面的代码,然后在浏览器中运行这个程序,会见到PHP的相关信息(如图1所示)。其中有一项“session.name”的参数(图中已经标出),这个就是我们需要的服务器“session.name”,一般是“PHPSESSID”。
   记下了SessionID的名称后,我们就可以实现永久的Session数据储存了!
   打开编辑器,输入下面的代码:
————————————————————————————
session_start();  // 启动Session
session_register(&apos;count&apos;);  // 注册Session变量Count
if(isset($PHPSESSID)) {
   session_id($PHPSESSID);
}  // 如果设置了$PHPSESSID,就将SessionID赋值为$PHPSESSID,否则生成SessionID
$PHPSESSID = session_id();  // 取得当前的SessionID
$count++;  // 变量count加1
setcookie(&apos;PHPSESSID&apos;, $PHPSESSID, time()+3156000);  // 储存SessionID到Cookie中
echo $count;  // 显示Session变量count的值
?>
————————————————————————————

 保存之后,利用和刚才拥有服务器权限时候的检测一样的方法,检测是否成功的保存了SessionID。
后记:
   其实真正的永久储存是不可能的,因为Cookie的保存时间有限,而服务器的空间也有限……
但是对于一些需要保存时间比较长的站点,以上方法就已经足够了!