5

我在使用在 tmp 目录中创建文件的函数(例如tmpfile()tempnam(). 他们似乎都无法写入 tmp 并返回 false。upload_tmp_dir在 php ini 中设置,文件上传工作正常。

在调试此错误时,我发现sys_get_temp_dir()不幸的是,我的 PHP 版本(5.1.6)不支持它获取 tmp 目录的位置。我还看到使用以下方法替换了以下功能sys_get_temp_dir()

if ( !function_exists('sys_get_temp_dir')) {
  function sys_get_temp_dir() {
    if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
    if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
    if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
    $tempfile=tempnam(__FILE__,'');
    if (file_exists($tempfile)) {
      unlink($tempfile);
      return realpath(dirname($tempfile));
    }
    return null;
  }
}

但是 $_ENV 数组中没有对 tmp 目录的引用,并且tempnam()正如我之前提到的那样失败。

open_basedir 也没有设置,我听说会导致类似的问题

我怎样才能找出 tmp 目录在哪里,或者它是否已设置?
这是 apache 服务器配置问题还是 PHP 问题?

谢谢你的帮助

4

6 回答 6

4

我正在运行 Ubuntu 18.04,当我从 CLI 运行 PHP 脚本时,我可以在 /tmp 目录中创建/修改文件,但是当我尝试访问与网页相同的脚本时,我永远找不到正在创建的文件. 事实证明,Apache 默认会创建一个私有的 tmp 目录。以下帖子对Odd Bits - Private /tmp directory问题提供了一些见解。但是,帖子中提到的 /usr/lib/systemd 目录不包含我机器上的 http 或 apache2 的任何服务。为了帮助追踪问题,我执行了以下命令:

sudo find / -mount -type f -exec grep -e "PrivateTmp" '{}' ';' -print

并在/lib/systemd/system/apache2.service中找到Odd Bits 帖子中提到的PrivateTmp=true 。将文件从 /lib/systemd/system 复制到 /etc/systemd/system/ 并将true更改为false并执行

systemctl daemon-restart
systemctl restart apache2

解决了这个问题。一个比我聪明的人建议将文件复制到 /etc 而不是在 /lib 中编辑它是正确的做法,因为 /lib 由包“拥有”,并且应该在 /etc 中执行本地编辑。systemd 手册页详细描述了 systemd 配置处理。

于 2018-12-18T11:45:11.070 回答
2

你可以在你的 php.ini 中设置上传临时目录——这样的东西应该可以工作:

upload_tmp_dir=/your-www/tmp/

此外,如果您无法编辑 php.ini 或不想在全局范围内执行此操作,您可以在脚本的开头使用它:

ini_set('upload_tmp_dir','/your-home-www/tmp/');
于 2011-06-21T22:19:18.337 回答
1

TMP、TEMP(可能还有 TMPDIR)仅在 Windows 上有效,并且通常指向C:\Windows\TEMP. 在 Linux 上,默认临时位置是/tmp. 要解决此问题(与tempnam()函数一起使用),您可以在网站空间的某处创建一个临时文件夹,指定适当的访问权限并将其作为第一个参数传递给上述函数。

不是一个很好的解决方案,但总比没有好。

于 2011-06-22T14:01:23.110 回答
0

可能不是最干净的,但这适用于我的旧 5.1.6 安装:

function get_temp_path() {
  static $path = null;
  if ($path !== null) return $path;
  $file = tmpfile();
  $meta = stream_get_meta_data($file);
  fclose($file);
  $path = dirname($meta['uri']);
  return $path;
}
于 2014-01-15T23:48:27.687 回答
0

我有同样的问题,解决方案是更改 apache 配置以将 TEMP 变量公开给 PHP,请参阅这篇文章

于 2016-05-23T14:29:14.590 回答
0

给像我这样的新手的提示:我认为 PHP 无法从我的临时文件夹中移动东西,但我只是因为文件夹的相对位置而感到困惑。这可能适用于其他人,所以我会解释一下,即使它与这个特定问题非常相关(因为这个特定问题可能是像我这样的新手的其他人的搜索结果)。

我的问题是我将上传表单从 /var/www/html/ 中的 functions.php 文件回显到 /var/www/html/user/ 中的 profile.php 文件,该文件在 / 中调用了 uploadphoto.php 文件变量/www/html/。上传的文件最终打算放在 /var/www/html/uploads 中。这最终意味着我在functions.php中对uploadphoto.php和uploads/的大部分引用分别写成“../uploadphoto.php”或“../uploads/[etc.jpg]”,以便逐步从 html/user/ 回到 html/(回显代码位于 html/user/profile.php 中)。这让我不经思考就在 uploadphoto.php 中直观地使用了以下命令:

move_uploaded_file($_FILES["file"]["tmp_name"][0], "../uploads/$filename")

看到问题了吗?uploadphoto.php 与 uploads/ 位于同一目录中,因此此处不需要 ../。几个小时以来,我确信我又弄乱了我的文件夹权限,因为我是图像上传的新手。我忘记检查更简单的错误。希望这对其他人有帮助。

于 2017-06-17T00:10:32.543 回答