簡體   English   中英

如何在長時間運行的腳本中“觸摸” php會話

[英]How can I “touch” a php session during long running script

我們的PHP項目有一個維護腳本,該腳本以特定的時間間隔運行,並根據各個時間表執行一系列任務,將其視為php的CRON

我遇到的問題是,以一定間隔執行的某些任務的運行時間比我們強化的會話長度(30分鍾)長,因此會話在該任務過程中過期,過早地結束了工作。

僅供參考:我不是在談論腳本運行時限制,我們已經利用set_time_limit()允許長時間運行的進程。

問題:是否有一種方法可以腳本執行過程中 “觸摸”會話,從而重置會話的到期時間? 設置會話變量是否合適,或者是否需要特定的PHP函數來實現此目的?


更具體地說,我們有一個實際的CRON作業,該作業每分鍾運行一次:

* * * * * user curl -XGET https://domain.com/maintenance.php

...進而使用我們的內部系統來查找計划在當時運行的任務,其中一些任務簡短而又有些復雜。 在長時間的復雜過程(運行時間超過30分鍾)中,發生了上述問題。


編輯:總結下面的許多評論...

  1. 我們要避免發出額外的RPC來完成此操作,我正在尋找的是一種解決方案,例如想象中的touch_session()

  2. 我相信我們可以排除更改會話值的可能性,因為在關閉請求之前,更改不會記錄在會話中,在我們看來這種情況為時已晚。

  3. 我們正在使用數據庫進行會話管理,因此我們可以簡單地編寫自己的touch_session()方法(可以調用該方法),並僅使用SQL查詢來更新時間戳,即UPDATE sessions SET expiration = '###' WHERE Session_ID = 'abc123'; 有什么陷阱嗎?

如果以上都不是,是否還有其他選項不需要進一步的rpc?

如評論中所述,您可以使用curl訪問涉及該會話的另一個腳本

touch.php

<?php
session_name('theNameOfYourSessionId');
session_start();

在您的維護腳本中像這樣用curl調用它:

$sid = session_id();
exec('user curl -XGET https://domain.com/maintenance.php?theNameOfYourSessionId='.$sid)

這應該可以解決問題。

除了卷曲以外,您還可以使用file_get_contents來避免卷曲問題。

$sid = session_id();
file_get_contents('https://domain.com/maintenance.php?theNameOfYourSessionId='.$sid);

另一種方法是簡單地接受會話可能已死並從數據庫恢復它們的生命。 如前所述,您需要使用多個應用程序服務器,並且無論如何都需要多個應用程序服務器解決方案,

那么,為什么不使用提供的會話ID作為數據庫中的標識符並將會話內容存儲在數據庫中呢? 輸入腳本並且所需的會話為空時,請調用數據庫並還原它。

因此,盡管有幾種解決方案可供使用,但沒有一個滿足我們的要求,但是它們要么開銷超過其價值,要么涉及安全問題,要么需要大量工作才能在大型應用程序中實施。

在PHP的情況下,$ _ SESSION只是會話記錄中存儲的數據的副本,直到請求結束並且新數據將覆蓋舊數據,因此$ _SESSION的任何操作均不會影響系統中實際會話記錄的有效期。

因為在我們獨特的情況下,我們使用MySQL進行會話管理,所以最簡單的答案是使用簡單的查詢創建我們自己的touch_session()方法:

UPDATE sessions SET expiration = NOW() WHERE Session_ID = 'ABC123'

注意,我們的垃圾回收使用NOW()-30分鍾使記錄過期,因此在上面的查詢中將過期設置為NOW()。

現在,可以將這種快速方法添加到任何可能長時間運行的維護腳本中,在這種情況下,經常調用該方法足以避免會話過期,但又不足以增加任何明顯的開銷。

希望這對其他類似情況的人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM