在svn导出后,Apache / PHP无法读取文件

时间:2014-02-24 09:00:47

标签: 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

现在,如果我访问我的浏览器并刷新我的网站,我将获得一个空白页面,我的错误日志将填充以下消息:

[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_once包含几行。
  • 要求一次没有错误,因此包含成功。
  • 如果我用SVN中的版本区分新的MyClass.php,它就是一样的。
  • 如果我检查权限,则所有者和权限都与任何其他文件相同。

它出错的文件,每次运行导出过程都不同。看似随机。它也是自上次更新以来未发生更改的文件的错误。

如果我运行apache2重启,一切正常。所以即使修复很简单,我也想了解发生了什么。 Apache缓存文件夹中的内容还是什么?

有人可以告诉我发生了什么事吗?

[编辑:为清晰起见而更新]

1 个答案:

答案 0 :(得分:1)

我的直接想法是,某些Apache进程将目录更改为/var/www(您移动了)或打开了一个文件。 POSIX文件系统的语义(与Windows相反)是可以移动甚至删除文件或目录,而不是在具有该对象打开的进程的脚下,但是当你可能期望各种有趣的行为时该进程尝试按名称访问该对象

举个例子,试试这个:

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

    $ mkdir /tmp/foo
    $ cd foo
    
  2. 运行另一个shell并执行

    $ rmdir /tmp/foo
    

    在其中。

  3. 现在转到第一个shell并执行

    $ pwd
    

    ...打印/tmp/foo。如你所见,

    • 第一个shell打开该目录并运行毫无疑问。
    • pwd命令工作正常(因为它无法访问文件系统)。
  4. 现在转到第二个shell并使用其原始名称重新创建已删除的目录:

    $ mkdir /tmp/foo
    

    现在看起来一切都还好,对吗?错。

  5. 返回第一个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中创建了该目录而失败了。

  6. 现在让我们“解决”第一个shell的问题:

    $ cd /tmp/foo
    $ touch blarb
    $ ls
    blarb
    

    如您所见,第一个shell现在与现实世界“同步”。

  7. 该怎么做?你这样做是错的。要么不在网络服务器的脚下拉地毯或重新启动它(可能只是使用service apache2 reload重新加载就可以了。)请注意,在任何一种情况下,重新加载似乎都是一个明智的解决方案。

    请注意,如果您再考虑一下这个问题,您会发现整个想法都很糟糕:整个操作期间以mv开头并以最后{{结尾}结束1}}您的网站根据定义出现故障。如果你做这样的事情会好得多:

    1. chmod到一个单独的目录。设置权限。
    2. 关闭网络服务器或更好地禁用网站的虚拟主机。
    3. 使用两个svn export来放置新网站。
    4. 启动网络服务器或带回虚拟主机。