问题
I am sending files uploaded to my server to Amazon S3. To do this, I:
- Use
move_uploaded_file()
to send file to a temp-uploads folder. - I use the S3 SDK to upload the file as an object to S3.
- I use
unlink()
to delete the file. unlink()
fails with Resource temporarily unavailable
Windows Server running PHP/Apache.
I can unlink later after the script is done running. Calling the unlink()
command outside of the script deletes the file from the server immediately. I was trying to figure out how to maybe release the file from move_uploaded_file()
, but can't find anything after searching for a while.
I do use $thumb1 = new Imagick($filetothumbnail);
and create a thumbnail. But I then call
$thumb1->clear();
$thumb1->destroy();
Maybe Imagick still has the file open? However, I have tested this with an excel file which does not make a thumbnail, and the file still fails to delete from the server.
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.
}
The upload to S3 function is:
$s3Client = new S3Client([
'version' => 'latest',
'region' => 'us-east-2',
'credentials' => [
'key' => s3key,
'secret' => s3secret,
],
]);
$result = $s3Client->putObject([
'Bucket' => 'bucketname',
'Key' => $filename,
'SourceFile' => $filepath,
]);
回答1:
A quick look at the docs suggests that the upload is asynchronous:
https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_promises.html
And you should probably use a promise to create a callback in which you can unlink your file. There are plenty of code examples in the link.
回答2:
This post helped solve this for me:
https://stackoverflow.com/a/41537354/1766536
Specifically, I had to use fopen
/fclose
and upload using Body
instead of SourceFile
来源:https://stackoverflow.com/questions/54915084/calling-php-unlink-after-move-uploaded-file-on-moved-file-fails