您好,登錄后才能下訂單哦!
本篇文章主要探討php文件鎖發生錯誤的解決方法。有一定的參考價值,有需要的朋友可以參考一下,跟隨小編一起來看解決方法吧。
微信公眾號項目調用微信公眾號的接口都需要access_token
,它的有效期是2小時。當時我的做法是把它存放在文件中,格式使用的是json
。{"access_token":"easWasdw32323", "expire":1588219064}
。偽代碼如下:
function getToken ($tokenFile) { $tokenJson = file_get_contents($tokenFile); if (!$tokenJson) { $token = loadToken($tokenFile); } else if (json_decode($tokenJson, true)['expire'] <= time()){ $token = loadToken($tokenFile); } else { $token = json_decode($tokenJson, true)['access_token']; } return $token; } function loadToken ($tokenFile) { $fp = fopen($tokenFile, 'r+'); $tokenJson = ...; // 調用微信接口獲取到token fwrite($fp, json_encode($tokenJson)); return $tokenJson['access_token']; }
出現的問題:
項目運行一段時間后就會出問題,但過一兩秒后再刷新就正常了。
問題原因分析:
假設token已經過期了,這時候有2個請求來了,分別命名為A、B。A來了,發現token到期后,去調用微信接口獲取新的token,獲取后,更新到存放token的文件中。
但是,文件沒有完全更新完畢的時候,B來了,讀入存放token的文件。因為token文件中數據沒有更新完整,B讀到的數據就會產生錯誤。
另外還有可能是A和B同時在更新文件內容,這樣就會產生數據混亂,也會導致錯誤發生。
如何規避這個錯誤呢?
文件鎖機制可以完成。
在PHP中提供了 flock()函數,可以對文件使用鎖定機制(鎖定或釋放文件)。當一個進程在訪問文件時加上鎖,其他進程要想對該文件進行訪問,則必須等到鎖定被釋放以后。這樣就可以避免在并發訪問同一個文件時破壞數據。
函數原型如下:
flock ( resource $handle , int $operation [, int &$wouldblock ] ) : bool
handle
:
文件系統指針,是典型地由 fopen() 創建的 resource(資源)。
operation
operation 可以是以下值之一:
LOCK_SH取得共享鎖定(讀取的程序)。
LOCK_EX 取得獨占鎖定(寫入的程序)。
LOCK_UN 釋放鎖定(無論共享或獨占)。
LOCK_NB附加鎖定(Windows 上還不支持)。
wouldblock
如果鎖定會堵塞的話(EWOULDBLOCK 錯誤碼情況下),可選的第三個參數會被設置為 TRUE。(Windows 上不支持)
demo1.php
<?php $file = 'data.txt'; $handler = fopen($file, 'a+') or die('文件資源打開失敗'); // 取得獨占鎖 if (flock($handler, LOCK_EX)) { sleep(5); flock($handler, LOCK_UN); } else { echo '鎖定失敗'; } fclose($handler);
demo2.php
<?php $file = 'data.txt'; $handler = fopen($file, 'a+') or die('文件資源打開失敗'); // 取得獨占鎖 if (flock($handler, LOCK_EX)) { fwrite($handler, 'sometest string'); flock($handler, LOCK_UN); } else { echo '鎖定失敗'; } fclose($handler);
先運行demo1.php然后立即運行demo2.php,會發現,因為被demo1.php鎖定了文件,demo2.php寫入不了新內容,只有等demo1.php釋放了鎖定,demo2.php才能拿到獨占鎖,然后才能寫入文件。
學完這些知識后,就能解決我之前的問題了。改進的代碼如下:
<?php function getToken ($tokenFile){ $tokenJson = file_get_contents($tokenFile); if (!$tokenJson) { $token = loadToken($tokenFile); } else if (json_decode($tokenJson, true)['expire'] <= time()){ $token = loadToken($tokenFile); } else { $token = json_decode($tokenJson, true)['access_token']; } return $token; } function loadToken ($tokenFile) { $fp = fopen($tokenFile, 'w'); // 取得獨占鎖 if (flock($fp, LOCK_EX)) { $tokenJson = ...; // 調用微信接口獲取到token fwrite($fp, json_encode($tokenJson)); flock($fp, LOCK_UN); } else { return false; } return $tokenJson['access_token']; }
以上就是php文件鎖發生錯誤的解決方法的詳細內容,代碼示例簡單明了,如果在日常工作遇到此問題。通過這篇文章,希望你能有所收獲,更多詳情敬請關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。