Send XML data to webservice using php curl - php

I'm working on Flight API of arzoo. The server must receive the posted data in simple POST Request. To achieve this i'm using PHP cURL. In the API Document it is clearly mention that the data should be sent in the following format:
<AvailRequest>
<Trip>ONE</Trip>
<Origin>BOM</Origin>
<Destination>NYC</Destination>
<DepartDate>2013-09-15</DepartDate>
<ReturnDate>2013-09-16</ReturnDate>
<AdultPax>1</AdultPax>
<ChildPax>0</ChildPax>
<InfantPax>0</InfantPax>
<Currency>INR</Currency>
<Preferredclass>E</Preferredclass>
<Eticket>true</Eticket>
<Clientid>77752369</Clientid>
<Clientpassword>*AB424E52FB5ASD23YN63A099A7B747A9BAF61F8E</Clientpassword>
<Clienttype>ArzooINTLWS1.0</Clienttype>
<PreferredAirline></PreferredAirline>
</AvailRequest>
I've taken the above code in a variable $xml. My PHP cURL code is as follows:
$URL = "http://59.162.33.102:9301/Avalability";
//setting the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
if (curl_errno($ch))
{
// moving to display page to display curl errors
echo curl_errno($ch) ;
echo curl_error($ch);
}
else
{
//getting response from server
$response = curl_exec($ch);
print_r($response);
curl_close($ch);
}
I'm not getting anything in response. I've spoken about the same with the API Provider but they found empty request in their log. Am i missing something from my end. Your reply will be appreciated. Thank You.

After Struggling a bit with Arzoo International flight API, I've finally found the solution and the code simply works absolutely great with me. Here are the complete working code:
//Store your XML Request in a variable
$input_xml = '<AvailRequest>
<Trip>ONE</Trip>
<Origin>BOM</Origin>
<Destination>JFK</Destination>
<DepartDate>2013-09-15</DepartDate>
<ReturnDate>2013-09-16</ReturnDate>
<AdultPax>1</AdultPax>
<ChildPax>0</ChildPax>
<InfantPax>0</InfantPax>
<Currency>INR</Currency>
<PreferredClass>E</PreferredClass>
<Eticket>true</Eticket>
<Clientid>777ClientID</Clientid>
<Clientpassword>*Your API Password</Clientpassword>
<Clienttype>ArzooINTLWS1.0</Clienttype>
<PreferredAirline></PreferredAirline>
</AvailRequest>';
Now I've made a little changes in the above curl_setopt declaration as follows:
$url = "http://59.162.33.102:9301/Avalability";
//setting the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Following line is compulsary to add as it is:
curl_setopt($ch, CURLOPT_POSTFIELDS,
"xmlRequest=" . $input_xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
$data = curl_exec($ch);
curl_close($ch);
//convert the XML result into array
$array_data = json_decode(json_encode(simplexml_load_string($data)), true);
print_r('<pre>');
print_r($array_data);
print_r('</pre>');
That's it the code works absolutely fine for me. I really appreciate #hakre & #Lucas For their wonderful support.

Previous anwser works fine. I would just add that you dont need to specify CURLOPT_POSTFIELDS as "xmlRequest=" . $input_xml to read your $_POST. You can use file_get_contents('php://input') to get the raw post data as plain XML.

Check this one. It will work.
function fetch($i1,$i2,$i3,$i4)
{
$input_data = '<I>
<i1>'.$i1.'</i1>
<i2>'.$i2.'</i2>
<i3>'.$i2.'</i3>
<i4>'.$i3.'</i4>
</I>';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://192.168.1.100:8080/avaliablity",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $input_data,
CURLOPT_HTTPHEADER => array(
"Cache-Control: no-cache",
"Content-Type: application/xml"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
}
fetch('i1','i2','i3','i4');

If you are using shared hosting, then there are chances that outbound port might be disabled by your hosting provider. So please contact your hosting provider and they will open the outbound port for you

Related

PHP / Curl Incoming Webhook to MS Teams doesn't work all of the time

I am using an incoming webhook on a web app to post some data to teams. I got this working in CURL after looking up some implementation methods, but it should be noted I have no experience in CURL. The thing is, it works about half the time, then the other half this comes up in the error log:
[01-Feb-2021 09:00:59 Europe/London] Error: Could not resolve host: outlook.office.com
Was hoping someone can take a look and see if there is something obvious I am doing wrong. This is the code used in my PHP file (with the webhook ID removed for privacy)
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_URL, 'webhook-id-here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"text\": \"$teamsMessage\"}");
$headers = array();
$headers[] = 'Content-Type:application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
error_log("Error: " . curl_error($ch), 0);
}
curl_close($ch);
Looks like a DNS problem. Could not resolve host: outlook.office.com.
Maybe any firewall involved in blocking that? Remove CURLOPT_SSL_VERIFYPEER and CURLOPT_IPRESOLVE.
Try this simplified solution, which works well for me. I am using JSON header instead of form encoding.
// Paste the URL here
$url = 'https://outlook.office.com/webhook/XXX';
// Use the text encoded as MARKDOWN.
// Any markdown character needs to be escaped!
$body = ['text' => 'Hello World'];
$curlHandle = curl_init($url);
curl_setopt_array($curlHandle, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($body)
]);
$response = curl_exec($curlHandle);
curl_close($curlHandle);
if ($response !== '1') throw new Exception('No Response from MS incoming webhook API');

