Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload feature #89

Merged
merged 4 commits into from
Sep 12, 2013
Merged

Upload feature #89

merged 4 commits into from
Sep 12, 2013

Conversation

dtelaroli
Copy link
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
Owner

Thanks @dtelaroli! Hope to finishing reviewing this this weekend!

@dtelaroli
Copy link
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

How to add mime type of the file?

@dtelaroli
Copy link
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

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
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
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

  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
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

To be precise it is a temporary path to temporary file. So parameter is ok.

I can't change what server does to my request. If it requires request build this way I have to comply. I also would do it differently if I could. FormData sends straight to API, and I'm rewriting this in PHP for my app, they are two, not related apps.

Now I know that this feature is simpler than I thought. Thank you for clarification.

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.

None yet

3 participants