SOAP Objects..

From: Date: Mon, 21 May 2001 16:34:20 +0000
Subject: SOAP Objects..
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-422@lists.php.net to get a copy of this message
Well folks here they are. Don't laugh too hard :). I have included a soaptesttim.php so you can see how it all works together. The soap response object is bare (literally nothing there) . The client send HTTPS is still not working but will be soon I hope. The rest of the objects work reasonably well I think. Thanks for all the encouragement. I would love to get some feedback and help. Also somebody (Stig?) said they would PEARify the code or help me do it that would be very nice. I am open to any and all suggestions on these objects. I need them like yesterday!. Don't even ask me about WSDL support yet :o :wq Tim Uckun Due Diligence Inc. http://www.diligence.com/ Americas Background Investigation Expert. If your company isn't doing background checks, maybe you haven't considered the risks of a bad hire.

<?php /* Name: soapval.php Version: .01 Description: A soap variable object to be used with other soap objects Author: Tim Uckun Last Modified Date: 05/21/01 Copyright (c) 20001 Tim Uckun All rights reserved. This Software is distributed under the GPL. For a list of your obligations and rights under this license please visit the GNU website at http://www.gnu.org/ */ /* Interface. public variables: None please don't attempt to directly access variables in objects Public Functions function soapval($name, $value, $type='') // constructor. Use this method to set your variables // it will guess at the type if you don't specify // it's acceptable to leave name blank (empty string) function serialize() // will output the XML fragment representing this variable // it will be called by other objects // no need to call it yourself */ class soapval { // all variables are private var $_name =''; var $_value; var $_type = ''; /** * Constructor Creates a new soap variable * * This is the constructor for this class * @param $name Name of the soap variable * @param $value The contents of the variable * @param $type Optional variable type. * If you don't specify the type it will guess * If the type is an array or struct it will guess about the contents of the struct. * You can use this to coerce soap types like int to boolean * * @return Nothing */ function soapval($name, $value, $type='') { $this->_name=$name; $this->_type=$this->_getSoapType($value , $type); $this->_value=$this->_getSoapvalue ($value, $this->_type); } function serialize() { switch($this->_type): case 'array': return $this->_serializeArray($this->_name, $this->_value); break; case 'struct': return $this->_serializeStruct($this->_name, $this->_value); break; default: return $this->_serializeScalar($this->_name, $this->_value, $this->_type); break; endswitch; } function _serializeStruct($name, $struct) { $s="<$name xmlns:ns2='http://xml.apache.org/xml-soap' xsi:type='ns2:Map'>\n"; reset($struct); while(list($key, $value)=each($struct)): $s .="<item>\n"; $type = $this->_getSoapType($value); $value= $this->_getSoapValue($value, $type); $keytype = $this->_getSoapType($key); $keyvalue = $this->_getSoapValue($key, $keytype); $s .= "<key xsi:type='xsd:$keytype'>$keyvalue</key>\n"; $s .= "<value xsi:type='xsd:$type'>$value</value>\n"; $s .="</item>\n"; endwhile; $s.= "</$name>\n"; return $s; } function _serializeArray($name, $values){ $s ="<$name xmlns:ns2=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"ns2:Array\" ns2:arrayType=\"xsd:ur-type[".sizeof($val)."]\">\n"; //echo "size of array is:".sizeof($val); for ($i=0; $i<sizeof($values); $i++): $itemname = "item"; $itemtype = $this->_getSoapType($values[$i]); $itemvalue= $this->_getSoapValue($values[$i], $type); $s.= $this->_serializeScalar($itemname, $itemvalue, $itemtype); endfor; $s.="</$name>\n"; return $s; } function _serializeScalar($name , $value, $type){ return "<$name xsi:type='xsd:$type'>$value</$name>\n"; } function _isValidSoapType($type){ $validSoapTypes = array ("i4","int", "boolean", "double" ,"string","dateTime.iso8601","base64","array","struct"); return in_array ($type,$validSoapTypes); } function _getSoapValue($value, $type){ // don't send anything here unless you ran // it through get soaptype first // this function needs good soap types // maybe we could combine the two functions... switch ($type): case 'boolean': if (strcasecmp($value,"true")==0 || $value==1 || $value==true): $value = 1; else: $value = 0; endif; break; case 'integer': // just to catch some oddball values $value= (int) $value; break; case 'double': $value= doubleval($value); break; case 'string': $value=htmlspecialchars($value); break; case 'base64': $value = base64_encode($value); break; default: // for all other types we do nothing // do nothing for now break; endswitch; return $value; } function _getSoapType($value, $type=''){ if ($type): // A type was specified so map it to lower $type=strtolower($type); if (!$this->_isValidSoapType($type)): // a type was specified but we don't recognize it. // let's just make it a string. $type = 'string'; endif; endif; // We still don't know the type // Let's guess if (!$type): // let's try to guess // get the php type $type=strtolower(gettype($value)); switch ($type): case 'boolean': // do nothing break; case 'integer': $type='int'; break; case 'double': // do nothing break; case 'string': // do nothing break; case 'array': // do nothing break; case 'object': $type = 'struct'; break; default: // How could we still not know? $type='string'; break; endswitch; endif; return $type; } } ?> <?php /* Name: soapmsg.php Version: .01 Description: A soap message object to be used with other soap objects It's basically an container for soapvar objects Author: Tim Uckun Last Modified Date: 05/21/01 Copyright (c) 20001 Tim Uckun All rights reserved. This Software is distributed under the GPL. For a list of your obligations and rights under this license please visit the GNU website at http://www.gnu.org/ */ /* Interface. public variables: None please don't attempt to directly access variables in objects Public Functions soapMsg($method , $target="" , $params=0) // constructor. Use this method to create a soap msg // Method is the name of the method // target is the URN // params is an array of soapval addparameter($par) // par is an soapval object getParameter($i) // retrieve a paramter by index getNumParameters() // returns the parameter count function method($meth='') // gets or sets the method function target($target='') // gets or sets the target function serialize() // serializes the entire message usually called by the soapclient object */ class soapMsg{ var $_parameters; var $_env_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">\n<SOAP-ENV:Body>\n" ; var $_env_footer="</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n"; var $_method=''; var $_target=''; function soapMsg($method , $target="" , $params=0) { $this->_method=$method; $this->_target=$target; if ($params): if (is_array($params) && sizeof($params)>0): $this->_parameters = $params; else: $this->addParam($params); endif; endif; } function addParameter($par) { $this->_parameters[]=$par; } function getParameter($i) { return $this->_parameters[$i]; } function getNumParameters() { return sizeof($this->_parameters); } function method($meth='') { if ($meth): $this->_method=$meth; endif; return $this->_method; } function target($target='') { if ($target): $this->_target=$target; endif; return $this->_target } function serialize() { $s = $this->_env_header; $s .= "<ns1:$this->_method xmlns:ns1='$this->_target' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>\n"; foreach ($this->_parameters as $param): $s .= $param->serialize(); endforeach; $s .= "</ns1:" . $this->_method . "s>\n"; $s .= $this->_env_footer; $s = str_replace("\n", "\r\n", $s); return $s; } } ?> <?php /* Name: soapclient.php Version: .01 Description: A soap response object to be used with other soap objects. nothing here yet just a skeleton Author: Tim Uckun Last Modified Date: 05/21/01 Copyright (c) 20001 Tim Uckun All rights reserved. This Software is distributed under the GPL. For a list of your obligations and rights under this license please visit the GNU website at http://www.gnu.org/ */ /* Interface. not much to see here just a skeleton to get stated working.. public variables: None please don't attempt to directly access variables in objects Public Functions soapresp($val) // constructor. Use this method to create a soap resp // $val is the raw XML from your client.. dump() // dumps the raw XML */ class soapResp { var $_value; var $_faultCode; var $_faultString; var $_headers; var $_XML; function soapresp($val) { $this->_XML=$val; $this->_value=xmltree($val); } function dump() { return $this->_value; } }// end of class soapResp ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Untitled</title> </head> <body> <?php //*----------------------- include './soapval.php'; include './soapmsg.php'; include './soapresp.php'; include './soapclient.php'; $send_int=2001; $send_string="happy!"; $send_arr=array(0, 1); $send_str=array("year"=>2001,"word"=>"happy"); $soap_env=new soapMsg( 'get_array', //Invoke Method Name 'urn:soap_test', //Invoke Target Object Id array( //Parametres List Below new soapval('intvalue', $send_int,"int"), new soapval('stringvalue', $send_string,"string"), new soapval('arrayvalue', $send_arr, "array"), new soapval('structvalue', $send_str, "struct"))); print "<B>SOAP Request XML:</B><font color='red'><PRE>\n"; print htmlspecialchars($soap_env->serialize()) . "\n<br>" ; $soapcl=new soapClient($soap_env); print_r($soapcl); $resp = $soapcl->sendHTTPS('https://secure.diligence.com/index.php'); print_r($resp); //print htmlspecialchars($resp->dump()) . "\n<br>" ; /**/ /* $test = new soapval('someint', $send_int,"int"); print htmlspecialchars($test->serialize()) . "\n<br>" ; $test = new soapval('somestring' , $send_string,"string"); print htmlspecialchars($test->serialize()) . "\n<br>" ; $test = new soapval('somestruct', $send_str, "struct"); print htmlspecialchars($test->serialize()) . "\n<br>" ; $test = new soapval('somearray', $send_arr, "array"); print htmlspecialchars($test->serialize()) . "\n<br>" ; print "</PRE></font>"; */ ?> </body> </html> <?php /* Name: soapclient.php Version: .01 Description: A soap client object to be used with other soap objects. It attempts to encapsulate various delivery methods for soapmsg objects Author: Tim Uckun Last Modified Date: 05/21/01 Copyright (c) 20001 Tim Uckun All rights reserved. This Software is distributed under the GPL. For a list of your obligations and rights under this license please visit the GNU website at http://www.gnu.org/ */ /* Interface. public variables: None please don't attempt to directly access variables in objects Public Functions soapClient($msg='') // constructor. Use this method to create a soap client // msg is the soapmsg object userAgent($agent='') // gets or sets the useragent (default is IE!) msg ($msg = '') // gets or sets the soapmsg object. Usually not needed and provided in the constructor sendHTTP($url, $timeout=0) // send the payload via HTTP to the URL sendHTTPS($url, $timeout=0) //// send the payload via HTTPS to the URL needs CURL to be compiled into php (--with-curl) */ class soapClient { var $_msg=''; var $_path; var $_server; var $_port; var $_errno; var $_errstring; // some servers are picky about the user agent so let's fake it var $_userAgent='Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'; function soapClient($msg='') { $this->_msg=$msg; return 1; } function userAgent($agent='') { if ($agent): $this->_userAgent = $agent; endif; return $this->_userAgent; } // obviously this has to be a valid soap msg function msg ($msg = '') { if ($msg): $this->_msg=$msg; endif; return $this->_msg; } function sendHTTP($url, $timeout=0) { if (!$this->_msg): $this->_errno=1; $this->errstr='No message to send, nothing to do.'; return 0; endif; $urlparts = @parse_url($url); /* this will crack the url like this.. [scheme] => https [host] => www.diligence.com [port] => 8080 [user] => tim [pass] => password [path] => /something.php [query] => something=something unless the user omitted somethings if so then the element is not defined */ if ( ! is_array($urlparts) ): $this->_errno=2; $this->errstr="Unable to parse URL $url"; return 0; endif; if (!$urlparts['port']): $urlparts['port'] = 80; endif; if($timeout>0): $fp=fsockopen($urlparts['host'], $urlparts['port'], &$this->errno, &$this->errstr, $timeout); else: $fp=fsockopen($urlparts['host'], $urlparts['port'], &$this->errno, &$this->errstr); endif; if (!$fp): $this->_errno=3; $this->errstr="Unable to open socket in function sendHTTP10, server = $server ; port= $port"; return 0; endif; $credentials=""; if ($urlparts['user']): $credentials="Authorization: Basic " . base64_encode($urlparts['user'] . ":" . $urlparts['pass']) . "\r\n"; endif; $body = $this->_msg->serialize(); $op= "POST " . $urlparts['path'] . " " . $this->_userAgent . "\r\n" . "Host: ". $urlparts['host'] . "\r\n" . $credentials . "Content-Type: text/xml\r\nContent-Length: " . strlen($body) . "\r\n\r\n" . $body; if (!fputs($fp, $op, strlen($op))) { $this->_errno=3; $this->errstr="Unable to write to the already opened socket"; return 0; } $result=""; while($data=fread($fp, 32768)) { $result .= $data; } $resp= new soapResp($result); return $resp; } function sendHTTPS($url, $timeout=0){ /* NOTE This function uses the CURL functions * Your php must be compiled with CURL */ print "<br> The URL is .. $url <br>"; $ch = curl_init(); if ($timeout): curl_setopt($ch, CURLOPT_TIMEOUT,$timeout); //times out after 4s endif; curl_setopt($ch, CURLOPT_HTTPHEADER, "Content-Type: text/xml"); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt ($ch, CURLOPT_USERAGENT, $this->_userAgent); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_VERBOSE,1); curl_setopt($ch, CURLOPT_POST, 1); $result=curl_exec ($ch); curl_close ($ch); print "RESULT $result<br>"; $resp= new soapResp($result); return $resp; } } // end class soapClient ?>
« previous php.pear.dev (#422) next »