2010-10-01 134 views
3

我必須在PHP中編寫腳本,它將動態地替換服務器上的一些文件。容易的事情,但問題是,我想避免在替換時用戶請求這個文件的情況。然後他可能會得到不完整的文件甚至錯誤。最好的方法來替換服務器上的文件

對我來說最好的解決方案是在更換時阻止訪問我的站點。設置.htaccess將所有請求重定向到有關短暫休息信息的頁面。但通常.htaccess文件已經存在,所以當服務器獲得uncomplited .htaccess文件時可能會出現這種情況。

有什麼方法可以解決它嗎?

編輯:非常感謝所有的答案,夥計們。你很聰明。

@ircmaxell你的想法對我來說聽起來很棒。我讀了PHP.net寫的東西,我不知道我是否理解正確。

所以,告訴我:如果我按照你寫的所有步驟添加了apc.file_update_protection到我的php.ini文件,那麼在任何時候都沒有辦法讓用戶得到未完成的文件?總會有一個正確的文件?你確定100%嗎?

這對我來說非常重要,因爲這些替換非常經常,並且在重命名時很有可能請求文件。

回答

0

也許做嘗試這樣的:

  1. 刪除文件並保存它的路徑
  2. LN -nfs movedfilepath pathtosorrypage.html
  3. 上傳文件到一些臨時文件夾在服務器上
  4. 刪除符號鏈接
  5. MV的newfile movedfilepath
1

待辦事項這項工作已經完成了嗎?我從來沒有爲此專門進行過測試,但我已經完成了你正在做的事情,而且這個問題從未出現過。 好像到

一件容易的事情對於操作系統
  1. 上傳/寫入到一個臨時文件
  2. 當書寫時,阻止訪問原始文件(對文件中等待請求)
  3. 刪除文件,重命名臨時文件,並刪除任何鎖

我很確定這是操作系統應該爲複製做什麼。如果您使用PHP自己編寫文件內容,那麼您只需自己完成此操作即可。

1

嘗試無軌Capistrano或方法,他們使用:

在目錄

你有兩件事情:

  1. 文件夾containering文件夾,每個子文件夾釋放
  2. 的軟鏈接到當前發佈文件夾

當您上傳新文件時,請上傳新版本文件夾。檢查看有沒有人當前正在運行的當前版本(這可能是一個有點棘手,假設你沒有,你也許可以用分貝條目做用戶的一個瘋狂的數字),然後重寫軟鏈接指向最新版本。

5

這裏的東西,很容易,而且可以在任何本地文件系統工作在Linux上:文件

  1. 上傳(或寫)到一個臨時文件名
  2. 移動文件(使用mv(移動)命令,無論是在FTP或命令行等,或PHP中的rename命令)來覆蓋現有的。

當您執行mv命令時,它基本上刪除舊的文件指針,並寫入新的文件指針。由於它是在文件系統級完成的,所以它是一個原子操作。因此,客戶端不能得到一箇舊文件...

APC建議doing this,以防止這些問題很從此起彼伏......

還要注意的是,你可以使用rsync做得一樣好(因爲它基本上做到這一點的場景)的背後...

0

選項1:如果你有很多用戶,這種替代是做不那麼頻繁了,你可以設置在網站上(塊訪問的維護),沒有一個在一段時間後登錄,最後切斷所有登錄的用戶,以便進行更換。

選項2:如果文件被更換頻繁地做(在這種情況下,你不應該做的保養,每天),它已經通過代碼實現。有兩個相同的文件(如果你想要同一個文件夾)。然後,通過代碼,當您要替換文件時,只需要提供副本,而替換所需的文件。你可以用簡單的IF來做。

僞代碼:

if (replaceTime - 15 seconds <= currentTime <= replaceTime + 15 seconds){ 
    // allows 30 seconds for another script to bring in the new image into 'myImage.jpg' 
    <img src="/myFiles/myOldImage.jpg" /> 
} else { 
    <img src="/myFiles/myImage.jpg" /> 
} 

不需要更新任何數據庫或手動移動/複製/重命名文件。

replaceTime + 15後已經過去了:

copyFileTo("myImage.jpg","myOldImage.jpg"); 
// Now you have the copy ready for the next time to replace 
相關問題