Ethan Keiley
Ethan Keiley

Reputation: 63

How to obtain image/png content via PHP

This is my first post to Stack Overflow so please forgive me if I have used incorrect formatting or conventions. I am trying to write a test scenario which receives a png image from a webpage POST (multipart/form-data), strips out the image which was posted and forwards that on to a 3rd party as Content-Type: image/png.

I have a php file (catcher.php) which is the recipient of the forwarded image. Post.php, the php file that posts the uploaded image to catcher.php is below:

<?php
    $img = imagecreatefrompng($_FILES['myfile']['tmp_name']);
    imagepng($img);
    $opts = array(
        'http'=>array(
            'method'=>"POST",
            'content'=>$img,
            'header'=>"Content-Type: image/png\r\n"               
        )
    );

    $context = stream_context_create($opts);
    file_get_contents( "http://localhost/catcher.php", false, $context);
?>

Post.php gets the file just fine from the webpage that posts it as multipart/form-data, however I am unsure how to access the image/png content in catcher.php.

My question is, in catcher.php, how do I access the image content? I have tried $_POST['content'] and I obtain the following error: "Undefined index: content". So I know I am just not looking for the correct data. Is there a specific superglobal variable such as $_POST or $_REQUEST that I can use to access the posted image content, or is there some other solution?

RESOLUTION I was able to find the result I was looking for with the following code for catcher.php:

$input = fopen("php://input","+r");
$destination = fopen($target_path, 'w');

stream_copy_to_stream($input, $destination);

fclose($input);
fclose($destination);
?>

Thank you both Marc and Brenden for your expedient responses!

Upvotes: 4

Views: 3871

Answers (2)

Brendan Long
Brendan Long

Reputation: 54242

The problem is that your data isn't encoded as multipart/form-data, it's just a PNG.

You have two options:

  1. Encode the data correctly for a POST -- then you can read it from $_POST or $_REQUEST.
  2. Keep post.php how it is and read the raw data from php://input in catcher.php.

For option 1, it looks like HttpRequest handles form encoding for you.

Upvotes: 1

Marc B
Marc B

Reputation: 360602

imagepng($img) does an immediate output of the binary garbage comprising the PNG. it's not captured into a variable. What you're actually posting is a string that probably says "GD Resource #7" or something similar.

The whole imagepng() bit is useless anyways - you're decoding a PNG into an in-memory representation, then trying to re-encode to PNG again. A pointless waste of memory, since the file is already on disk. You could do the whole thing with:

<?php
if ($_FILES['myfile']['error'] !== UPLOAD_ERR_OK) {
   die("Upload failed with error code " . $_FILES['myfile']['error']);
}

$opts = array(
    'http'=>array(
        'method'=>"POST",
        'content'=> file_get_contents($_FILES['myfile']['tmp_name']),
        'header'=>"Content-Type: image/png\r\n"               
    )
);

$context = stream_context_create($opts);
file_get_contents( "http://localhost/catcher.php", false, $context);

Note the addition of checking for upload success - assumingn an upload succeeded will cause you grief down the line.

That being said, you're also not doing a proper POST file upload. For that to work, you have to actually simulate a full-blown HTML form with <input type="file"> present, and enctype="multipart/form-data" and whatnot. All you're doing is sending a raw PNG to the server.

You can probably retrieve it by reading from php://input in your catcher script.

Upvotes: 3

Related Questions