页面跳转时中间参数保存(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测试代码:
<form method="post">
<input type="submit" name="submit" value="ok !">
</form>
<?php
$m = new Memcache();
$m->connect('localhost', '11211'); //栈的有效期为从现在开始今天的剩余时间
$tomorrow = strtotime('tomorrow');
$now = time();
$expire = $time_remaind = $tomorrow-$now; if (!empty($_POST['submit'])) {
$url_refer = out($m, $expire);
if ($url_refer) {
header("Location: http://$url_refer");
exit;
}
} else {
in($m, $expire);
} //入栈
//判断是刷新的话不再将当前URL记入栈
function in($m, $expire)
{
$url_now = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $jsonStack = $m->get('zzb');
if (empty($jsonStack)) {
$arrStack = array();
$arrStack[] = $url_now;
} else {
$arrStack = json_decode($jsonStack, true);
$url_refer = array_pop($arrStack);
if ($url_refer == $url_now) {
$arrStack[] = $url_refer;
} else {
$arrStack[] = $url_refer;
$arrStack[] = $url_now;
}
}
$jsonStack = json_encode($arrStack);
$m->set('zzb', $jsonStack, MEMCACHE_COMPRESSED, $expire);
} //出栈
//如果没有获得来源URL,则还是跳转到本页面
function out($m, $expire)
{
$jsonStack = $m->get('zzb');
if (empty($jsonStack)) {
echo 'empty stack<br>';
}
$arrStack = json_decode($jsonStack, true); $url_now = array_pop($arrStack);
$url_refer = array_pop($arrStack); $jsonStack = json_encode($arrStack);
$m->set('zzb', $jsonStack, MEMCACHE_COMPRESSED, $expire); return $url_refer;
}
html 按钮表示进入此页操作完成后,提交返回
下边是cookie的测试代码(判断是否是刷新行为时,可以用PHP的end()函数代替array_pop()):
<?php
ob_start();
if (!empty($_POST['submit'])) {
$url_refer = out();
if ($url_refer) {
header("Location: http://$url_refer");
exit;
}
} else {
in();
} //入栈
//判断是刷新的话不再将当前URL记入栈
function in()
{
$url_now = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $jsonStack = empty($_COOKIE['zzb']) ? '' : $_COOKIE['zzb'];
if (empty($jsonStack)) {
$arrStack = array();
$arrStack[] = $url_now;
} else {
$arrStack = json_decode($jsonStack, true);
$url_refer = array_pop($arrStack);
if ($url_refer == $url_now) {
$arrStack[] = $url_refer;
} else {
$arrStack[] = $url_refer;
$arrStack[] = $url_now;
}
}
echo '<pre>';
print_r($arrStack);
$jsonStack = json_encode($arrStack);
setcookie('zzb', $jsonStack);
} //出栈
//如果没有获得来源URL,则还是跳转到本页面
function out()
{
$jsonStack = empty($_COOKIE['zzb']) ? '' : $_COOKIE['zzb'];
if (empty($jsonStack)) {
echo 'empty stack<br>';
}
$arrStack = json_decode($jsonStack, true); $url_now = array_pop($arrStack);
$url_refer = array_pop($arrStack);
echo '<pre>';
var_dump($url_refer, $url_now);
print_r($arrStack); $jsonStack = json_encode($arrStack);
setcookie('zzb', $jsonStack); return $url_refer;
}
?>
<form method="post">
<input type="submit" name="submit" value="ok !">
</form>
-------------分割线---------
刚才准备把这个功能应用到项目中去,但是发现,当时写代码的时候只图方便省事,把所有的功能都写到了一个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;
}
没有显示行号,方便有用到的同学复制(*^__^*)
页面跳转时中间参数保存(memcache/cookie)的更多相关文章
- Spring MVC 页面跳转时传递参数
页面仍然使用 JSP,在跳转时如果想传递参数则需要用到类 RedirectAttributes. 首先看看如何打开一个普通页面: // 登录页面(每个页面都要独立的 Action 来支持其呈现) @R ...
- VUE:页面跳转时传递参数,及参数获取
https://www.cnblogs.com/zhongchao666/p/9679807.html https://blog.csdn.net/mf_717714/article/details/ ...
- 页面跳转时,url 传大数据的参数不全的问题+序列化对象
1.页面跳转时,url 传大数据的参数不全的问题 //传参: url: '/pages/testOfPhysical/shareEvaluation?detailInfo=' +encodeURICo ...
- 自定制页面跳转时携带原搜索参数的URL
介绍 django自带反向解析生成URL的功能,目的是避免硬编码,较少代码维护的代价. 前端页面使用模板语法,如:{% url "rbac: request menu_list" ...
- [Xcode 实际操作]九、实用进阶-(24)使用Segue(页面的跳转连接)进行页面跳转并传递参数
目录:[Swift]Xcode实际操作 本文将演示使用Segue(页面的跳转连接)进行页面跳转并传递参数. 参照结合:[Xcode10 实际操作]九.实用进阶-(23)多个Storyboard故事板中 ...
- 微信小程序:页面跳转时传递数据到另一个页面
一.功能描述 页面跳转时,同时把当前页面的数据传递给跳转的目标页面,并在跳转后的目标页面进行展示 二.功能实现 1. 代码实现 test1页面 // pages/test1/test1.js Page ...
- [android]-如何在向服务器发送request时附加已保存的cookie数据
[android]-如何在向服务器发送request时附加已保存的cookie数据 应用场景:在开发android基于手机端+服务器端的应用时,登陆->获取用户信息->获取授权用户相关业务 ...
- 微信小程序页面跳转,带参数跳转
1. wx.navigateTo (保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面.) 路径:只能跳转非tabbar路径 参数: 'path?key=v ...
- 使用iframe框架后的页面跳转时目标页面变为iframe的子页面的问题
<frameset rows="4,200,10,*,120" cols="*" framespacing="0" framebord ...
随机推荐
- Redis 通信协议简单研究
1.Redis网络通信协议 Redis底层网络通信协议其实是通过TCP来完成的. 2.Redis通信协议 Redis的通信协议首先是以行来划分,每行以\r\n行结束.每一行都有一个消息头,消息头共分为 ...
- 洛谷P13445 [USACO5.4]奶牛的电信Telecowmunication(网络流)
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...
- hdu6444 Neko's Loop
要想A一道题,你需要正版ide,正版草稿纸,正版键盘,正版双手,但最重要的是正版大脑.(改编自wxf在微积分群的吐槽) 分析一下题意,选的所有数的下标模gcd(n,k)都是同余的,而且是在所有同余的下 ...
- BZOJ2622 深入虎穴(最短路径)
如果对某个点能求出与其相邻的所有点到达出口的最短时间,那么该点的答案就可以在其中取次小值了. 对于dijkstra魔改一下就能做到这个.初始时将所有出口的最短时间设为0并放入堆,记录最短和次短路径,每 ...
- oracle clob blob dblink
Create global temporary table temp on commit preserve rows as select * from abc@xxx select * from te ...
- 以 BZOJ 2002 为例学习有根树LCT(Link-Cut Tree)
以BZOJ 2002 弹飞绵羊为例学习有根树LCT(Link-Cut Tree) 注:本文非常简单,只涉及有根树LCT,对于无根树,LCT还有几个本文没有提到的操作,以后慢慢更新 =v= 知识储备 [ ...
- HGOI 20181103 题解
problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...
- NOIP2018备考——DP专题练习
P4095 [HEOI2013]Eden 的新背包问题 P2657 [SCOI2009]windy数 P3413 SAC#1 - 萌数 P3205 [HNOI2010]合唱队 P476 ...
- 【codevs1245】最小的 N 个和
题目大意:给定两个有 N 个数字的序列,从这两个序列中任取一个数相加,共有 \(N^2\) 个和,求这些和中最小的 N 个. 题解:由于数据量是 10W,必须减少每次选取的决策集合中元素的个数.可以发 ...
- python独立环境virtualenv(并在pycharm中指定)
上篇文章中讲到 Django 如何启动以及配置 sessions 功能.sessions 功能用是跟踪用户的状态,经常结合 Cookie 功能实现自动登录功能. 所谓的“自动登录”指的是:我们登录一些 ...