How-to set downloaded filename for S3 pre-signed URLs in PHP

AWS S3 lets you set custom headers for pre-signed URLs.


If you use S3 to store files then the chances are at some point you’ll be letting users download these files themselves. If you don’t want to fetch the file yourself and you want to send the user directly to S3 to download it - you can do this securely using pre-signed URLs. In short, a temporary URL is generated to allow the user access to the file and it has a timed expiry.

If you’re normalising and storing your files with something like this structure:

file_id     file_name       file_type       aws_path

1022        sample          pdf             uploaded/documents/1022.pdf
1023        budget          xlsx            uploaded/documents/1023.xlsx

If you were sending the user to S3 directly, they’d be given a file to download of 1022.pdf - hardly an ideal filename. You can modifying the filename for the user when you create the pre-signed URL, like so:

$s3Client = new Aws\S3\S3Client([
    'profile' => 'default',
    'region' => 'us-east-2',
    'version' => '2006-03-01',

$cmd = $s3Client->getCommand('GetObject', [
    'Bucket' => 'my-bucket',
    'Key' => 'testKey',
    'ResponseContentDisposition' => 'attachment; filename=sample.pdf'

$url = $s3Client->createPresignedRequest($cmd, '+20 minutes');

Header("Location: ".$url); exit();

Once you then forward the user to the give URL they will be given a download with the correct file name.