if you need a zip file from the answer, I think you could just write a tmp file to save the twist, and pass it as a workaround: I have never tried this with multi-pole curls, but I think it should work.
$fh = fopen('/tmp/foo', 'w'); $cUrl = curl_init('http://example.com/foo'); curl_setopt($cUrl, CURLOPT_FILE, $fh); // redirect output to filehandle curl_exec($cUrl); curl_close($cUrl); fclose($fh); // close filehandle or the file will be corrupted
if you do NOT need anything other than the part of the xml response you can disable the headers
curl_setopt($cUrl, CURLOPT_HEADER, FALSE);
and add parameter to accept only xml as response
curl_setopt($cUrl, CURLOPT_HTTPHEADER, array('Accept: application/xml'));
[EDIT]
A shot in the dark ... you can test with these curlopt settings to see if this improves their performance
$headers = array ( 'Content-Type: multipart/form-data; boundary=' . $boundary, 'Content-Length: ' . strlen($requestBody), 'X-EBAY-API-COMPATIBILITY-LEVEL: ' . $compatLevel, // API version 'X-EBAY-API-DEV-NAME: ' . $devID, 'X-EBAY-API-APP-NAME: ' . $appID, 'X-EBAY-API-CERT-NAME: ' . $certID, 'X-EBAY-API-CALL-NAME: ' . $verb, 'X-EBAY-API-SITEID: ' . $siteID, ); $cUrl = curl_init(); curl_setopt($cUrl, CURLOPT_URL, $serverUrl); curl_setopt($cUrl, CURLOPT_TIMEOUT, 30 ); curl_setopt($cUrl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($cUrl, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($cUrl, CURLOPT_HTTPHEADER, $headers); curl_setopt($cUrl, CURLOPT_POST, 1); curl_setopt($cUrl, CURLOPT_POSTFIELDS, $requestBody); curl_setopt($cUrl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($cUrl, CURLOPT_FAILONERROR, 0 ); curl_setopt($cUrl, CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt($cUrl, CURLOPT_HEADER, 0 ); curl_setopt($cUrl, CURLOPT_USERAGENT, 'ebatns;xmlstyle;1.0' ); curl_setopt($cUrl, CURLOPT_HTTP_VERSION, 1 ); // HTTP version must be 1.0 $response = curl_exec($cUrl); if ( !$response ) { print "curl error " . curl_errno($cUrl ) . PHP_EOL; } curl_close($cUrl);
[EDIT II]
This is just an attempt, as already mentioned, I cannot get my curled pages to respond using data with multiple forms. So be careful with me here;)
$content_type = ""; //use last know content-type as a trigger $tmp_cnt_file = "tmp/tmpfile"; $xml_response = ""; // this will hold the "usable" curl response $hidx = 0; //header index.. counting the number of different headers received function read_header($cUrl, $string)// this will be called once for every line of each header received { global $content_type, $hidx; $length = strlen($string); if (preg_match('/Content-Type:(.*)/', $string, $match)) { $content_type = $match[1]; $hidx++; } /* should set $content_type to 'application/xop+xml; charset=utf-8; type="text/xml"' for the first and to 'application/zip' for the second response body echo "Header: $string<br />\n"; */ return $length; } function read_body($cUrl, $string) { global $content_header, $xml_response, $tmp_cnt_file, $hidx; $length = strlen($string); if(stripos ( $content_type , "xml") !== false) $xml_response .= $string; elseif(stripos ($content_type, "zip") !== false) { $handle = fopen($tmp_cnt_file."-".$hidx.".zip", "a"); fwrite($handle, $string); fclose($handle); } /* elseif {...} else{...} depending on your needs echo "Received $length bytes<br />\n"; */ return $length; }
and of course set the correct curlopts
// Set callback function for header curl_setopt($cUrl, CURLOPT_HEADERFUNCTION, 'read_header'); // Set callback function for body curl_setopt($cUrl, CURLOPT_WRITEFUNCTION, 'read_body');
don't forget to NOT save the curl response to the variable due to memory problems, hope all you need is $ xml_response anyway.
//$response = curl_exec($cUrl); curl_exec($cUrl);
And to parse the code, you can reference $xml_response and the temporary files you created, starting with tmp/tmpfile-2 in this scenario. Again, I could not verify the code above. So this may not work (but it should imho;))
[EDIT III]
Suppose we want a curl to write all incoming data directly to another (outgoing) stream, in this case a socket connection
I'm not sure how simple it is:
$fs = fsockopen($host, $port, $errno, $errstr); $cUrl = curl_init('http://example.com/foo'); curl_setopt($cUrl, CURLOPT_FILE, $fs); // redirect output to sockethandle curl_exec($cUrl); curl_close($cUrl); fclose($fs); // close handle
else we will have to use our well-known recording and title functions with just a little trick
//first open the socket (before initiating curl) $fs = fsockopen($host, $port, $errno, $errstr); // now for the new callback function function socket_pipe($cUrl, $string) { global $fs; $length = strlen($string); fputs($fs, $string); // add NOTHING to the received line just send it to $fs; that was easy wasn't it? return $length; } // and of course for the CURLOPT part // Set callback function for header curl_setopt($cUrl, CURLOPT_HEADERFUNCTION, 'socket_pipe'); // Set the same callback function for body curl_setopt($cUrl, CURLOPT_WRITEFUNCTION, 'socket_pipe'); // do not forget to fclose($fs); //when we're done
The fact is that not editing the result and just connecting it to $fs will require that apache listen on a specific port, which is then assigned to you by a script. Or you need to add ONE header line directly after fsockopen
fputs($fp, "POST $path HTTP/1.0\n"); //where path is your script of course