Stream DATA From openai GPT-3 API using php - php

I'm having trouble with the OpenAI API, Basically what I'm trying to do is stream each data node that is streamed back from the openai API response and output each data node one at a time as it streams in from the API call, but I have no clue how this is done, I researched for hours and can not find any information on how this can be achieved with PHP.
How can I get my code to output each data node in real time as the API streams in the data?
The Following is the best I can come up with, it outputs all the data at once after the call is complete, but It does not stream in the data.
function openAI(){
$OPENAI_API_KEY="API_KEY_GOES_HERE";
$user_id="1"; // users id optional
$prompt="tell me what you can do for me.";
$temperature=0.5; // 1 adds complete randomness 0 no randomness 0.0
$max_tokens=30;
$data = array('model'=>'text-davinci-002',
'prompt'=>$prompt,
'temperature'=>$temperature,
'max_tokens'=>$max_tokens,
'top_p'=>1.0,
'stream'=>TRUE,// stream back response
'frequency_penalty'=>0.0,
'presence_penalty'=>0.0,
'user' => $user_id);
$post_json= json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_json);
$headers = array();
$headers[] = 'Content-Type: application/json';
// $headers[] = 'Content-Type: text/event-stream';
$headers[] = "Authorization: Bearer $OPENAI_API_KEY";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
return $result;
curl_close($ch);
}
echo openAI();

I ended up solving my problem. Hopefully my answer will help someone in the future.
I made the following additions to my code. This simple logic makes what I inquired about work.
// This should be at the very top, alternatively can be set in you php.ini file
#ini_set('zlib.output_compression',0);
#ini_set('implicit_flush',1);
// This function discards the contents of the topmost output buffer and turns off this output buffering.
#ob_end_clean();
The following curl_setopt should also be added. I personally added it on the line after CURLOPT_POSTFIELDS
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) {
# str_repeat(' ',1024*8) is needed to fill the buffer and will make streaming the data possible
echo $data.str_repeat(' ',1024*8);
return strlen($data);
});
Alternatively instead of adding str_repeat(' ',1024*8) you can shut off buffering in your web servers config file, e.g.(nginx.conf)
gzip off;
proxy_buffering off;

Related

Obtain lockstate from Apache DavLockDB / WebDAV

