Apache/PHP在svn导出后读取文件时遇到问题

Apache/PHP在svn导出后读取文件时遇到问题,php,apache,svn,Php,Apache,Svn,我有一个我无法解决的最奇怪的问题。我已经看过好几次了,每次问题都是完全无法解释的,上一次我发现通过重启apache它是“可以解决的” 我有一个我的网站所在的文件夹。当我在Subversion中完成更新后,我会继续更新我的网站。这是这样做的: mv www www-backup-xyz svn export https://my-svn-repo.com/updated-web-folder www chmod -R 770 www chown -R [apache-user:group] www

我有一个我无法解决的最奇怪的问题。我已经看过好几次了,每次问题都是完全无法解释的,上一次我发现通过重启apache它是“可以解决的”

我有一个我的网站所在的文件夹。当我在Subversion中完成更新后,我会继续更新我的网站。这是这样做的:

mv www www-backup-xyz
svn export https://my-svn-repo.com/updated-web-folder www
chmod -R 770 www
chown -R [apache-user:group] www
现在,如果我进入浏览器并刷新我的网站,我将得到一个空白页面,我的错误日志将充满如下消息:

[Mon Feb 24 08:40:56 2014] [error] [client x.x.x.x] PHP Fatal error:  Class 'MyClass' not found in /path/to/script/script.php on line 46
  • 指示的行是我第一次实例化MyClass的地方
  • 该类有自己的PHP文件,上面几行使用require\u包含了该文件
  • require once没有错误,因此include成功
  • 如果我将新的MyClass.php与SVN中的版本区分开来,则是相同的
  • 如果我检查权限,则所有者和权限都与任何其他文件相同
每次运行导出过程时,它所出错的文件都不同。似乎是随机的。它还显示自上次更新以来未更改的文件上的错误

如果我运行apache2重启,一切都会恢复正常。因此,尽管解决方法相当简单,但我想了解发生了什么。Apache缓存文件夹中的内容还是什么

有人能告诉我发生了什么事吗


[编辑:为清晰起见进行了更新]

我的直接想法是,某些Apache进程将目录更改为
/var/www
(您移动了该目录)或打开了其中的一个文件。POSIX文件系统(与Windows相反)的语义是,可以从打开该对象的进程底部移动甚至删除文件或目录,但当该进程试图按名称访问该对象时,您可能会看到各种有趣的行为

例如,请尝试以下方法:

  • 在一个控制台(终端仿真器窗口、
    screen
    /
    tmux
    窗格/窗口或其他)上运行shell(
    bash
    或其他),然后执行以下操作:

    $ mkdir /tmp/foo
    $ cd foo
    
  • 运行另一个shell并执行以下操作

    $ rmdir /tmp/foo
    
    $ pwd
    
    在里面

  • 现在转到第一个shell并执行以下操作

    $ rmdir /tmp/foo
    
    $ pwd
    
    …以打印
    /tmp/foo
    。如你所见

    • 第一个shell打开了该目录,并在不知情的情况下运行
    • pwd
      命令工作正常(因为它不能到达文件系统)
  • 现在转到第二个shell并用其原始名称重新创建已删除的目录:

    $ mkdir /tmp/foo
    
    现在看来一切都好了,对吧?错

  • 返回第一个shell并通过在其中创建文件来尝试使用此新目录:

    $ touch blarb
    touch: cannot touch `blarb': No such file or directory
    
    如您所见,我们似乎在
    /tmp/foo
    目录中,但无法在其中创建文件

    我们甚至可以通过尝试重新创建
    /tmp/foo
    ,获得更多乐趣:

    $ mkdir /tmp/foo
    mkdir: cannot create directory `/tmp/foo': File exists
    
    …失败是因为我们在第二个shell中创建了该目录

  • 现在,让我们“修复”第一个shell的问题:

    $ cd /tmp/foo
    $ touch blarb
    $ ls
    blarb
    
    如您所见,第一个shell现在与实际世界“同步”

  • 这是怎么回事?你做错了。要么不要将地毯拉到web服务器脚下,要么重新启动它(可能仅仅是使用
    服务apache2重新加载即可)。请注意,在这两种情况下,重新加载似乎都是明智的解决方案

    请注意,如果你再仔细考虑一下,你会发现整个想法有点糟糕:在整个操作过程中,从
    mv
    开始到最后一次
    chmod
    结束,你的站点从定义上看都出现了故障。因此,如果你能这样做会更好:

    mv www www-backup-xyz
    svn export https://my-svn-repo.com/updated-web-folder www
    chmod -R 770 www
    chown -R [apache-user:group] www
    
  • svn导出
    到一个单独的目录。设置权限
  • 关闭web服务器或更好地禁用站点的vhost
  • 做两次
    mv
    s将你的新站点放置到位
  • 启动Web服务器或使vhost返回

  • 谢谢你。这解释了很多。编辑这是否意味着,理论上每次文件或文件夹被替换时都可能发生这种情况?@Coo,我认为您不应该依赖web服务器的任何特定行为。请注意,如果站点是动态的(
    CGI
    或诸如此类),事情会变得更加复杂,因为即使在您更改Web服务器时,Web服务器本身没有打开任何文件/目录,
    PHP
    (或您正在使用的任何东西)可能会,或者它的托管过程(如果有的话)。