2015-03-11 2 views
16

Я пытаюсь выяснить, как добавить метаданные или заголовки (Expires, CacheControl и т. Д.) В файл, загруженный с помощью фасад Laravel 5.0 Storage. Я использую страницу здесь как ссылку.Добавить метаданные, заголовки (Expires, CacheControl) в файл, загруженный в Amazon S3 с использованием фасада Laravel 5.0 Storage

http://laravel.com/docs/5.0/filesystem

Следующий код работает правильно:

Storage::disk('s3')->put('/test.txt', 'test'); 

После рытья я также обнаружил, что есть параметр «видимость», которая устанавливает ACL для «общественного чтения», поэтому следующее тоже работает правильно.

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')); 

Но что создает ошибку, когда параметр «видимость» не может быть преобразован из строки массив. Я проверил источник AwsS3Adapter, и кажется, что есть код для параметров, но я не вижу, как правильно их передать. Я думаю, что это занимает следующее:

protected static $metaOptions = [ 
    'CacheControl', 
    'Expires', 
    'StorageClass', 
    'ServerSideEncryption', 
    'Metadata', 
    'ACL', 
    'ContentType', 
    'ContentDisposition', 
    'ContentLanguage', 
    'ContentEncoding', 
]; 

Любая помощь в отношении того, как этого добиться, будет оценена по достоинству.

ответ

21

Во-первых, вам нужно вызвать getDriver, чтобы вы могли отправлять по множеству параметров. И тогда вам нужно отправить параметры в виде массива.

Так для примера:

Storage::disk('s3') -> getDriver() -> put('/index4.txt', 'test', [ 'visibility' => 'public', 'Expires' => 'Expires, Fri, 30 Oct 1998 14:19:41 GMT']); 

Имейте в виду, что если вы устанавливаете «CacheControl» он должен быть передан как «CacheControl». Это может быть справедливо для других ключей с символами, отличными от alphanumierc.

+2

Это отлично подойдет для меня. Благодаря! –

+0

Посмотрите мой ответ ниже (https://stackoverflow.com/a/46145866/7377984), если вы хотите установить глобальные значения по умолчанию в config – Paras

1

Эй, я решил эту проблему, необходимо создать пользовательский 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() 
{ 
    // 
} 
} 

Добавить поставщика в список поставщиков в конфиге/app.php

'App\Providers\CustomS3Filesystem', 

создать новое имя filesistem в конфиге/файловые системы

's3-new' => [ 
      'driver' => 's3_custom', 
      'key' => 'XXX', 
      'secret' => 'XXX', 
      'bucket' => 'XXX', 
     ], 

использовать новый созданный пользовательский адаптер s3

Storage::disk('s3-new')->put(filename, file_get_contents($file), public); 

I us ed laravel для настройки адаптера s3 http://laravel.com/docs/5.0/filesystem#custom-filesystems

Надеюсь, это может вам помочь.

0

Я использую 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.

+0

Это работает в Laravel 4.2, но не в 5.x – delatbabel

1

Чтобы расширить ответ на @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() 
    { 
     // 
    } 
} 
5

Если вы хотите иметь глобальные значения по умолчанию с заголовками, это работает в 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'] 
], 
+0

Почему downvote? Это решение работает, и если вы не верите, что это работает, хотелось бы знать, почему вы так думаете? – Paras

+0

Ничего себе, это должен быть лучший ответ, но кто-то отказался от него без причины – Paras

+0

Я не уверен, почему это было ниспровергнуто, это отлично сработало для меня в Laravel 5.4. – mitchdav

0

Ответ от @Paras хорошо. Но есть одна вещь, которая может запутать newcommers:

'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'))] 
0

После попытки вышеуказанных ответов и не в состоянии иметь возможность добавлять клиентов пользовательских метаданных получается, что после того, как копаться в коде SDK это немного легче, чем я думал (Предположит, что $path является путь к файлу изображения). Мне, похоже, не нужно было вызывать метод getDriver(), не слишком уверен, что это имеет значение с текущей версией AWS SDK.

Storage::put(
    'image.jpg', 
    file_get_contents($path), 
    [ 
     'visibility' => 'public', 
     'Metadata' => [ 
      'thumb' => '320-180', 
     ], 
    ] 
); 

Так что теперь, если вы просмотреть недавно загруженный файл в S3 вы увидите пользовательские метаданные:

enter image description here

Надеется, что это помогает кому-то.