AWS S3 locks a local file?

Jan 14, 2017,

When uploading a temp file to S3 you may notice that you can't remove a temp file.

$client = AWS::createClient('s3');
$result = $client->putObject(array(
        'Bucket'     => self::$bucketName,
        'Key'        => 'screenshot/testing.png',
        'SourceFile' => $temp_path,
        'ACL'        => 'public-read'
    ));
);

unlink($temp_path); // <--- ERROR: Permission denied / is busy

Unpleasant right? Ok, the reason is simple - AWS SDK open a file, but don't close it.

The solution is simple - use Body option instead of SourceFile.

$client = AWS::createClient('s3');
$result = $client->putObject(array(
        'Bucket'     => self::$bucketName,
        'Key'        => 'screenshot/testing.png',
        'Body'       => file_get_contents($temp_path),  // <--- as a string
        'ACL'        => 'public-read'
    ));
);

unlink($temp_path);

Ok, but what if a temp file is huge and you don't want load it to a memory?

No problem, you will be glad to hear that Body option accepts resource too.


$tempFile = fopen($temp_path, "r");
$client = AWS::createClient('s3');
$result = $client->putObject(array(
        'Bucket'     => self::$bucketName,
        'Key'        => 'screenshot/testing.png',
        'Body'       => $tempFile,  // <--- as a resource
        'ACL'        => 'public-read'
    ));
);
fclose($tempFile);
unlink($temp_path);