【问题标题】:Google app-engine - Uploaded files not public on google cloud storage谷歌应用引擎 - 上传的文件在谷歌云存储上不公开
【发布时间】:2014-08-17 14:32:58
【问题描述】:

我有一个允许用户上传图片的应用,我希望其他用户能够看到该图片。

我正在使用 CloudStorageTools::createUploadUrl 方法来允许用户通过 POST 上传。然后,我正在获取上传的文件并使用 move_uploaded_file 将其存储在 Google Cloud Storage 上。

然后,我使用 CloudStorageTools::getPublicUrl 来获取文件的 URL。它返回正确的 URL,但该文件不可公开访问,因此我收到 XML 错误响应“AccessDenied”。

我知道这是因为该文件未公开共享,但我不知道在上传后如何将其公开。

我尝试将“acl=public-read”选项传递给 createUploadUrl,但它返回了未知选项的错误。

我在此页面上看到了如何执行此操作的示例:https://developers.google.com/appengine/docs/php/googlestorage/public_access 但是,我的工作流程要求我允许使用 createUploadUrl 方法进行正常的 POST 上传,如下所示:https://developers.google.com/appengine/docs/php/googlestorage/user_upload

如何让用户上传的文件自动公开访问?

【问题讨论】:

  • 我认为唯一的方法是使用临时上传的文件 $_FILES['myfile']['tmp_name'],并使用带有 acl 选项的 stream_context_create 将其存储到 Google Cloud Storage ,而不是简单地 move_uploaded_file。有没有更好的办法?

标签: php google-app-engine google-cloud-storage


【解决方案1】:

使用带有流的 file_put_contents 让它工作。

$file = $_FILES['myfile']
$storeAt = 'gs://bucketname/filename.jpg

旧代码

$saved = move_uploaded_file($file['tmp_name'],$storeAt);

新代码,设置权限和 MIME 类型

$options = array('gs'=>array('acl'=>'public-read','Content-Type' => $file['type']));
$ctx = stream_context_create($options);
$saved = file_put_contents($storeAt, file_get_contents($file['tmp_name']), 0, $ctx);

走吧!

【讨论】:

【解决方案2】:

截至 2014 年 9 月 23 日,我设法通过 appEngine 将文件上传到 Google Storage Cloud,并将 acl 设置为 public-read(所有人),如下所示:

form.php

<?
require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
use google\appengine\api\cloud_storage\CloudStorageTools;
$options = [ 'gs_bucket_name' => 'yourbucketname' ];
$upload_url = CloudStorageTools::createUploadUrl('/upload_handler.php', $options);

?>
<form action="<?php echo $upload_url?>" enctype="multipart/form-data" method="post">
    Files to upload: <br>
   <input type="file" name="userfile" size="40">
   <input type="submit" value="Send">
</form>    

upload_handler.php

<?php
require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
use google\appengine\api\cloud_storage\CloudStorageTools;

$fileName = 'gs://yourbucket/'.$_FILES['userfile']['name'];
echo $fileName."<br>";

$options = array('gs'=>array('acl'=>'public-read','Content-Type' => $_FILES['userfile']['type']));
$ctx = stream_context_create($options);

if (false == rename($_FILES['userfile']['tmp_name'], $fileName, $ctx)) {
  die('Could not rename.');
}

$object_public_url = CloudStorageTools::getPublicUrl($fileName, true);
echo $objectPublicUrl."<br>";
//header('Location:' .$objectPublicUrl); // redirects the user to the public uploaded file, comment any previous output (echo's).
?>

为了能够接受大文件,我还在我的应用程序的基本目录中创建了一个自定义 php.ini

php.ini

; This is a simple php.ini file on App Engine
; It enables output buffering for all requests by overriding the
; default setting of the PHP interpreter.
output_buffering = "On"
max_file_uploads = 0
upload_max_filesize = 100M
session.gc_maxlifetime = 10000

app.yaml,将所有图片文件设置为静态,.php's 设置为可运行,如下所示:

application: myapp
version: 1
runtime: php
api_version: 1
threadsafe: true

handlers:
# Serve images as static resources.
- url: /(.+\.(gif|png|jpg))$
  static_files: \1
  upload: .+\.(gif|png|jpg)$
  application_readable: true

# Serve php scripts.
- url: /(.+\.php)$
  script: \1

希望它可以帮助其他人;)

【讨论】:

    【解决方案3】:

    选项 max_file_uploads 不能为 0。

    max_file_uploads = 10(或任何你想要的)

    【讨论】:

      【解决方案4】:

      这里列出的选项似乎都不再起作用了。

      我能够获得公共访问文件的唯一方法是创建一个具有公共访问权限的存储桶并将其用于上传的文件。

      gsutil defacl set public-read gs://bucket
      

      【讨论】:

        猜你喜欢
        • 2014-10-30
        • 2012-10-13
        • 1970-01-01
        • 2015-02-01
        • 1970-01-01
        • 2013-05-17
        • 1970-01-01
        • 1970-01-01
        • 2015-08-29
        相关资源
        最近更新 更多