Добавьте метаданные, заголовки (Expires, CacheControl) в файл, загруженный в Amazon S3, используя фасад Laravel 5.0 Storage
Я пытаюсь выяснить, как добавить метаданные или заголовки (Expires, CacheControl и т.д.) в файл, загруженный с использованием фасада Laravel 5.0 Storage. Я использую страницу здесь как ссылку.
http://laravel.com/docs/5.0/filesystem
Следующий код работает правильно:
Storage::disk('s3')->put('/test.txt', 'test');
После копания я также обнаружил, что существует параметр "видимости", который устанавливает ACL в "public-read", поэтому следующее также работает правильно.
Storage::disk('s3')->put('/test.txt', 'test', 'public');
Но я хотел бы иметь возможность установить некоторые другие значения в заголовок файла. Я пробовал следующее:
Storage::disk('s3')->put('/index4.txt', 'test', 'public', array('Expires'=>'Expires, Fri, 30 Oct 1998 14:19:41 GMT'));
Что не работает, я также пробовал:
Storage::disk('s3')->put('/index4.txt', 'test', array('ACL'=>'public-read'));
Но это создает ошибку, в которой параметр 'visibility' не может быть преобразован из строки в массив. Я проверил источник AwsS3Adapter, и кажется, что есть код для параметров, но я не вижу, как правильно их передать. Я думаю, что он принимает следующее:
protected static $metaOptions = [
'CacheControl',
'Expires',
'StorageClass',
'ServerSideEncryption',
'Metadata',
'ACL',
'ContentType',
'ContentDisposition',
'ContentLanguage',
'ContentEncoding',
];
Любая помощь в том, как добиться этого, будет оценена.
Ответы
Ответ 1
Во-первых, вам нужно вызвать getDriver, чтобы вы могли отправлять по массиву параметров. И тогда вам нужно отправить параметры в виде массива.
Итак, для вашего примера:
Storage::disk('s3') -> getDriver() -> put('/index4.txt', 'test', [ 'visibility' => 'public', 'Expires' => 'Expires, Fri, 30 Oct 1998 14:19:41 GMT']);
Имейте в виду, что если вы устанавливаете "Cache-Control", он должен быть передан как "CacheControl". Это может быть справедливо для других ключей с символами, отличными от alphanumierc.
Ответ 2
Если вы хотите иметь глобальные значения по умолчанию с заголовками, это работает в Laravel 5.4. Измените файл config/filesystems.php
следующим образом:
s3' => [
'driver' => 's3',
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET'),
'options' => ['CacheControl' => 'max-age=315360000, no-transform, public',
'ContentEncoding' => 'gzip']
],
Ответ 3
После выполнения вышеуказанных ответов и невозможности добавить пользовательские метаданные пользователя, выясняется, что после копания кода SDK это немного легче, чем я думал (предположим, что $path
- путь к файлу изображения), Мне, похоже, не нужно было вызывать метод getDriver()
, не слишком уверен, что это имеет какое-то значение в текущей версии AWS SDK.
Storage::put(
'image.jpg',
file_get_contents($path),
[
'visibility' => 'public',
'Metadata' => [
'thumb' => '320-180',
],
]
);
Итак, теперь, если вы просматриваете недавно загруженный файл в S3, вы увидите пользовательские метаданные:
![введите описание изображения здесь]()
Надеюсь, это поможет кому-то.
Ответ 4
Эй, я решил эту проблему, вам нужно создать пользовательскую файловую систему S3
Сначала создайте новый файл CustomS3Filesystem.php и сохраните его в приложении/поставщиках, эта пользовательская файловая система S3 использует адаптер S3, но вы можете добавлять метаданные и заголовки.
<?php namespace App\Providers;
use Storage;
use League\Flysystem\Filesystem;
use Aws\S3\S3Client;
use League\Flysystem\AwsS3v2\AwsS3Adapter as S3Adapter;
use Illuminate\Support\ServiceProvider;
class CustomS3Filesystem extends ServiceProvider {
public function boot()
{
Storage::extend('s3_custom', function($app, $config)
{
$s3Config = array_only($config, ['key', 'region', 'secret', 'signature', 'base_url']);
$flysystemConfig = ['mimetype' => 'text/xml'];
$metadata['cache_control']='max-age=0, no-cache, no-store, must-revalidate';
return new Filesystem(new S3Adapter(S3Client::factory($s3Config), $config['bucket'], null, ['mimetype' => 'text/xml', 'Metadata' => $metadata]), $flysystemConfig);
});
}
public function register()
{
//
}
}
Добавить поставщика в список поставщиков в config/app.php
'App\Providers\CustomS3Filesystem',
создать новое имя fileistem в config/filesystems
's3-new' => [
'driver' => 's3_custom',
'key' => 'XXX',
'secret' => 'XXX',
'bucket' => 'XXX',
],
Использовать новый созданный пользовательский адаптер s3
Storage::disk('s3-new')->put(filename, file_get_contents($file), public);
Я использовал документацию laravel для настройки адаптера s3
http://laravel.com/docs/5.0/filesystem#custom-filesystems
Надеюсь, это может вам помочь.
Ответ 5
Чтобы расширить ответ на @sergiodebcn, вот тот же класс CustomS3Filesystem, работающий на S3 v3 и последний Laravel. Примечание. Я удалил XML-тип mimetype и установил время кэширования на 5 дней:
namespace App\Providers;
use Illuminate\Support\Arr;
use Storage;
use League\Flysystem\Filesystem;
use Aws\S3\S3Client;
use League\Flysystem\AwsS3v3\AwsS3Adapter as S3Adapter;
use Illuminate\Support\ServiceProvider;
class CustomS3Filesystem extends ServiceProvider
{
/**
* Format the given S3 configuration with the default options.
*
* @param array $config
* @return array
*/
protected function formatS3Config(array $config)
{
$config += ['version' => 'latest'];
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
}
return $config;
}
/**
* Bootstrap a custom filesystem
*
* @return void
*/
public function boot()
{
Storage::extend('s3_custom', function($app, $config)
{
$s3Config = $this->formatS3Config($config);
return new Filesystem(
new S3Adapter(
new S3Client($s3Config),
$config['bucket'],
null,
[
'CacheControl' => 'max-age=432000'
]
)
);
});
}
public function register()
{
//
}
}
Ответ 6
Ответ от @Paras хорош. Но есть одна вещь, которая может запутать новичков:
'options' => [
'Expires' => gmdate('D, d M Y H:i:s GMT', strtotime('+1 month')),
>>> WRONG visibility' => 'public', WRONG <<<
]
Если вы хотите определить глобальные параметры для HEADERS, массив опций - правильный путь. Но если вы также хотите определить видимость, вы не можете ее смешивать. Видимость должна определяться вне массива опций.
👍
'visibility' => 'public',
'options' => ['Expires' => gmdate('D, d M Y H:i:s GMT', strtotime('+1 month'))]
Ответ 7
Я использую Laravel 4.2, но я думаю, что мое решение может также помочь в Laravel 5.0 (не могу сказать точно, поскольку я еще не пытался обновить). Вам необходимо обновить мета параметры в конфигурации для используемого вами драйвера Flysystem. В моем случае я создал соединение под названием s3static для доступа к ведру, где храню изображения, которые не будут меняться.
Мой конфигурационный файл:
's3static' => [
'driver' => 'awss3',
'key' => 'my-key',
'secret' => 'my-secret',
'bucket' => 'my-bucket',
// 'region' => 'your-region',
// 'base_url' => 'your-url',
'options' => array(
'CacheControl' => 'max_age=2592000'
),
// 'prefix' => 'your-prefix',
// 'visibility' => 'public',
// 'eventable' => true,
// 'cache' => 'foo'
],
Теперь, когда я помещаю любые файлы на S3 с помощью этого соединения, у них есть набор метаданных Cache-Control.
Ответ 8
Это пример того, как загрузить файл на S3 начиная с Laravel 5.8 с заголовками истечения срока действия и управления кэшем, например:
Storage::put($directory . '/' . $imageName,
$image, [
'visibility' => 'public',
'Expires' => gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60 * 24 * 7)),
'CacheControl' => 'max-age=315360000, no-transform, public',
]);
Также не забудьте снять флажок "Отключить кэш" в Chrome, если вы тестируете, и он никогда не работает, что заставило меня плохо работать в течение часа, когда мой браузер не будет кешировать данные, даже если я наконец-то получил правильные заголовки в S3.