【发布时间】:2014-03-18 00:50:55
【问题描述】:
我正在努力为我的用户提供流畅的数据输入体验,即使他们离开浏览器一段时间,然后回来发现他们已经因为会话超时而被注销。
就我而言,这一点尤其重要,因为我要求我的用户在问卷中输入可能超过 100 个的答案(有点像所得税表)。因此,如果不时不时遇到会话超时,他们无法一直响应所有这些答案,这是完全可以理解的。
我一直在阅读有关如何最好地保留用户输入的数据直到超时发生的信息,并决定构建一个解决方案,其中用户的答案首先存储在会话变量中,并且在会话超时时,存储在数据库中。我还将文件名存储在发生会话超时的数据库中,以便我可以将用户带回那个地方。
现在可以了。因此,如果发生超时,则要求用户再次登录,然后将其带回问卷中发生超时的地方。到目前为止,一切顺利。
但我怀疑我的解决方案的效率。当我查看存储在客户端 PC(即我的 PC;使用 XAMMP-PHP-MySQL 设置)上的 cookie 中的会话信息时,我看到了我刚刚存储在数据库中的所有信息,很好地位于 cookie 中.会话超时后,cookie 仍保留在客户端的 PC 上。在客户端再次登录后,将客户端 cookie 的内容读取到新会话中对我来说不是更简单吗?我知道饼干的名字。但是我找不到将 cookie 中的 key=>value 对读入新会话变量的好例子。 cookie 如下所示:
last_active|i:1392715552;loginName|s:4:"Carl";password|s:7:"secret";answer|s:17:"log in and finish";auth|s:3:"yes";logname|s:4:"Carl";LastLogin|s:19:"2014-02-18 15:59:16";SearchCredits|s:4:"1144";UniqueClockRecordID|s:13:"530320ebd7d20";ClockType|s:0:"";ClockMaterial|s:0:"";MovementDuration|s:0:"";TypeOfTrains|s:0:"";SameBarrel|s:0:"";PassingStrike|s:0:"";TypeStriking|s:0:"";StrikingMechanism|s:0:"";ChimeMelodies|s:4:"NULL";ChimeMechanism|s:0:"";BellOrGong|s:0:"";HowManyBells|s:0:"";SortGong|s:0:"";WheelsGoingTrain|s:4:"NULL";WheelsStrikingTrain|s:4:"NULL";WheelsChimingTrain|s:4:"NULL";WheelsAlarmTrain|s:4:"NULL";SubTypeLongcase|s:0:"";SubTypeChronometer|s:0:"";SubTypeStreet|s:0:"";SubTypeTable|s:0:"";SubTypeTurret|s:0:"";TypeAutoWinder|s:0:"";SubTypeWall|s:0:"";EscapementType|s:0:"";PlatformEscapementType|s:0:"";HowManyDials|s:0:"";SettingDial|s:0:"";ClockmakerOnDial|s:4:"NULL";RetailerOnDial|s:4:"NULL";CityOnDial|s:4:"NULL";CountryOnDial|s:4:"NULL";SayingOnDial|s:4:"NULL";AnythingElseOnDial|s:4:"NULL";FakeRealClockmaker|s:0:"";Clockmaker|s:4:"NULL";BestGuessClockmaker|s:4:"NULL";ClockmakerClockNumber|s:4:"NULL";ClockmakerOnClockPlates|s:4:"NULL";AnythingElseOnPlates|s:4:"NULL";OtherMarksOnClock|s:4:"NULL";ClockCountry|s:4:"NULL";EarliestClockMadeDate|s:10:"0000-00-00";LatestClockMadeDate|s:10:"0000-00-00";BestGuessClockMadeDate|s:10:"0000-00-00";MarriageOriginal|s:0:"";MarriageDescription|s:4:"NULL";Damaged|s:0:"";DamageDescription|s:4:"NULL";CaseStyle|s:0:"";BuildingType|s:0:"";CaseMaterial|s:0:"";CaseHeight|s:4:"NULL";CaseWidth|s:4:"NULL";CaseDepth|s:4:"NULL";PlinthHeight|s:4:"NULL";PlinthWidth|s:4:"NULL";PlinthDepth|s:4:"NULL";TrunkHeight|s:4:"NULL";TrunkWidth|s:4:"NULL";TrunkDepth|s:4:"NULL";HoodHeight|s:4:"NULL";HoodWidth|s:4:"NULL";HoodDepth|s:4:"NULL";CaseOther|s:4:"NULL";DialShape|s:0:"";DialDiameter|s:4:"NULL";DialHeight|s:4:"NULL";DialWidth|s:4:"NULL";DialThickness|s:4:"NULL";DialMaterial|s:0:"";FalsePlate|s:0:"";Hands|s:0:"";HandsMaterial|s:0:"";SubDials|s:0:"";ClockLevers|s:0:"";WeightSpring|s:0:"";GoingTrainWeight|s:4:"NULL";StrikingTrainWeight|s:4:"NULL";ChimingTrainWeight|s:4:"NULL";AlarmTrainWeight|s:4:"NULL";LengthSpringGoing|s:4:"NULL";HeightSpringGoing|s:4:"NULL";ThicknessSpringGoing|s:4:"NULL";LengthSpringStriking|s:4:"NULL";HeightSpringStriking|s:4:"NULL";ThicknessSpringStriking|s:4:"NULL";LengthSpringChiming|s:4:"NULL";HeightSpringChiming|s:4:"NULL";ThicknessSpringChiming|s:4:"NULL";LengthSpringAlarm|s:4:"NULL";HeightSpringAlarm|s:4:"NULL";ThicknessSpringAlarm|s:4:"NULL";GoingFusee|s:0:"";StrikingFusee|s:0:"";ChimingFusee|s:0:"";NumberOfPillars|s:4:"NULL";PlatesShape|s:0:"";PlateDiameter|s:4:"NULL";A_PlateTopWidth|s:4:"NULL";A_PlateBottomWidth|s:4:"NULL";PlateHeight|s:4:"NULL";PlateWidth|s:4:"NULL";FrameDepth|s:4:"NULL";PlateThickness|s:4:"NULL";CalendarType|s:0:"";MaintainingPowerType|s:0:"";StrikeSilent|s:0:"";RiseFall|s:0:"";PullRepeat|s:0:"";HoldFast|s:0:"";WindingKey|s:0:"";CaseKey|s:0:"";Pendulum|s:3:"yes";PendulumLength|s:6:"234567";PendulumTemperatureCompensation|s:3:"yes";PendulumTemperatureCompensationType|s:0:"";BalanceTemperatureCompensation|s:0:"";BalanceTemperatureCompensationType|s:0:"";PictureClockURL|s:4:"NULL";PictureClockImg|s:4:"NULL";AuctionedWhen|s:10:"0000-00-00";AuctionHouse|s:0:"";AuctionLotNumber|s:4:"NULL";AuctionedInCity|s:4:"NULL";RealisedAuctionValue|s:4:"NULL";RealisedAuctionValueCurrency|s:0:"";EstimatedValueClock|s:4:"NULL";EstimatedValueClockCurrency|s:0:"";MoreInfoOnClock|s:4:"NULL";OtherPartsToClock|s:4:"NULL";TickingSoundClock|s:4:"NULL";StrikingSoundClock|s:4:"NULL";ChimingSoundClock|s:4:"NULL";AlarmSoundClock|s:4:"NULL";ClockForSale|s:0:"";PriceForSale|s:4:"NULL";PriceForSaleCurrency|s:0:"";Stolen|s:0:"";MissingDate|s:10:"0000-00-00";FinalComment|s:4:"NULL";
虽然 cookie 内容清楚地显示了 key=>value 对设计,但我相信它只是写成一个长字符串。我需要某种解析器来将此 cookie 写回到新的会话变量中。是否有现有的程序可以做到这一点?
之前,我选择了一个基于读取 cookie 的解决方案,与临时存储会话值相比,我希望获得一些关于使用 cookie 将我的用户带回会话超时的智慧的智慧在数据库中,就像我目前所做的那样。
【问题讨论】:
-
请告诉我您没有将客户端用户名和密码存储在客户端 PC 上的持久 cookie 中。
-
1) 会话数据不存储在客户端 cookie 中。它是如何到达那里的? 2) 为什么不做一个很长的会话超时? 3) 为什么不简单地将所有数据都存储在数据库中,而不是采用这种两层方法?
-
@Anigel:我自己并没有主动将客户端名称和密码存储在 cookie 中。但我确实将它们存储在会话中。我可以看到会话创建了一个 cookie,只要下次删除所有 cookie 时打开浏览器,该 cookie 就会持续。如果这仍然不安全,请告诉我。
-
您可以使用长寿命会话或心跳来保持会话活跃,我将在这里查看它们。或者,将已回答的问题提交并存储在服务器端,然后在他们重新登录时将其返回到最后回答的问题。您可以使用 ajax 或将问卷分解为他们提交的多个阶段来做到这一点。会话 id 是用户端会话 cookie 中唯一需要的东西
-
有谁知道为什么我的会话信息在 cookie 中可见?由于设置(可能在 php.ini 中),这是自动完成的吗?我还没有编写任何创建 cookie 的代码。我只是在每个新页面上使用 session_start() 来确保会话变量在页面之间存在。
标签: php cookies logout session-timeout