Asked  7 Months ago    Answers:  5   Viewed   322 times

im a beginner to programming and following a tutorial on web services with php and soap using Apache2.4 web server. the tutorial uses soap without wsdl file

Client:

<?php
$options = array(
    "location" => "http://localhost/web-services/soap_service.php",
    "uri" => "http://localhost", 
    "trace" => 1,
);

try {
    $client = new SoapClient(null, $options);
    $students = $client->getStudentNames();
    echo $students;
} catch(SoapFault $ex) {
    echo var_dump($ex);
}
?>

Server:

<?php
require_once('Students.php');

$options = array("uri" => "http://localhost");
$server = new SoapServer(null, $options);
$server->setClass('Students');
$server->handle();
?>

Class used in server:

<?php
class Students{

    public function getStudentFirstName(){

        $studentFN = array("Dale", "Harry", "Shelly", "Bobby",
                "Donna", "Audrey", "James", "Lucy", "Tommy",
                "Andy", "John");

        return $studentFN;

    }

    public function getStudentLastName(){

        $studentLN = array("Cooper", "Truman", "Johnson", "Briggs",
            "Hayward", "Horne", "Hurley", "Moran", "Hill",
            "Brennan", "Smith");

        return $studentLN;

    }

    public function getStudentNames(){

        $studentNames = "Dale Cooper, Harry Truman, Shelly Johnson, " .
                "Bobby Briggs, Donna Hayward, Audrey Horne, " .
                "James Hurley, Lucy Moran, Tommy Hill, " .
                "Andy Brennan, John Smith";

        return $studentNames;

    }

}
?>

i keep getting this error:

object(SoapFault)#2 (10) { ["message":protected]=> string(33) "looks like we got no XML document"....................

so far i did the following:

  1. extension=php_soap.dll in php.ini is uncommented (removed ;)
  2. php_soap.dll is found in phpext
  3. all files are encoded in UTF-8 without BOM
  4. no trailing white spaces after or before the php marks (as far as i can tell)

the tutorial doesnt use a wsdl file, maybe i need to change more settings in php.ini?

what could be the problem???

Thanks in advance.

 Answers

70

SOLVED

in soap_client.php, in catch, i added "echo $client->__getLastResponse();" which gave me the following output:

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0

Warning: Cannot modify header information - headers already sent in Unknown on line 0
Dale Cooper, Harry Truman, Shelly Johnson, Bobby Briggs, Donna Hayward, Audrey Horne, James Hurley, Lucy Moran, Tommy Hill, Andy Brennan, John Smith

that last line is the string i passed to the client.

so what i tried was to uncomment "always_populate_raw_post_data = -1" in php.ini as the error suggested & restarted my Apache2.4 web-server and now it works, getting my string with no errors:

Dale Cooper, Harry Truman, Shelly Johnson, Bobby Briggs, Donna Hayward, Audrey Horne, James Hurley, Lucy Moran, Tommy Hill, Andy Brennan, John Smith

hope i helped someone with this, as i saw alot of unanswered questions about this error.

Saturday, May 29, 2021
 
Andres
answered 7 Months ago
63

I figured this out and posted the solution on a more generic question of this problem here

For completeness I have included the answer here as well...

It would seem that I was close but needed to include the NotificationService.wsdl when instantiating the SoapServer class. The WSDL then allows that SoapServer class to format the response accordingly.

$server = new SoapServer( PHPEWS_PATH.'/wsdl/NotificationService.wsdl', array(

The WSDL was not included in the php-ews library download, however it is included with the Exchange Server installation. If like me you don't have access to the Exchange Server installation you can find the file here. I also had to add the following to the end of the WSDL because I was storing the WSDLs locally and not using autodiscovery:

<wsdl:service name="NotificationServices">
    <wsdl:port name="NotificationServicePort" binding="tns:NotificationServiceBinding">
        <soap:address location="" />
    </wsdl:port>
</wsdl:service>

So the full working PHP code is as follows:

class ewsService {
    public function SendNotification( $arg ) {
        $result = new EWSType_SendNotificationResultType();
        $result->SubscriptionStatus = 'OK';
        //$result->SubscriptionStatus = 'Unsubscribe';
        return $result;
  }
}

$server = new SoapServer( PHPEWS_PATH.'/wsdl/NotificationService.wsdl', array(
    'uri' => $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'],
));
$server->setObject( $service = new ewsService() );
$server->handle();

Which gives the following output:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/exchange/services/2006/messages">
    <SOAP-ENV:Body>
        <ns1:SendNotificationResult>
            <ns1:SubscriptionStatus>OK</ns1:SubscriptionStatus>
        </ns1:SendNotificationResult>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Hope that helps someone else because that took me a while to figure out!

Wednesday, March 31, 2021
 
KHM
answered 9 Months ago
KHM
57

At your WSDL's type, there's a sequence named Demande_de_mot_de_passe which use a element named Demande_de_mot_de_passeRequest and not Demande_de_mot_de_passe_Input.

Your print from SoapUI describe the message request, but if it's document style, Demande_de_mot_de_passe is a type. On the other hand if it's RPC is the method name.

Starting if it's RPC you can do as showed below. You should use as native object as you can (SOAP will work better with they). A stdObject will be good enough:

$request = new stdClass();

$demande_de_mot_de_passeRequest->Code_societe = '000';
$demande_de_mot_de_passeRequest->Ident_type = 'A';
$demande_de_mot_de_passeRequest->Ident_code = 'xxxxxx';
$demande_de_mot_de_passeRequest->Dat_demande = '00000000';
$demande_de_mot_de_passeRequest->Adr_mail = 'xxxxxx';
$demande_de_mot_de_passeRequest->Adr_cpos = 'xxxxxx';
$demande_de_mot_de_passeRequest->Nom = 'xxxxxx';
$demande_de_mot_de_passeRequest->Prenom = 'xxxxxx';
$demande_de_mot_de_passeRequest->Dat_naiss = '00000000';

$request->Demande_de_mot_de_passeRequest = $demande_de_mot_de_passeRequest;

$response = $client->Demande_de_mot_de_passe($request);

If your SOAP binding is document, you just have to add a new upper level named Demande_de_mot_de_passe

/** The variable $demande_de_mot_de_passeRequest is created as above **/

$demande_de_mot_de_passe = new stdClass();
$demande_de_mot_de_passe->Demande_de_mot_de_passeRequest = $demande_de_mot_de_passeRequest;
$request->Demande_de_mot_de_passe = $demande_de_mot_de_passe;

$response = $client->Demande_de_mot_de_passe($request);

Your WSDL doesn't need a list/collections (it's not your case), so you don't need to create/parse variables with SoapVar. There's others examples that you can read about (one is mine, but it's in portuguese) and other is about the BOGUS node:

http://forum.imasters.com.br/topic/535213-enviar-xml-via-soap/?p=2137411 http://www.fischco.org/blog/2011/3/26/php-soapserver-objects-arrays-and-encoding.html

Saturday, August 7, 2021
 
ClmentM
answered 4 Months ago
87

It looks like your client receives some invalid XML - either the WSDL itself or the response returned by the server. Try to invoke the client with the trace option set to TRUE and check the actual XML send/received via the __getLastRequest() and __getLastResponse() methods.

Tuesday, August 10, 2021
 
Gaurav
answered 4 Months ago
96

I realized the issue was that when the server tried to access the wsdl file, Magento was issuing a 302 redirect to the storefront.

To fix it, I logged into the Magento admin panel, navigated to System -> Configuration -> Web, and turned off "Auto-redirect to Base URL". Works like a charm now.

Saturday, August 28, 2021
 
Yuriy Faktorovich
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share