How to create SOAP request from XML with PHP - php

I am trying to create SOAP request, but it gives me error: An exception occurred whilst trying to authenticate you. String reference not set to an instance of a String. Parameter name: s
My code is:
$wsdl = "https://securedwebapp.com/api/service.asmx?WSDL";
$trace = true;
$exceptions = false;
$debug = true;
$client = new SoapClient($wsdl,
array(
'trace' => $trace,
'exceptions' => $exceptions,
'debug' => $debug,
));
$xml = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:kas="KashFlow">
<soapenv:Header/>
<soapenv:Body>
<kas:GetInvoice>
<kas:UserName>xxx</kas:UserName>
<kas:Password>xxx</kas:Password>
<kas:InvoiceNumber>184576</kas:InvoiceNumber>
</kas:GetInvoice>
</soapenv:Body>
</soapenv:Envelope>';
//var_dump($xml);
$args = array(new SoapVar($xml, XSD_ANYXML));
$res = $client->__soapCall('GetInvoice', $args);
var_dump($res);
echo "<hr>Last Request";
echo "<pre>", htmlspecialchars($client->__getLastRequest()), "</pre>";
Does anyone know how to solve? The request works fine if I use:
$wsdl = 'https://securedwebapp.com/api/service.asmx?WSDL';
$trace = true;
$exceptions = false;
$debug = true;
$client = new SoapClient($wsdl,
array(
'trace' => $trace,
'exceptions' => $exceptions,
'debug' => $debug,
));
$params = array(
'InvoiceNumber' =>'81217',
'UserName' => 'xxx',
'Password' => 'xxx'
);
$resp = $client->GetInvoice($params);
print_r($resp);
This is request with simple parameters, but in real situation I have complex XML request, that I do not know how to form as php object. That is why I would send it as XML as I am trying to do at first place.

Nowadays, it is strongly advised to use a WSDL to PHP generator in order to avoid encountering this sort of issues.
I recomend using the PackageGenerator project which allows to generate a PHP SDK based on the WSDL. The generated PHP SDK contains all that is necessary to construct the request, send the request and handle the response only using an OOP approach.

Related

WP/PHP SoapClient: The server was unable to process the request due to an internal error

