Интеграция плагина JqueryUpload с AWS php sdk для загрузки изображений в S3

Я работаю над интеграцией плагина jqueryfileupload с AWS. Я успешно завершил раздел загрузки, но теперь хочу интегрировать функцию изменения размера изображения.
Я использую этот код плагина. Я создал пример с использованием минимального кода, как показано ниже.

index.html

 <!DOCTYPE HTML>
 <html>
 <head>
 <meta charset="utf-8">
 <title>jQuery File Upload Example</title>
 </head>
 <body>
 <input id="fileupload" type="file" name="files[]" data-url="aws/" multiple>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
 <script src="js/vendor/jquery.ui.widget.js"></script>
 <script src="js/jquery.iframe-transport.js"></script>
 <script src="js/jquery.fileupload.js"></script>
 <script>
   $(function () {
     $('#fileupload').fileupload({
      dataType: 'json',
      done: function (e, data) {
        $.each(data.result.files, function (index, file) {
            $('<p/>').text(file.name).appendTo(document.body);
        });
      }
    });
  });
   </script>
  </body> 
 </html>

awssdk.php --- это файл, который я вызываю после выбора изображения.

      <?php 
    $bucket = "my bucket name";
    $subFolder = "";  // leave blank for upload into the bucket directly
    if (!class_exists('S3'))require_once('S3.php');

    //AWS access info
   if (!defined('awsAccessKey')) define('awsAccessKey', 'my key');
   if (!defined('awsSecretKey')) define('awsSecretKey', 'my secret key');


    $options = array( 'image_versions' => array(
     'small' => array(
    'max_width' => 1920,
    'max_height' => 1200,
    'jpeg_quality' => 95
 ),

'medium' => array(
    'max_width' => 800,
    'max_height' => 600,
    'jpeg_quality' => 80
),

'thumbnail' => array(
    'max_width' => 80,
    'max_height' => 80
)
   ) 
  );

  //instantiate the class
  $s3 = new S3(awsAccessKey, awsSecretKey);

  function getFileInfo($bucket, $fileName) {
   global $s3;
   $fileArray = "";
   $size = $s3->getBucket($bucket);
   $furl = "http://" . $bucket . ".s3.amazonaws.com/".$fileName;
   $fileArray['name'] = $fileName;
   $fileArray['size'] = $size;
   $fileArray['url'] = $furl;
   $fileArray['thumbnail'] = $furl;
   $fileArray['delete_url'] = "server/php/index.php?file=".$fileName;
   $fileArray['delete_type'] = "DELETE";
   return $fileArray;
 }

  function uploadFiles($bucket, $prefix="") {
   global $s3;
   if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
     return "";
  }
  $upload = isset($_FILES['files']) ? $_FILES['files'] : null;
  $info = array();
  if ($upload && is_array($upload['tmp_name'])) {
foreach($upload['tmp_name'] as $index => $value) {
    $fileTempName = $upload['tmp_name'][$index];
    $fileName = (isset($_SERVER['HTTP_X_FILE_NAME']) ?      $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index]);
    $fileName = $prefix.str_replace(" ", "_", $fileName);
    // $response = $s3->create_object($bucket, $fileName, array('fileUpload' => $fileTempName, 'acl' => AmazonS3::ACL_PUBLIC, 'meta' => array('keywords' => 'example, test'),));
    $response = $s3->putObjectFile($fileTempName,$bucket,'images/'.$fileName,S3::ACL_PUBLIC_READ);
    //print_r($response);
    if ($response==1) {
        $info[] = getFileInfo($bucket, $fileName);
    } else {
             echo "<strong>Something went wrong while uploading your file... sorry.</strong>";
    }
}
} else {
    if ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
        $fileTempName = $upload['tmp_name'];
        $fileName = (isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name']);
        $fileName =  $prefix.str_replace(" ", "_", $fileName);
        //$response = $s3->create_object($bucket, $fileName, array('fileUpload' => $fileTempName, 'acl' => AmazonS3::ACL_PUBLIC, 'meta' => array('keywords' => 'example, test'),));
        $response = $s3->putObjectFile($upload['tmp_name'],$bucket,$fileName,S3::ACL_PUBLIC_READ);
        if ($response->isOK()) {
            $info[] = getFileInfo($bucket, $fileName);
        } else {
                 echo "<strong>Something went wrong while uploading your file... sorry.</strong>";
        }
    }
}
header('Vary: Accept');
$json = json_encode($info);
$redirect = isset($_REQUEST['redirect']) ? stripslashes($_REQUEST['redirect']) : null;
if ($redirect) {
    header('Location: ' . sprintf($redirect, rawurlencode($json)));
    return;
}
if (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
    header('Content-type: application/json');
} else {
    header('Content-type: text/plain');
}
 return $info;
 }
?>

Вот класс S3, который я использую.

