4

I am trying to upload a file using a RESTful web service as follows:

$filename = "pathtofile/testfile.txt";
$handle = fopen($filename, "r");
$filecontents = fread($handle, filesize($filename));
fclose($handle);

$data = array('name' => 'testfile.txt', 'file' => $filecontents);

$client = curl_init($url);
curl_setopt($client, CURLOPT_POST, true);
curl_setopt($client, CURLOPT_POSTFIELDS, $data);
curl_setopt($client, CURLOPT_RETURNTRANSFER, 1);
curl_close($client);

But I keep gettig file is empty as a response for this request.

I tried also sending the file path like:

$data = array('name' => 'testfile.txt', 'file' => 'pathtofile/testfile.txt');
curl_setopt($client, CURLOPT_POSTFIELDS, $data);

Or: just sending the contents of the file only like:

curl_setopt($client, CURLOPT_POSTFIELDS, $filecontents);

But the same response: file is empty.

Note that: the file exists and not empty, and I am just trying to only upload the file no additional fields .

I saw this post , but the same problem, any ideas?

Community
  • 1
  • 1
Mahmoud Gamal
  • 78,257
  • 17
  • 139
  • 164

1 Answers1

1

Try this:

$data = array ('myfile' => '@'.$filename);

This will fill $_FILE ['myfile'] for the receiving end.

Edit: to actually put the file contents as the body, you could do it directly:

//Get the file data
$body = file_get_contents ($filename);
$len = strlen ($body);

//Open a direct connection to the server on port 80
$socket = fsockopen ('hostname.example.com', 80);

//Write the HTTP request headers
fwrite ($socket, "POST /path/to/url HTTP/1.1\r\n");
fwrite ($socket, "Host: hostname.example.com\r\n");
fwrite ($socket, "Connection: Close\r\n");
fwrite ($socket, "Content-Length: " . $len . "\r\n");

//Empty line marks end of headers, start of body
fwrite ($socket, "\r\n");

//Actually write the body
fwrite ($socket, $body);

//Get the result (half a kB at a time)
$result = '';
while (!feof ($socket)) $result .= fread ($socket, 512);

//Clean up nicely
fclose ($socket);

Note that that code is untested, but it should give you the general idea.

Steven Don
  • 2,436
  • 15
  • 14
  • Thanks for the response, But I have tried it but it seems like the problem is in the service itself, I reviewed their documentation and they said that *the entire request body is saved as a new file* so how would `$data` looks like and what parameters should I pass to the service in this case should it be the contents of the file and the content type only or what? When I just send the contents of the file nothing posted to the service. – Mahmoud Gamal Feb 14 '12 at 14:13
  • Wow, that is a weird API. Can you post a link to it? If it really does work that way, you may have to skip cURL and do it yourself via a direct socket write, as it doesn't appear cURL for PHP lets you set the POST body directly (accepting only an array or a URL-encoded string). – Steven Don Feb 14 '12 at 14:27
  • Note that they said that: *File should be sent as a binary stream* but I tried it as I said in my question above and it works but the file url gives me: Bad request or malformed parameters, and i checked the server and no file was uploaded or uploaded empty, so could you explain this. – Mahmoud Gamal Feb 14 '12 at 14:33
  • I've amended my answer to show how it can be done using direct socket writes. – Steven Don Feb 14 '12 at 14:58
  • Thanks alot for your responses, I tried it It gives me no errors and no reponses as well I debug it using Firebug but there is no files uploaded, and how can I get the reponse they provided in thier documentation in the form of `file_key` and `file_url` – Mahmoud Gamal Feb 14 '12 at 15:12
  • The result should be in `$result`. That would include the headers though. To split into headers and body, `list ($headers, $body) = explode ("\r\n\r\n", $result, 2);` – Steven Don Feb 14 '12 at 15:53
  • But why I couldn't do that with curl i.e. how to make the entire request body as a new file and make the content type with the file content type. is this possible and why they mention that? – Mahmoud Gamal Feb 14 '12 at 16:12
  • They designed the API in a very non-standard way. Personally, I'd call it bad design, but maybe they have a good reason for it. (The PHP interface to) cURL doesn't allow it simply because it's been written for the common case, not this weird edge-case. It just doesn't know how to handle it. – Steven Don Feb 14 '12 at 16:23