Php 使用Laravel5.0存储门面向上传到AmazonS3的文件中添加元数据、标题(Expires、CacheControl)
我正在尝试了解如何将元数据或头(Expires、CacheControl等)添加到使用Laravel 5.0 Storage facade上传的文件中。我把这里的这一页作为参考 以下代码正常工作:Php 使用Laravel5.0存储门面向上传到AmazonS3的文件中添加元数据、标题(Expires、CacheControl),php,amazon-s3,laravel-5,flysystem,Php,Amazon S3,Laravel 5,Flysystem,我正在尝试了解如何将元数据或头(Expires、CacheControl等)添加到使用Laravel 5.0 Storage facade上传的文件中。我把这里的这一页作为参考 以下代码正常工作: Storage::disk('s3')->put('/test.txt', 'test'); 挖掘之后,我还发现有一个“可见性”参数,它将ACL设置为“公共读取”,因此以下内容也可以正常工作 Storage::disk('s3')->put('/test.txt', 'test', '
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'));
protected static $metaOptions = [
'CacheControl',
'Expires',
'StorageClass',
'ServerSideEncryption',
'Metadata',
'ACL',
'ContentType',
'ContentDisposition',
'ContentLanguage',
'ContentEncoding',
];
这不起作用,我也尝试过:
Storage::disk('s3')->put('/index4.txt', 'test', array('ACL'=>'public-read'));
但这会产生一个错误,即“可见性”参数无法从字符串转换为数组。我已经检查了AwsS3Adapter的源代码,似乎有选项代码,但我似乎看不到如何正确地传递它们。我认为需要采取以下措施:
Storage::disk('s3')->put('/index4.txt', 'test', 'public', array('Expires'=>'Expires, Fri, 30 Oct 1998 14:19:41 GMT'));
protected static $metaOptions = [
'CacheControl',
'Expires',
'StorageClass',
'ServerSideEncryption',
'Metadata',
'ACL',
'ContentType',
'ContentDisposition',
'ContentLanguage',
'ContentEncoding',
];
任何关于如何实现这一点的帮助都将不胜感激。嘿,我解决了这个问题,您需要创建一个自定义的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/filesystems中创建新的fileistem名称
'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适配器
我希望这会对您有所帮助。首先,您需要调用getDriver,以便发送一系列选项。然后您需要将选项作为数组发送 以你为例:
Storage::disk('s3') -> getDriver() -> put('/index4.txt', 'test', [ 'visibility' => 'public', 'Expires' => 'Expires, Fri, 30 Oct 1998 14:19:41 GMT']);
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',
]);
请注意,如果要设置“缓存控制”,则必须将其作为“缓存控制”传递。对于其他非alphanumierc字符的键,这很可能是正确的。我使用的是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上时,它们都有缓存控制元数据集 为了扩展@sergiodebcn的答案,这里是用于S3V3和最新的Laravel的同一个CustomS3Filesystem类。注意:我已删除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()
{
//
}
}
如果您想使用全局默认的标题,这在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']
],
@Paras的答案是好的。但有一件事会让新来者感到困惑:
'options' => [
'Expires' => gmdate('D, d M Y H:i:s GMT', strtotime('+1 month')),
>>> WRONG visibility' => 'public', WRONG <<<
]
“选项”=>[
'Expires'=>gmdate('D,dm Y H:i:s GMT',strottime('+1个月)),
>>>错误的可见性“=>“public”,错误的在尝试上述答案并且无法添加客户用户元数据之后,在挖掘SDK代码之后,结果证明这比我想象的要容易一些(假设$path
是图像文件的路径)。我似乎不需要调用getDriver()
方法,也不太确定这是否与当前版本的AWS SDK有任何区别
Storage::put(
'image.jpg',
file_get_contents($path),
[
'visibility' => 'public',
'Metadata' => [
'thumb' => '320-180',
],
]
);
因此,现在如果您在S3中查看新上载的文件,您将看到自定义元数据:
希望这对其他人有所帮助。这是一个关于如何将文件上传到S3的示例,从Laravel 5.8开始,该文件带有过期和缓存控制头,例如:
Storage::disk('s3') -> getDriver() -> put('/index4.txt', 'test', [ 'visibility' => 'public', 'Expires' => 'Expires, Fri, 30 Oct 1998 14:19:41 GMT']);
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中得到了正确的标题。查看下面的答案()如果您希望在ConfigDriver中设置全局默认值谢谢,没有getDriver()一切都正常直到我需要设置“ContentType”元数据。为什么否决?这个解决方案有效,如果你不相信它有效,想知道你为什么这么认为吗?哇,这应该是最好的答案,但有人无缘无故否决了它。我也不确定为什么否决了它,它在Laravel 5.4中对我非常有效。这是一个工作即使在Laravel 5.8中也是如此。很好,谢谢!谢谢你,我认为它可能被否决了,因为这是一个全局解决方案,而不是每个文件/上传的解决方案。你可能不想将其设置为全局级别。当我问这个问题时,我没有这样做。这根本没有文档记录。