WSDL error on translating SOAP client from PHP5 to PHP4/nuSOAP - php

Alright, I'm tired of racking my brain on this, so hopefully someone here can enlighten me:
I'm trying to access a SOAP service using PHP and nuSOAP. While I have successfully accessed the service using PHP5's built-in SoapClient, I am unfortunately limited to PHP4, and using nuSOAP; resulting in a WSDL error that I can't figure out.
The PHP5 code (works):
$wsdl= 'https://mybilling.hipointinc.com:8443/wsdl.fcgi?get=Session.xsd';
$soap_client = new SoapClient($wsdl, array('trace'=>1));
$args = array("login" => $account_id, "password" => $password, "domain" => $domain);
$session = $soap_client->login($args);
The nuSOAP code (doesn't work):
$wsdl= 'https://mybilling.hipointinc.com:8443/wsdl.fcgi?get=Session.xsd';
$namespace = 'https://mybilling.hipointinc.com/UM/SOAP/Session';
$soap_client = new soapclient($wsdl, true, null, $namespace);
$args = array("login" => $account_id, "password" => $password, "domain" => $domain);
$session = $soap_client->call('login', array($args));
This returns the following error:
wsdl error: http://schemas.portaone.com/soap:LoginRequest (LoginRequest) is not a supported type.
Why does the PHP5 version work, while the nuSOAP version doesn't? I'm sure it just something stupid I've overlooked, but I would appreciate some help.
For more info, I'm using the Porta Switch, PortaBilling XML API: documentation

Ok, after exploring this some more, I finally came to the answer: I had to upgrade the version of the nuSOAP library I was using. Turns out I had an older version, and simply updating that version resolved the problem (Sigh) I knew it was something stupid, but for any of you future coders who happen upon this thread via google: Learn from my mistake, and make sure the resources you are using are up-to-date.

Related

MapReduce with PHP and MongoDB

I'm fairly new to Mongo and I have what I thought was a simple question. How do I do MapReduce with PHP and the non legacy MongoDB driver http://php.net/manual/en/set.mongodb.php or the higher level package mongodb/mongodb found at https://packagist.org/packages/mongodb/mongodb?
Every example I've seen seems to use the legacy driver (http://php.net/manual/en/book.mongo.php). They all use the MongoCode object, which doesn't exist in mongodb.php. It exists in mongo.php (the legacy driver). When I try and use it, it will say that "Class 'MongoCode' not found".
My code looks something like:
$function = "function() { emit(this); }";
$map = new \MongoCode($function);
$command = $db->command([
"mapreduce" => "db.archiveData",
"map" => $map,
"query" => $query,
"out" => "data"
]);
To make things more confusing, when I look at the source at https://github.com/mongodb/mongo-php-library, there is a unit test for MapReduce (https://github.com/mongodb/mongo-php-library/blob/4dc36f6231df133a57ff0dc5a0123945133d25ba/tests/Operation/MapReduceFunctionalTest.php). But it uses the MongoDB\Operation\MapReduce, which doesn't seem to exist in the 1.1 version of mongodb/mongodb.
I thought maybe I would call it on the server using JavaScript. But when I look at http://php.net/manual/en/mongodb.execute.php, it says it "is deprecated in MongoDB 3.0+". So that doesn't feel like something I should use.
So is it that:
MapReduce is not supported with mongodb/mongodb. Or maybe it is not supported yet, but will be?
I have to use the legacy driver for MapReduce?
I have to figure out a way to call db.collection.mapReduce via JavaScript on the server?
I have to use the Aggregation Pipeline (https://docs.mongodb.com/manual/aggregation/) to do map reduce type of actions? But that feels much more limited.
What am I missing?
So I now have clarity on where things are at.
MapReduce will be officially supported in 1.2.0 of PHPLib (https://jira.mongodb.org/browse/PHPLIB-53)
Until then, there is a completely usable workaround by using the command object as per https://docs.mongodb.com/php-library/current/upgrade/#mapreduce-command-helper
Example is here as well:
$database = (new MongoDB\Client)->selectDatabase('db_name');
$cursor = $database->command([
'mapReduce' => 'collection_name',
'map' => new MongoDB\BSON\Javascript('...'),
'reduce' => new MongoDB\BSON\Javascript('...'),
'out' => 'output_collection_name',
]);
$resultDocument = $cursor->toArray()[0];
You can also use MapReduce via Doctrine (http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/map-reduce.html), but that is using legacy and a shim. So probably not a good choice for a new project.

Non asmx?wsdl SOAP server

I am looking for some advices and exmaples. Since now I havent seen trouble consuming SOAP services with PHP.
A third party has developed a service, they provided me a file with the WSDL and all the needed XSD schemas. But since their service URL has this look : https://webservice.com/xml_listen.cgi I am really struggling how to approach it.
I have tried the basic stuff that I have used until this moment about the previous services that I have consumed like:
$client = new SoapClient(array(
'location' => "https://webservice.com/xml_listen.cgi",
'uri' => "https://webservice.com/xml_listen.cgi",
'trace' => 1 ));
$return = $client->__soapCall("SomeFuncion",array());
var_dump($return);
I am hoping to find a way how to consume this kind of non WSDL services.
Thank you in advance!

Object reference not set to an instance of an object error when trying SOAP call

I am trying to connect to and authenticate with a webservice using SOAP / wsdl, but I constantly get the error:
<b>Fatal error</b>: Uncaught SoapFault exception: [a:InternalServiceFault] Object reference not set to an instance of an object. in /path/install.php:16
Below is my current code:
<?php
header("Content-Type: text/plain");
$userinfo = array(
'Username'=>'test',
'Password'=>'test'
);
$wsdl_url = 'https://ws-e-distribution.kmd.dk/standard/ServiceAutorisation/ServiceAutorisation.svc?wsdl';
$client = new SoapClient($wsdl_url);
print_r($client->__getFunctions());
print_r($client->__getTypes());
//This is the problematic line:
$response = $client->__soapCall('LogOn', array('LogOn' => $userinfo));
var_dump($response);
I have tried every possible way of wrapping the username and password parameters that I could conceive of or find anyone suggesting:
using a custom class
using a stdClass
using SoapVar
using SoapParam
using a simple array
double wrapped array
A lot of combinations of the above.
And I've tried calling the function like $client->__soapCall('LogOn', [milliontries]) as well as $client->LogOn([milliontries])
...nothing works, please help.
Update:
I finally managed to get a different error (that suggests at least I hit upon something slightly less wrong). My code now looks like this:
$response = $client->LogOn(array('logon' => array('Username' => 'test','Password' => 'test')));
Which gives me an error about the LogOnType being unsupported (in Danish, which suggests to me that at least I have some sort of connection to the server now). The username and password array has no effect, I can substitute an empty string and get the same result, the thing that makes the difference is the lowercase logon.
If anyone can set up a working example that gives the error incorrect username or password I will be forever grateful... but any pointers will be much appreciated.
As far as I understand the wsdl gives all the information needed to do this, I'm just too much of a [your_pick] to get it...?
Unbelievable ! It only took nine hours to write these 16 lines of code.
<?php
header("Content-Type: text/plain");
$userinfo = array(
'Username'=>'test',
'Password'=>'test'
);
$wsdl_url = 'https://ws-e-distribution.kmd.dk/standard/ServiceAutorisation/ServiceAutorisation.svc?wsdl';
$client = new SoapClient($wsdl_url, array('trace' => 1, "exception" => 0));
print_r($client->__getFunctions());
print_r($client->__getTypes());
//This actually works ! :) :) :)
$response = $client->LogOn(array('logon' => new SoapVar($userinfo, SOAP_ENC_OBJECT, 'LogOnUsername', 'http://schemas.datacontract.org/2004/07/WebServiceAutorisation.BL')));
var_dump($response);
I was so close several times, and it turned out the namespace (the URL) was the magic bit I was missing. I had been using the namespace from the main wsdl (or no namespace at all) in every attempt at using SoapVar's.
Well now, on to the actual purpose of logging in, probably won't be any easier

WCF callback service to php client

I have created a WCF Service with callback and using wsDualHttp Binding.
I want to connect to this service using PHP client.
In PHP , SoapClient is used to call the WCF service like below:
$wsdl = "http://pathto/file.svc?wsdl"
$client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions));
$response = $client->somefunction();
Please guide in getting for callback in PHP.
I am sorry, but IMO its impossible to have callback from wcf to php (for exaple, this post also say so:
http://wso2.org/forum/thread/24111).
Probably you can check for some websocket solution to receive behavior you ste looking for.
Take a look on node.js, for ecample: http://bergie.iki.fi/blog/dnode-make_php_and_node-js_talk_to_each_other/

Consuming a webservice and changing an endpoint with SOAPCLIENT

I am consuming a third-party webservice and I'm using soapUI to test it. I was advised to load the WSDL, leave it untouchted, then change the endpoint in SOAPUI before executing the calls to the endpoints. This works fine and is behaving as I would expect it to.
I'm now trying to emulate this in PHP but I'm having problems changing the endpoint. I'm loading the WSDL into SOAPCLIENT and then using this command to change the endpoint:
$client->__setLocation($endpointURI);
However this is not acting like I'd expect it to and is giving me a "500:Internal Server Error" response when I the go to make a soap call after modifying the location/endpoint. I'm certain that all other parameters are correct and was wondering if anyone could shed some light on the issue and confirm that doing this 'set location' cmd should be the equivalent of changing the endpoint manually in SOAPUI.
Any ideas/opinions appreciated.
While instantiating SoapClient try to add an array key named 'location' with the new endpoint.
$options = array('login' => 'x', 'password' => 'y', 'location' => $endpointURI);
$client = new SoapClient($address, $options);
Try calling __soapCall with the location override in there:
$result = $this->soap_client->__soapCall('whatever', ['location' => $file_location]);
I'm finding __setLocation is not working while the above workaround does.

Categories