【问题标题】:Calling PHP unlink() after move_uploaded_file() on moved file fails在移动文件上的 move_uploaded_file() 之后调用 PHP unlink() 失败
【发布时间】:2019-03-09 01:18:13
【问题描述】:

我正在将上传到我的服务器的文件发送到 Amazon S3。为此,我:

  • 使用move_uploaded_file() 将文件发送到临时上传文件夹。
  • 我使用 S3 SDK 将文件作为对象上传到 S3。
  • 我使用unlink() 删除文件。
  • unlink() 失败,资源暂时不可用

运行 PHP/Apache 的 Windows Server。

脚本运行完成后,我可以稍后取消链接。在脚本之外调用unlink() 命令会立即从服务器中删除文件。我试图弄清楚如何从move_uploaded_file() 释放文件,但搜索了一段时间后找不到任何东西。

我确实使用$thumb1 = new Imagick($filetothumbnail); 并创建一个缩略图。但我随后打电话给

$thumb1->clear();
$thumb1->destroy();

也许 Imagick 仍然打开文件?但是,我已经用一个不制作缩略图的 excel 文件对此进行了测试,但该文件仍然无法从服务器中删除。

if(isset($_FILES['file'])){
  $name = $_FILES['file']['name'];
  $size = $_FILES['file']['size'];
  $tmp = $_FILES['file']['tmp_name'];
  $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));

  $newname = time().'_'.$j['id'].'_'.$name;
  $thumbname = 'tn_'.time().'_'.$j['id'].'_'.$name;
  move_uploaded_file($_FILES["file"]["tmp_name"], "temp-uploads/".$newname);

  //Now, generate thumbnail for the file:
  $filetothumbnail = $_SERVER['DOCUMENT_ROOT'].'/temp-uploads/'.$newname;
  $thumbnails = $_SERVER['DOCUMENT_ROOT'].'/temp-uploads/thumbs/';

  //Send to AWS Bucket
  $s3_filepath = 'project-assets/'.$newname;
  upload_s3_file($s3_filepath, "temp-uploads/".$newname);

  $filepath = s3url.$s3_filepath;

  if($ext == 'jpg' || $ext == 'jpeg' || $ext == 'png' || $ext == 'gif'){

  $thumb1 = new Imagick($filetothumbnail);
  $compression_type = Imagick::COMPRESSION_JPEG; 

  $thumb1->setImageCompression($compression_type); 
  $thumb1->setImageCompressionQuality(40);
  $thumb1->thumbnailImage(500, 0);
  $thumb1->setImageFormat('jpg');
  $thumb1->writeimage($thumbnails.$thumbname);
  $thumb1->clear();
  $thumb1->destroy();

  //If thumbnail is there. Only for certain file types.
  $s3_thumbpath = 'project-thumbnails/'.$thumbname;
  upload_s3_file($s3_thumbpath, "temp-uploads/thumbs/".$thumbname);

  unlink("temp-uploads/thumbs/".$thumbname); //Delete Thumbnail.

  $thumbpath = s3url.$s3_thumbpath;

  } else {
  $thumbpath = 0;
  }


  unlink("temp-uploads/".$newname); //Delete Uploaded File.
}

上传到S3的函数是:

$s3Client = new S3Client([
  'version'     => 'latest',
  'region'      => 'us-east-2',
  'credentials' => [
     'key'    => s3key,
     'secret' => s3secret,
   ],
]);

$result = $s3Client->putObject([
  'Bucket' => 'bucketname',
  'Key' => $filename,
  'SourceFile' => $filepath,
]);

【问题讨论】:

  • 我怀疑是 S3 SDK 锁定了文件,与 move_uploaded_file 无关。
  • 您是否要删除创建的临时文件?
  • 请出示您的完整代码
  • @markt 添加了完整代码。 S3可能还没有完成吗?我认为上传到 S3 在完成之前不会执行进一步的代码。也许只是增加延迟或等待?
  • 我会尝试使用完整路径。 $_SERVER['DOCUMENT_ROOT'].'/temp-uploads/thumbs/'

标签: php imagick


【解决方案1】:

快速查看文档表明上传是异步的:

https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_promises.html

并且您可能应该使用一个承诺来创建一个回调,您可以在其中取消链接您的文件。链接中有很多代码示例。

【讨论】:

  • 这可能是正确的答案。那时候我想过那个。我开始阅读有关在内部使用 Promise 的内容并被转移了注意力。非常感谢。
  • 这并没有解决锁定的文件。更改为Body 而不是SourceFile 并正确打开/关闭文件让我unlink() 上传后的文件。
【解决方案2】:

这篇文章帮我解决了这个问题:

https://stackoverflow.com/a/41537354/1766536

具体来说,我必须使用fopen/fclose 并使用Body 而不是SourceFile 上传

【讨论】:

    猜你喜欢
    • 2023-01-22
    • 2019-06-22
    • 2013-08-05
    • 1970-01-01
    • 2013-12-17
    • 2016-07-25
    • 1970-01-01
    • 2016-09-14
    • 2023-03-30
    相关资源
    最近更新 更多