zoukankan      html  css  js  c++  java
  • 教你如何使用php session

    1.

    2、怎样理解cookie和session?
       由于cookie和session关系密切,这里我们一并介绍。
       打个比方:在河南时,我常到一家熟食店买馋嘴鸭,该店老板为了促进销售,特发布“每购满10只即可免费赠送一只”的优惠措施。除了家里有什么红白喜事要飨客之外,应该不会有人一次性购买10只烤鸭吧?所以老板得想个法子来记录顾客的消费数量,这里总共有三种方案:
       Ⅰ、老板记住每一个顾客的消费数量,等到顾客消费满10只的时候自动奉送一只。这好比HTTP协议本身是有状态的,可以记住顾客的活动行为。但遗憾的是,出于种种考虑http协议本身是不能有状态的,老板自个也没有这么超常的记忆力,故这种方案行不通!
       Ⅱ、老板发给顾客一张积分卡,上面记录着消费的数量,一般还有个有效期限。每次买烤鸭时,如果顾客出示这张卡片,老板就知道这位顾客曾经光顾过小店。这种做法就是在客户端保持状态,好比是cookie技术。打开(windows系统)C:Documents and Settings用户名Cookies,你会发现一些*.txt格式的小文件,这就是你浏览某些网站,它们发给你的“积分卡”(cookies)。
       Ⅲ、老板发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次买烤鸭时,如果顾客出示该卡片,则老板搬出店里的划名册,找到你的卡号并加1个积分。这种做法就是在服务器端保持状态。
    好比是session技术。
        cookie 和session最大的区别在于: cookie是把积分卡发给顾客,上面记录了顾客所有的消费信息。Session则是把只有卡号(session id)的积分卡发给顾客,自家记录了顾客所有的消费信息。Cookie是保存在客户端的;session是保存在服务器端,而session id则是保存在客户端,通常也是一个cookie小文件,由于这个小文件除了session id(好比卡号)外什么也没有,因此比cookie安全多了。

    3、cookie和session有什么用?
       常见的用法,比如在有些网站下载东西需要会员先登陆。http协议本身是无状态的,无法得知顾客是否已经登陆,怎么办呢?cookie和session就可以知道。再比如网上购物,购物车怎么知道顾客挑选过哪些商品呢?cookie和session也可以记录。总而言之,cookie和session就是能够记录顾客状态的技术,尽管二者属于不同的技术,但只要cookie能做到的,session也能做到!

    2.

    COOKIE篇

    1、什么是cookie?
    0Cookie技术是一个非常有争议的技术,自经诞生它就成了广大网络用户和Web开发人员的一个争论焦点。有一些网络用户,甚至包括一些资深的Web专家也对它的产生和推广感到不满,这倒不是因为Cookie技术的功能太弱或别的技术性能上的原因,而仅仅是因为他们觉得Cookie的使用,对网络用户的隐私构成了危害。因为Cookie是由Web服务器保存在用户浏览器上的小文本文件,它包含有关用户的信息(如身份识别号码、密码、用户在Web站点上购物的方式或用户访问该站点的次数)。
        那么Cookie技术究竟怎样呢?是否真的给网络用户带来了个人隐私的危害呢?还是让我们看了下面的内容,再做回答吧。
          在WEB技术发展史上,Cookie技术的出现是一个重大的变革。最先是Netscape在它的Netscape Navigator 浏览器中引入了Cookie技术,从那时起,World Wide Web 协会就开始支持Cookie标准。以后又经过微软的大力推广(因为微软的IIS Web服务器所采用的ASP技术很大程度的使用了Cookie技术),即在微软的Internet Explorer浏览器中完全支持Cookie技术。到现在,绝大多数的浏览器都支持Cookie技术,或者至少兼容Cookie技术的使用。
          按照Netscape官方文档中的定义,Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie是由Web服务器保存在用户浏览器上的小文件,它可以包含有关用户的信息(如身份识别号码、密码、用户在Web站点购物的方式或用户访问该站点的次数)。无论何时用户链接到服务器,Web站点都可以访问Cookie信息。
        如果你使用的是windows系统,那么请打开C:Documents and Settings用户名Cookies,你会发现该目录下有好多*.txt格式的小文件。那就是cookie文件。当然,在该目录下你也可能什么都发现不了,那时因为你新装了系统或者从未浏览过因特网,也或者你的浏览器禁用了cookie。否则该目录下总会有点东西的。
         通俗地讲,浏览器用一个或多个限定的文件来支持Cookie。这些文件在使用Windows操作系统的机器上叫做Cookie文件,在Macintosh 机器上叫做magic Cookie 文件,这些文件被网站用来在上面存储Cookie数据。网站可以在这些Cookie文件中插入信息,这样对有些网络用户就有些副作用。有些用户认为这造成了对个人隐私的侵犯,更糟的是,有些人认为Cookie是对个人空间的侵占,而且会对用户的计算机带来安全性的危害。
         目前有些Cookie是临时的,另一些则是持续的。临时的Cookie只在浏览器上保存一段规定的时间,一旦超过规定的时间该Cookie就会被系统清除。例如在PHP中Cookie被用来跟踪用户进程直到用户离开网站。持续的Cookie则保存在用户的Cookie文件中,下一次用户返回时,仍然可以对它进行调用。
         在Cookie文件中保存Cookie,一些用户会过分地认为这将带来很大的问题。主要是有些用户担心Cookie会跟踪用户网上冲浪的习惯,譬如用户喜爱到那些类型的站点、爱从事些什么活动等。害怕这种个人信息一旦落入一些别有用心的家伙手中,那么个人也就可能成为一大堆广告垃圾的对象,甚至遭到意外的损害。不过,这种担心压根儿不会发生,因为网站以外的用户是无法跨过网站来获得Cookie信息的。所以想以这种目的来应用Cookie是不可能的。不过,由于一些用户错误的理解以及“以讹传讹”,一些浏览器开发商别无选择,只好作出相适的响应(例如Netscape Navigator4.0和Internet Explorer3.0都提供了屏蔽Cookie的选项)。个人认为,无风不起浪,如果网站程序员没有严谨思路的话,cookie确实也存在些许安全问题,不过这些瑕疵并不足以掩盖cookie的优秀品质,大多数人还是非常乐意使用它的。
         对Cookie技术期待了这么久的结果是,迫使许多浏览器开发商在它们的浏览器中提供了对Cookie的灵活性控制功能。例如,目前的两大主流浏览器 Netscape Navigator 和 Internet Explorer是这样处理Cookie的:Netscape Navigator4.0不但可以接受Cookie进行警告,而且还可以屏蔽掉Cookie;InternetExplorer3.0也可以屏蔽 Cookie,但在Internet Explorer4.0中就只能进行接受警告而没有提供屏蔽选项,不过在Internet Explorer4.0之后的更新版本中又加入了屏蔽Cookie的功能选项。
         此外,很多最新的技术甚至已经可以在不能屏蔽Cookie的浏览器上进行Cookie的屏蔽了。例如,可以通过将Cookie文件设置成不同的类型来限制 Cookie的使用。但是,非常不幸地是,要是你想完全屏蔽Cookie的话,肯定会因此拒绝许多的站点页面。因为当今已经有许多Web站点开发人员爱上了Cookie技术的强大功能,例如Session对象的使用就离不开Cookie的支持。


    2、Cookie工作原理?
        当客户访问某个基于PHP技术的网站时,在PHP中可以使用setcookie函数生成一个cookie,系统经处理把这个cookie发送到客户端并保存在C:Documents and Settings用户名Cookies目录下。cookie是 HTTP标头的一部分, 因此setcookie函数必须在任何内容送到浏览器之前调用。这种限制与header()函数一样(如需了解head()函数,请自行查阅)。当客户再次访问该网站时,浏览器会自动把C:Documents and Settings用户名Cookies目录下与该站点对应的cookie发送到服务器,服务器则把从客户端传来的cookie将自动地转化成一个 PHP变量。在PHP5中,客户端发来的cookie将被转换成全局变量。你可以通过$_COOKIE[‘xxx’]读取。

         尽管今天仍有一些网络用户对于Cookie的争论乐此不倦,但是对于绝大多数的网络用户来说还是倾向于接受Cookie的。因此,我们尽可以放心地使用Cookie技术来开发我们的WEB页面。

    3、Cookie常见函数
    ● SetCookie  函数创建了一个Cookie,并且把它附加在HTTP头的后面。必须注意的一点是:Cookie是HTTP协议头的一部分,用于浏览器和服务器之间传递信息,所以必须在任何属于HTML文件本身的内容输出之前调用SetCookie函数,调用该函数前即使有空格、空白行都不行。如果setCookie()认了第二,就没有哪个元素敢认第一。使用setcookie()函数的前提是客户浏览器支持cookie,如果客户将之禁用的话,setcookie()也就英雄无用武之地了。
       int SetCookie(string name, string value, int expire, string path, string domain, int secure,bool httponly);  
    参数说明:
       name;设置cookie变量的名称。
       value;设置cookie的值。
       expire;设置cookie过期时间。如果要把cookie保存为浏览器进程,即浏览器关闭后就失效。那么可以直接把expiretime设为0。 Eg:setcookie(“name”,”value”,0)。该参数不设置的话,关闭浏览器也能结束一个cookie。
        path:表示web服务器上的目录,默认为被调用页面所在目录. 这里还有一点要说明的,比如你的站点有几个不同的目录(比如一个购物目录,一个论坛目录),那么如果只用不带路径的Cookie的话,在一个目录下的页面里设的Cookie在另一个目录的页面里是看不到的,也就是说,Cookie是面向路径的。实际上,即使没有指定路径,WEB服务器会自动传递当前的路径给浏览器的,指定路径会强制服务器使用设置的路径。解决这个问题的办法是在调用 SetCookie时加上路径和域名,域名的格式可以是“http://www.phpuser.com/”,也可是“.phpuser.com”。 SetCookie函数里表示value的部分,在传递时会自动被encode,也就是说,如果value的值是“test value”在传递时就变成了“test%20value”,跟URL的方法一样。当然,对于程序来说这是透明的,因为在PHP接收Cookie的值时会自动将其decode。

        domain:cookie可以使用的域名,默认为被调用页面的域名。这个域名必须包含两个".",所以如果你指定你的顶级域名,你必须用".mydomain.com" 。设定域名后,必须采用该域名访问网站cookie才有效。如果你使用多个域名访问该页,那么这个地方可以为空或者访问这个cookie的域名都是一个域下面的。
        secure:如果设为"1",表示cookie只能被用户的浏览器认为是安全的服务器所记住。
        除了name之外所有的参数都是可选的。value,path,domain三个参数可以用空字符串""代换,表示没有设置;expire 和 secure两个参数是数值型的,可以用0表示。expire参数是一个标准的Unix时间标记,可以用time()或mktime()函数取得,以秒为单位。secure参数表示这个Cookie是否通过加密的HTTPS协议在网络上传输。
        httponly:如果设为1,则表示cookie只能被http协议所使用,任何脚本语言,比如javascrīpt是不能获取PHP所创建的 cookie的,这就有效削弱了来自XSS的攻击。(注意了:这是PHP5才有的选项,咱也没有用过。看了官方手册尝试着翻译的,如有疑问,请参考官方手册。)
        当前设置的Cookie不是立即生效的,而是要等到下一个页面或刷新后才能看到.这是由于在设置的这个页面里Cookie由服务器传递给客户浏览器,在下一个页面或刷新后浏览器才能把Cookie从客户的机器里取出传回服务器的原因。

    4.

    PHP SESSION原理

    我们知道,session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据。HTTP协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联系,最早,Netscape将cookie引入浏览器,使得数据可以客户端跨页面交换,那么服务器是如何记住众多用户的会话数据呢?

    首先要将客户端和服务器端建立一一联系,每个客户端都得有一个唯一标识,这样服务器才能识别出来。建议唯一标识的方法有两种:cookie或者通过GET方式指定。默认配置的PHP使用session的时会建立一个名叫”PHPSESSID”的cookie(可以通过php.ini修改session.name值指定),如果客户端禁用cookie,你也可以指定通过GET方式把session id传到服务器(修改php.ini中session.use_trans_sid等参数)。

    我们查看服务器端session.save_path目录会发现很多类似sess_vv9lpgf0nmkurgvkba1vbvj915这样的文件,这个其实就是session id “vv9lpgf0nmkurgvkba1vbvj915″对应的数据。真相就在这里,客户端将session id传递到服务器,服务器根据session id找到对应的文件,读取的时候对文件内容进行反序列化就得到session的值,保存的时候先序列化再写入。

    事实就是这样,所以如果服务器不支持session或者你想自定义session,完全可以DIY,通过PHP的uniqid生成永不重复的session id,然后找个地方存储session的内容即可,你也可以学flickr把session存储在MySQL数据库中。

    使用session之前为什么必须先执行session_start()?

    了解的原理之后,所谓的session其实就是客户端一个session id服务器端一个session file,新建session之前执行session_start()是告诉服务器要种一个cookie以及准备好session文件,要不然你的session内容怎么存;读取session之前执行session_start()是告诉服务器,赶紧根据session id把session文件反序列化。

    只有一个session函数可以在session_start()之前执行,session_name():读取或指定session名称(比如默认的就是”PHPSESSID”),这个当然要在session_start之前执行。

    session影响系统性能

    session在大访问量网站上确实影响系统性能,影响性能的原因之一由文件系统设计造成,在同一个目录下超过10000个文件时,文件的定位将非常耗时,PHP支持session目录hash,我们可以通过修改php.ini中session.save_path = “2;/path/to/session/dir”,那么session将存储在两级子目录中,每个目录有16个子目录[0~f],不过好像PHP session不支持创建目录,你需要事先把那么些目录创建好 。

    还有一个问题就是小文件的效率问题,一般我们的session数据都不会太大(1~2K),如果有大量这样1~2K的文件在磁盘上,IO效率肯定会差。

    其实还有很多中存储session的方式,可以通过php -i|grep “Registered save handlers”查看,比如Registered save handlers => files user sqlite eaccelerator可以通过文件、用户、sqlite、eaccelerator来存,如果服务器装了memcached,还有会mmcache的选项。当然还有很多,比如MySQL、PostgreSQL等等。都是不错的选择。

    session的同步

    我们前端可能有很多台服务器,用户在A服务器上登录了,种下了session信息,然后访问网站的某些页面没准跳到B服务器上去了,如果这个时候B服务器上没有session信息又没有做特殊处理,可能就会出问题了。

    session同步有很多种,如果你是存储在memcached或者MySQL中,那就很容易了,指定到同样的位置即可,如果是文件形式的,你可以用NFS统一存储。

    还有一种方式是通过加密的cookie来实现,用户在A服务器上登录成功,在用户的浏览器上种上一个加密的cookie,当用户访问B服务器时,检查有无session,如果有当然没问题,如果没有,就去检验cookie是否有效,cookie有效的话就在B服务器上重建session。这种方法其实很有用,如果网站有很多个子频道,服务器也不在一个机房,session没办法同步又想做统一登录那就太有用了。

    当然还有一种方法就是在负载均衡那一层保持会话,把访问者绑定在某个服务器上,他的所有访问都在那个服务器上就不需要session同步了,这些都是运维层面的东西。就说这么多吧,根据自己的应用来选择使用session,不要因为大家都说session影响系统性能就畏首畏尾,知道问题,解决问题才是关键,惹不起躲得起不适合这里。

    5.

    Session的管理

    直到现在,我只讨论了如何维护应用程序的状态,只是简单地涉及到了如果保持请求之间的关系。接下来,我阐述下在实际中用到比较多的技术 – Session的管理。涉及到session的管理,就不是单单地维持各个请求之间的状态,还需要维持会话期间针对每个特定用户使用到的数据。我们常常把这种数据叫做session数据,因为这些数据是跟某个特定用户与服务器之间的会话相关联的。如果你使用php内置的session的管理机制,那么session数据一般是保存在/tmp这个服务器端的文件夹中,并且其中的session数据会被自动地保存到超级数组$_SESSION中。一个最简单的使用session的例子,就是将相关的session数据从一个页面传递(注意:实际传递的是session id)到另一个页面。下面用示例代码1, start.php, 对这个例子加以演示:

    1. <?php 
    2. session_start(); 
    3. $_SESSION['foo'] = 'bar'; 
    4. ?> 
    5. <a href="continue.php">continue.php</a> 

    假如用户点击start.php中的链接访问continue.php,那么在continue.php中就可以通过$_SESSION['foo']获取在start.php中的定义的值’bar’。看下面的示例代码2:

    示例代码2 – continue.php

    1. <?php 
    2. session_start(); 
    3. echo $_SESSION['foo']; /* bar */ 
    4. ?> 

    是不是非常简单,但是我要指出的话,如果你真的这样来写代码的话,说明你对php底层的对于session的实现机制还不是非常了解透彻。在不了解php内部给你自动做了多少事情的情况下,你会发现如果程序出错的话,这样的代码将变的很难调试,事实上,这样的代码也完全没有安全性可言。

    4.

    2Session常见函数及用法?
     Session_start() :开始一个会话或者返回已经存在的会话。
       说明:这个函数没有参数,且返回值均为true。如果你使用基于cookie的session(cookie-based sessions),那么在使用Session_start()之前浏览器不能有任何输出,否则会发生以下错误:
    Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………
    你可以在php="">php.ini里启动session.auto_start=1,这样就无需每次使用session之前都要调用session_start()。但启用该选项也有一些限制,如果确实启用了 session.auto_start,则不能将对象放入会话中,因为类定义必须在启动会话之前加载以在会话中重建对象。
    请求结束后所有注册的变量都会被序列化。已注册但未定义的变量被标记为未定义。在之后的访问中这些变量也未被会话模块定义,除非用户以后定义它们。
    警告: 有些类型的数据不能被序列化因此也就不能保存在会话中。包括 resource 变量或者有循环引用的对象(即某对象将一个指向自己的引用传递给另一个对象)。
    注册SESSION变量:
    PHP5使用$_SESSION[‘xxx’]=xxx注册SESSION全局变量。和GET,POST,COOKIE的使用方法相似。
        注意:session_register(),session_unregister ,session_is_registered在php5下不再使用,除非在php.ini里把register_globle设为on,不过出于安全考虑,强烈建议关闭register_globle。HTTP_SESSION_VARS也不提倡使用了,官方建议用$_SESSION代替之。例如:
    Page1.php
    <?php
    Session_start();       //使用SESSION前必须调用该函数。
    $_SESSION[‘name’]=”我是黑旋风李逵!”;   //注册一个SESSION变量
    $_SESSION[‘passwd’]=”mynameislikui”;
    $_SESSION[‘time’]=time();
    echo '<br /><a href="page2.php">通过COOKIE传递SESSION</a>';   _fcksavedurl=""page2.php">通过COOKIE传递SESSION</a>';  " //如果客户端支持cookie,可通过该链接传递session到下一页。
    echo '<br /><a href="page2.php?' . SID . '">通过URL传递SESSION</a>';//客户端不支持cookie时,使用该办法传递session.
    ?>
    Page2.php
    <?php
    session_start();
    echo $_SESSION['name']; // 
    echo $_SESSION['passwd'];   // 
    echo date('Y m d H:i:s', $_SESSION['time']);
    echo '<br /><a href="page1.php">返回山一页</a>';
    ?>


    有两种方法传递一个会话 ID 
    cookie 
    URL 参数 
    会话模块支持这两种方法。cookie 更优化,但由于不总是可用,也提供替代的方法。第二种方法直接将会话 ID 嵌入到 URL 中间去。 
    PHP 可以透明地转换连接。除非是使用 PHP 4.2 或更新版本,需要手工在编译 PHP 时激活。 Unix ,用 --enable-trans-sid 配置选项。如果此配置选项和运行时选项 session.use_trans_sid 都被激活(修改php.ini),相对 URI 将被自动修改为包含会话 ID。 
    ● session_id
        session_id() 用于设定或取得当前session_id。php5中既可以使用session_id(),也可以通过附加在url上的SID取得当前会话的session_id和session_name。
        如果session_id()有具体指定值的话,将取代当前的session_id值。使用该函数前必须启动会话:session_start();
        当我们使用session cookies时,如果指定了一个session_id()值,每次启动session_start()都会往客户端发送一个cookie值。不论当前session_id是否与指定值相等。
    session_id()如果没有指定值,则返回当前session_id();当前会话没有启动的话,则返回空字符串。
     ● 检查session是否存在?
        在以往的php版本中通常使用session_is_register()检查session是否存在,如果您使用$_SESSION[‘XXX’]=XXX来注册会话变量,则session_is_register()函数不再起作用。你可以使用
    isset($_SESSION[‘xxx’])来替代。
    ● 更改session_id  
        session_regenerate_id() 更改成功则返回true,失败则返回false。
    使用该函数可以为当前session更改session_id,但不改变当前session的其他信息。例如:
    <?php
    session_start();
    $old_sessionid = session_id();
    session_regenerate_id();
    $new_sessionid = session_id();
    echo "原始 SessionID: $old_sessionid<br />";
    echo "新的 SessionID: $new_sessionid<br />";
    echo"<pre>";
    print_r($_SESSION);
    echo"</pre>";
    ?>
    ● session_name() 返回当前session的name或改变当前session的name。如果要改变当前session的name,必须在session_start() 之前调用该函数。注意:session_name不能只由数字组成,它至少包含一个字母。否则会在每时每刻都生成一个新的session id.
    session改名示例:
    <?php
    $previous_name = session_name("WebsiteID");
    echo "新的session名为: $previous_name<br />";
    ?>

    ● 如何删除session
    1、unset ($_SESSION['xxx'])删除单个session,unset($_SESSION['xxx']) 用来unregister一个已注册的session变量。其作用和session_unregister()相同。 session_unregister()在PHP5中不再使用,可将之打入冷宫。
    unset($_SESSION)  此函数千万不可使用,它会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量。
    2、$_SESSION=array()删除多个session
    3、session_destroy()结束当前的会话,并清空会话中的所有资源。。该函数不会unset(释放)和当前session相关的全局变量(globalvariables),也不会删除客户端的session cookie.PHP默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数。
        返回值:布尔值。
        功能说明:这个函数结束当前的session,此函数没有参数,且返回值均为true

       session_unset() 如果使用了$_SESSION,则该函数不再起作用。由于PHP5必定要使用$_SESSION,所以此函数可以打入冷宫了。

    下面是PHP官方关于删除session的案例:
    <?php
    // 初始化session.
    session_start();
    /*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
    $_SESSION = array();
    /***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session id的cookie.***/
    if (isset($_COOKIE[session_name()])) {
       setcookie(session_name(), '', time()-42000, '/');
    }
    // 最后彻底销毁session.
    session_destroy();
    ?>

    由此我们可以得出删除Session的步骤:
    session_start()
    $_SESSION=array()/unset($_SESSION['xxx'])
    session_destroy()

    ● SESSION安全:
        会话模块不能保证存放在会话中的信息只能被创建该会话的用户看到。根据其存放的数据,还需要采取更多措施来主动保护会话的完整性。 
        评估会话中携带的数据并实施附加保护措施通常要付出代价,降低用户的方便程度。例如,如果要保护用户免于受简单的社交策略侵害(注:指在 URL 中显示的会话 ID 会被别人在电脑屏幕上看到,或被别的网站通过 HTTP Referer 得到等),则应该启用session.use_only_cookies。此情形下,客户端必须无条件启用 cookie,否则会话就不工作。 
        有几种途径会将现有的会话 ID 泄露给第三方。泄露出的会话 ID 使第三方能够访问所有与指定 ID 相关联的资源。第一,URL 携带会话 ID。如果连接到外部站点,包含有会话 ID 的 URL 可能会被存在外部站点的 Referer 日志中。第二,较主动的攻击者可能会侦听网段的数据包。如果未加密,会话 ID 会以明文方式在网络中流过。对此的解决方式是在服务器上实施 SSL 并强制用户使用。 
        默认情况下,所有与特定会话相关的数据都被存储在由 INI 选项 session.save_path 指定的目录下的一个文件中。对每个会话会建立一个文件(不论是否有数据与该会话相关)。这是由于每打开一个会话即建立一个文件,不论是否有数据写入到该文件中。注意由于和文件系统协同工作的限制,此行为有个副作用,有可能造成用户定制的会话处理器(例如用数据库)丢失了未存储数据的会话。
            上面介绍函数下文将会用到,但还有一些有关session的函数也介绍一下:
     session_encode
        函数功能:sesssion信息编码
        函数原型:string session_encode(void);
        返回值:字符串
        功能说明:返回的字符串中包含全局变量中各变量的名称与值,形式如:a|s:12:"it is a test/";c|s:4:"lala"; a是变量名 s:12代表变量a的值"it is a test的长度是12 变量间用分号”;”分隔。
     session_decode
        函数功能:sesssion信息解码
        函数原型:boolean session_decode (string data)
        返回值:布尔值
        功能说明:这个函数可将session信息解码,成功则返回逻辑值true
    Php5 不再使用session_id,而是把它变成一个常量SID,并保存在cookie中。如果客户端禁用了cookie,php会自动通过url自动传动传递SID,其条件是设置php.ini中的session.use_trans_sid = 1。此时即使客户端即使禁用了cookie也没关系了。
       用 strip_tags() 来输出 SID 以避免 XSS 相关的攻击。

    Session跨页传递问题:
    session跨页传递需要考虑三种情况:
    ①客户端禁用了cookie。
    ②浏览器出现问题,暂时无法存取cookie
    ③php.ini中的session.use_trans_sid = 0或者编译时没有打开--enable-trans-sid选项
    为什么会这样呢?下面解释一下原因:
    Session文件分为两部分:session变量保存在服务器端(默认以文件方式存储session);而session id则以cookie形式保存在客户端。(注意:session默认是基于cookie的)。
        当用户的浏览器向服务器提出请求时,同时发送包含session id的cookie(默认情况下)。服务器根据客户端提供的session id来得到用户的文件,即保存在服务器端的session变量值。事实上,session id可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取Session的目录……。也就是说,session id是取得存储在服务上的session变量的身份证。当代码session_start();运行的时候,就在服务器上产生了一个session文件,随之也产生了与之唯一对应的一个session id,定义session变量以一定形式存储在刚才产生的session文件中。通过session id,可以取出定义的变量。跨页后,为了使用session,你必须又执行session_start();将又会产生一个session文件,与之对应产生相应的session id(:又会产生是有条件的,如果用户没有禁止Cookie的话,session id是可以隐藏的传过去的,也就是说不会产生新的session id,但如果禁止了Cookie的话,就需要手动传递session id来解决此问题了,见例2)),用这个session id是取不出前面提到的第一个session文件中的变量的,因为这个session id不是打开它的“钥匙”。如果在session_start();之前加代码session_id($session id);将不产生新的session文件,直接读取与这个id对应的session文件。
        PHP中的session在默认情况下是使用客户端的Cookie来保存session id的,所以当客户端的cookie出现问题的时候就会影响session了。必须注意的是:session不一定必须依赖cookie,这也是 session相比cookie的高明之处。当客户端的Cookie被禁用或出现问题时,PHP会自动把session id附着在URL中,这样再通过session id就能跨页使用session变量了。但这种附着也是有一定条件的,其一:“php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项”;其二:运行PHP的服务器必须是unix/linux系统,windows不具备此项功能
         明白了以上的道理,我们就可以得出解决session跨页传递问题的三条途径:
    1、设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项,让PHP自动跨页传递session id。
    2、手动通过URL传值、隐藏表单传递session id。
    3、用文件、数据库等形式保存session_id,在跨页过程中手动调用。
    下面举例说明:
    第一种情况:
    s1.php
    <?php

    ini_set("session.use_trans_sid",1);

    ini_set("session.use_only_cookies",0);

    ini_set("session.use_cookies",0);

    session_start();
    $_SESSION['var1']="中华人民共和国";
    $url="<a href="."/"s2.php/">下一页</a>";
    echo $url;
    ?>
    s2.php
    <?php
    session_start();
    echo "传递的session变量var1的值为:".$_SESSION['var1'];
    ?>
    运行以上代码,在客户端cookie正常的情况下,应该可以在得到结果“中华人民共和国”。
    现在你手动关闭客户端的cookie,再运行,可能得不到结果了吧。如果得不到结果,再“设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项”,又得到结果“中华人民共和国”

    第二种途径:
    s1.php

    <?php
    session_start();
    $_SESSION['var1']="中华人民共和国";
    $sn = session_id();
    $url="<a href='./s2.php?s=.$sn./'>下一页</a>"; //PHP5定义了一个常量SID来表示session_id(),$url还可以写成$url='<a href="page2.php?' . SID . '">下一页</a>';
    echo $url;
    ?>


    s2.php

    <?php
    session_start();
    echo "传递的session变量var1的值为:".$_SESSION['var1'];
    ?>


    第三种途径:
    login.html

    <!DOCTYPE html="">HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>Login</title>
    <meta http-equiv="Content-Type" content="text/html;">
    </head>
    <body>
    请登录:
    <form method="post" action="mylogin1.php">
    用户名:<input name="name" type="text" ><br>
    口 令:<input name="pass" type="password" ><br>
    <input type="submit" value="登录">
    </form>
    </body>
    </html>


    mylogin1.php

    <?php
    $name=$_POST['name'];
    $pass=$_POST['pass'];
    if(!$name || !$pass) {
    echo "用户名或密码为空,请<a href=/'login.html/'>重新登录</a>";
    die();
    }
    if (!($name=="laogong" && $pass=="123")) {
    echo "用户名或密码不正确,请<a href=/'login.html/'>重新登录</a>";
    die();
    }
    //注册用户
    ob_start();
    session_start();
    $_SESSION['user']= $name;
    $psid=session_id();
    $fp=fopen("e://tmp//phpsid.txt","w+");
    fwrite($fp,$psid);
    fclose($fp);
    //身份验证成功,进行相关操作
    echo "已登录<br>";
    echo "<a href=/'mylogin2.php/'>下一页</a>";
    ?>

     


    mylogin2.php

    <?php
    $fp=fopen("e://tmp//phpsid.txt","r");
    $sid=fread($fp,1024);
    fclose($fp);
    session_id($sid);
    session_start();
    if(isset($_SESSION['user']) && $_SESSION['user']="laogong" ) {
    echo "已登录!";
    }
    else {
    //成功登录进行相关操作
    echo "未登录,无权访问";
    echo "请<a href=/'login.html/'>登录</a>后浏览";
    die();
    }
    ?>

     http://bbs.csdn.net/topics/392147309?page=1#post-402234038

    1.

    <?php
    Session_start(); //使用SESSION前必须调用该函数。
    $_SESSION['name']="我是黑旋风李逵!"; //注册一个SESSION变量
    $_SESSION['passwd']="mynameislikui";
    $_SESSION['time']=time();
    echo '<br /><a href="ph2.php">通过COOKIE传递SESSION</a>'; //如果客户端支持cookie,可通过该链接传递session到下一页。
    echo '<br /><a href="ph2.php?' . SID . '">通过URL传递SESSION</a>';//客户端不支持cookie时,使用该办法传递session.
    ?>

    2.

    <?php
    session_start();
    echo $_SESSION['name']; //
    echo $_SESSION['passwd']; //
    echo date('Y m d H:i:s', $_SESSION['time']);
    echo '<br /><a href="ex7_1.php">返回山一页</a>';

    3.

    <?php
    session_start();
    $old_sessionid = session_id();
    session_regenerate_id();
    $new_sessionid = session_id();
    echo "原始 SessionID: $old_sessionid<br />";
    echo "新的 SessionID: $new_sessionid<br />";
    echo"<pre>";
    print_r($_SESSION);
    echo"</pre>";
    ?>

    4.

    <?php
    session_start();
    $_SESSION['var1']="中华人民共和国";
    $sn = session_id();
    $url="<a href='./s2.php?s=.$sn./'>下一页</a>"; //PHP5定义了一个常量SID来表示session_id(),$url还可以写成$url='<a href="page2.php?' . SID . '">下一页</a>';
    echo $url;
    ?>

    5.

    <?php
    session_start();
    echo "传递的session变量var1的值为:".$_SESSION['var1'];
    ?>

    6.

    <!DOCTYPE html="">HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>Login</title>
    <meta http-equiv="Content-Type" content="text/html;">
    </head>
    <body>
    请登录:
    <form method="post" action="mylogin1.php">
    用户名:<input name="name" type="text" ><br>
    口 令:<input name="pass" type="password" ><br>
    <input type="submit" value="登录">
    </form>
    </body>
    </html>

    7.

    <?php
    $name=$_POST['name'];
    $pass=$_POST['pass'];
    if(!$name || !$pass) {
    echo "用户名或密码为空,请<a href=/'login.html/'>重新登录</a>";
    die();
    }
    if (!($name=="laogong" && $pass=="123")) {
    echo "用户名或密码不正确,请<a href=/'login.html/'>重新登录</a>";
    die();
    }
    //注册用户
    ob_start();
    session_start();
    $_SESSION['user']= $name;
    $psid=session_id();
    $fp=fopen("e://tmp//phpsid.txt","w+");
    fwrite($fp,$psid);
    fclose($fp);
    //身份验证成功,进行相关操作
    echo "已登录<br>";
    echo "<a href=/'mylogin2.php/'>下一页</a>";
    ?>

    8.

    <?php
    $fp=fopen("e://tmp//phpsid.txt","r");
    $sid=fread($fp,1024);
    fclose($fp);
    session_id($sid);
    session_start();
    if(isset($_SESSION['user']) && $_SESSION['user']="laogong" ) {
    echo "已登录!";
    }
    else {
    //成功登录进行相关操作
    echo "未登录,无权访问";
    echo "请<a href=/'login.html/'>登录</a>后浏览";
    die();
    }
    ?>

  • 相关阅读:
    Git core objects
    各平台预定义的宏
    跨平台获取可执行文件的目录
    Windows、Linux、Mac OSX编译jni动态库
    xmpp整理笔记:发送图片信息和声音信息
    xmpp整理笔记:聊天信息的发送与显示
    xmpp整理笔记:用户网络连接及好友的管理
    小技巧,如何在Label中显示图片
    xmpp整理笔记:xmppFramework框架的导入和介绍
    xmpp整理笔记:环境的快速配置(附安装包)
  • 原文地址:https://www.cnblogs.com/feiyun8616/p/6652416.html
Copyright © 2011-2022 走看看