Send SOAP XML Request via PHP

Aim
The aim of this example is to create a simple PHP script that cam be fed a url from the command line and xml from the standard in. It will then send the xml to the url and get the response. This works with http and secure http or https too. Use this PHP script to quickly and easily test your web services or third party web services. This also demonstrates reading from standard in or STDIN.

Save this file as soaper.php
 1. <?php
 2. ini_set('display_errors', "1");
 3. 
 4. $url= $argv[1];
 5. 
 6. echo "url\n$url\n";
 7. 
 8. preg_match("/https?:\/\/([^\/]*)(.*)/", $url, $matches);
 9. $host=$matches[1];
10. $request=$matches[2];
11. 
12. $mxml=fread(STDIN,65536);
13. $yt =curl_init();
14. $header =   "POST $request  HTTP/1.0\r\n";
15. $header .=  "Host: $host\r\n";
16. $header .=  "Content-Type: text/xml\r\n";
17. $header .=  "Content-Length: ".strlen($mxml)."\r\n";
18. $header .=  "Content-Transfer-Encoding: text\r\n";
19. $header .=  "Connection-Close: close\r\n\r\n";
20. 
21. echo "header\n$header\n";
22. 
23. $header .=  $mxml;
24. 
25. curl_setopt($yt, CURLOPT_SSL_VERIFYPEER,0);
26. curl_setopt($yt, CURLOPT_URL, $url);
27. curl_setopt($yt, CURLOPT_CUSTOMREQUEST, $header);
28. curl_setopt($yt, CURLOPT_RETURNTRANSFER, true);
29. 
30. $rxml=curl_exec($yt);
31. echo "sent\n$mxml\n";
32. echo "received\n$rxml\n";
33. 
34. echo curl_error($yt);
35. ?>
Hide line numbers

You can run this example like below. This will feed the xml from the file text.xml and send it to the url https://myurl/myService.

php soaper.php https://myurl/myService < text.xml

Here is a real example of sending a charging request to the AmountCharging Parlay Interface.

php soaper.php https://myparlay.com:445/payment_oneoff_ws_ctx_path/AmountCharging < xmltosend.xml

Liskov Substitution Principle, Covariance and Contravariance Explained

The Liskov Substitution Principle (LSP), introduced by Barbara Liskov states that..

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

From this principle comes two other Covariance and Contravariance. What are these in plain english? To satisfy LSP a derived funtion must have covariant return types and contravarient arguments. Covariant means that a derived class's overriding function must have equal or more restrictive return types than the base class's overridden function. Contravariant means that a derived class's overriding function can have equal or less restrictive arguments than the base class's overridden function.

Let's take a look at a simple pseudo code example using sets. I have two classes, class A and derived class B. Now class A has a virtual function called hello which accepts a number 1,2,3 or 4 as an argument and returns a number that is 1,2 or 3.

Now class B that is derived from A, and overrides hello has more restrictive return types (1 or 2) and less restrictive arguments (1,2,3,4 or 5).
 1. A{
 2.     {1,2,3}helo({1,2,3,4})
 3. 
 4. }
 5. 
 6. B:A{
 7.     {1,2}helo({1,2,3,4,5})
 8. 
 9. }
Hide line numbers

It's easy to see how this works. Lets assume (code below) that we are calling the base class hello through a pA pointer. Now to able to substitute derived class B instead of A, you can plainly see that B's hello has to return a number that is greater than one and less than three (equal or more restrictive). If B's hello returns 1 or 2 it's fine, but if it returns 4 then the 'assert' breaks. Also, if B's hello only accepted 1,2 and 3 as arguments then this will break because we're giving it 4. So clearly B's hello has to be able to accept 1,2,3 and 4 as a minimum.
 1. assert( pA->hello(4) >= 1 && pA->hello(1) <= 3)
Hide line numbers

General Programming Principles

Here are some general programming principles that cover a wide range of topics such as design patterns, idioms and good programming practice. These apply to all languages.

OO Design Ptterns Chart - periodic table
Double Dispatch and visitor Pattern
Liskov Substitution Principle, Covariance and Contravariance