替换服务器上文件的最佳方法

时间:2010-10-01 14:19:43

标签: php .htaccess deployment

我必须用PHP编写脚本,它将不时地动态替换服务器上的某些文件。简单的事情,但问题是我想避免用户在更换期间请求此文件时的情况。然后他可能会得到未完成的文件甚至错误。

对我而言,最佳解决方案是在替换期间阻止访问我的网站。设置.htaccess将所有请求重定向到页面,并提供有关短暂休息的信息。但通常.htaccess文件已经存在,因此可能存在服务器获取未经编译的.htaccess文件的情况。

有什么办法可以解决吗?

编辑:非常感谢你们的所有答案,伙计们。你很聪明。

@ircmaxell你的想法对我来说听起来很棒。我读了PHP.net写的那些家伙,我不知道我是否理解正确。

所以,请告诉我:如果我执行了您编写的所有步骤并将apc.file_update_protection添加到我的php.ini中,那么用户将无法随时获取未完成的文件?会有一个正确的文件吗?你确定100%吗?

这对我来说非常重要,因为这些替换很常见,并且在重命名期间有很大的机会请求文件。

5 个答案:

答案 0 :(得分:5)

这是一件很简单的事情,可以在linux上的任何本地文件系统上运行:

  1. 将文件上传(或写入)临时文件名
  2. 移动文件(使用mv(移动)命令,在FTP或命令行等中,或在PHP中使用rename命令)覆盖现有文件。
  3. 执行mv命令时,它基本上删除了旧文件指针,并写入新文件指针。由于它是在文件系统级别完成的,因此它是一个原子操作。所以客户端无法获取旧文件...

    APC建议doing this以防止这些问题突然出现......

    另请注意,您也可以使用rsync来执行此操作(因为它基本上是在幕后执行此操作)...

答案 1 :(得分:1)

这不起作用吗?我从未对此进行过具体的测试,但我已经完成了你所做的事情并且这个问题从未出现过。 对操作系统来说似乎很容易

  1. 上传/写入临时文件
  2. 写入完成后,阻止访问原始文件(请求等待文件)
  3. 删除文件,重命名临时文件并删除任何锁
  4. 我很确定这是操作系统应该做的复制。如果你自己用PHP编写文件内容,你就必须自己做...

答案 2 :(得分:1)

尝试无轨Capistrano或他们使用的方法:

在目录中你有两件事:

  1. 包含文件夹的文件夹,每个子文件夹都是一个发行版
  2. 指向当前版本文件夹的软链接
  3. 上传新文件时,请上传制作新版本文件夹。检查当前没有人正在运行当前版本(这可能有点棘手,假设您没有疯狂的用户数量,您可能可以使用db条目),然后重写软链接以指向最新版本。

答案 3 :(得分:0)

或许可以这样试试:

  1. 删除文件并保存其路径
  2. ln -nfs movedfilepath pathtosorrypage.html
  3. 将文件上传到服务器上的某个临时文件夹
  4. 删除符号链接
  5. mv newfile movedfilepath

答案 4 :(得分: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