我在 CakePHP 中发现的一个简洁的功能是能够设置flash
消息,比如在某些save
脚本上,然后将该消息显示在下一页上。类似的东西,Post updated
或Error - no file found.
蛋糕的方式就是用这个session
对象。我试图避免像瘟疫这样的会话,因为它们对可扩展性有奇怪的要求。我不能简单地将闪存消息存储在 cookie(客户端)中,然后在该 cookie 显示在下一页上后将其删除吗?这种方法的一些优点/缺点是什么 - 或者更简单地说,为什么 Cake 使用session
(我假设这与_SESSION
集合有关)。
干杯!
附言在我的实现中,我还在javascript中使用setTimeout
命令使其淡出。我发现这是结束整个过程的好方法。
cookie 的问题在于用户可能会禁用此功能。如果是这样,您的 Flash 消息将不会显示。CakePHP 尽量足够通用并使用会话存储。
您有 3 个选项:
- 会话:最常用的方法。它可以在任何客户端计算机上运行,但正如您所说,它可能会给某些服务器配置带来问题。
- Cookie:一般来说,这是一个不错的选择,但用户可能会阻止这种机制。仅当您的应用要求包括需要 Cookie 时,才推荐使用。
- 数据库:通用解决方案。问题是它需要访问数据库(慢)。ID 应与 URL(GET 方法)一起传递,以便应用程序知道哪个数据库寄存器对应于此访问。
在我的应用程序中,我使用第二种和第三种方法的组合:我测试 cookie,如果它们可用,我就使用它们。如果没有,我使用数据库访问,但我总是缓存数据库访问,以便不会对每条消息进行多次查询。
我不明白为什么你不能使用自创建日期起 10 分钟过期的 cookie。 如果用户离开并在 11 分钟内回来,他们可能不会看到 flash cookie 消息,则不利之处......但是您不必担心用 cookie 淹没客户端。
只需制定一些简单的内容规则,以确保没有特权信息放入闪存消息中,您应该很好。
一个简单的实现可以是这样的过程:
function setFlash($id ,$message){
setcookie("flash_{$id}", $message, time() + 60 * 10);
}
function getFlashes(){
$flashes = array();
foreach($_COOKIE as $id => $value){
if(strpos($id, "flash_") === 0){
$flashes[$id] = $value;
//clear flash and set expiration to 10 minutes in past
setcookie($id, "", time() * 60 * -10);
}
}
return $flashes;
//Input cleansing not included for brevity/clarity
}
或者,如果闪存来自客户端,则可以使用类似 https://github.com/marcuswestin/store.js 的内容来尝试使用localSession存储来管理闪存消息。
另一个想法是通过 url 中的哈希传输消息:
if (isset($_POST['submit'])) {
...
header("Location: ".$_SERVER["REQUEST_URI"]."#".urlencode($msg));
...
}
优势:
- 在没有cookie/会话/数据库/内存缓存等的情况下工作:-)
- 不像 cookie 那样依赖客户端时钟
- 没有其他客户端请求可以"窃取"消息
缺点:
- 看起来很丑 最大安全 URL 长度为
- 2000 个字符(请参阅不同浏览器中 URL 的最大长度是多少?
- 需要客户端 JavaScript 来读取和显示哈希值
- 如果已添加书签:每次都会再次显示消息
不幸的是,会话在后面跟标题("位置...")时并不总是可靠的;
我正在考虑按照建议将其放入GET请求或哈希标签中,您可以使用javascript使用window.history.pushState从URL中删除它。
编辑:除非使用session_write_closed();。