【问题标题】:Apache / PHP has trouble reading files after svn exportsvn 导出后 Apache / PHP 无法读取文件
【发布时间】:2014-02-24 18:34:29
【问题描述】:

我有一个我想不通的最奇怪的问题。我现在已经看过好几次了,每次问题都完全莫名其妙,最后一次我发现它是通过重新启动 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 包含在上面几行中。
  • require 一次没有错误,因此包含成功。
  • 如果我将新的 MyClass.php 与 SVN 中的版本进行比较,它是相同的。
  • 如果我检查权限,所有者和权限都与任何其他文件相同。

每次运行导出过程时出错的文件都不同。看似随意。自上次更新以来未更改的文件也会出错。

如果我重新启动 apache2,一切都会再次正常。因此,即使修复相当简单,我也想了解正在发生的事情。 Apache 是否正在缓存文件夹中的内容或其他内容?

谁能告诉我发生了什么事?

[编辑:为清楚起见已更新]

【问题讨论】:

    标签: php apache svn


    【解决方案1】:

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

    举个例子,试试这个:

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

      $ 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 现在与现实世界“同步”了。

    从中得到什么?你这样做是错的。要么不要将地毯拉到 Web 服务器的脚下,要么重新启动它(可能只是使用 service apache2 reload 重新加载就可以了)。请注意,无论哪种情况,重新加载似乎都是一个明智的解决方案。

    请注意,如果您再考虑一下,您会发现整个想法有点臭:在整个操作期间,从 mv 开始到最后一个 chmod 结束根据定义,网站出现故障。所以如果你能做这样的事情会更好:

    1. svn export 到一个单独的目录。设置权限。
    2. 关闭网络服务器,或者——最好是——禁用网站的虚拟主机。
    3. 执行两次mvs 以建立您的新网站。
    4. 启动网络服务器或恢复虚拟主机。

    【讨论】:

    • 谢谢你。这解释了很多。编辑;这是否意味着,理论上每次替换文件或文件夹时都会发生这种情况?
    • @Coo,我想说您不应该依赖于网络服务器的任何特定行为。请注意,如果站点是动态的(CGI 或诸如此类),事情会变得更加复杂,因为即使网络服务器本身在您更改它时没有打开任何文件/目录,PHP(或任何你是using) 可能,或其托管进程(如果有)。
    猜你喜欢
    • 2018-08-11
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多