如何使用 Codeigniter/PHP 将文件上传到亚马逊 S3?

Posted

技术标签:

【中文标题】如何使用 Codeigniter/PHP 将文件上传到亚马逊 S3?【英文标题】:How can I upload a file to amazon S3 with Codeigniter/PHP? 【发布时间】:2012-04-29 05:45:18 【问题描述】:

我正在尝试将文件上传到我的 Amazon S3 存储桶。我的朋友过去曾在我们的网站上进行过这项工作,但一年后它被破坏了,我不知道出了什么问题。我们使用的是Geoff gaudreault开发的S3 php library。

这个库对我来说看起来很简单,实际上它看起来有一个关键功能:putObject()

不幸的是,我什至没有走出大门。我收到以下错误消息: Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.

这是我的上传表单action的codeigniter PHP:

    function s3()

    $config['upload_path'] = $_SERVER["DOCUMENT_ROOT"].'/temp/';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size'] = '1000000';
    $config['max_width']  = '1024000';
    $config['max_height']  = '768000';

    $this->load->library('upload', $config);

    if ( ! $this->upload->do_upload())
    
        $error = array('error' => $this->upload->display_errors());

        print_r($error);
        echo 'failure';
    
    else
    
       $data = array('upload_data' => $this->upload->data()); 
        $fn = $data['file_name'];
        $type = substr($fn, strrpos($fn, '.') + 1);

    $this->load->library('s3');
    $temp_file_path = $_SERVER["DOCUMENT_ROOT"]."/temp/" . $data['file_name'];
    $contents = read_file($temp_file_path); // will this blow up or timeout for large files?! 
    $newFileName = uniqid().".".substr($temp_file_path, strrpos($temp_file_path, '.') + 1);
     $contentPath = "mysite.com/Images"; 

    $this->s3->putObject($newFileName, $contents, $contentPath, 'private', $type);
    echo 'success';
    

有人有什么想法吗?

【问题讨论】:

Error 324 empty response on Application hosted by AWS的可能重复 嗨 Colin,我不确定如何从命令行访问我的 S3 服务器。我的 EC2 服务器 /etc/apache2/error.log 没有提到这个错误 324。想法? 首先要指出的是,您可以将 CodeIgniter 中的功能用于文件名/路径等。首先,您可以使用 encrypt_name 选项而不是手动生成 $newFileName。其次,$data['full_path'] 包含上传文件的完整路径,$data['file_ext'] 包含文件扩展名,最后,不使用$_SERVER['DOCUMENT_ROOT'] 你应该可以简单地使用$config['upload_path'] = './temp'; 上传脚本采用相对于索引的路径。 php 在你的根目录中。 HTH 太棒了,谢谢加文!让我花几分钟时间消化一下你刚才说的话,我还是个新手.... 嗨 Gavin,我认为错误在于我对 AWS S3.php 库的使用。我可以使用 CI 的文件上传类上传到我的服务器没有问题。只有当我向该库发出 $this->load->library('s3'); 和随后的 putObject() 调用时,事情才会爆发。 【参考方案1】:

我切换到different S3 PHP library,也称为 S3.php,这是这个非常好的 Netuts 教程源代码的一部分。

只需将我的 AWS 密钥和存储桶名称插入演示的 page.php 文件,我就可以在 2 分钟内上传到我的存储桶。所以这个教程超级简单。非常令人兴奋!

【讨论】:

这是用于核心 php 而不是 codeigniter 框架 这个问题(和这个答案)太老了,AWS 在其存储库中有一个新的 sdk github.com/aws/aws-sdk-php 并且可以通过 composer 或复制 sdk 轻松安装为 codeigniter 中的库。【参考方案2】:

在代码点火器中

这里链接到 s3 存储桶中的 upload 和 delete 图像

<?php

