zoukankan      html  css  js  c++  java
  • 深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现

    1.session的注意点:
    @session_start();//这个配置需要注意,session开启中会有影响,所以使用错误抑制符进行限制【并且使用php.ini对session进行自动开启】

    session_start()前的输出问题:
    【session信息本身会增加到http头信息,也就是http主体不能在头前】
    对php.ini中的输出缓存进行配置,out_buffer的配置【注意:开启之后能够保证输出内容在脚本中缓存】

    【注意】
    (1)脚本中session变量的键只能是字符串类型的【$_SESSION[10]这样是错误的,因为session本身是需要进行序列化】
    (2)如果不声明session_start()的话,$_SESSION变量就相当于一个普通数组进行操作【与session文件不进行交互】
    (3)不能unset来删除$_SESSION来删除所有session变量,而是通过将session设置为空来实现【unset只是将读取出来的session数据销毁,对session文件的数据无影响】
    (4)删除session文件【session_destory()实现对session文件的销毁】【只删除文件,不会对$_SESSION变量进行处理】【一旦执行session_destory操作,不会再执行session写操作,即使有session变量存在】
    【注意完全删除一个session:将与当前session相关的数据完全销毁之后,再删除文件以及sessionID(在cookie中)的删除】
    【完全删除session需要考虑的就是会话机制本身】

    2.session的存储处理
    session.save_path进行session文件的路径修改

    当请求变多之后,session文件会变多,此时如何管理?
    通过session.save_path进行多级子目录进行管理【根据sessionID进行分级管理】

    sessionID的形成算法:hash【session.hash_bits_per_character = 5(这里表示第一级子目录总共有2^5=32种分别为0-9,a-v)】

    session文件的管理还是有问题:
    文件量大,管理不方便
    难共享【分布式的服务器的管理问题】

    解决方案:将session数据放入数据库服务器中进行保存管理【将session入库的处理】


    3.session入库
    将session机制中读文件和写文件的机制,通过数据库进行介入管理。
    【设置一个公共类进行session入口的所有方法】

    session_set_save_handle();//函数的使用,结合session的机制,进行调用指定的方法
    这个方法的使用,按照一定的顺序进行规范调用。
    //关于session的文件创建(入库不需要文件创建)和需要session读写等操作的机制还是session自身的机制【所以需要使用指定的session函数:session_set_save_handle以及内部的方法要具体实现】
    【相当于实现了一个注册函数,结合php内部机制实现session的入库操作(只是入库将session机制本身需要创建的文件,改为对数据库的操作)】
    session入库本身就是讲原本要写入文本中的数据,写入数据库中【从而解决了session文本太过多,难以管理】


    设计存入数据库表内的数据的格式【数据类型,因为sessionID本身就是唯一或者主键形式的】


    【注意】
    【对session的入库操作需要单独进行封装,不过也不需要感觉太难,就是不使用session对文件处理的机制,对文件的写文件等机制进行session_set_save_handle重写(保存session基本机制(对session处理的时机不变),只有读写针对的情景不一样),将session对文件的处理移到数据库读写来提升性能】
    session_set_save_handle:执行的顺序需要注意
    对open和close的方法进行初始化和析构处理

    4.session的垃圾回收
    session里的gc函数实现session的垃圾回收【因为session的垃圾回收比脚本要特殊,脚本结束,php垃圾回收,但是session需要先写数据,然后再释放】

    如果session入库之后,由于session中保存的没有用的sessionID也需要进行回收,这也属于session的垃圾回收
    【如何判断是否失效的原则】
    cookie中如果sessionID失效,也会导致session内的ID失效(cookie中保存sessionID被刷新,那么服务器上保存的id再也找不到对应的id,此时服务器上的id便后失效)【失效sessionID其实出现的次数非常多】
    php处理sessionID是否是垃圾的原则:php认为某条ID多长时间不使用,来判断是否是垃圾【垃圾回收基于时间:默认1440s,通过php配置进行修改】


    session.gc相关的配置都是关于session的垃圾处理【每当开启session_start()都会有概率进行垃圾回收】
    【session_start()会进行垃圾回收的查找,但是只是有几率进行gc垃圾回收,这也是为了提升性能。因为并不是,每次session_start都会实现一次gc垃圾处理】
    【用mysql入库的数据内进行时间来判断垃圾回收的处理机制:这里的处理机制更加容易控制】


    【session_set_save_handle:执行的顺序有合理性,删除在读取之后,能够保证即使过期还是可以正常读取(有可能)】

    【重点!!!】
    【使用入库之后处理session的顺序需要自己对session处理的机制】
    (1)session_start()。首先进行open【操作初始化】
    (2)执行read,进行读取
    (3)有可能执行gc垃圾回收
    (4)在脚本执行过程中时,会针对session变量和有可能执行session_destory
    (5)脚本执行完成,如果没有执行session_destory,那么就会执行一个write操作
    (6)脚本执行完成后,进行close操作

    以上就是把session在脚本中执行的顺序


    5.session中常见的问题
    (1)session和cookie的区别和联系
    存储位置,安全级别。二者的联系也是sessionID
    (2)session数据的有效期
    浏览器关闭。
    请求中的cookie保存的sessionID失效【默认中的sessionID的cookie变量是一个临时变量】
    【这一点要注意,如果没有将cookie中的sessionID进行持久化,那么重新开启一个浏览器,就相当于重新获得一个sessionID】
    (3)由问题2带来一个问题:如何持久化session。【同一个用户的再次开启同一个浏览器的话,能够获得同一个sessionID】
    延长cookie变量的有效期【持久化sessionID的cookie变量】
    至于session本身的保留跟session的持久化只是一部分
    【只有cookie中关于sessionID做到持久化,session中保留的数据才有意义】
    【不过服务器端对session保存的时间的长短也要和cookie中设置的sessionID的时间要统一】


    session_set_cookie_params();//这个函数的使用
    setcookie();//两个函数都正常


    (4)cookie禁用,session并不能用【url传递sessionID并不安全】
    session.use_only_cookie:进行session使用的配置


    以上就是session的所有问题

    6.设计列表:分类管理【重点】
    无限分类【一级一级的分类下去:用于头部或者对层级深度的不同进行一级级展示】
    树状列表【各级节点:节点关系由数据表进行关联】
    【n个节点(数据),n-1条边(数据关系:通过一个字段来实现关联)】
    实现无限分类

    【重点】
    如何将关联的数据进行联系【数据库实现上下级的关联创建!!!】
    【sql语句的查找是关键:sql将该节点上的值取出来和任何节点中判断父节点的值,将结果进行返回即可实现】

    在插入数据时的配置也需要对类id和关联id进行对应添加,这一点也是创建分类时的关键


    【重点】
    利用递归实现无限分类
    【一次性获取所有的数据,将数据进行递归查找】【节省数据库开销】
    这一点思路要注意【虽然表示sql语句中进行条件判断的思路比较容易整理,但是通过这样的一次性操作,然后对数组进行分组之后进行无线分类显示能够实现功能】
    【只要有这个对数组操作的思路即可实现递归,递归的一级级的判断依据就是父id是否等于子数据中的关联id,来进行递归】
    【递归点和递归出口时递归需要注意的重点,而这个无线分类的递归其实更加简单,只要针对条件进行递归即可,不需要有递归出口】
    【递归中需要共享所有递归的结果放在一个容器中,所以需要使用静态变量来做数组容器】


    例子:
    <?php


    //一:
    mysql_connect('127.0.0.1:3306', 'root', '123456');
    $sql = "select * from itcast_shop.it_category where 1 order by sort_order";
    $result = mysql_query($sql);
    while($row = mysql_fetch_assoc($result)) {
    $list[] = $row;
    }
    echo '<pre>';
    //var_dump($list);


    //二,递归查找
    /**
    *
    * @param $arr array 当前所有的可能分类,在该数组内查找子分类
    * @param $p_id int 当前查找的父ID
    *
    * @param $deep int 当前递归调用的深度
    *
    * @return array 排序好的数组列表!
    */
    function getTree($arr, $p_id, $deep=0) {
    //利用一个静态局部变量将所有依次找到的元素,都保存
    static $tree = array();
    //遍历所有的可能分类,找到parent_id==$p_id
    foreach($arr as $row) {
    //判断是否为子分类
    if($row['parent_id'] == $p_id) {
    //是子分类
    //记录当前所找到
    $row['deep'] = $deep;
    $tree[] = $row;
    //利用当前查找的分类,找其子分类
    //递归调用
    getTree($arr, $row['cat_id'], $deep+1);
    }
    }

    return $tree;
    }

    $tree = getTree($list, 0);

    //var_dump($tree);

    foreach($tree as $row) {
    echo $row['deep'];
    echo str_repeat('&nbsp;&nbsp;', $row['deep']);//将一个字符串重复
    echo $row['cat_name'];
    echo '<br>';
    }

    以上实现了递归调用的方法【重点递归的实现和递归的容器需要考虑静态变量来实现】

  • 相关阅读:
    【转】Oracle学习系列
    昏昏昏昏昏昏,怎么变成这样了。:(
    SQLServer 2K 安装重复出现挂起问题解决办法
    ORM iBATIS 学习,没弄清楚。
    MagicLinux让我用我一个方便的方法引导你吧。
    SOA大赛初赛文档已经提交.心中大石掉下.
    继续一下目标。
    ORM已经理解了.
    Spot the Bug Episode 2 中BUG的修改
    MaglicLinux启动加入了BOO.INI搞定.这个方便了.
  • 原文地址:https://www.cnblogs.com/shuoshuren/p/4231857.html
Copyright © 2011-2022 走看看