Im trying to connect to a web service from php (WorkPress)whit soapClient and i'm getting this: 'The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.'
Any idea?
This is what I´m doing, the responce is a true or false.
$wsdlUrl = 'https://#####.svc?wsdl';
$client = new SoapClient($wsdlUrl);
var_dump($client->__getTypes());
echo '</br>';
$xmlr = new SimpleXMLElement('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:ExisteMiembro>
<!--Optional:-->
<tem:carnet>######</tem:carnet>
<!--Optional:-->
<tem:key>#######</tem:key>
</tem:ExisteMiembro>
</soapenv:Body>
</soapenv:Envelope>');
$params = new stdClass();
$params->xml = $xmlr->asXML();
$result = new SimpleXMLElement($client->ExisteMiembro($params));
Solved, I used this code instead and it works,
ini_set('soap.wsdl_cache_enabled', 0);
ini_set('soap.wsdl_cache_ttl', 900);
ini_set('default_socket_timeout', 15);
try {
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$wsdlUrl = 'https://######.svc?wsdl';
$soapClientOptions = array(
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
);
$client = new SoapClient($wsdlUrl, $soapClientOptions);
$checkVatParameters = array(
'carnet' => '###',
'key' => '###'
);
$result = $client->ExisteMiembro($checkVatParameters);
print_r($result);
return true;
}
catch(Exception $e) {
echo $e->getMessage();
var_dump("entro al msj de error");
}

How to avoid resulted in a `418 You look like a robot (4)

I am using guzzle php library to scrape the data from other sites.
PHP script without proxy
$httpClient = new \GuzzleHttp\Client();
$response = $httpClient->get($url);
$htmlString = (string) $response->getBody();
But when I am using a proxy I am facing the 504 gateway time out error.
Script with proxy:
$httpClient = new \GuzzleHttp\Client(['proxy' => 'http://92.51.77.126']);
$response = $httpClient->get($url);
$htmlString = (string) $response->getBody();
Referance: https://docs.guzzlephp.org/en/stable/request-options.html#proxy
I just found a solution.
I have bought a premium proxy and used it as a describe in the github issues.
$httpClient = new \GuzzleHttp\Client([
'proxy' => 'username:password#IP:Port', //use without "socks5://" scheme
'verify' => true, // used only for SSL check , u can set false too for not check
'curl' => [CURLOPT_PROXYTYPE => 7],
]);
$response = $httpClient->get($url);
$htmlString = (string) $response->getBody();
Simler Issue: https://github.com/guzzle/guzzle/issues/1484

How to receive Soap response in php

However, what I want is to be able to get response request and populate PHP
I already did that using soapUI and got the response in xml format like
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://bsestarmfdemo.bseindia.com/2016/01/IMFUploadService/MFAPIResponse</a:Action>
<a:RelatesTo>uuid:804ed18e-630f-4b16-86ee-6f97ee71743e</a:RelatesTo>
</s:Header>
<s:Body>
<MFAPIResponse xmlns="http://bsestarmfdemo.bseindia.com/2016/01/">
<MFAPIResult>100|PAYMENT NOT INITIATED FOR GIVEN ORDER</MFAPIResult>
</MFAPIResponse>
</s:Body>
</s:Envelope>
MY PHP Code
I don’t have much experience with SOAP but am required to build a validator for my work and using a specific SOAP wsdl.
I’ve set up the connect
<?php
$url= "http://bsestarmfdemo.bseindia.com/StarMFFileUploadService/StarMFFileUploadService.svc?wsdl";
$method = "MFAPI";
$error=0;
$fault=0;
$client = new SoapClient($url, array('soap_version' => SOAP_1_2 , 'SoapAction'=>'http://tempuri.org/IStarMFFileUploadService/MFAPI'));
$actionHeader= array();
$actionHeader[] = new SoapHeader('http://www.w3.org/2005/08/addressing',
'Action',
'http://tempuri.org/IStarMFFileUploadService/MFAPI');
$actionHeader[] = new SoapHeader('http://www.w3.org/2005/08/addressing',
'To',
'http://bsestarmfdemo.bseindia.com/MFUploadService/MFUploadService.svc/Basic');
$client->__setSoapHeaders($actionHeader);
$featchData = array('Param' => array('UserId' => 'xxxxx', 'Flag' => 'xxxx', 'EncryptedPassword' => 'xxxx', 'param' => 'xxxx') );
try{
$resultData = $client->__call($method, array($featchData));
}
catch (SoapFault $resultData) {
$error = 1;
}
if($error==1) {
$result=$fault;
}else{
$result = $resultData;
var_dump($result);
}
// echo $result;
?>

How do I access Web Service via SOAP in PHP?

I tried something like this :
try{
$opts = array(
'http'=>array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$client = new SoapClient('http://83.166.204.26:7147/TEST/WS/Harmont%20Blaine_TEST/Page/WebItem?wsdl',
array('stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE));
));
print_r($client);
}
catch(Exception $e){
echo $e->getMessage();
}
and the result of my var_dump function is:
SOAP-ERROR: Parsing WSDL: Couldn't load from .... failed to load external entity...
how can i access the web service via soap ? thx.
This is the beginning of the xml :
I just downloaded the file from 83.166.204.26:7147/TEST/WS/Harmont%20Blaine_TEST/Page/WebItem?wsdl. I saved it on wsdl format and now i'm getting the functions
$client = new SoapClient("WebItem.wsdl", array('proxy_host' => "83.166.204.26",
'proxy_port' => 7147,
'proxy_login' => "xxxxxx",
'proxy_password' => "xxxxxxxx"));
echo "<pre>"; var_dump($client->__getFunctions()); echo "</pre>";
Firstly:
URL that you supply required Basic authentication. When using HTTP basic authentication, PHP will only send the credentials when invoking the service, not when fetching the WSDL.
You CAN get a wsdl, if basic authentication is required:
$login = 'xxx';
$password = 'xxx';
$client = new SoapClient(
'http://' . urlencode($login) . ':' . urlencode($password) . '#83.166.204.26:7147/TEST/WS/Harmont%20Blaine_TEST/Page/WebItem?wsdl',
array(
'login' => $login,
'password' => $password
)
);
Secondly :
Your return XML does not look like valid WSDL file. Read SoapClient documentation page for proper usage - first argument of new SoapClient() must be URI of WSDL file or null for non-WSDL usage. (Here is an example of WSDL file ) May be you need to create SoapClient in non-WSDL mode?

Twitter API returns error 215, Bad Authentication Data

I am trying to call following Twitter's API to get a list of followers for a user.
http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username
And I am getting this error message in response.
{
code = 215;
message = "Bad Authentication data";
}
I can't seem to find the documentation related to this error code. Anyone has any idea about this error?
A very concise code without any other php file include of oauth etc.
Please note to obtain following keys you need to sign up with https://dev.twitter.com and create application.
<?php
$token = 'YOUR_TOKEN';
$token_secret = 'YOUR_TOKEN_SECRET';
$consumer_key = 'CONSUMER_KEY';
$consumer_secret = 'CONSUMER_SECRET';
$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path
$query = array( // query parameters
'screen_name' => 'twitterapi',
'count' => '5'
);
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_token' => $token,
'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
'oauth_timestamp' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_version' => '1.0'
);
$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);
$arr = array_merge($oauth, $query); // combine the values THEN sort
asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)
// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));
$url = "https://$host$path";
// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);
// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);
// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));
// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&","&",$url); //Patch by #Frewuill
$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it
// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);
// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));
// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
foreach ($twitter_data as &$value) {
$tweetout .= preg_replace("/(http:\/\/|(www\.))(([^\s<]{4,68})[^\s<]*)/", '$1$2$4', $value->text);
$tweetout = preg_replace("/#(\w+)/", "#\\1", $tweetout);
$tweetout = preg_replace("/#(\w+)/", "#\\1", $tweetout);
}
echo $tweetout;
?>
Regards
The only solution I've found so far is:
Create application in twitter developer panel
Authorize user with your application (or your application in user account) and save "oauth_token" and "oauth_token_secret" which Twitter gives you. Use TwitterOAuth library for this, it's pretty easy, see examples coming with library.
Using this tokens you can make authenticated requests on behalf of user. You can do it with the same library.
// Arguments 1 and 2 - your application static tokens, 2 and 3 - user tokens, received from Twitter during authentification
$connection = new TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $tokens['oauth_token'], $tokens['oauth_token_secret']);
$connection->host = 'https://api.twitter.com/1.1/'; // By default library uses API version 1.
$friendsJson = $connection->get('/friends/ids.json?cursor=-1&user_id=34342323');
This will return you list of user's friends.
FOUND A SOLUTION - using the Abraham TwitterOAuth library. If you are using an older implementation, the following lines should be added after the new TwitterOAuth object is instantiated:
$connection->host = "https://api.twitter.com/1.1/";
$connection->ssl_verifypeer = TRUE;
$connection->content_type = 'application/x-www-form-urlencoded';
The first 2 lines are now documented in Abraham library Readme file, but the 3rd one is not. Also make sure that your oauth_version is still 1.0.
Here is my code for getting all user data from 'users/show' with a newly authenticated user and returning the user full name and user icon with 1.1 - the following code is implemented in the authentication callback file:
session_start();
require ('twitteroauth/twitteroauth.php');
require ('twitteroauth/config.php');
$consumer_key = '****************';
$consumer_secret = '**********************************';
$to = new TwitterOAuth($consumer_key, $consumer_secret);
$tok = $to->getRequestToken('http://exampleredirect.com?twitoa=1');
$token = $tok['oauth_token'];
$secret = $tok['oauth_token_secret'];
//save tokens to session
$_SESSION['ttok'] = $token;
$_SESSION['tsec'] = $secret;
$request_link = $to->getAuthorizeURL($token,TRUE);
header('Location: ' . $request_link);
The following code then is in the redirect after authentication and token request
if($_REQUEST['twitoa']==1){
require ('twitteroauth/twitteroauth.php');
require_once('twitteroauth/config.php');
//Twitter Creds
$consumer_key = '*****************';
$consumer_secret = '************************************';
$oauth_token = $_GET['oauth_token']; //ex Request vals->http://domain.com/twitter_callback.php?oauth_token=MQZFhVRAP6jjsJdTunRYPXoPFzsXXKK0mQS3SxhNXZI&oauth_verifier=A5tYHnAsbxf3DBinZ1dZEj0hPgVdQ6vvjBJYg5UdJI
$ttok = $_SESSION['ttok'];
$tsec = $_SESSION['tsec'];
$to = new TwitterOAuth($consumer_key, $consumer_secret, $ttok, $tsec);
$tok = $to->getAccessToken();
$btok = $tok['oauth_token'];
$bsec = $tok['oauth_token_secret'];
$twit_u_id = $tok['user_id'];
$twit_screen_name = $tok['screen_name'];
//Twitter 1.1 DEBUG
//print_r($tok);
//echo '<br/><br/>';
//print_r($to);
//echo '<br/><br/>';
//echo $btok . '<br/><br/>';
//echo $bsec . '<br/><br/>';
//echo $twit_u_id . '<br/><br/>';
//echo $twit_screen_name . '<br/><br/>';
$twit_screen_name=urlencode($twit_screen_name);
$connection = new TwitterOAuth($consumer_key, $consumer_secret, $btok, $bsec);
$connection->host = "https://api.twitter.com/1.1/";
$connection->ssl_verifypeer = TRUE;
$connection->content_type = 'application/x-www-form-urlencoded';
$ucontent = $connection->get('users/show', array('screen_name' => $twit_screen_name));
//echo 'connection:<br/><br/>';
//print_r($connection);
//echo '<br/><br/>';
//print_r($ucontent);
$t_user_name = $ucontent->name;
$t_user_icon = $ucontent->profile_image_url;
//echo $t_user_name.'<br/><br/>';
//echo $t_user_icon.'<br/><br/>';
}
It took me way too long to figure this one out. Hope this helps someone!!
The answer by Gruik worked for me in the below thread.
{Excerpt | Zend_Service_Twitter - Make API v1.1 ready}
with ZF 1.12.3 the workaround is to pass consumerKey and consumerSecret in oauthOptions option, not directrly in the options.
$options = array(
'username' => /*...*/,
'accessToken' => /*...*/,
'oauthOptions' => array(
'consumerKey' => /*...*/,
'consumerSecret' => /*...*/,
)
);
UPDATE:
Twitter API 1 is now deprecated. Refer to above answer.
Twitter 1.1 does not work with that syntax (when I wrote this answer). Needs to be 1, not 1.1. This will work:
http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=username
The url with /1.1/ in it is correct, it is the new Twitter API Version 1.1.
But you need an application and authorize your application (and the user) using oAuth.
Read more about this on the Twitter Developers documentation site
:)
You need to send customerKey and customerSecret to Zend_Service_Twitter
$twitter = new Zend_Service_Twitter(array(
'consumerKey' => $this->consumer_key,
'consumerSecret' => $this->consumer_secret,
'username' => $user->screenName,
'accessToken' => unserialize($user->token)
));
After two days of research I finally found that to access s.o. public tweets you just need any application credentials, and not that particular user ones. So if you are developing for a client, you don't have to ask them to do anything.
To use the new Twitter API 1.1 you need two things:
the Abraham's TwitterOAuth library that Dante Cullari already mentioned
a brand new or already working application created via the Twitter Developer site
First, you can (actually have to) create an application with your own credentials and then get the Access token (OAUTH_TOKEN) and Access token secret (OAUTH_TOKEN_SECRET) from the "Your access token" section.
Then you supply them in the constructor for the new TwitterOAuth object. Now you can access anyone public tweets.
$connection = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET );
$connection->host = "https://api.twitter.com/1.1/"; // change the default
$connection->ssl_verifypeer = TRUE;
$connection->content_type = 'application/x-www-form-urlencoded';
$tweets = $connection->get('http://api.twitter.com/1.1/statuses/user_timeline.json?screen_name='.$username.'&count='.$count);
Actually I think this is what Pavel has suggested also, but it is not so obvious from his answer.
Hope this saves someone else those two days :)
This might help someone who use Zend_Oauth_Client to work with twitter api. This working config:
$accessToken = new Zend_Oauth_Token_Access();
$accessToken->setToken('accessToken');
$accessToken->setTokenSecret('accessTokenSecret');
$client = $accessToken->getHttpClient(array(
'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
'version' => '1.0', // it was 1.1 and I got 215 error.
'signatureMethod' => 'HMAC-SHA1',
'consumerKey' => 'foo',
'consumerSecret' => 'bar',
'requestTokenUrl' => 'https://api.twitter.com/oauth/request_token',
'authorizeUrl' => 'https://api.twitter.com/oauth/authorize',
'accessTokenUrl' => 'https://api.twitter.com/oauth/access_token',
'timeout' => 30
));
It look like twitter api 1.0 allows oauth version to be 1.1 and 1.0, where twitter api 1.1 require only oauth version to be 1.0.
P.S We do not use Zend_Service_Twitter as it does not allow send custom params on status update.
Be sure that you have read AND write access for application in twitter
I'm using HybridAuth and was running into this error connecting to Twitter. I tracked it down to (me) sending Twitter an incorrectly cased request type (get/post instead of GET/POST).
This would cause a 215:
$call = '/search/tweets.json';
$call_type = 'get';
$call_args = array(
'q' => 'pancakes',
'count' => 5,
);
$response = $provider_api->api( $call, $call_type, $call_args );
This would not:
$call = '/search/tweets.json';
$call_type = 'GET';
$call_args = array(
'q' => 'pancakes',
'count' => 5,
);
$response = $provider_api->api( $call, $call_type, $call_args );
Side note: In the case of HybridAuth the following also would not (because HA internally provides the correctly-cased value for the request type):
$call = '/search/tweets.json';
$call_args = array(
'q' => 'pancakes',
'count' => 5,
);
$response = $providers['Twitter']->get( $call, $call_args );
I was facing the same problem all the time the only solution I figurae out is typing CONSUMER_KEY and CONSUMER_SECRET directly to new TwitterOAuth class defination .
$connection = new TwitterOAuth( "MY_CK" , "MY_CS" );
Don't use variable or statics on this and see if the issue sloved .
Here first every one need to use oauth2/token api then use followers/list api.
Other wise you will get this error. Because followers/list api requires Authentication.
In swift (for mobile app) me also got the same problem.
If you want to know the api's and it's parameters follow this link , Get twitter friends list in swift?
I know that this is old but yesterday I faced the same issue when calling this URL using C# and the HttpClient class with the Bearer authentication token:
http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username
It turns out that the solution for me was to use HTTPS instead of HTTP. So my URL would look like this:
https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username
So here is a snippet of my code:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.twitter.com/1.1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer **** YOUR BEARER TOKEN GOES HERE ****");
var response = client.GetAsync("statuses/user_timeline.json?count=10&screen_name=username").Result;
if (!response.IsSuccessStatusCode)
{
return result;
}
var items = response.Content.ReadAsAsync<IEnumerable<dynamic>>().Result;
foreach (dynamic item in items)
{
//Do the needful
}
}
Try this twitter API explorer, you can sign in as a developer and query whatever you want.

Categories