zoukankan      html  css  js  c++  java
  • 页面跳转时中间参数保存(memcache/cookie)

    2014年1月19日 17:30:27

    我这篇文章就说了一句话:用cookie保存页面间跳转时的参数

    情景: 客服在后台操作的时候,经常从列表页进入到编辑页,编辑完信息后,还要自动返回之前的列表页

    问题:

    1.如果客服是从列表第二页跳转到编辑页面,那么编辑完成后应该会自动跳转到列表页的第二页,这样就牵扯到这个"第二页"的参数的保存问题

    2.如果是多个页面一层层深入,那么中间参数保存是很浪费脑细胞的

    方案:

    之前想过两种方法:一是用smarty模版插件保存,二是:用程序保存.但这都会使程序中徒添很多与逻辑无关的代码,跳转赋值保存非常麻烦

    现在又想起了两种方法:

    前提:用PHP数组模拟"栈",将客服操作的URL用栈保存下来

    第一种方案:用cookie/session保存这个"栈",达到跳转间保存URL的目的(建议使用)

    第二种方案:用memcache保存这个栈(或者用其他nosql直接使用其栈的功能)

    我刚刚实现了用memcache保存栈的目的,用cookie和session也一样

    优缺点:

    cookie/session可以设置expire=0(有效期)来保证管理员关闭浏览器后清除所有操作历史(cookie栈)

    也可以设置expire=n,来指定保存栈的时间

    选用memcache没什么优点,只是我在一开始想到了用memcache来实现这个功能,后来代码写完了,才想起来cookie/session方案,不过原理都一样

    用服务器内存存储时要注意,栈名称要根据管理员来区分,用cookie的话则不用担心这个

    缺点:

    栈内只保存了URL,也就是说只能保存get中间参数,对于中间参数有post的就不能记录了

    cookie的数量大小各个浏览器有限制:http://blog.sina.com.cn/s/blog_59b6f23e0100a703.html

    注意:如果程序执行时,连续设置同名cookie,而不刷新页面,只有最后一步的cookie设置会生效

    例如:

    你的程序有两段代码:

    第一段先执行清空cookie的代码

    第二段再重新给cookie赋值,

    这两步之间不把cookie输出到客户端浏览器,则清空cookie那个步骤是不起作用的,不管是用setcookie()还是header('Set-Cookie: ....'),都不行

    下边贴出memcache测试代码:

     1 <form method="post">
     2     <input type="submit" name="submit" value="ok !">
     3 </form>
     4 <?php
     5 $m = new Memcache();
     6 $m->connect('localhost', '11211');
     7 
     8 //栈的有效期为从现在开始今天的剩余时间
     9 $tomorrow = strtotime('tomorrow');
    10 $now = time();
    11 $expire = $time_remaind = $tomorrow-$now;
    12 
    13 if (!empty($_POST['submit'])) {
    14     $url_refer = out($m, $expire);
    15     if ($url_refer) {
    16         header("Location: http://$url_refer");
    17         exit;
    18     }
    19 } else {
    20     in($m, $expire);
    21 }
    22 
    23 //入栈
    24 //判断是刷新的话不再将当前URL记入栈
    25 function in($m, $expire)
    26 {
    27     $url_now = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    28 
    29     $jsonStack = $m->get('zzb');
    30     if (empty($jsonStack)) {
    31         $arrStack = array();
    32         $arrStack[] = $url_now;
    33     } else {
    34         $arrStack = json_decode($jsonStack, true);
    35         $url_refer = array_pop($arrStack);
    36         if ($url_refer == $url_now) {
    37             $arrStack[] = $url_refer;
    38         } else {
    39             $arrStack[] = $url_refer;
    40             $arrStack[] = $url_now;
    41         }
    42     }
    43         $jsonStack = json_encode($arrStack);
    44         $m->set('zzb', $jsonStack, MEMCACHE_COMPRESSED, $expire);
    45 }
    46 
    47 //出栈
    48 //如果没有获得来源URL,则还是跳转到本页面
    49 function out($m, $expire)
    50 {
    51     $jsonStack = $m->get('zzb');
    52     if (empty($jsonStack)) {
    53         echo 'empty stack<br>';
    54     }
    55     $arrStack = json_decode($jsonStack, true);
    56 
    57     $url_now = array_pop($arrStack);
    58     $url_refer = array_pop($arrStack);
    59 
    60     $jsonStack = json_encode($arrStack);
    61     $m->set('zzb', $jsonStack, MEMCACHE_COMPRESSED, $expire);
    62 
    63     return $url_refer;
    64 }
    View Code

    html 按钮表示进入此页操作完成后,提交返回

    下边是cookie的测试代码(判断是否是刷新行为时,可以用PHP的end()函数代替array_pop()):

     1 <?php
     2 ob_start();
     3 if (!empty($_POST['submit'])) {
     4     $url_refer = out();
     5     if ($url_refer) {
     6         header("Location: http://$url_refer");
     7         exit;
     8     }
     9 } else {
    10     in();
    11 }
    12 
    13 //入栈
    14 //判断是刷新的话不再将当前URL记入栈
    15 function in()
    16 {
    17     $url_now = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    18 
    19     $jsonStack = empty($_COOKIE['zzb']) ? '' : $_COOKIE['zzb'];
    20     if (empty($jsonStack)) {
    21         $arrStack = array();
    22         $arrStack[] = $url_now;
    23     } else {
    24         $arrStack = json_decode($jsonStack, true);
    25         $url_refer = array_pop($arrStack);
    26         if ($url_refer == $url_now) {
    27             $arrStack[] = $url_refer;
    28         } else {
    29             $arrStack[] = $url_refer;
    30             $arrStack[] = $url_now;
    31         }
    32     }
    33 echo '<pre>';
    34 print_r($arrStack);
    35         $jsonStack = json_encode($arrStack);
    36         setcookie('zzb', $jsonStack);
    37 }
    38 
    39 //出栈
    40 //如果没有获得来源URL,则还是跳转到本页面
    41 function out()
    42 {
    43     $jsonStack = empty($_COOKIE['zzb']) ? '' : $_COOKIE['zzb'];
    44     if (empty($jsonStack)) {
    45         echo 'empty stack<br>';
    46     }
    47     $arrStack = json_decode($jsonStack, true);
    48 
    49     $url_now = array_pop($arrStack);
    50     $url_refer = array_pop($arrStack);
    51 echo '<pre>';
    52 var_dump($url_refer, $url_now);
    53 print_r($arrStack);
    54 
    55     $jsonStack = json_encode($arrStack);
    56     setcookie('zzb', $jsonStack);
    57 
    58     return $url_refer;
    59 }
    60 ?>
    61 <form method="post">
    62     <input type="submit" name="submit" value="ok !">
    63 </form>
    View Code

     -------------分割线---------

    刚才准备把这个功能应用到项目中去,但是发现,当时写代码的时候只图方便省事,把所有的功能都写到了一个controller里了,导致该功能入口需要很大的改变

    如果把不同的功能写到不同的控制器中,这样可以为每个控制器开一个栈,逻辑实现会简单些,but ...... 错呀

    --------------再分------------

    上边说的和解决的都是理论情景:列表页->子列表页->子列表页->...->进入某列表项->一层层返回

    但实际经常遇到情况是:列表页->进入某列表项->返回列表

    如果功能逻辑被设计成理论情况,即多层进入,多层返回,那就是设计有问题,需要重新设计

    下边是用cookie写的单层进入返回(列表页->进入某列表项->返回列表):

      public function in($FunctionModule)
        {
            ob_start();
            $url_now = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
     
            //每次都重写栈,保证栈内只有一个元素,适合单层跳转
            $arrStack = array($url_now);
            $jsonStack = json_encode($arrStack);
            
            setcookie($FunctionModule, $jsonStack);
            return;
        }
    
    
        public function out($FunctionModule)
        {
            ob_start();
            $jsonStack = empty($_COOKIE[$FunctionModule]) ? '' : $_COOKIE[$FunctionModule];
            
            if (empty($jsonStack)) {
                return '';
            }
            
            $arrStack = json_decode($jsonStack, true);
            $url_refer = array_pop($arrStack);
            $jsonStack = json_encode($arrStack);
            
            setcookie($FunctionModule, $jsonStack);
    
            return $url_refer;
        }

    没有显示行号,方便有用到的同学复制(*^__^*)

  • 相关阅读:
    javascript实现数据结构:串--堆分配存储表示
    javascript实现数据结构:串--定长顺序存储表示以及kmp算法实现
    javascript实现数据结构与算法系列:队列 -- 链队列和循环队列实现及示例
    javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
    线性链表的例子:一元多项式
    javascript实现数据结构与算法系列:功能完整的线性链表
    javascript实现数据结构与算法系列:循环链表与双向链表
    javascript实现数据结构与算法系列:线性表的静态单链表存储结构
    javascript实现数据结构:线性表--线性链表(链式存储结构)
    javascript实现数据结构:线性表--简单示例及线性表的顺序表示和实现
  • 原文地址:https://www.cnblogs.com/iLoveMyD/p/3526065.html
Copyright © 2011-2022 走看看