【问题标题】:php chmod not working on newly created files on Azure Web Appphp chmod 无法处理 Azure Web App 上新创建的文件
【发布时间】:2016-11-02 20:20:51
【问题描述】:

我正在尝试将使用 CodeIgniter 构建的应用程序从数据中心托管服务器迁移到 Azure Web App 服务上运行。我已经解决了一些问题,但这个问题让我们很难过。 . .

使用 CodeIgniter,CI_Log 类构造方法调用 system/core/common.php 文件中名为 is_really_writable 的函数,以确保日志目录可写。此函数在给定文件夹中创建一个文件,然后尝试对文件执行 chmod 以设置权限,然后将其删除。如果它能够完成这些操作,则假定它可以写入目录。

调用此命令时,我的日志文件中出现以下错误:

错误 - 2016-11-02 12:19:42 --> 严重性:警告 --> chmod(): 没有这样的文件或目录 D:\home\site\wwwroot\system\core\Common.php 92

错误 - 2016-11-02 12:19:42 --> 严重性:警告 --> 取消链接(应用程序/日志/1f3202d820180a39f736f20fce790de8):没有这样的文件或目录 D:\home\site\wwwroot\system\core \Common.php 93

然后我的日志文件夹有我正常的日志文件,还有很多垃圾文件,比如上面的“1f3202d820180a39f736f20fce790de8”。似乎这个函数有时必须返回 true,因为它确实写入了一个日志文件(如果函数返回 false,它就不会这样做)。

我唯一的想法是: - 这可能与 Azure 上的权限有关。我发现这不太可能,因为它必须至少成功几次,因为正在创建和写入日志。 - 也许服务器真的很慢,并且在尝试 chmod 然后取消链接之前没有创建文件。不过我觉得这不太可能,因为我认为 fopen 函数在创建文件之前不会返回。

如果我无法使其正常工作,我已经准备好放弃尝试使用 Azure Web App 服务了。有什么想法吗?

作为参考,这里是相关函数的代码:

function is_really_writable($file)
{
    // If we're on a Unix server with safe_mode off we call is_writable
    if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") != TRUE)
    {
        return is_writable($file);
    }

    // For windows servers and safe_mode "on" installations we'll actually
    // write a file then read it.  Bah...
    if (is_dir($file))
    {
        $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));

        if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
        {
            return FALSE;
        }

        fclose($fp);
        @chmod($file, DIR_WRITE_MODE);
        @unlink($file);
        return TRUE;
    }
    elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
    {
        return FALSE;
    }

    fclose($fp);
    return TRUE;
}

这里是调用它的日志类的构造方法:

public function __construct()
{
    $config =& get_config();

    $this->_log_path = ($config['log_path'] != '') ? $config['log_path'] : APPPATH.'logs/';

    if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
    {
        $this->_enabled = FALSE;
    }

    if (is_numeric($config['log_threshold']))
    {
        $this->_threshold = $config['log_threshold'];
    }

    if ($config['log_date_format'] != '')
    {
        $this->_date_fmt = $config['log_date_format'];
    }
}

根据gary-liu-msft 的建议,我做了更多的工作来隔离这只是 CodeIgniter 的一个问题,我 100% 确定这只是我们目前使用的 CodeIgniter 的版本。我创建了一个具有相同功能的脚本,并让它运行了数千次而没有遇到相同的行为。我将首先尝试更新到最新版本的 CodeIgniter 2,如果这不起作用,我们将不得不尝试最新的版本 3。一旦我为遇到此问题的其他人找到解决方案,我将进行更新。

【问题讨论】:

  • 我还应该提到这个应用程序非常慢(25 秒加载页面,在我们当前的生产 Windows 服务器上需要 6 秒,是的,我知道这很糟糕,但我使用了最长的加载页面之一作为比较环境的测试)。我还没有确定差异是由于我们迁移到 Azure SQL 或 PHP 的数据库造成的,但我感觉导致这种迟缓的任何原因都可能导致我的上述问题。
  • 您在场景中使用的是哪个 CI 版本?您是否有任何自定义配置,或者您只是在 Azure Web Apps 上部署 CI 应用程序?
  • 我们使用的是 2.1.4,我们的应用程序中的核心 CodeIgniter 类没有自定义配置。
  • 看来你用的是老版本,现在最新稳定版3.1,在github.com/bcit-ci/CodeIgniter/blob/develop/system/core/…改了这个功能。它在我这边运行良好。您可以尝试升级您的 CI 版本并重试。
  • 感谢您的建议,我会尝试一下,但看起来将应用程序从 2.1.4 迁移到 3.1 需要做很多工作,而且该功能似乎没有从我们使用的版本更改,所以我认为这无关紧要。我想我可能只是制作自己的简单 php 脚本来模拟问题,这样我就可以将其隔离到实际问题,而不是将其视为 CI 的问题。如果其他人遇到此问题,我会报告任何发现

标签: php codeigniter azure azure-web-app-service


【解决方案1】:

chmod 是 Linux 结构,而不是 Windows。除非您使用的是应用服务的 Linux 预览版,否则您的 Web 应用位于 Windows 之上,不会让您运行 chmod

在您应用的wwwroot 下,您的应用仍然拥有完整的写入权限。

【讨论】:

  • 这在 Windows 服务器上运行良好,正如我提到的,它似乎至少返回 true 几次,因为正在创建日志文件。此外,chmod 是 Azure Web App 环境中支持的功能。您可以在他们的 Kudu 环境中从命令提示符使用它。
猜你喜欢
  • 2019-02-04
  • 1970-01-01
  • 2011-06-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多