I run an Apache webserver with mod_dav/mod_dav_fs on a windows server.
Users can edit certain files via WebDAV.
WebDAV is set up and running correctly so far...
The question is, how can I find out if and which files are currently opened via WebDAV?
Apache writes this info into its "DavLockDB".
Is there a way to read that file or to find out which files are currently locked?
I already tried it with via php:
$fp = fopen($file, 'c');
if (!flock($fp, LOCK_EX|LOCK_NB, $wouldblock)) {
// lock not obtained
echo 'file maybe open';
}
else {
// lock obtained
echo 'file is free';
}
This gives me a correct result if the file is opened locally on the server, but not if the file is opened via WebDAV.
Has anyone ever had a similar problem?
Kind regards
Thomas
I've been tied to and frustrated by WebDAV for some years, and I often had a need to be able to identify locked files and occasionally unlock them. I recently wrote a small tool in PHP to achieve this that you can see on Github.
Most of my answers were found in the RFC document & on the webdav.org site.I didn't encounter a solution using the DavLockDB and went the official route sending cURL requests to the DAV server as a real application would with HTTP verbs to get the info that I needed about files or directories.
In short you choose a file or directory as an endpoint and send PROPFIND request. If the endpoint is a directory you'll get a list of resources (files/directories) & their properties that are in that directory (and possibly under it depending on your DEPTH setting). If the endpoint is a file you'll get the file properties. In both cases the information is returned as XML and if any resource is locked the properties will include a LockToken.
Here's a PHP function that you could use based on a method in the repository noted above:
function propfind() {
$location = 'https://example.com:8000' // ROUTE TO SERVER
$endpoint = '/webdav/'; // FINAL DESTINATION
$auth = 'user:pass'; // BASE64 ENCODED USERNAME:PASSWORD
$url = $location.$endpoint;
$host = parse_url($location, PHP_URL_HOST);
$ch = curl_init();
// FIX LOCALHOST SSL CERTIFICATE ISSUES
if ($_SERVER['SERVER_NAME'] == 'localhost') curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+'); // CREATE A STREAM TO SAVE THE VERBOSE CONNECTION DATA
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PROPFIND');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml; charset="utf-8"',
'Host: '.$host,
'Authorization: Basic '.$auth,
'Depth: 1',
));
/*
// OPTIONALLY LIMIT THE RESPONSE TO SPECIFIC PROPERTIES
$xml = '<?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:creationdate/><D:getlastmodified/><D:getcontentlength/></D:prop></D:propfind>';
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
*/
$response = curl_exec($ch);
$curlInfo = curl_getinfo($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
if(curl_error($ch)) {
return array('error'=>curl_errno($ch).': '.curl_error($ch), 'response'=>print_r($curlInfo,1), 'verbose'=>$verboseLog);
}
curl_close($ch);
return array($response, $verboseLog);
}
A sample response might be:
<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>/webdav/test.xlsx</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype/>
<lp1:creationdate>2020-04-11T20:30:58Z</lp1:creationdate>
<lp1:getcontentlength>9853</lp1:getcontentlength>
<lp1:getlastmodified>Thu, 06 Aug 2020 16:17:05 GMT</lp1:getlastmodified>
<lp1:getetag>"123456-789b-ab12345cd67e89"</lp1:getetag>
<lp2:executable>T</lp2:executable>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery>
<D:activelock>
<D:locktype><D:write/></D:locktype>
<D:lockscope><D:exclusive/></D:lockscope>
<D:depth>infinity</D:depth>
<ns0:owner xmlns:ns0="DAV:"><ns0:href>Username</ns0:href></ns0:owner>
<D:timeout>Second-896</D:timeout>
<D:locktoken>
<D:href>opaquelocktoken:a12bc34d-567e-8901-23d4-5ab6cd7e8f90</D:href>
</D:locktoken>
</D:activelock>
</D:lockdiscovery>
<D:getcontenttype>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Note the <D:locktoken> entry which indicates that the file is locked. In theory you could use the function recursively to map out the whole resource and highlight any locked files.
To unlock a file you need the credentials of the user that created the lock. Then send the request using UNLOCK as the HTTP verb:
function unlock () {
$lockToken = 'opaquelocktoken:a12bc34d-567e-8901-23d4-5ab6cd7e8f90';
$location = 'https://example.com:8000' // ROUTE TO SERVER
$endpoint = '/webdav/'; // FINAL DESTINATION
$auth = 'user:pass'; // BASE64 ENCODED USERNAME:PASSWORD
$url = $location.$endpoint;
$host = parse_url($location, PHP_URL_HOST);
$ch = curl_init();
// FIX LOCALHOST SSL CERTIFICATE ISSUES
if ($_SERVER['SERVER_NAME'] == 'localhost') curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'UNLOCK');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Host: '.$host,
'Authorization: Basic '.$auth,
'Lock-Token: <'.$lockToken.'>',
));
$response = curl_exec($ch);
$curlInfo = curl_getinfo($ch);
if(curl_error($ch)) {
$unlockStatus = 'ERROR: '.curl_error($ch).print_r($curlInfo,1);
}
else {
$unlockStatus = array(
'status' => ($curlInfo['http_code'] == '204' ? 'ok' : 'Fail'),
'response' => htmlentities($response),
'curlInfo' => $curlInfo,
);
}
curl_close($ch);
return $unlockStatus;
}
NB: In a more manual way you can get properties and unlock files from the command line with 2 cURL commands:
// GET RESOURCE PROPERTIES
curl -X PROPFIND '{path-to-resource}' -H 'Authorization:Basic {base64 encoded username:password}' -H 'Depth:1'
// UNLOCK A LOCKED FILE
curl -X UNLOCK '{path-to-resource}' -H 'Authorization: Basic {base64 encoded username:password}' -H 'Lock-Token: <{lock-token-from-first-request}>'

Downloading Files with PHP and CURL

