session_cache_expire() returns the current setting of session.cache_expire. The value returned should be read in minutes, defaults to 180. If new_cache_expire is given, the current cache expire is replaced with new_cache_expire. 
"只要每session_start(),就会产生新id并更改cookie,这意味着原来的cookie就没用了":
我不是什么高手,但是我觉得这正是用session 和cookie给合的原因,首先用cookie保存了信息在客户端,session过期了,但cookie还在,session可以利用cookie初始化一下,这样即使session过期时间设短一点也不影响,避免了session过期时间过长造成的服务器资源浪费.拙见,见笑了!

解决方案 »

  1.   

    楼上的id应该是取自war3的那位天才UD选手疯狂青蛙
      

  2.   

    你好!MAD_FROG() !
    "只要每session_start(),就会产生新id并更改cookie,这意味着原来的cookie就没用了":
    我不是什么高手,但是我觉得这正是用session 和cookie给合的原因,首先用cookie保存了信息在客户端,session过期了,但cookie还在,session可以利用cookie初始化一下,这样即使session过期时间设短一点也不影响,避免了session过期时间过长造成的服务器资源浪费.
    ——————————————————————————————————————————您能否给段代码?简单的代码模型!给个思路!我测 的代码模型如下:
      
       1、session存数据库
       2、登录成功后启动新会话:登录页:login.php
           require("include/session_inc.php"); //设置session 数据库保存
           session_start(); 
            $_SESSION['name']=$username;   //注册一个SESSION变量
            $_SESSION['passwd']=$password;
            $_SESSION['admin']='true';
            $_SESSION['time']=time();
            $lifetime=24*3600;
            setcookie(session_name(),session_id(),time()+$lifetime,"/");
       3、测试页:test.php if (isset($_COOKIE['PHPSESSID'] ) && $_COOKIE['PHPSESSID'] !='' ) 
    {
    $sessionid=$_COOKIE['PHPSESSID'];
    require("include/session_inc.php");
    session_id($sessionid);
    session_start();
       if($_SESSION['admin']!='true')
       {
       echo session_id();
       echo "cookied存在但session不正确";
       echo "请重新登录";
       }
       else
       { 
        echo session_id();
        echo "成功取得原cookieID";
        echo $_SESSION['name'];  
        echo $_SESSION['passwd'];
        echo date('Y n j H i',$_SESSION['time']);
        echo "成功验证";
       }
    }else
    {
    require("session_inc.php");
    session_start();
       if($_SESSION['admin']!='true')
       {
       echo session_id();
       echo "cookie不存在,session也不存在";
       echo "请重新登录";
       }
       else
       { 
       echo session_id();
       echo $_SESSION['name'];  
       echo "cookie和session都存在";
       echo "成功验证";
       } }
            大家看这个模型有没有什么问题?有没有更好的!
        我测试结果是:
        登录成功后正常,但下次不登录直接进测页就会出总题!我也不在道问题在什么地方?大家测一下看有什么问题!
      

  3.   

    你好!MAD_FROG() !
    session可以利用cookie初始化一下!
    你的意思是说,如果用户登录时要求保存一定时间,那登录成功后存cookie 时一定要存数组变量了,就是按正常使用cookie!
    下次判断验证时从cookie取出数据变量,用这些变量初始化session!
    能给个代码模型吗?
      

  4.   

    $sessionid=$_COOKIE['PHPSESSID'];
    require("include/session_inc.php");
    session_id($sessionid);require("session_inc.php");
    session_start();
    你的这2个逻辑判断是不是有问题啊,上面通过判断cookie存储的session_id获取验证,那你下面呢?难道说没有获取cookie以后就新创建一个会话?那么下面的判断 if($_SESSION['admin']!='true')这个不就永远不会出现$_SESSION['admin']=='true'的情况!!
    另外你说遇到错误,请指明具体错误,大家也好帮助你啊!
      

  5.   

    session_cache_expire
    (PHP 4 >= 4.2.0, PHP 5)session_cache_expire -- Return current cache expire
    Description
    int session_cache_expire ( [int new_cache_expire] )
    session_cache_expire() returns the current setting of session.cache_expire. The value returned should be read in minutes, defaults to 180. If new_cache_expire is given, the current cache expire is replaced with new_cache_expire. The cache expire is reset to the default value of 180 stored in session.cache_limiter at request startup time. Thus, you need to call session_cache_expire() for every request (and before session_start() is called). 例子 1. session_cache_expire() example<?php/* set the cache limiter to 'private' */session_cache_limiter('private');
    $cache_limiter = session_cache_limiter();/* set the cache expire to 30 minutes */
    session_cache_expire(30);
    $cache_expire = session_cache_expire();/* start the session */session_start();echo "The cache limiter is now set to $cache_limiter<br />";
    echo "The cached session pages expire after $cache_expire minutes";
    ?>  
     
      

  6.   

    回hnxxwyq(独自流浪):我代码模型的思路是这样的:
    1、如果验证成功。设cookie存活期。
    2、测试页逻辑!
     先测试cookie
     如果存在cooKie,则取回ID,看session中有无相应变量(即$_session['admin']= true)。有则通过验证。没有重新登录。
     如果不存在cookie,则看有没有session,(即$_session['admin']= true)。有的话说明验证过了。问题在于,如果不登录而直接打开测页,cookie总是不存在。
      

  7.   

    session通过cookie保存它的id,这个过程是自动的,不需要你手工操作,
    默认这个cookie在浏览器关闭后自动失效,如果想保存cookie就设置session.cookie_lifetime长一些。
    下面这个测试注释掉ini_set这一行和不注释掉效果是完全不同的。
    先打开页面,刷新,然后关闭页面,再打开。看效果。<?phpini_set("session.cookie_lifetime", 60);
    session_start();print_r(session_get_cookie_params());
    if(!isset($_SESSION['login'])){
    echo '没登录';
    $_SESSION['login'] = 1;
    }
    else{
    echo '已登录';
    }
    ?>
      

  8.   

    楼上 ini_set("session.cookie_lifetime", 60);这是否是指session ID 和cookie ID(两者是一个数)在60内均存在且有效。即使重新打开IE。这应是设置所有cookie的默认生命周期。结果可能影响session的生命周期。可能是使session 和cookie生命周期同步吧(当session不被清理的情况下)我还没测试。但如:我手动设置cookie 生命周期,会改变默认设置。这种情况怎办?
      

  9.   

    回yueliangdao0608((深圳)PHP和MYSQLQQ:38257291) 上面我也先前看过。但不知道,这个缓存究竟是如保运作的?有什么作用?有应用实例吗?
      

  10.   

    1. session的传递只有一个session id, 默认PHPSESSID=xxxxxxxx保存在cookie里,
    因为cookie有lifetime,所以session.cookie_lifetime就是用来设置这个lifetime的。对服务器来说,第一次登录以后获得了PHPSESSID,以后服务器只认这个ID,如果客户端关闭了IE对服务器来说根本不可能知道IE关闭了,重新打开IE的时候,只要请求的页面里PHPSESSID是相同的,它就认为你是一直登录着的。而如何让IE关闭页面之后再请求页面还带有这个PHPSESSID就只需要设置cookie的lifetime,不管是设置session.cookie_lifetime还是代码中setcookie(session_name(), session_id(), time() + 3600)效果是一样的。
    2. session.gc_maxlifetime是垃圾回收(Garbage Collection)时间,也就是说每一个用户登录都会生成session文件,如果用户中途关闭IE,那么服务器就会生成一个垃圾文件。gc_maxlifetime就是用来定时删除一些过期的垃圾文件的。
    3. session.cache_expire()是设置页面缓存的,具体在HTTP协议里说的很清楚的,跟以上session变量没有什么关系。
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
    4. 不要以为session就是cookie, cookie只不过是session id传递的一种方法,用form,url都可以实现session. cookie保存的仅仅是session id,不是说cookie不能保存数据,而是cookie保存数据不安全,session就是为了要解决这个问题,所以session id是一个散列字符串,在有效时间内是不能被人猜出来的。
      

  11.   

    回:Meteorlet(www.dictworld.com) 
    多谢指点:
    我觉你说得最明白,我觉你说的2、3、4点都是有道理的,也最为透彻。也解我不少疑惑。但我的问题仍在第1点:
       如果cookie只是存ID的情况下,我设session.cookie_lifetime,用(session_name(), session_id(), time() + 3600)
    或session_set_cookie_params(),即设cookie存活期,这个服务器session无关。
       如果session ID有存活期且未过期,且服务器端存在session的情况下(未被垃圾收集或人工注消),当关闭浏览器后下次打开浏览器时,如何用这个ID取得服务器端的session呢?
       我的难题就在这?
        
       我测试的情况是,只要session_start(),就会产生新的ID并覆盖原来的cookie,即使我这次成功取得了,下次cookie又变了,除非我每次取得后再手动重设cookie,这还得cookie过期计算时间,我没有试过!比较复杂!
      大家有没有好的方法!
      
      

  12.   

    看来还得我来回答
    session_set_cookie_params里的整数可不能用time()+....这种
    楼主要想让客户端缓存session的cookie,这样客户端关掉浏览器10分钟后重启电脑回来还能用这个session,不用重新登录
    这个问题在手册的留言里有讨论,其中session_set_cookie_params的整数参数是缓存服务器过后多少秒数,你要保留一天session,参数就是86400,而不是time()+86400
    用httpwatch抓一下cookie就很容易理解了,session处理模块自动集成了setcookie的处理,当然还设置了其他http header_______________________________
    www.cosrc.com
    caare.cosrc.com
      

  13.   

    session_start()的工作原理是这样的:
    1) 首先在cookie(如果配置成cookie传递Session ID的话)里找PHPSESSID=xxxxx
    2)读取PHPSESSID的值,如果读不到就重新随机初始化一个ID
    3)初始化超全局数组$_SESSION(这一步就是读取文件反序列化的过程)所以如果成功写入cookie的话,那么关闭IE再打开,只要cookie里有这个ID,服务器都认为是一样的。
    以下代码运行一次输出success,运行第二次输出login,关闭IE再打开还是显示login:
    <?php
    session_start();
    setcookie(session_name(), session_id(), time() + 3600);
    if (empty($_SESSION['login']))
    {
        $_SESSION['login'] = 1;
        print("Success");
    } else {
        print("Login");
    }
    ?>而且session_start()之前的session id是可以自己初始化的,比如:
    session_id($_COOKIE[session_name()]);
    session_start();
      

  14.   

    另外session_set_cookie_params必须写在session_star前面,否则不起作用
    至于session_set_cookie_params会不会自动导致session数据过期加长还没看,估计会自动加长服务器端session数据的过期时间原理是这样的,用户进来,服务器检查是否有cookie传递过来的session id,有就从服务器查找对应的id数据,没有就new一个,通过cookie发到客户端
    这是默认状态,session id是浏览器进程cookie,关掉浏览器就没了,如果要保存登录,就用session_set_cookie_params来设置传递session id的cookie过期时间。
    如果访问量较大,那么最好不要用这种方式,因为...服务器自动延长了session数据的过期时间,加长了服务器端检索session数据的时间&负载。
    _______________________________
    www.cosrc.com
    care.cosrc.com
      

  15.   

    假设:把session id的过期时间设成1年
    那么服务器要把你的session数据保存1年,如果有一直有新ip来访问,oh my god
    如同那歌唱的了:i will be right here waiting for you
    但愿不是那么处理session数据的。
      

  16.   

    感谢楼上两位指点!又让我多学了东西!
    我也一直测试,已有点眉目!
    我原来的问题是这样的:
    即使我设了session_set_cookie_params($time);这只是设置了客户端cookie的周期。实际上服务器session是不认这个的。他只认sessionID。
    如果session.lifetime的默认生存周期为0,即INI里的那个。
    意味着,只要session_start(),就会重写cookie,并且生存周期为0。因为session_name()重名。
    所以,即使设cookie设置了生存期,只要遇session_start()就归零了!
    解决的方法可能是样:
    1、如果登录成功
      session_start();
      用这个sessionID,但不用默认的phpsessID变量名设cookie.
    如:
      setcookie("DPHP",session_id(),$lifetime,"/");  即用另一个变量但用同一ID存cookie及生存期。
    2、验证
      判 断
      if (isset($_COOKIE['DPHP']) && $_COOKIE['DPHP']!='')例如:
    require("include/session_inc.php");
     
      if (isset($_COOKIE['DPHP']) && $_COOKIE['DPHP']!='')
      {
       session_id($_COOKIE['DPHP']);
       session_start();
        if($_SESSION['admin']!='true')
    {

    echo "cookie存在但session不正确请得新登录";
    }
    else
    {
    /*   $lifetime=mktime($_SESSION['cookietime'])-mktime();
            if ($lifetime>0)
    {
    $lifetime=time()+$lifetime;
    setcookie(session_name(),session_id(),$lifetime,"/");
    */ 
            echo "cookie、session均正确,成功新登录";
    }
    }
     else
       { 
      session_start();  if($_SESSION['admin']='true')
      {
      echo "成功登录";
      }
      else
      {
      echo "请重新登录";
      }
    }
     
    这样,只要$_COOKIE['DPHP']存在,就用这个ID取服务器端的SEssion.
    $_COOKIE['PHPSESSID']只有浏览器生存期
    而$_COOKIE['DPHP']生存期手设
    两个都是同一ID。
    这样就实现cookie和session的结合应用了,达到最佳效果!我认为,cookie和session的生存期是不相关(只在浏览器不关闭时相关)。因此,要想取session,session生存期应>cookie生存期,由于session会大量存在,因此这种应用不宜超过两周!
      

  17.   

    这样,只要$_COOKIE['DPHP']存在,就用这个ID取服务器端的SEssion.
    $_COOKIE['PHPSESSID']只有浏览器生存期
    而$_COOKIE['DPHP']生存期手设
    两个都是同一ID。
    这样就实现cookie和session的结合应用了,达到最佳效果!===========================================================   这样做意义何在???
      

  18.   

    我查了不少文章,说cookie和session结合用才能最好!但究竟如何结合,没有文章指出!
    但大家却都说两者结合用最好!
    结合用:我的理解是,既可以用cookie的特点,也可以用session的特点!
       问题如下:
       1、如果客户不需要单独保存一个cookie周期,那直接用session好了!每次登录成功后设session变量,只验证session;
       2、如果用户需要设一个cookie存活期,比如,两周内,不用登录可直接验证!那如何办呢?session好像解决不了这个问题,不少文章都推荐,直接用cookie,不要用session了。因为session和cookie的同步只有浏览器周期。我测试发现,实际上,session和cookie的同步只是因为有同一个ID,另一个就是可能和缓存有关!
       如果关闭浏览器,缓存就没有了,ID下次打开浏览器时只要遇session_start();就会改变——即重写cookie。且同时将cookie的周期设为0。这意味即使你以前设过cookie周期,也没有用了。
      所以,试图能过设cookie的存活期来实现下次验证时不用登录行不通(可能在第二次是行,但第三次就不行了)
       3、解决问题第三种办法:实现用户自定义免登录期限,且同时用session.同时用session实现以下两种情况:
      如果用户要求免登录期限,用非默认session_name()——phpsessiD的保存cookie名及ID。并以下次验证时将ID取回,用这ID初始化session,从session文件中取变量验证!
     如果用户登录时没有要求免登录期限,则登录成功后直接设session变量。在浏览器周期验证session.
       
       上面的关键在于,客户端cookie只保存ID,通过这个ID和session沟通。从而既实现安全,又实现多种验证需求!   上面这个问题的误区是:cookie周期和session周期是同步的。实际上也只是在浏览器周期同步。关闭浏览器,两者不相关。——目前我测试中还有找到有相关的地方,各位可测试看看!
       因此,我认为,session_set_cookie_params(),来设cookie的周期是没有用的。
       setcookie(session_name(),session_id(),$lifetime,"/");这个语句也没有用。因为只要遇session_start(),它就归零!但你只要用session,就不能不用session_start(),所以它没有意义。
      
      

  19.   

    总结一下:
       1、要求是只用在客户端存sessionID实现客户可设免登录期验证;
       2、cookie周期和session周期不同步,或可理解为不相关。cookie周期是手设或系统指定(系统批定的话所有cookie保存期就一样);session周期与垃圾清理机制有关。
        所以,要用既用、cookie周期和session周期,session周期应>cookie周期;
       3、通过用其他cookie名保存sessionID,以免被覆盖。并这个ID实现与 session通信并验证!  不知我说的是否明白,大家是否有更好的办法?也是进一步测试中。
      

  20.   

    上面的关键在于,客户端cookie只保存ID,通过这个ID和session沟通。从而既实现安全,又实现多种验证需求!-------------------------------------------  就问一句, 既然客户端只保存ID, 那么我看到你电脑上的cookie中保存的ID后,在我的电脑上伪造一个同样ID的cookie, 服务端如何辨别?
      

  21.   

    回helloyou0(你好!) :
    这个是cookie通病了,如果只用cookie,你仍然会遇到这样的问题!cookie没法解决!最多是加密(我没试过)。保证cookie安全,1是用设变量,2是设有效期,3是加密;但这仍然会被盗用。
    用session且在客户端保存ID,这说明除了具有cookie的安全后,还要用session的安全。即使客户端ID是正确的,还要看session文件是否存在,看session文件中的变量是否存在,是否过期。
    如果session文件不存在,这个ID就没用了。
    如果session文件中的某个验证变量不存,这个ID也没有用了,必须重新登录设session变量
      

  22.   

    其实,我上面说了这么多,就想解决一点,如何用session实现免登录验证!比如:用户选择两周内不用登录即可验证,不知道大家都是如何解决这个问题的!