4

I am trying to add a REST api in Yii2 to be used by mobile applications to upload image/audio file. I am trying to use PUT method to get the image/file data from the http form-data, but for some reason the fopen("php://input", "r"); returns empty stream. I tried the code as give in this sample http://www.php.net/m...put-method.php.

<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");

/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");

/* Read the data 1 KB at a time
   and write to the file */
while ($data = fread($putdata, 1024))
  fwrite($fp, $data);

/* Close the streams */
fclose($fp);
fclose($putdata);
?>

Meanwhile, using POST method works though. Using the following code for POST

$putdata = fopen($_FILES['photo']['tmp_name'], "r");
        $filename = $this->documentPath.uniqid().'.jpg';
        /* Open a file for writing */
        $fp = fopen($filename, "w");

        /* Read the data 1 KB at a time
           and write to the file */
        while ($data = fread($putdata, 1024))
          fwrite($fp, $data);

        /* Close the streams */
        fclose($fp);
        fclose($putdata);
6
  • did you find solution? Commented Jul 10, 2014 at 16:56
  • 1
    nope, i used post for now Commented Jul 10, 2014 at 19:48
  • with REST? If yes how? Commented Jul 11, 2014 at 19:09
  • 1
    use the above code that I posted for the POST(the second block). I basically put that code in actionUpload method in my rest api controller class. Commented Jul 11, 2014 at 19:17
  • 1
    Here you go. gist.github.com/appcodr/ff02301b259488a69710. For testing you can use postman client(chrome extension) and then in the URL params add a "data" variable for filename and choose a photo to upload Commented Jul 11, 2014 at 19:44

2 Answers 2

6

Since version 2.0.10, a built-in mechanism has appeared that allows you to use PUT with formData: https://www.yiiframework.com/doc/api/2.0/yii-web-multipartformdataparser

So, at first you need to add parser to config file

return [
    'components' => [
        'request' => [
            'parsers' => [
                'multipart/form-data' => 'yii\web\MultipartFormDataParser'
            ],
        ],
        // ...
    ],
    // ...
];

Next - execute getBodyParams to populate $_FILES. This should be executed before requesting of any file.

$restRequestData = Yii::$app->request->getBodyParams();

And then files became available with general methods:

$file = UploadedFile::getInstancesByName('photo');
Sign up to request clarification or add additional context in comments.

Comments

2

Here's how you send PUT with curl:

curl -X PUT -d 'BLABLABLA' http://localhost/upload

Then disable csrf validation in your upload controller:

\yii::$app->request->enableCsrfValidation = false;

Here's an example upload controller action using your code:

public function actionIndex()
{
   \yii::$app->request->enableCsrfValidation = false;
   $putdata = fopen("php://input", "r");
   // make sure that you have /web/upload directory (writeable) 
   // for this to work
   $path = \yii::getAlias('@webroot')."/upload/myputfile.ext";

   $fp = fopen($path, "w");

   while ($data = fread($putdata, 1024))
      fwrite($fp, $data);

   /* Close the streams */
   fclose($fp);
   fclose($putdata);

}

Check the upload:

$ cat /path/to/webroot/upload/myputfile.ext
BLABLABLA

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.