Bing Image search API v5.0 example for PHP

I'm trying, without success, to get some results using Bing's Image search API without HTTP/Request2.php component (as used in the official examples).
I understand that the only two required parameters to make a very primitive call are q which is the query string and the subscription key. The key must be sent using headers. After looking around I found this very simple example to send headers with PHP:
$sURL = "https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=cats";
$aHTTP = array(
'Ocp-Apim-Subscription-Key' => 'xxxxxxx',
);
$context = stream_context_create($aHTTP);
$contents = file_get_contents($sURL, false, $context);
echo $contents;
But it does not output anything. Would you kindly help me with a very basic example of use of Bing's API?
SOLVED
Thanks to Vadim's hint I changed the way headers are sent and now output is a Json encoded result. (Remember to add your API subscription key.)
$sURL = "https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=cats";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sURL);
curl_setopt($ch, CURLOPT_TIMEOUT, '1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data',
'Ocp-Apim-Subscription-Key: xxxxx'
));
$content = curl_exec($ch);
echo $content;
Just another tip. The syntax of query filters and other parameters change form version to version. For example the following work correctly in version 5.0:
To search only for JPEG images of cats and get 30 results use:
q=cats&encodingFormat='jpeg'&count=30
To search only for 'portrait' aspect images with size between 200x200 and 500x500 use:
q=cats&aspect=Tall&size=Medium
Try using cURL
$sURL = "https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=cats";
$key = "xxxxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sURL);
curl_setopt($ch, CURLOPT_TIMEOUT, '1');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 'ocp-apim-subscription-key:$key');
$content = curl_exec($ch);
echo $content;
Here is my working code..
Replace ******** with your bing subscription key.
$sURL = "https://api.cognitive.microsoft.com/bing/v5.0/images/search?q=microsoft-surface&count=6&mkt=en-US";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $sURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data',
'Ocp-Apim-Subscription-Key: *******************'
));
$contents = curl_exec($ch);
$myContents = json_decode($contents);
if(count($myContents->value) > 0) {
foreach ($myContents->value as $imageContent) {
echo '<pre/>';
print_r($imageContent);
}
}

Adding attachment to Jira via API

I am using Jira's API to add an attachment file to a case. My issue is after my code attaches a file, and I go to the JIRA case to confirm, I see two things. First, if it is an image, I can see a thumbnail of the image. If I click it, though, I get an error saying "The requested content cannot be loaded. Please try again." Second, under the thumbnail, instead of showing the name of the file, it has the path that the file was originally uploaded from (id: c:/wamp/www/...." Is there a reason this is happening? Here is my code:
$ch = curl_init();
$header = array(
'Content-Type: multipart/form-data',
'X-Atlassian-Token: no-check'
);
$attachmentPath = $this->get_file_uploads();
//$attachmentPath comes out to be something like:
//c:/wamp/www/mySite/web/system/files/my_folder/DSC_0344_3.JPG
$data = array('file'=>"#". $attachmentPath, 'filename'=>'DSC_0344_3.JPG');
$url= 'https://mysite.atlassian.net/rest/api/2/issue/20612/attachments/';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS ,$data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");
$result = curl_exec($ch);
$ch_error = curl_error($ch);
Once the file gets added to Jira, when I log into jira, I can see the thumbnail but the title under the file is something like: c:/wamp/www/mySite/web/system/files/my_folder/DSC_0344_3.JPG instead of the file name.
thanks
You need to use:
$data = array('file'=>"#". $attachmentPath . ';filename=DSC_0344_3.JPG');
It is an issue in PHP cURL <5.5.0 but > 5.2.10, see JIRA API attachment names contain the whole paths of the posted files
When using PHP >= 5.5.0 it is better to switch to the CURLFile approach as also documented in that link.
$cfile = new CURLFile($attachmentPath);
$cfile->setPostFilename('DSC_0344_3.JPG');
$data = array('file'=>$cfile);
For anybody in the future: here's a function i wrote that works on php 7
function attachFileToIssue($issueURL, $attachmentURL) {
// issueURL will be something like this: http://{yourdomainforjira}.com/rest/api/2/issue/{key}/attachments
// $attachmentURL will be real path to file (i.e. C:\hereswheremyfilelives\fileName.jpg) NOTE: Local paths ("./fileName.jpg") does not work!
$ch = curl_init();
$headers = array(
'X-Atlassian-Token: nocheck',
'Content-type: multipart/form-data'
);
$cfile = new CURLFile($attachmentURL);
$cfile->setPostFilename(basename($attachmentURL));
$data = array("file" => $cfile);
curl_setopt_array(
$ch,
array(
CURLOPT_URL => $issueURL,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $data,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_USERPWD => "{username}:{password}"
)
);
$result = curl_exec($ch);
$ch_error = curl_error($ch);
if ($ch_error)
echo "cURL Error: " . $ch_error;
curl_close($ch);
}

