Send PHP generated image (GD) to Amazon S3

Asked

Viewed 457 times

2

I have the following code to upload an image to my Bucket S3:

// Send.class.php
public function sendFile($file, $file_name) {
    try {
        $s3 -> putObject([
            "Bucket" => "mybucket",
            "Key" => "image/".$file_name,
            "SourceFile" => $file,
            "ACL" => "public-read"
        ]);

        return true;
    } catch(S3Exception $e) {
        return false;
    }
}

// index.php
$send = new Send();

$send -> sendFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);

The above code works correctly, however, I want to send images generated by PHP (initially originated in Javascript - jQuery - where I am using the plugin jqScribble: https://github.com/jimdoescode/jqScribble/blob/master/image_save.php) for my Bucket too, so I tried:

// index.php

error_reporting(E_ALL); // mostrar erros
ini_set('display_errors', 'On'); // mostrar erros

$send = new Send();

$data = $_POST["imgdt"]; // imagem originada no JavaScript

$data = substr($data, strpos($data, ",") + 1);

$data = base64_decode($data);
$imgRes = imagecreatefromstring($data);

ob_start();
imagepng($imgRes);
$imageImage = ob_get_contents();
ob_end_clean();

$send -> sendFile($imageImage, "test.png");

But, the following error is returned:

Fatal error: in /var/www/html/vendor/guzzlehttp/psr7/src/functions.php on line 299

And the function that corresponds to the error line (299) is:

function try_fopen($filename, $mode)
{
    $ex = null;
    set_error_handler(function () use ($filename, $mode, &$ex) {
        $ex = new \RuntimeException(sprintf( // linha 299
            'Unable to open %s using mode %s: %s',
            $filename,
            $mode,
            func_get_args()[1]
        ));
    });

    $handle = fopen($filename, $mode);
    restore_error_handler();

    if ($ex) {
        /** @var $ex \RuntimeException */
        throw $ex;
    }

    return $handle;
}

From what I understand, the error occurs because it is not possible to open the file using the function fopen, however, I don’t know which alternatives to turn to. How can I resolve this?

  • 1

    I could be mistaken, it seems that this missing a piece of the error, tells me one thing, is using version 5.2 of PHP?

  • The error that appears is only this same message. I am using version 7.0 that comes as default on Ubuntu 16.04

  • Checks the source code after the upload or element inspector attempt, it may be returning HTML.

  • Unfortunately, returns only the error: <br>&#xA;<b>Fatal error</b>: in <b>/var/www/html/vendor/guzzlehttp/psr7/src/functions.php</b> on line <b>299</b><br>

  • @Guilhermenascimento I believe the error is in the generated image and not in another part of the code (as the error itself tells), since for images uploaded ($_FILE) works normally. However, I don’t know where I’m going wrong.

  • 1

    The first function parameter sendFile() expects a path from a physical file. But it is passing as stream/Resource of output buffer ob_get_contents(). Save the generated image to disk and enter the path.

  • @Danielomine however I do not want to save on the disk the image, just send directly to the S3

  • This function presented in the question does not support what you want to do. Create the file, run the function and delete it. You are complicating something simple.

Show 3 more comments

1 answer

1


The method putObject expects a file path, but you are passing a stream. For this it is possible to use the S3 Stream Wrapper, which enables the use of the protocol (wrapper) s3://

Your function should look like this:

public function sendFile($fileContents, $file_name) {
    try {

        // registra o stream wrapper pra poder usar o protocolo s3://
        $s3->registerStreamWrapper();

        // abre o stream
        $s3Stream = fopen('s3://'.'mybucket'.'/image/'.$file_name, 'w', false, stream_context_create(
            array(
                's3' => array(
                    'ContentType'=> 'image/png'
                )
            )
        ) );

        //escreve
        fwrite($s3Stream, $fileContents);

        //fecha
        fclose($s3Stream);

        return true;
    } catch(S3Exception $e) {
        return false;
    }
}

You can find the documentation here: http://docs.aws.amazon.com/aws-sdk-php/v2/guide/feature-s3-stream-wrapper.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.