web-dev-qa-db-ja.com

Laravel 5.0 Storage facadeを使用して、Amazon S3にアップロードされたファイルにメタデータ、ヘッダー(Expires、CacheControl)を追加します

Laravel 5.0 Storage facadeを使用してアップロードされたファイルにメタデータまたはヘッダー(Expires、CacheControlなど)を追加する方法を見つけようとしています。参照として、このページを使用しています。

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

次のコードは正しく動作します。

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

掘り下げた後、ACLを「public-read」に設定する「visibility」パラメーターがあることもわかりましたので、以下も正しく機能します。

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',
];

これを達成する方法についての助けがあれば幸いです。

24
alexmcfarlane

まず、getDriverを呼び出して、オプションの配列を送信できるようにする必要があります。そして、オプションを配列として送信する必要があります。

だからあなたの例では:

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

「Cache-Control」を設定する場合は、「CacheControl」として渡す必要があることに注意してください。これは、英数字以外の文字を含む他のキーにも当てはまる場合があります。

29
Matt McDonald

ヘッダー付きのグローバルデフォルトを使用する場合、これは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']
],
21
Paras

上記の回答を試み、顧客のユーザーメタデータを追加できなかった後、SDKコードを調べた後、私が思ったよりも少し簡単であることがわかりました(_$path_はイメージファイルへのパスであると想定)。 getDriver()メソッドを呼び出す必要もないようですが、それがAWS SDKの現在のバージョンと何か違いがあるかどうかもわかりません。

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

したがって、新しくアップロードされたファイルをS3で表示すると、カスタムメタデータが表示されます。

enter image description here

これが誰かを助けることを願っています。

5
XanT

@Parasからの回答は適切です。しかし、初心者を混乱させる可能性のあることが1つあります。

'options'     => [
    'Expires' => gmdate('D, d M Y H:i:s GMT', strtotime('+1 month')),
    >>> WRONG visibility' => 'public', WRONG <<<
]

HEADERSのグローバルオプションを定義する場合は、options配列が適切です。しかし、可視性も定義したい場合は、混同することはできません。可視性はオプション配列の外で定義する必要があります。

????

'visibility'  => 'public',
'options'     => ['Expires' => gmdate('D, d M Y H:i:s GMT', strtotime('+1 month'))]

これは、Laravel 5.8の時点でファイルをS3にアップロードする方法の例であり、有効期限とキャッシュ制御ヘッダーが付いています。次に例を示します。

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の[キャッシュを無効にする]チェックボックスをオフにすることを忘れないでください。テストを行っても動作しない場合は、ブラウザがキャッシュしない場合に1時間問題が発生します。 S3でようやくヘッダーが正しくなったにもかかわらず、.

2
danno_blammo

こんにちはこの問題を解決しました。カスタムS3ファイルシステムを作成する必要があります

まず、新しいファイルCustomS3Filesystem.phpを作成してapp/providersに保存します。このカスタム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',

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 を使用しました

これがお役に立てば幸いです。

1
sergiodebcn

@sergiodebcnの答えを拡張するために、S3 v3と最新のLaravelで機能する同じCustomS3Filesystemクラスを次に示します。 XML MIMEタイプを削除し、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()
    {
        //
    }
}
1
delatbabel

私は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
Venky Rao