Search code examples
phpwsdlzend-framework2

Why success is not being returned in my PHP WSDL (Zf2)


I used these two resources as launching pad for my creation of a WSDL endpoint server.

https://odan.github.io/2017/11/20/implementing-a-soap-api-with-php-7.html
https://www.youtube.com/watch?v=e_7jDqN2A-Y&t=799s

By combining these two I was able to come up with a hybrid system that works. My issue that I am trying resolve right now is getting a response back from the api.php/endpoint server.

In the odan git example, it worked to the letter. But once I made changes to the code that requires objects. I started getting errors.

PHP Notice:  Trying to get property of non-object

Here is a portion of the server code.


class wenoError
{
    public $response = "Sucess";

    public static function authenticate($header_params)
    {
        if($header_params->username == 'WEX' && $header_params->password == 'WEX1') return true;
        else throw new SOAPFault('Wrong user/pass combination', 601);
    }

    /**
    * @param string $payload
    * @return string $delivery
    */
    public function receivePayload($payload)
    {

        $xml = base64_decode($payload);

        $fileName = 'message-'.rand().'.xml'; 
        $file = file_put_contents('messages/'.$fileName, $xml);
        $xml2json = simplexml_load_string($xml);
        $jsonOut = json_encode($xml2json); 
        $arrayJson = json_decode($jsonOut, TRUE);
        //$seeArray = print_r($arrayJson, true);
        //file_put_contents('messages/converted-'.$fileName.'.json', $arrayJson['Header']['MessageID']);
        $response = "Success";
        return $response;

    }

}
    $serverUrl = "https://localhost/WenoErrors/api.php";
    $options = [
        'uri' => $serverUrl,
    ];
    $server = new Zend\Soap\Server('wsdl', $options);

    if (isset($_GET['wsdl'])) {
    $soapAutoDiscover = new \Zend\Soap\AutoDiscover(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence());
    $soapAutoDiscover->setBindingStyle(array('style' => 'document'));
    $soapAutoDiscover->setOperationBodyStyle(array('use' => 'literal'));
    $soapAutoDiscover->setClass('wenoError');
    $soapAutoDiscover->setUri($serverUrl);

    header("Content-Type: text/xml");
    echo $soapAutoDiscover->generate()->toXml();
    } else {
    $soap = new \Zend\Soap\Server($serverUrl . '?wsdl');
    $soap->setObject(new \Zend\Soap\Server\DocumentLiteralWrapper(new wenoError()));
    $soap->handle();
    }

What I don't understand is the error message of $response being a non-object. According to the PHP manual https://www.php.net/manual/en/language.oop5.properties.php

The property is set correctly at the top of the class, the property is declared and a value us set.

What went wrong?

UPDATE:

Adding the client code.

$client = new Zend\Soap\Client('https://localhost/WenoErrors/api.php?wsdl');
$delivery = $client->call('receivePayload',[['payload' => $message]]); 

Dumping client yields:

C:\eRxGateway\www\apa\WenoErrors\clientapi.php:55:
  object(client)[3]
   public 'delivery' => null

UPDATE:

What finally worked for me was this change.

First change:

$server = new Zend\Soap\Server('wsdl', $options);

$server = new Zend\Soap\Server(null, $options);

Solution

  • Your code seems to work fine for me. Though, I am getting a different result then yours as below:

    $client = new Zend\Soap\Client('http://localhost/test/api.php?wsdl');
    $message = ' -> Hello World'; 
    $delivery = $client->call('receivePayload',[['payload' => $message]]);
    var_dump($delivery);
    
    object(stdClass)#4 (1) {
      ["receivePayloadResult"]=>
      string(7) "Success"
    }
    

    Step 1

    Please try to remove all the '/tmp/wsdl-****' files from your /tmp directory. You seem to be on windows, so instead of /tmp it might be something else like C:\Windows\Temp. You can easily find which directory by going into your php.ini file and looking for the below directive.

    soap.wsdl_cache_dir="/tmp" 
    

    Step 2

    Also, for developing and testing purposes always put the below ini directive at the start of your client php file, which in your case is clientapi.php file.

    ini_set("soap.wsdl_cache_enabled", 0);
    

    You shouldn't be required to put this directive at the start of the server(api.php) file, but you can if the above still does not work for you.