How to get info on sent PHP curl request

I'm trying to debug a curl request to a webservice 'getToken' endpoint.
I'm not 100% confident that the URL and the auth info is getting written in to the curl handle correctly.
I'm trying to use curl_getinfo($ch, CURLINFO_HEADER_OUT); to capture the sent request, but it doesn't give me much info. Is there a way to get more in depth diagnostics about what the actual curl request looks like?
Here's the code:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 1); // just getting header to see if we got an auth token
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1); // capture the header info
curl_setopt($ch, CURLOPT_VERBOSE, 1); // turn verbose on
// execute the curl request
$rh = fopen("request.txt", "w"); // open request file handle
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_exec($ch); // execute request
$sent_request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
fwrite($rh, $sent_request); // save the request info
fclose($rh);
!rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
This all works as far as it goes, but returns a 401 every time-- the API admin assures me that the username / pass I have is correct.
I was wondering if I'm somehow getting the URL value wrong, or not sending the right username / pass, but this info isn't printed in the request data saved:
HEAD /export/auth HTTP/1.1
Authorization: Basic Y2FpcmRzdW5mYTpENWlAaVM4cw==
Host: webservices.mycompany.com
Accept: */*
You can see that the username/pass is not recorded (I assume for security). The endpoint URL I think is the host value plus the start of the HEAD value, so webservices.mycompany.com/export/auth?
The "Verbose Information" statement prints nothing. Not sure why on this either!
Thanks for help.
EDIT: added verbose mode from Php - Debugging Curl thanks to commenter immulatin
If you set CURLINFO_HEADER_OUT to true, outgoing headers are available in the array returned by curl_getinfo(), under request_header key:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://foo.com/bar");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "someusername:secretpassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
$info = curl_getinfo($ch);
print_r($info['request_header']);
This will print:
GET /bar HTTP/1.1
Authorization: Basic c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk
Host: foo.com
Accept: */*
Note the auth details are base64-encoded:
echo base64_decode('c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk');
// prints: someusername:secretpassword
Also note that username and password need to be percent-encoded to escape any URL reserved characters (/, ?, &, : and so on) they might contain:
curl_setopt($ch, CURLOPT_USERPWD, urlencode($username).':'.urlencode($password));
You can also use a proxy tool like Charles to capture the outgoing request headers, data, etc. by passing the proxy details through CURLOPT_PROXY to your curl_setopt_array method.
For example:
$proxy = '127.0.0.1:8888';
$opt = array (
CURLOPT_URL => "http://www.example.com",
CURLOPT_PROXY => $proxy,
CURLOPT_POST => true,
CURLOPT_VERBOSE => true,
);
$ch = curl_init();
curl_setopt_array($ch, $opt);
curl_exec($ch);
curl_close($ch);
curl_getinfo() must be added before closing the curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/bar");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "someusername:secretpassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
$info = curl_getinfo($ch);
print_r($info['request_header']);
curl_close($ch);
The request is printed in a request.txt with details
$ch = curl_init();
$f = fopen('request.txt', 'w');
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $f,
));
$response = curl_exec($ch);
fclose($f);
curl_close($ch);
You can also use curl_getinfo() function.

Send File to HTTPS URL using CURL and PHP

I am attempting to send a file to an Https URL with this code:
$file_to_upload = array('file_contents'=>'#'.$target_path);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSER, FALSE);
curl_setopt($ch, CURLOPT_UPLOAD, TRUE);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'file='.$file_to_upload);
$result = curl_exec($ch);
$error = curl_error($ch);
curl_close ($ch);
echo " Server response: ".$result;
echo " Curl Error: ".$error;
But for some reason I'm getting this response:
Curl Error: Failed to open/read local data from file/application
Any advice would help thanks!
UPDATE: When I take out CURLOPT_UPLOAD, I get a response from the target server but it says that there was no file in the payload
You're passing a rather strange argument to CURLOPT_POSTFIELDS. Try something more like:
<?
$postfields = array('file' => '#' . $target_path);
// ...
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
?>
Also, you probably want CURLOPT_RETURNTRANSFER to be true, otherwise $result won't get the output, it'll instead be sent directly to the buffer/browser.
This example from php.net might be of use as well:
<?php
$ch = curl_init();
$data = array('name' => 'Foo', 'file' => '#/home/user/test.png');
curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);
?>
On top of coreward's answer:
According to how to upload file using curl with php, starting from php 5.5 you need to use curl_file_create($path) instead of "#$path".
Tested: it does work.
With the # way no file gets uploaded.

Categories