function profile_upload()

    //print_r($_FILES);
    if ($this->session->userdata('user_login')) 

        $file = $_FILES['agent_profile_file']['tmp_name'];

        if (file_exists($file)) 
            $allowedExts = array("gif", "jpeg", "jpg", "png");
            $typefile    = explode(".", $_FILES["agent_profile_file"]["name"]);
            $extension   = end($typefile);

            if (!in_array(strtolower($extension), $allowedExts)) 
                //not image
                $data['message'] = "images";
             else 
                $userid = $this->session->userdata['user_login']['userid'];

                $full_path = "agent_image/" . $userid . "/profileImg/";

                /*if(!is_dir($full_path))
                mkdir($full_path, 0777, true);
                */
                $path = $_FILES['agent_profile_file']['tmp_name'];

                $image_name = $full_path . preg_replace("/[^a-z0-9\._]+/", "-", strtolower(uniqid() . $_FILES['agent_profile_file']['name']));
                //move_uploaded_file($path,$image_name);

                $data['message'] = "sucess";

                $s3_bucket = s3_bucket_upload($path, $image_name);

                if ($s3_bucket['message'] == "sucess") 
                    $data['imagename'] = $s3_bucket['imagepath'];
                    $data['imagepath'] = $s3_bucket['imagename'];
                

                //print_r($imagesizedata);
                //image
                //use $imagesizedata to get extra info
            
         else 
            //not file
            $data['message'] = "images";
        

     else 
        $data['message'] = "login";
    
    echo json_encode($data);
    //$file_name2 = preg_replace("/ /", "-", $file_name);


// Helper file add code
// image compress code
function compress($source, $destination, $quality)

    ob_start();
    $info = getimagesize($source);

    if ($info['mime'] == 'image/jpeg') 
        $image = imagecreatefromjpeg($source);
     elseif ($info['mime'] == 'image/gif') 
        $image = imagecreatefromgif($source);
     elseif ($info['mime'] == 'image/png') 
        $image = imagecreatefrompng($source);
    

    $filename = tempnam(sys_get_temp_dir(), "beyondbroker");

    imagejpeg($image, $filename, $quality);

    //ob_get_contents();
    $imagedata = ob_end_clean();
    return $filename;


// type for if image then it will reduce size
// site for it in web of mobile because mobile webservice image will in base 64
// $tempth will file temp path
// $image_path will file where to save path

function s3_bucket_upload($temppath, $image_path, $type = "image", $site = "web")

    $bucket = "bucket-name";

    $data = array();

    $data['message'] = "false";

    // For website only
    if ($site == "web") 
        if ($type == "image") 
            $file_Path = compress($temppath, $image_path, 90);
         else 
            $file_Path = $temppath;
        
    

    try 
        $s3Client = new S3Client([
            'version'     => 'latest',
            'region'      => 'us-west-2',
            'credentials' => [
                'key'    => 'aws-key',
                'secret' => 'aws-secretkey',
            ],
        ]);

        // For website only
        if ($site == "web") 

            $result = $s3Client->putObject([
                'Bucket'     => $bucket,
                'Key'        => $image_path,
                'SourceFile' => $file_Path,
                //'body'=> $file_Path,
                'ACL'        => 'public-read',
                //'StorageClass' => 'REDUCED_REDUNDANCY',
            ]);

            $data['message']   = "sucess";
            $data['imagename'] = $image_path;
            $data['imagepath'] = $result['ObjectURL'];
         else 
            // $tmp = base64_decode($base64);
            $upload            = $s3Client->upload($bucket, $image_path, $temppath, 'public-read');
            $data['message']   = "sucess";
            $data['imagepath'] = $upload->get('ObjectURL');
        

     catch (Exception $e) 
        $data['message'] = "false";
        // echo $e->getMessage() . "\n";
    

    return $data;

【讨论】:

以上是关于如何使用 Codeigniter/PHP 将文件上传到亚马逊 S3?的主要内容,如果未能解决你的问题,请参考以下文章

Codeigniter 3 会话不适用于 PHP 7.1.4

CodeIgniter PHP - 如何在使用“select *”时选择在连接中选择哪个 ID

SYSTEMPATH/CodeIgniter.php 在第 219 行

动态 PHP 变量不适用于使用 mPDF 的 codeigniter php 视图文件

php优秀框架codeigniter学习系列——CodeIgniter.php概览

分析codeIgniter.php文件