I am trying to download a file from an API that I am successfully talking to, however, when I hit the file, it outputs just a bunch of crazy characters. I believe it is the .zip stream, and I just need to get the .csv file that should be in there.
From the API documentation:
curl -XGET -H 'X-API-TOKEN: <API TokenZ' -H 'Content-Type: application/json' https://co1.qualtrics.com/API/v3/surveys/SV_50EhstBgHEG2voV/export-responses/2671b6ec-66e0-4e7b-90bc-77174363763d/file -o responses.zip
Here is what I have:
$file = 'https://co1.qualtrics.com/API/v3/surveys/'.$qualtrics_id.'/export-responses/'.$file_json['result']['fileId'].'/file';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo $result;
curl_close ($ch);
And this is what it gives me:
PKr�JOTest survey.csv�Wmo�����¸�w���W��"��i��M6�m�˂�h����T���3�$+�}{-ĶD93�<3~tܸ+�Dt� ���qW����eQam����� wR+��T̊\����$���(�;��B�]��jeō�[)�{ϭ��o�a�'i���7\V���F��N��*�{�{�����7��:�\I�\�4�cɕU�� �u��"�MS|��It;�ng��<�͢�$�'�g���C$�d9��~���b-T왗�~������mwsu�l�9H�w<�:ڒ������>����J��i�3� �J�~���+�xr��J���W�m�ѰR�V��*X��lYk�޲��Tc9Wl)FRS��B�]��%7����R�zYU��tۭP�T�Y��_��-����v8��VP�K��R� *n�2�ƈu�&����-V� ��y%��� Kh�,���o��e���Y�w���K�.#x�c;]����6��!��уһJƗ�vl+���T��-���A�DTa:P����x�JK��h�y� �t �܈BRLA0K+*� �}�-�AX�\`%`�]+����򒠳d,�n�׵g�R��[Y��]� 3�R)��x�?�ۭFjH%��]Ǥ�7����߄p���B"���#p�[����0d�+L���!�������?��x�JoV�Iz"�J���h%��lM�z��ZU![�x�40��$�0hY�0�xST��U�^��G"XT �;�ʞk�����sr�#��� ��F��,4D�v(T6r"w#QI���T;d7㊪^��bW6��pT�B��Q\~`�V�R�/�� ,q�R���\�U�B0ԇ6 ��>ռ�oT�֪|ߖ� � gߍ�x��ĩ����k4$�D�Z�Y���o+�Ƿٞ��d ��K:��r*��O�PXIYB�T�������E5-��������p����S��n�ڳ��$Ptʱ_��቎8��9�S�6��J`��'Q?هJ+X�,� ��#�C�)N���%�����[J`�y���J�"b�?�,� |�JT��ߔ��V���9���c�+��!7��X��}��V�P�nC�9fjվP�|E�0�A��`�}������'��r��H1o��8���ҕ�{�B4� �0>罐i���<�תFp��~��O���L:jEP�N#݈\�#T�4����� ��D����!�_�I<�� ��X��r�SK��MyDG*�h�>�8JM��F���=+��8���8!��e�3�5��K)X|`��3v�� oR���z�}�6������5����gu��5��j��W�I���#b,z���sH�yӜ�c�1����D�uA�:U��b���e�x!�Me>��fH���me�Vn�#d%u�ǔD6C���ynT`a�_��My޳G ���ҹ��͛�n7�HK��e��8�W�E�|״�~���& }�G��T���Jd�!i�^�؂]�4�n�Uc����#�R#��[\��NDDx�� �.4�����i{�:��чw�;��ժۘh`�o��{_y�nE�7���M^Nu����zd*t��h�!}#�9p�����v����_�-�����m��e#��X᧾���� [�����9�m.d����-��l�\�NϮ�+��Yӻ�nO��U7��|~���Xw�����6��Es���dw�<-Z�Ͽ!��8�#��&Z��]�OK��\�����3��3ӳ3��3�3�ٙ$>?�������:?s�����8�fq6�N��$�J�=�C]���F���� �FLY�.F�b��w���Y����״��~���ۏ­����g6�/�%�E<^��ы�q���a2M��?3o����w_q���;y����_��J��h<�b��eI���$�&i2��G���&Ϭ�.������d���I�'���E���t�ݦ�b�_���8ɲy�%q�$x��l����,�������PK��{pnZPKr�JO��{pnZTest survey.csvPK=�
I am not sure what to do with this, I would like to at least be able to download the zip file with the .csv files in there, however, it would be more than ideal to simply get the "Test survey.csv" file, but I haven't been able to do either, I have tried many different things such as:
// header('Content-Type: application/zip');
// readfile($result);
// $z = new ZipArchive();
// $h = $z->getStream( $result );
// stream_get_contents($result);
All with no luck, any help is appreciated. Thank you.
with the CURLOPT_RETURNTRANSFER option is set curl_exec will return downloaded content in the result. So, your variable $result actually contains the content of the file (PKr�... is a ZIP-header)
So, all you need, just to save the content of the variable in a file, instead of echoing it into the browser.
For example.
...
$result = curl_exec($ch);
file_put_contents('downloaded.zip', $result); // save the string to a file
curl_close ($ch);

How to send and receive JSON data between two servers via php

Obviously I am not using the right keywords in my searches or am not understanding what others have written in blogs or forums, et al.
Looking for information on passing data between two servers. The data will be preferably contained within a JSON array.
If you know of someone who has written a blog fully encompassing this I would really like a chance to read it. Otherwise could you offer some thoughts?
More detailed:
As a user visits a page a PHP function will be called and some data will be "packaged up" in a JSON array and then a POST command to the other server. The second server after receiving the POST will do some processing and then "package up" some data and return it in a JSON array. Then the user will be presented with the results.
With the following I am receiving a HTTP 200 response. Just no data.
SITE 1:
$data_string = json_encode(array('user_id'=>123));
$ch = curl_init('http://site2.dev/retrieve');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)
));
$result = curl_exec($ch);
$status = curl_getinfo($ch);
curl_close($ch);
$result = json_decode($result);
SITE 2:
public function retrieve() {
return json_encode(array('some'=>'456'));
}
The Json array was chosen as it can be encrypted and yes HTTPS will be used in the final environment.
Both servers will have Laravel 4 as the PHP Framework.
Thank you for your thoughts and comments.
Add this:
curl_setopt($ch, CURLOPT_HEADER, 0);
and put quotes on content-length:
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type: application/json','"Content-Length: ' . strlen($data_string) . '"'));

Reading POST data in PHP from cUrl

I am using cUrl in PHP to request from some external service.
Interesting enough, the server is responding with raw "multipart/form-data" instead of binary file data.
My website is using a shared hosting, therefore PECL HTTP is not an option.
Is there a way to parse this data with PHP?
Sample code:
$response = curl_exec($cUrl);
/* $response is raw "multipart/form-data" string
--MIMEBoundaryurn_uuid_DDF2A2C71485B8C94C135176149950475371
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: binary
(xml data goes here)
--MIMEBoundaryurn_uuid_DDF2A2C71485B8C94C135176149950475371
Content-Type: application/zip
Content-Transfer-Encoding: binary
(binary file data goes here)
*/
EDIT: I tried piping the response to a localhost HTTP request, but the respond data is likely to exceed the allowed memory size in PHP process. Expending mem limit is not very practical, this action also dramatically reduces the server performance dramatically.
If there is no alternatives to the original question, you may suggest a way to handle very large POST requests, along with XML parsing, in terms of streams in PHP.
I know this would be hard, please comment. I am open for discussions.
if you need the zip file from the response I guess you could just write a tmp file to save the curl response to, and stream that as a workaround:
Never tried that with multipart curls, but I guess 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 but the xml part of the response you might want to disable headers
curl_setopt($cUrl, CURLOPT_HEADER, FALSE);
and add option to only accept xml as a response
curl_setopt($cUrl, CURLOPT_HTTPHEADER, array('Accept: application/xml'));
//That's a workaround since there is no available curl option to do so but http allows that
[EDIT]
A Shot in the dark...
can you test with these curlopt settings to see if modifiying these help anything
$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 a try, as mentioned I cannot get my curled pages to respond with a multipart form data. So be gentle 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 proper 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 a variable because of the memory issues,
hopefully all you need will be in the $xml_response above anyways.
//$response = curl_exec($cUrl);
curl_exec($cUrl);
And for parsing your code you can refer to $xml_response and the temp files you created starting with tmp/tmpfile-2 in this scenario. Again, I have not been able to test the code above in any way. So this might not work (but it should imho ;))
[EDIT III]
Say we want curl to write all incoming data directly to another (outgoing) stream, in this case a socket connection
I'm not sure if it is as easy as this:
$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 known write and header 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 thing is, not editing the result and simply piping it to $fs will make it necessary that apache is listening on a certain port which you then assign your script to.
Or you will need to add ONE header line directly after fsockopen
fputs($fp, "POST $path HTTP/1.0\n"); //where path is your script of course
I'm sorry i can't help much because you did not put much code but i remember i was having a similar issue when i was playing with curl_setopt options.
Did you use CURLOPT_BINARYTRANSFER?
From php documentation -> CURLOPT_BINARYTRANSFER-> TRUE to return the raw output when CURLOPT_RETURNTRANSFER is used.
just set CURLOPT_RETURNTRANSFER CURLOPT_POST
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt($c, CURLOPT_TIMEOUT, 1);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS,
array());
$rst_str = curl_exec($c);
curl_close($c);
You can re-assemble you Binary data doing something like this, I hope it helps.
$file_array = explode("\n\r", $file, 2);
$header_array = explode("\n", $file_array[0]);
foreach($header_array as $header_value) {
$header_pieces = explode(':', $header_value);
if(count($header_pieces) == 2) {
$headers[$header_pieces[0]] = trim($header_pieces[1]);
}
}
header('Content-type: ' . $headers['Content-Type']);
header('Content-Disposition: ' . $headers['Content-Disposition']);
echo substr($file_array[1], 1);
If you don't need binary data, have you tried below?
curl_setopt($c, CURLOPT_NOBODY, true);

PUT string of data to XML server using PHP

I need to put a string of data like so: '< client>...<\client>' onto an XMl server (example url:'http://example.appspot.com/examples') using PHP.
(Context: Adding a new client's details to the server).
I have tried using CURLOPT_PUT, with a file and with just a string (since it requires CURLOPT_INFILESIZE and CURLOPT_INFILE) but it does not work!
Are there any other PHP functions that could be used to do such a thing? I have been looking around but PUT requests information is sparse.
Thanks.
// Start curl
$ch = curl_init();
// URL for curl
$url = "http://example.appspot.com/examples";
// Put string into a temporary file
$putString = '<client>the RAW data string I want to send</client>';
/** use a max of 256KB of RAM before going to disk */
$putData = fopen('php://temp/maxmemory:256000', 'w');
if (!$putData) {
die('could not open temp memory data');
}
fwrite($putData, $putString);
fseek($putData, 0);
// Headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Binary transfer i.e. --data-BINARY
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
// Using a PUT method i.e. -XPUT
curl_setopt($ch, CURLOPT_PUT, true);
// Instead of POST fields use these settings
curl_setopt($ch, CURLOPT_INFILE, $putData);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($putString));
$output = curl_exec($ch);
echo $output;
// Close the file
fclose($putData);
// Stop curl
curl_close($ch);
since I haven't worked with cURL so far I can't really answer to that topic. If you'd like to use cURL I'd suggest looking at the server log and see what actually didn't work (so: Was the output of the request really what it's supposed to be?)
If you don't mind switching over to another technology/library I'd suggest you to use the Zend HTTP Client which is really straight forward to use, simple to include and should satisfy all your needs. Especially as performing a PUT Request is as simple as that:
<?php
// of course, perform require('Zend/...') and
// $client = new Zend_HTTP_Client() stuff before
// ...
[...]
$xml = '<yourxmlstuffhere>.....</...>';
$client->setRawData($xml)->setEncType('text/xml')->request('PUT');
?>
Code sample is from: Zend Framework Docs # RAW-Data Requests
Another way to add string body to the PUT request with CURL in PHP is:
<?php
$data = 'My string';
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // Define method type
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // Set data to the body request
?>
I hope this helps!

Categories