Upload feature by dtelaroli · Pull Request #89 · nategood/httpful · GitHub
Skip to content

Upload feature - #89

Merged
nategood merged 4 commits into
nategood:masterfrom
dtelaroli:master
Sep 12, 2013
Merged

nategood merged 4 commits into
nategood:masterfrom
dtelaroli:master

Conversation

@dtelaroli

Copy link
Copy Markdown
Contributor

Implemented basic feature to upload files.

Use:

\Httpful\Request::post($this->url)
->body(array())
->attach(array('indexToPost' => '/path/to/file'))
->send()

The content type should be multipart/form-data
Method should be POST
Data should be array

@nategood

Copy link
Copy Markdown
Owner

@dtelaroli

Copy link
Copy Markdown
Contributor Author

Ok @nategood

Related issue #2

nategood added a commit that referenced this pull request Sep 12, 2013
@nategood
nategood merged commit f48c8a7 into nategood:master Sep 12, 2013
@wojciechczerniak

Copy link
Copy Markdown

How to add mime type of the file?

@dtelaroli

Copy link
Copy Markdown
Contributor Author

The mime you have on server side.

Eg.

$_FILE['nameOfFile']['type']

The upload no need to know the mime type, only the name on the disk (including temp file).

@wojciechczerniak

Copy link
Copy Markdown

I have to send POST with content-type multipart/form-data and this sample payload:

------WebKitFormBoundaryhJORK1NjsBw3ht1f
Content-Disposition: form-data; name="data"; filename="blob"
Content-Type: application/json
------WebKitFormBoundaryhJORK1NjsBw3ht1f
Content-Disposition: form-data; name="file[0]"; filename="sample.stl"
Content-Type: application/octet-stream
------WebKitFormBoundaryhJORK1NjsBw3ht1f--

With Guzzle I get the right answer:

$request = $client->post('cartitems/register');
$request->setHeader('Accept', 'application/json');
$request->setHeader('APICode', self::$keyAPI);
$request->addPostFile( 'data', $tmpfname, 'application/json' );
$request->addPostFile('file', PATH . 'content/sample.stl', 'application/octet-stream');

With HTTPful I can't specify content-type of files and this fails and API complains about wrong request body:

$request = Request::post('cartitems/register');
$request->addHeader('Accept', 'application/json');
$request->addHeader('APICode', self::$keyAPI);
$request->body( array() );
$request->attach(array('data' => $tmpfname )); //type: "application/json"
$request->attach(array('file' => (PATH . 'content/sample.stl') )); //type: "application/octet-stream"
$request->expectsJson();

I just don't see any other difference. Guzzle allows to add files mime types that are in the sample payload.

@dtelaroli

Copy link
Copy Markdown
Contributor Author

application/json is not a file
use body to set it

the Content-Type to send files is multipart/form-data

maybe you should send file in other request or send json as string

@dtelaroli

Copy link
Copy Markdown
Contributor Author

try this:

\Httpful\Request::post('cartitems/register')
                    ->addHeader('Accept', 'application/json')
                    ->sendTypes(\Httpful\Mime::FORM)
                    ->body("your json")
                    ->attach(array('file' => (PATH . 'content/sample.stl')))
                    ->send();

this:

\Httpful\Request::post('cartitems/register')
                    ->addHeader('Accept', 'application/json')
                    ->sendTypes(\Httpful\Mime::FORM)
                    ->body(array('data' => 'yourjson' ))
                    ->attach(array('file' => (PATH . 'content/sample.stl')))
                    ->send();

or this:

\Httpful\Request::post('cartitems/register')
                    ->addHeader('Accept', 'application/json')
                    ->sendTypes(\Httpful\Mime::FORM)
                    ->body(array('key1' => 'value', 'key2' => 'value2', 'keyn' => 'valuen'))
                    ->attach(array('file' => (PATH . 'content/sample.stl')))
                    ->send();

you will receive in server a $_FILES and $_POST data
my server side RESTful is Java, so, i don't know how you will get the parameters in the PHP

@wojciechczerniak

Copy link
Copy Markdown
  1. Illegal string offset 'file' Httpful/Request.php: 383 As you stated in original post body should be an array, so file can be attached to payload.
  2. Sends request but API returns error. So it's not how request should look like. [requestError] => Wrong request body. Check if all parameters set correctly.
  3. HTTPful error: Array to string conversion Httpful/Request.php: 811

I don't have access to server side. It's some company API. Example client in javascript appends json in Blob object:

var data = new FormData();
data.append("data", new Blob([$("#requestJson").val()], { type: "application/json" }));
data.append("file[" + fileIdx + "]", new Blob([value.files[i]], { type: "application/octet-stream" }), value.files[i].name);

Taking that under consideration I created in PHP a temporary file with my json:

    /* Prepare the data for HTTP PUT. */
    $tmpfname = tempnam("/tmp", "FOO");
    $putData = fopen($tmpfname, "w");
    fwrite($putData, json_encode($requestB));  // write json to temp file
    fseek($putData, 0); //go back to the beggining of file

and attached it as file with content-type as shown in code attached earlier. My request looks like the one from example and also shown above. And finally I receive a proper response from API server.

I can do it in Guzzle but I was looking for a way to do it in HTTPful. The rest of API works great but I will have to rewrite everything to Guzzle because of this one request. Guzzle has an option to add file mime, without that it returns the same responseError as HTTPful. With mime everything works fine. Looks like with HTTPful I can't go as far. Thanks for your answers.

@dtelaroli

Copy link
Copy Markdown
Contributor Author

The attach method not accept file, the parameter should be path to file

Why you not send data as json???

data.append("data", $("#requestJson").val());

This module to AngularJs work for me to upload files and data as json: https://github.com/danialfarid/angular-file-upload/blob/master/angular-file-upload.js#L86.

Have you sure that file upload from FormData to PHP work, before the Httpful request?

PS: The upload feature is new, and it is very simple, so, if you need extra features like a Guzzle, open a issue and wait or send pull request.

@wojciechczerniak

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants