2015-06-25 6 views
2

Я делаю некоторые тесты с laravel, загружая изображения в Amazon S3 и манипулируя имиджами с beanstalkd. Обратите внимание, что это просто тестирование.Как правильно настроить обработку изображений в laravel с помощью beanstalkd во время загрузки в Amazon S3?

Вот моя реализация:

// routes.php

Route::post('/', function() 
{ 
    $validator = Validator::make(Input::all(), array(
     'title' => 'required', 
     'file' => 'required|mimes:jpeg,jpg,png', 
    )); 

    if($validator->fails()) 
    { 
     return Redirect::to('/'); 
    } 

    // Upload File 
    $file = Input::file('file'); 

    $now = new DateTime; 
    $hash = md5($file->getClientOriginalName().$now->format('Y-m-d H:i:s')); 
    $key = $hash.'.'.$file->getClientOriginalExtension(); 

    $s3 = AWS::createClient('s3'); 

    $s3->putObject(array(
     'Bucket'  => 'bellated', 
     'Key'   => $key, 
     'SourceFile' => $file->getRealPath(), 
     'ContentType' => $file->getClientMimeType(), 
    )); 

    // Create job 
    Queue::push('\Proc\Worker\ImageProcessor', array(
     'bucket' => 'bellated', 
     'hash'  => $hash, 
     'key'  => $key, 
     'ext'  => $file->getClientOriginalExtension(), 
     'mimetype' => $file->getClientMimeType(), 
    )); 

    Log::info('queue processed'); 

    return Redirect::to('/complete'); 
}); 

// процессор обработки изображений

<?php namespace Proc\Worker; 

use Imagine\Gd\Imagine; 
use Imagine\Image\Box; 

class ImageProcessor { 

    protected $width; 
    protected $height; 
    protected $image; 

    public function fire($job, $data) 
    { 
      $s3 = \AWS::createClient('s3'); 



     try { 
    $response = $s3->getObject(array(
      'Bucket'  => $data['bucket'], 
      'Key'   => $data['key'], 
     )); 
} catch (Exception $e) { 
    return; 
} 

     $imagine = new Imagine(); 
     $image = $imagine->load((string)$response->get('Body')); 

     $size = new Box(100, 100); 
     $thumb = $image->thumbnail($size); 

     $s3->putObject(array(
      'Bucket'  => 'bellated', 
      'Key'   => $data['hash'].'_100x100.'.$data['ext'], 
      'Body'  => $thumb->get($data['ext']), 
      'ContentType' => $data['mimetype'], 
     )); 



    } 

} 

Когда у меня есть 'синхронизации' в качестве очереди - все работает отлично, и я получить оба изображения (оригинал и размер) в Amazon, но после того, как я переключился на «beanstlakd» и запустил очередь php artisan: слушаю, я продолжаю получать эту ошибку:

Next exception 'Aws\S3\Exception\S3Exception' 
    with message 'Error executing "GetObject" 
    on "https://s3.eu-central-1.amazonaws.com/bellated/cd05ec14f7a19047828d7ed79d192ee3.jpg"; 
AWS HTTP error: 
Client error: 404 NoSuchKey 
(client): The specified key does not exist. - 
    <?xml version="1.0" encoding="UTF-8"?> 
    <Error> 
     <Code>NoSuchKey</Code> 
     <Message>The specified key does not exist.</Message> 
     <Key>cd05ec14f7a19047828d7ed79d192ee3.jpg</Key> 
     <RequestId>9390AD2904820C3E</RequestId> 
     <HostId> 
     nZK1ivZn3bs6xy0S/tGe+A7yoZgKKccLpUDObKuwS2Zmi8LXUgFI5JpkQWCkwchCw6tgW7jyvGE= 
     </HostId> 
    </Error>' 
    in /home/vagrant/Code/laravel/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php:152 

Любые идеи о том, что может быть причиной этого или как я могу продолжить это?

+0

Какую версию Laravel вы используете? – whoacowboy

+0

5.1 - Мне просто нужно выяснить, как отлаживать или какая разница при запуске этой консольной команды. – funguy

ответ

1

Похоже, вы устанавливаете ключ s3 для имени файла, которое может вызвать у вас горе.

$s3->putObject(array(
     'Bucket'  => 'bellated', 
     'Key'   => $data['hash'].'_100x100.'.$data['ext'], 
     'Body'  => $thumb->get($data['ext']), 
     'ContentType' => $data['mimetype'], 
    )); 

Ошибка заставляет меня думать об этом.

Client error: 404 NoSuchKey 
(client): The specified key does not exist. - 
<Key>cd05ec14f7a19047828d7ed79d192ee3.jpg</Key> 

В целом, похоже, что вы делаете это с трудом. Я не уверен, как заставить ваш код работать, но Laravel делает много того, что вы пытаетесь сделать прямо из коробки.

Вот как я сделал то, что вы пытаетесь сделать.

Вам необходимо настроить свою среду.

.env

S3_KEY=MYKEYMYKEYMYKEYMYKEY 
    S3_SECRET=MYSECRETMYSECRETMYSECRETMYSECRETMYSECRET 
    S3_REGION=us-east-1 
    S3_BUCKET=bucketname 

конфигурации/filesystem.php

<?php 
    return [ 
     'default' => 'local', 
     'cloud' => 's3', 
     'disks' => [ 
      'local' => [ 
       'driver' => 'local', 
       'root' => storage_path().'/app', 
      ], 
     's3' => [ 
      'driver' => 's3', 
      'key' => env('S3_KEY'), 
      'secret' => env('S3_SECRET'), 
      'region' => env('S3_REGION'), 
      'bucket' => env('S3_BUCKET'), 
     ], 
     ], 
    ]; 

routes.php Быстрый тест

Route::get('s3',function(){ 
     $success = Storage::disk('s3')->put('hello.txt','hello'); 
     return ($success)?'Yeay!':'Boo Hoo'; 
    }); 

Я знаю, что это с текстовым файлом, но это то же самое.

Как бы я работал с Queuing, используя Laravel's Job (он используется для команды).

В терминале типа, который сделает приложение/Jobs/NewJob.php.

php artisan make:job NewJob --queued 

Настройте свою работу следующим образом.

NewJob.PHP

<?php 

    namespace App\Jobs; 

    use ...; 

    class NewJob extends Job implements SelfHandling, ShouldQueue 
    { 
     public $content; 
     public $path; 

     use InteractsWithQueue, SerializesModels; 
     public function __construct($content, $path) 
     { 
      $this->content = $content; 
      $this->path = $path; 
     } 

     public function handle() 
     { 
      Storage::disk('s3')->put($this->path,$this->content) 
     } 
    } 

И ваш контроллер что-то вроде этого

<?php 

    namespace App\Http\Controllers; 

    use ...; 

    class ImageController extends Controller 
    { 
     public function sendImage($content, $path) 
     { 
      $this->dispatch(new NewJob($content, $path)); 
     } 
    }