simple function to call a soap operation
without the new php5 soap objects
martin kouba - 24.01.2005
parameters:
host .... address of the server that is running the webservice
port .... port to access the webservice; http => 80
url ..... url of the webservice; where shall be posted to
action .. the soap action; including the namespace
vars .... the arguments of the webservice in an associative array
<?
function soap_operation($host, $port, $url, $action, $vars) {
/////////////////////////////////////////////////////////////////////////////
// simple function to call a soap operation //
// without the new php5 soap objects //
// martin kouba - 24.01.2005 //
// updated for ssl connections - 12.08.2005 //
// updated for multiline results - 04.04.2006 //
// parameters: //
// host .... address of the server that is running the webservice //
// port .... port to access the webservice; http => 80 //
// url ..... url of the webservice; where shall be posted to //
// action .. the soap action; including the namespace //
// vars .... the arguments of the webservice in an associative array //
/////////////////////////////////////////////////////////////////////////////
// define eol that is used by the server
// windows webservices seem to need a \r\n
$eol = "\r\n";
// extract namespace from soap action
preg_match('/(https?:\/\/.*\/)(.*)/', $action, $matches) or die("Invalid SOAPAction: '$action'");
$soap_ns = $matches[1];
$soap_action = $matches[2];
// create soap envelope
// convert to utf8 and get the content length
$content =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".$eol.
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">".$eol.
" <soap:Body>".$eol.
" <".$soap_action." xmlns=\"".$soap_ns."\">".$eol;
while (list($key, $value) = each($vars)) {
$content.= " <".$key.">".$value."</".$key.">".$eol;
}
$content .=
" </".$soap_action.">".$eol.
" </soap:Body>".$eol.
"</soap:Envelope>";
$content = utf8_encode($content);
$content_length = strlen($content);
// create soap header
// the connection should be closed right after the response
// since HTTP 1.1 connections are Keep-Alive per default
// we set "Connection: close"
$headers =
"POST ".$url." HTTP/1.1".$eol.
"Host: ".str_replace("ssl://","",$host)."".$eol.
"Connection: close".$eol.
"Content-Type: text/xml; charset=utf-8".$eol.
"Content-Length: ".$content_length."".$eol.
"SOAPAction: \"".$soap_ns.$soap_action."\"".$eol.$eol;
// debug
#echo "<pre>".$headers.$content."</pre>";
#echo '<pre>$host: '; var_dump($host); echo '</pre>';
#echo '<pre>$port: '; var_dump($port); echo '</pre>';
// make connection to server and post header and the soap envelope
$fp = fsockopen($host, $port, $errno, $errstr, 10);
// debug
#echo '<pre>$errorno: '; var_dump($errno); echo '</pre>';
#echo '<pre>$errstr: '; var_dump($errstr); echo '</pre>';
if (!$fp) {
return false;
}
fputs($fp, $headers);
fputs($fp, $content);
// the connection should be closed after the response
// yet, we want to set a timeout to react before the php script timeout comes in
stream_set_timeout($fp, 20);
$data = "";
$status = socket_get_status($fp);
while(!feof($fp) && !$status['timed_out']) {
$data .= fgets($fp, 1024);
$status = socket_get_status($fp);
}
fclose($fp);
// debug
echo '<pre>$data: '; var_dump($data); echo '</pre>';
echo '<pre>$soap_action: '.$soap_action.'</pre>';
// extract the soap result
preg_match('/<'.$soap_action.'Result>(.*)<\/'.$soap_action.'Result>/is', $data, $matches) or die("Invalid SOAPResponse: '$data'");
return $matches[1];
}
#$host = "foo.bar";
#$port = 80;
#$soap_url = "/Foo/FooBar.asmx";
#$soap_action = "http://foobar.com/webservices/FooBar";
#$soap_parameter = array("UserName" => $user, "OldPassword" => $old_pwd, "NewPassword" => $new_pwd);
// do the soap (uncomment it when you are ready)
#$result = soap_operation($host, $port, $soap_url, $soap_action, $soap_parameter);
// show result in a textarea
print("<form><textarea style='width:500;height:300'>");
print_r($result);
print("</textarea></form>");
?>
|