JqueryUploadPLugin поставляется с классом PHP на стороне сервера для загрузки изображений, и это здорово. Но поскольку я использую AWS, мне приходится использовать их API для загрузки изображений, и код плагина не будет работать. Как я уже упоминал выше, я реализовал часть загрузки. , но мне нужна помощь в создании эскизов изображений и изображений разных размеров перед загрузкой. Я хочу, чтобы изображения загружались в 3 вариантах ex: original,1024x768,100x100.
Файл UploadHandler.php имеет несколько функций для создания масштабированных изображений, например: protected function create_scaled_image($file_name, $version, $options) для масштабирования и другие. Я застрял в интеграции этих функций, так как я новичок в OO php и AWS.
Любой, кто сделал что-то подобное и может внести свой вклад, был бы полезен
Спасибо.


person KillABug    schedule 05.07.2013    source источник
comment
Вы не упомянули, где именно вы застряли? Если у вас уже работает загрузка, в чем проблема, если вы просто добавляете еще немного кода для создания миниатюр?   -  person rineez    schedule 05.07.2013
comment
Да, но я хочу использовать те же функции, что и в UploadHandler.php (я добавил на него ссылку). У него есть несколько замечательных функций, которые отлично работают, но они связаны с некоторой зависимостью, которая меня беспокоит. Мне нужна помощь в использовании этих пример функций:protected function create_scaled_image($file_name, $version, $options) для масштабирования и др.   -  person KillABug    schedule 05.07.2013


Ответы (2)


Похоже, вы пытаетесь использовать методы класса UploadHandler внутри своего кода в awssdk.php.

Я думаю, что правильный путь для вас будет заключаться в настройке класса UploadHandler, а точнее функции handle_file_upload. Это, вероятно, будет более полезным для вас, поскольку таким образом вы получите доступ ко всем хорошим функциям класса UploadHandler.

И вы можете поместить только следующие строки в свой awssdk.php

require('UploadHandler.php');
$upload_handler = new UploadHandler();

Вы можете видеть, что в настоящее время код этой функции сохраняет загруженные файлы по пути, указанному в опции «upload_dir». Вам просто нужно создать объект класса S3 внутри этой функции и изменить код для сохранения загруженного файла на S3.

Я думаю, что строка, которую вам придется изменить в UploadHandler, вероятно, это строка 703.

move_uploaded_file($uploaded_file, $file_path);

Должно стать:

$s3 = new S3(awsAccessKey, awsSecretKey);
$response = $s3->putObjectFile($uploaded_file,$bucket,$file->name,S3::ACL_PUBLIC_READ);
if ($response->isOK()) {
    $info[] = getFileInfo($bucket, $fileName);
} else {
   $file->error = "<strong>Something went wrong while uploading your file... sorry.</strong>";
}

Вам также может понадобиться перенести связанный код, например функцию getFileInfo, в класс UploadHandler.

Строки 707-711 предназначены для обработки загрузки файлов с помощью метода PUT. Чтобы справиться с этим случаем, вам нужно будет сохранить эти строки, чтобы сначала загрузить файл на ваш сервер, а затем передать файл на S3, а затем вы можете отменить связь файла на своем сервере. Но также безопасно просто закомментировать эти строки, если вы разрешаете только метод POST.

Строки 697-701 предназначены для обработки разделенных загрузок (я не уверен). Вам также придется изменить это, если вы хотите справиться и с этим случаем.

person rineez    schedule 05.07.2013
comment
Да, но путь, указанный в upload_dir, должен быть путем к каталогу S3. Но каталоги S3 повсюду http://, и это не позволит мне иметь такой путь. Я пробовал это 'upload_dir' => dirname('https://s3.amazonaws.com/elasticbeanstalk-us-east-1-966938761981/images/'), 'upload_url' => 'https://s3.amazonaws.com/elasticbeanstalk-us-east-1-966938761981/images/', - person KillABug; 05.07.2013
comment
Я получаю эту ошибку для move_uploaded_file --›move-uploaded-file/a]: не удалось открыть поток: HTTP-оболочка не поддерживает доступные для записи соединения, если я изменю пути, как в комментариях выше. - person KillABug; 05.07.2013
comment
Я ценю ваш ответ, но я немного застрял, пытаясь помочь себе, мне понадобится ваша помощь.To handle this case you will have to keep those lines to let the file be uploaded to your server first and then transfer the file to S3, Я не получил ваши эти строки, так как сам AWS поддерживает загрузку через PUT - person KillABug; 05.07.2013
comment
Извините, я не знал, что AWS поддерживает загрузку PUT. Вот почему я так сказал. Если класс S3 уже поддерживает загрузку из запроса PUT, вы определенно можете заменить эти строки (707-711) кодом AWS для загрузки PUT. По сути, все, что вам нужно изменить, это три случая обработки загрузки файла. Но вы не можете просто заменить URL-адреса Amazon API вместо upload_dir. Я думаю, что вы действительно можете избавиться от всего кода, связанного с upload_dir. - person rineez; 06.07.2013
comment
На самом деле я предлагал вам взять код загрузки файла в awssdk.php и поместить его в UploadHandler.php. - person rineez; 06.07.2013
comment
Я пробую это!! Проверим и сообщим вам!! Большое спасибо за ваш отзыв - person KillABug; 06.07.2013
comment
Мне удалось загрузить изображение, как вы предложили, но, как я уже говорил, я хочу загрузить изображение в разных версиях (размерах), например original,1024x768,thumbnail(100x100) и т. д. Я пытаюсь использовать массив image_versions и создавать изображения разных размеров, а затем загружать. Но я знаю, как сначала создать, а затем загрузить миниатюры и другие размеры. - person KillABug; 07.07.2013
comment
Извините, я не заметил, что масштабирование происходит только после строки 719 внутри метода handle_image_file. Поэтому я думаю, что для того, чтобы сделать это должным образом, необходимо изменить подход. Возможно, вам придется вернуть эти ранее измененные строки и сначала сохранить загруженные файлы на вашем сервере. И поместите код для загрузки на S3 где-то после строки 719. Четко поймите логику метода handle_file_upload и определите правильное место для загрузки S3. Может быть, можно загрузить на S3 незадолго до return $file;. Я также обновлю свой ответ после того, как поближе познакомлюсь с этим кодом. - person rineez; 08.07.2013
comment
Хорошо, ринез!! Вы хотите сказать, что мне нужно сначала сохранить изображение на моем сервере, а затем переместить его на S3? Я не уверен, что это хорошо, так как загрузка больших изображений может занять много времени. Я проверяю это со своей стороны. Кроме того, спасибо за помощь, вы оказали мне большую поддержку в этом, и надеюсь, что я справлюсь с этим с вашей помощью! - person KillABug; 08.07.2013
comment
Привет, rineez, я работал над этим и внес несколько изменений, но, как я уже сказал, требуется время, когда я загружаю его сначала на свой сервер, а затем на S3. Это занимает около 5 секунд для изображения размером 500 КБ, что, по моему мнению, слишком много. много. Вы нашли лучший способ сделать это? - person KillABug; 08.07.2013
comment
@KillABug Рад, что смог помочь :) . В любом случае обычная загрузка изображения PHP с помощью метода POST всегда будет временно сохранять файл во временной папке веб-сервера. Поэтому трудно поверить, что время, затрачиваемое на сохранение изображения на сервере php, может быть здесь узким местом. Сколько времени ушло на загрузку прямо на S3? А также, пожалуйста, проверьте, сколько времени занимает закомментированный код для загрузки на S3 (т.е. время для загрузки на веб-сервер плюс только изменение размера). - person rineez; 08.07.2013
comment
Я выполню шаги, которые вы упомянули, и обновлю, если результаты различаются. Между тем, мне нужна окончательная помощь по URL-адресу возврата и индикатору выполнения, который мне нужно интегрировать. Я получаю индикатор выполнения для моей локальной загрузки (т.е. мой сервер) и не весь цикл загрузки и обратный URL для удаления, который возвращает плагин по умолчанию - person KillABug; 08.07.2013
comment
Я принял ответ rineez, но задержка является проблемой. Я проверил прямую загрузку POST, изображение загружается на S3 примерно за 14 секунд (размер: 1,8 МБ). Теперь я попытался загрузить то же изображение с помощью плагина на S3, и это занимает около 22 секунд. Тот же плагин на моем текущем сервере занимает около 15 секунд с обрезкой до разных размеров. Не знаю, как я могу это исправить! :( - person KillABug; 09.07.2013
comment
22 секунды до S3 - с преобразованием изображения или без преобразования изображения? (Я думаю, было бы лучше задать этот вопрос о задержке как отдельный вопрос, так как это может помочь вам привлечь внимание людей, у которых больше опыта в этой области.) - person rineez; 09.07.2013
comment
С преобразованием изображений. На самом деле я добавил вопрос уже но нет ответа!! - person KillABug; 10.07.2013
comment
красивый. Затем я проголосую за него, чтобы привлечь больше внимания, а также постараюсь разместить там свои предложения в качестве ответа. - person rineez; 10.07.2013
comment
Следует помнить, что вы хотели повторно использовать код, доступный в UploadHandler blueimp, для изменения размера изображений. Изображения, хранящиеся на вашем сервере, являются требованием для этого кода изменения размера изображения в UploadHandler. Таким образом, оптимизация производительности, скорее всего, будет включать отказ от использования функции изменения размера, предоставляемой UploadHandler от blueimp. - person rineez; 10.07.2013
comment
Да, верно, rineez, bcoz, я считаю, что очень хорошо написано и оптимизировано, и, кроме изменения всей логики, я не нахожу причин не использовать его! Думаю, вы согласитесь1 ;) - person KillABug; 12.07.2013

Возможно, вы ищете Stream Wrapper. http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html#amazon-s3-stream-wrapper

"The Amazon S3 stream wrapper allows you to store and retrieve data from Amazon S3 using built-in PHP functions like file_get_contents, fopen, copy, rename, unlink, mkdir, rmdir, etc."

Я тоже ищу такое же решение. Я основал этот https://gist.github.com/tim-peterson/8172999 Мое это может помочь. Я все еще жду, когда AWS одобрит мою учетную запись, поэтому я не могу протестировать какое-либо решение.

person Cassiano    schedule 24.09.2014