<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3//EN" []>
<book>
  <bookinfo>
    <title>XML-RPC for PHP</title>
    <subtitle>version 1.0b9</subtitle>
    <date>7th July 2001</date>
    <authorgroup>
      <author>
	<firstname>Edd</firstname>
	<surname>Dumbill</surname>
	<affiliation>
	  <orgname><ulink url="http://usefulinc.com/">Useful 
	      Information Company</ulink></orgname>
	  <address>
	    <email>edd@usefulinc.com</email>
	  </address>
	</affiliation>
      </author>
    </authorgroup>
    <copyright>
      <year>1999,2000,2001</year>
      <holder>Edd Dumbill, Useful Information Company</holder>
    </copyright>
    <legalnotice>
      <para>License is granted to use or modify this software ("XML-RPC
	for PHP") for commercial or
	non-commercial use provided the copyright of the author is
	preserved in any distributed or derivative work.</para>
      
      <para> THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
	PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
	OF THE POSSIBILITY OF SUCH DAMAGE.</para>
    </legalnotice>
  </bookinfo>
  <toc>
  </toc>
  <chapter id="introduction">

	<title>Introduction</title>

    <para>XML-RPC is a format devised by <ulink
		url="http://www.userland.com/">Userland Software</ulink> for
      achieving remote procedure call via XML. XML-RPC has its own web
      site, <ulink
		   url="http://www.xmlrpc.com/">www.XmlRpc.com</ulink></para>
    <para>The most common implementations of XML-RPC available at the
      moment use HTTP as the transport. A list of implementations for
      other languages such as Perl and Python can be found on the 
      <ulink
	     url="http://www.xmlrpc.com/">www.XmlRpc.com</ulink>.</para>
    <para>This collection of PHP classes provides a framework for
      writing XML-RPC clients and servers in PHP.</para>
    <warning>
      <para>The <emphasis>server code</emphasis> works only with versions of PHP3
	>= 3.0.12. The code is also known to work with PHP4.
      </para>
    </warning>

    <sect1>
      <title>Acknowledgements</title>
      <para>Jim Winstead <email>jimw@php.net</email></para>
      <para>Peter Kocks <email>peter.kocks@baygate.com</email></para>
      <para>Nicolay Mausz <email>mausz@flying-dog.com</email></para>
      <para>Ben Margolin
	<email>ben@wendy.auctionwatch.com</email></para>
      <para>Dan Libby <email>dan@libby.com</email></para>
      <para>Gaetano Giunta <email>g.giunta@libero.it</email></para>
      <para>Idan Sofer <email>i_sofer@yahoo.com</email></para>
      
    </sect1>
  </chapter>
  
  <chapter id="manifest">
    <title>Files in the distribution</title>
    
    <glosslist>
      <glossentry>
	<glossterm>xmlrpc.inc</glossterm>
	<glossdef>
	  <para>the XML-RPC classes. <function>include()</function> this in
	    your PHP files to use the classes.</para>
	</glossdef>
      </glossentry>
      
      <glossentry>
	<glossterm>xmlrpcs.inc</glossterm>
	<glossdef>
	  <para>the XML-RPC server class.  <function>include()</function>
	    this in addition to xmlrpc.inc to get server
	    functionality</para>
	</glossdef>
      </glossentry>
      
      <glossentry>
	<glossterm>bettydemo.php</glossterm>
	<glossdef>
	  <para>demo which retrieves a state name from a number using Dave
	    Winer's XML-RPC server at betty.userland.com</para>
	</glossdef>
      </glossentry>

	  <glossentry>
		<glossterm>server.php</glossterm>
		<glossdef>
		  <para>a sample server hosting three functions: a US State lookup
			tool, a struct sorter and an echo function.</para>
		</glossdef>
	  </glossentry>

	  <glossentry>
		<glossterm>client.php, agesort.php, echotest.php</glossterm>
		<glossdef>
		  <para>client code to exercise the various functions in
		  server.php</para>
		</glossdef>
	  </glossentry>

			<glossentry>
				<glossterm>base64test.php, stringtest.php</glossterm>
				<glossdef>
					<para>
						Tests to verify that encoding and decoding of base 64 and
						entities is functioning correctly.
					</para>
				</glossdef>
			</glossentry>

	  <glossentry>
		<glossterm>vardemo.php</glossterm>
		<glossdef>
		  <para>examples of how to construct xmlrpcval types</para>
		</glossdef>
	  </glossentry>

	  <glossentry>
		<glossterm>demo1.txt, demo2.txt, demo3.txt</glossterm>
		<glossdef>
		  <para>XML-RPC responses captured in a file for testing purposes (you
			can use these to test the
			<function>xmlrpcmsg->parseResponse()</function>
			method).</para>
		</glossdef>
	  </glossentry>

			<glossentry>
		<glossterm>httptest.php</glossterm>
		<glossdef>
		  <para>Testing that HTTP response detection works OK.</para>
		</glossdef>
	  </glossentry>
		<glossentry>
		<glossterm>test.pl, test.py</glossterm>
		<glossdef>
		  <para>Perl and Python programs to exercise server.php to test
					that some of the methods work. 
						Make sure you point these at your server, not mine!</para>
		</glossdef>
	  </glossentry>
					<glossentry>
		<glossterm>workspace.testPhpServer.fttb</glossterm>
		<glossdef>
		  <para>Frontier scripts to exercise the demo server. Thanks to Dave
						Winer for permission to include these. See <ulink
																															url="http://www.xmlrpc.com/discuss/msgReader$853">Dave's announcement of these.</ulink></para>

		</glossdef>
	  </glossentry>

      <glossentry>
	<glossterm>phpunit.php</glossterm>
	<glossdef>
	  <para>Fred Yankowski's unit test framework for PHP.</para>
	</glossdef>
      </glossentry>
      
      <glossentry>
	<glossterm>testsuite.php</glossterm>
	<glossdef>
	  <para>Start of a unit test suite for this software
	    package. If you do development on this software, please
	    consider submitting tests for this suite.</para>
	</glossdef>
      </glossentry>
      <glossentry>
	<glossterm>which.php</glossterm>
	<glossdef>
	  <para>A demo of the
	    <function>interopEchoTests.whichToolkit</function>
	    method.</para>
	</glossdef>
      </glossentry>
      <glossentry>
	<glossterm>discuss.php, comment.php</glossterm>
	<glossdef>
	  <para>Software used in the PHP chapter of <xref linkend="jellyfish"> to
	    provide a comment server and allow the attachment of
	    comments to stories from Meerkat's data store.</para>
	</glossdef>
      </glossentry>
    </glosslist>
  </chapter>
  <chapter id="bugs">
	<title>Bugs</title>
	<para>This is a bare framework. The "nice" bits haven't been put in
	  yet. Specifically, no HTTP response checking is performed, and no type
	  validation or coercion has been put in.  PHP being a loosely-typed
	  language, this is going to have to be done explicitly.</para>
	<para>dateTime.iso8601 is supported opaquely. It can't be done
      natively as the XML-RPC specification explictly forbids passing of
      timezone specifiers in ISO8601 format dates. You can, however, use
      the <xref linkend="iso8601encode"> and <xref
						   linkend="iso8601decode"> functions to do the encoding and decoding for you.</para>
    <para>If alternative character set encoding is sent in HTTP header
      than it will be ignored for the moment.  We speak only UTF-8...</para>
    <para>If more than 32k of HTTP headers are encountered (like, why?) then the
      response parsing code will break.</para>
    
  </chapter>
  <chapter id="support">
    <title>Support</title>
    <sect1>
      <title>Online Support</title>

      <para>XML-RPC for PHP is offered "as-is" without any warranty or
	commitment to support. However, informal advice and help is
	available via the XML-RPC for PHP mailing list and XML-RPC.com.
      </para>
    <itemizedlist>
      <listitem>
	<para>The <emphasis>PHP XML-RPC interest mailing list</emphasis> 
	  is run by the author.  More details <ulink
						     url="http://www.usefulinc.com/xmlrpc/list.html">can be found 
	    here</ulink>.</para>
      </listitem>
      <listitem><para>For more general XML-RPC questions, there is a
	  Yahoo! Groups <ulink
			 url="http://groups.yahoo.com/group/xml-rpc/">XML-RPC mailing list</ulink>.</para>
      <listitem>
	<para>The <ulink
			 url="http://www.xmlrpc.com/discuss">XML-RPC.com</ulink>
	  discussion group is a useful place to get help with using
	  XML-RPC. This group is also gatewayed into the Yahoo! Groups mailing list.</para>
      </listitem>
    </itemizedlist>  
    </sect1>
    <sect1 label="The Jellyfish Book" id="jellyfish" xreflabel="The
	   Jellyfish Book">
      <title>The Jellyfish Book</title>
      <para>	
	<graphic
		 fileref="http://www.oreilly.com/catalog/covers/progxmlrpc.s.gif" 
		 format="gif" width="145" depth="190" align="right"></graphic>
	Together with Simon St.Laurent and Joe Johnston, I wrote a
	book on XML-RPC for O'Reilly and Associates on XML-RPC. It
	features a rather fetching jellyfish on the cover.
      </para>
      <para>Complete details of the book are 
	<ulink
	       url="http://www.oreilly.com/catalog/progxmlrpc/">available 
	  from O'Reilly's web site.</ulink>
      </para>
      <para>I'm responsible for the chapter on PHP, which includes a
	worked example of creating a forum server, and hooking it up
	the O'Reilly's <ulink
			      url="http://meerkat.oreillynet.com/">Meerkat</ulink> service
	in order to allow commenting on news stories from around the
	Web.</para>
      <para>If you've benefitted from the effort I've put into writing
	this software, then please consider buying the book!</para>
    </sect1>
  </chapter>
  <chapter id="apidocs">
	<title>Class documentation</title>
	<sect1 id="xmlrpc-client" xreflabel="xmlrpc_client">
	  <title>xmlrpc_client</title>
	  <para>This is the basic class used to represent a client of an
		XML-RPC server.</para>
	  <sect2>
		<title>Creation</title>
		<para>The constructor has the following syntax:</para>
		<funcsynopsis>
		  <funcprototype>
			<funcdef>$client=new xmlrpc_client</funcdef>
			<paramdef><parameter>$server_path</parameter></paramdef>
			<paramdef><parameter>$server_hostname</parameter></paramdef>
			<paramdef><parameter>$server_port</parameter></paramdef>
		  </funcprototype>
		</funcsynopsis>
	  <para>Here's an example client set up to query Userland's XML-RPC
		server at <emphasis>betty.userland.com</emphasis>:</para>
	  <programlisting>
$client=new xmlrpc_client("/RPC2", "betty.userland.com", 80);</programlisting>
	  <para>The <parameter>server_port</parameter> parameter is
		optional, and if omitted will default to 80.</para>
	  </sect2>
	  <sect2>
		<title>Methods</title>
		<para>This class supports the following methods.</para>
		<sect3 id="xmlrpc-client-send" xreflabel="xmlrpc_client->send">
		  <title>send</title>
		  <para>This method takes the form:</para>
		  <funcsynopsis>
			<funcprototype>
							<funcdef>$response=$client->send</funcdef>
							<paramdef><parameter>$xmlrpc_message</parameter></paramdef>
							<paramdef><parameter>$timeout</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		 
		  <para>Where <parameter>$xmlrpc_message</parameter> is an
			instance of <classname>xmlrpcmsg</classname> (see <xref
			  linkend="xmlrpcmsg">), and 
						<parameter>$response</parameter> is an
			instance of <classname>xmlrpcresp</classname> (see <xref 
			  linkend="xmlrpcresp">).</para>

					<para>The <parameter>$timeout</parameter> is optional, and
						will be set to <literal>0</literal> (wait forever) if omitted. This timeout
						value is passed to <function>fsockopen()</function>.</para>
				
		  <para>If the value of <parameter>$response</parameter> is
			<literal>0</literal> rather than an
			<classname>xmlrpcresp</classname> object, then this
			signifies an I/O error has occured. You can find out what
			the I/O error was from the values
			<function>$client->errno</function> and
			<function>$client->errstring</function>.
			</para>
		  <para>In addition to low-level errors, the XML-RPC server you
			were querying may return an error in the
			<classname>xmlrpcresp</classname> object. See <xref
			  linkend="xmlrpcresp"> for details of
			how to handle these errors.
		  </para>
		</sect3>
		<sect3>
		  <title>setCredentials</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$client->setCredentials</funcdef>
			  <paramdef><parameter>$username</parameter></paramdef>
							<paramdef><parameter>$password</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>This method sets the username and password for authorizing the
						client to a server. With the default (HTTP) transport, this
						information is used for HTTP Basic authorization.
						
		  </para>
		</sect3>

		<sect3>
		  <title>setDebug</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$client->setDebug</funcdef>
			  <paramdef><parameter>$debugOn</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para><parameter>$debugOn</parameter> is either
			<literal>0</literal> or <literal>1</literal> depending on
			whether you require the client to print debugging
			information to the browser.  The default is not to output
			this information.</para>
		  <para>
			The debugging information includes the raw data returned
			from the XML-RPC server it was querying, and the PHP value
			the client attempts to create to represent the value
			returned by the server.  This option can be very useful when 
			debugging servers as it allows you to see exactly what the
			server returns.
		  </para>
		</sect3>
	  </sect2>
	</sect1>
	<sect1 id="xmlrpcmsg" xreflabel="xmlrpcmsg">
	  <title>xmlrpcmsg</title>
	  <para>This class provides a representation for a request to an
		XML-RPC server. A client sends an
		<classname>xmlrpcmsg</classname> to a server, and receives back
		an <classname>xmlrpcresp</classname> (see <xref
		  linkend="xmlrpc-client-send">).</para>
	  <sect2>
		<title>Creation</title>
		<para>The constructor takes the following form:</para>
		<funcsynopsis>
		  <!-- one of (funcprototype funcdef) -->
		  <funcprototype>
			<funcdef>$msg=new xmlrpcmsg</funcdef>
			<paramdef><parameter>$methodName</parameter></paramdef>
			<paramdef><parameter>$parameterArray</parameter></paramdef>
		  </funcprototype>
		</funcsynopsis>
		<para>Where <parameter>$methodName</parameter> is a string
		  indicating the name of the method you wish to invoke, and
		  <parameter>$parameterArray</parameter> is a simple
		  <classname>Array</classname> of
		  <classname>xmlrpcval</classname> objects.  Here's an example
		  message to the <emphasis>US state name</emphasis> server:
		</para>
		<programlisting>
$msg=new xmlrpcmsg("examples.getStateName",
		  array(new xmlrpcval(23, "int")));
		</programlisting>
		<para>
		  This example requests the name of state number 23. For more
		  information on <classname>xmlrpcval</classname> objects, see
		  <xref linkend="xmlrpcval">.
		</para>
	  </sect2>
	  <sect2>
		<title>Methods</title>
		<sect3>
		  <title>serialize</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$outString=$msg->serialize</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Returns the an XML string representing the XML-RPC
			message.</para>
		</sect3>
		<sect3>
		  <title>addParam</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$msg->addParam</funcdef>
			  <paramdef><parameter>$xmlrpcVal</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Adds the <classname>xmlrpcval</classname>
			<parameter>$xmlrpcVal</parameter> to the parameter list for
			this method call.</para>
		</sect3>
		<sect3>
		  <title>getParam</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$xmlrpcVal=$msg->getParam</funcdef>
			  <paramdef><parameter>$n</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Gets the <parameter>$n</parameter>th parameter in the
			message. Use this method in server implementations. Returns
			the <literal>undef</literal> value if no such parameter
			exists.</para>
		</sect3>
		<sect3>
		  <title>getNumParams</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$n=$msg->getNumParams</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns the number of parameters attached to this message.
		  </para>
		</sect3>
		<sect3>
		  <title>method</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$methName=$msg->method</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
			<funcprototype>
			  <funcdef>$msg->method</funcdef>
			  <paramdef><parameter>$methName</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Gets or sets the method contained in the XML-RPC message.</para>
		</sect3>
		<sect3>
		  <title>parseResponse</title>
		  <funcsynopsis>

			<funcprototype>
			  <funcdef>$response=$msg->parseResponse</funcdef>
			  <paramdef><parameter>$xmlString</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Given an incoming XML-RPC server response contained in
			the string
			<parameter>$xmlString</parameter>, this method constructs
			an <classname>xmlrpcresp</classname> response object and
			returns it, setting error codes as appropriate (see <xref
			  linkend="xmlrpc-client-send">).
		  </para>
		  <para>
			This method processes any HTTP/MIME headers it finds.
		  </para>
		</sect3>
		<sect3>
		  <title>parseResponseFile</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$response=$msg->parseResponseFile</funcdef>
			  <paramdef><parameter>$fileHandle</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Given an incoming XML-RPC server response on the file handle
			<parameter>$fileHandle</parameter>, this method reads the
			data and passes it to <function>parseResponse</function>
		  </para>
		  <para>
			This method is useful to construct responses from
			pre-prepared files (see files <literal>demo1.txt, demo2.txt, 
			  demo3.txt</literal> in this distribution). It processes
			any HTTP headers it finds.
		  </para>
		</sect3>
	  </sect2>
	</sect1>
	<sect1 id="xmlrpcresp" xreflabel="xmlrpcresp">
	  <title>xmlrpcresp</title> 
	  <para>This class is used to contain responses to XML-RPC
		requests. A server method handler will construct an
		<classname>xmlrpcresp</classname> and pass it as a return value.
	  This same value will be returned by the result of an invocation of 
	  the <function>send</function> method of the
		<classname>xmlrpc_client</classname> class.</para>
	  <sect2>
		<title>Creation</title>
		<funcsynopsis>
		  <!-- one of (funcprototype funcdef) -->
		  <funcprototype>
			<funcdef>$resp=new xmlrpcresp</funcdef>
			<!-- one of (paramdef varargs void) -->
			<paramdef><parameter>$xmlrpcval</parameter></paramdef>
		  </funcprototype>
		  <funcprototype>
			<funcdef>$resp=new xmlrpcresp</funcdef>
			<paramdef><parameter>0</parameter></paramdef>
			<paramdef><parameter
				>$errcode</parameter></paramdef>
			<paramdef><parameter
				>$errstring</parameter></paramdef>
		  </funcprototype>
		</funcsynopsis>
		<para>The first instance is used when execution has happened
		  without difficulty: <parameter>$xmlrpcval</parameter> is an
		  <classname>xmlrpcval</classname> value with the result of the
		  method execution contained in it.</para>
		<para>
		  The second type of constructor is used in case of
		  failure. <parameter>$errcode</parameter> and
		  <parameter>$errstring</parameter> are used to provide
		  indication of what has gone wrong.  See <xref
			linkend="xmlrpc-server"> for more information on passing
		  error codes.
		</para>
	  </sect2>
	  <sect2>
		<title>Methods</title>
		<sect3>
		  <title>faultCode</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$fn=$resp->faultCode</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Returns the integer fault code return from the XML-RPC
			response <parameter>$resp</parameter>.
			A zero value indicates success, any other value
			indicates a failure response.</para>
		</sect3>
		<sect3>
		  <title>faultString</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$fs=$resp->faultString</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns the human readable explanation of the fault
			indicated by <function>$resp->faultCode</function>.
		  </para>
		</sect3>
		<sect3>
		  <title>value</title>		  
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$xmlrpcVal=$resp->value</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns an <classname>xmlrpcval</classname> object
			containing the return value sent by the server. If the
			response's <function>faultCode</function> is non-zero then
			the value returned by this method should not be used (it may 
			not even be an object).
		  </para>
		</sect3>
		<sect3>
		  <title>serialize</title><para></para>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$outString=$resp->serialize</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Returns an XML string representation of the response.</para>
		</sect3>
	  </sect2>
	</sect1>
	<sect1 id="xmlrpcval" xreflabel="xmlrpcval">
	  <title>xmlrpcval</title> 
	  <para>This is where a lot of the hard work gets done.  This class
		enables the creation and encapsulation of values for XML-RPC.
	  </para>
	  <para>
		Ensure you've read the XML-RPC spec at <ulink
		url="http://www.xmlrpc.com/stories/storyReader$7">http://www.xmlrpc.com/stories/storyReader$7</ulink>
		before reading on as it will make things clearer.
	  </para>
	  <para>The <classname>xmlrpcval</classname> class can store
		arbitrarily complicated values using the following types:
		<literal>i4 int boolean string double  dateTime.iso8601 base64
		  array struct</literal>. You should refer to the <ulink
		url="http://www.xmlrpc.com/stories/storyReader$7">spec</ulink>
		for more information on what each of these types mean.
	  </para>
	  <sect2>
		<title>Notes on types</title>
		<sect3>
		  <title>int</title>
		  <para>The type <classname>i4</classname> is accepted as a
			synonym for <classname>int</classname>. The value parsing
			code will always convert <classname>i4</classname> to
			<classname>int</classname>: <classname>int</classname> 
			is regarded by this implementation as the canonical name for 
			this type.</para>
		</sect3>
		<sect3>
		  <title>base64</title>
		  <para>Base 64 encoding is performed transparently to the
			caller when using this type.  Therefore you ought to
			consider it as a "binary" data type, for use when you want
			to pass none 7-bit clean data.  Decoding is also
			transparent.
		  </para>
		</sect3>
		<sect3>
		  <title>boolean</title>
		  <para>The values <literal>true</literal> and
			<literal>1</literal> map to <literal>true</literal>. All
			other values (including the empty string)
			are converted to <literal>false</literal>.
		  </para>
		</sect3>
		<sect3>
		  <title>string</title>
		  <para>
			The characters <literal>&lt; &gt; &quot;</literal> and
			<literal>&amp;</literal> are converted to their entity
			  equivalents <literal>&amp;lt; &amp;gt;
				&amp;quot;</literal> and <literal>&amp;amp;</literal>
			  for transport through XML-RPC.  The current XML-RPC spec
			  recommends only encoding <literal>&lt; &amp;</literal> but 
			  this implementation goes further, for reasons explained by 
			  <ulink url="http://www.w3.org/TR/REC-xml#syntax">the XML 1.0
				recommendation</ulink>.
		  </para><para>TODO: <literal> &amp;apos;</literal> entity not
			yet supported</para>
		</sect3>
	  </sect2>
	  <sect2 id="xmlrpcval-creation" xreflabel="xmlrpcval constructors">
		<title>Creation</title>
		<para>The constructor is the normal way to create an
		  <classname>xmlrpcval</classname>. The constructor can take
		  these forms:
		</para>
		<funcsynopsis>
		  <!-- one of (funcprototype funcdef) -->
		  <funcprototype>
			<funcdef>$myVal=new xmlrpcval</funcdef>
			<!-- one of (paramdef varargs void) -->
			<paramdef></paramdef>
		  </funcprototype>
		  <funcprototype>
			<funcdef>$myVal=new xmlrpcval</funcdef>
			<!-- one of (paramdef varargs void) -->
			<paramdef><parameter>$stringVal</parameter></paramdef>
		  </funcprototype>
		  <funcprototype>
			<funcdef>$myVal=new xmlrpcval</funcdef>
			<!-- one of (paramdef varargs void) -->
			<paramdef><parameter>$scalarVal</parameter></paramdef>
			<paramdef><parameter>"int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64"</parameter></paramdef>
		  </funcprototype>
		  <funcprototype>
			<funcdef>$myVal=new xmlrpcval</funcdef>
			<!-- one of (paramdef varargs void) -->
			<paramdef><parameter>$arrayVal</parameter></paramdef>
			<paramdef><parameter>"array" | "struct"</parameter></paramdef>
		  </funcprototype>
		</funcsynopsis>
		<para>The first constructor creates an empty value, which must
		  be altered using the methods <function>addScalar</function>,
		  <function>addArray</function> or
		  <function>addStruct</function> before it can be used.
		</para>
		<para>
		  The second constructor creates a simple string value.
		</para>
		<para>
		  The third constructor is used to create a scalar value.  The
		  second parameter must be a name of an XML-RPC type. Examples:	
		</para>
		<programlisting>
		  $myInt=new xmlrpcvalue(1267, "int");
		  $myString=new xmlrpcvalue("Hello, World!", "string");
		  $myBool=new xmlrpcvalue(1, "boolean");
		</programlisting>
	
		<para>
		  The fourth constructor form can be used to compose complex
		  XML-RPC values. The first argument is either a simple array in 
		  the case of an XML-RPC <classname>array</classname> or 
		  an associative array in the case of a
		  <classname>struct</classname>. The elements of the array
		  <emphasis>must be <classname>xmlrpcval</classname> objects
			themselves</emphasis>.
		  Examples:</para>
		<programlisting>
		  $myArray=new xmlrpcval(array(
		      new xmlrpcval("Tom"), new xmlrpcval("Dick"),
		      new xmlrpcval("Harry")), "array");

		  $myStruct=new xmlrpcval(array(
		      "name" => new xmlrpcval("Tom"),
		      "age" => new xmlrpcval(34, "int"),
		      "geek" => new xmlrpcval(1, "boolean")), "struct");
		</programlisting>
		<para>See the file <literal>vardemo.php</literal> in this
		  distribution for more examples.</para>
	  </sect2>
	  <sect2 id="xmlrpcval-methods" xreflabel="xmlrpcval methods">
		<title>Methods</title>
		<sect3>
		  <title>addScalar</title>
		  <funcsynopsis>
			<!-- one of (funcprototype funcdef) -->
			<funcprototype>
			  <funcdef>$ok=$val->addScalar</funcdef>
			  <!-- one of (paramdef varargs void) -->
			  <paramdef><parameter>$stringVal</parameter></paramdef>
			</funcprototype>
			<funcprototype>
			  <funcdef>$ok=$val->addScalar</funcdef>
			  <!-- one of (paramdef varargs void) -->
			  <paramdef><parameter>$scalarVal</parameter></paramdef>
			  <paramdef><parameter>"int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64"</parameter></paramdef>
			</funcprototype>

		  </funcsynopsis>
		  <para>
			If <parameter>$val</parameter> is an empty
			<classname>xmlrpcval</classname> this method makes it a
			scalar value, and sets that value.  If
			<parameter>$val</parameter> is already a scalar value, then
			no more scalars can be added and <literal>0</literal> is
			returned. If all went OK, <literal>1</literal> is returned.
		  </para>
		  <para>There is a special case if <parameter>$val</parameter>
			is an <classname>array</classname>: the scalar value passed
			is appended to the array.</para>
		</sect3>
		<sect3>
		  <title>addArray</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$ok=$val->addArray</funcdef>
			  <paramdef><parameter>$arrayVal</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Turns an empty <classname>xmlrpcval</classname> into an
			<classname>array</classname> with contents as specified by
			<parameter>$arrayVal</parameter>.  See the fourth
			constructor form for more information.</para>
		</sect3>
		<sect3>
		  <title>addStruct</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$ok=$val->addArray</funcdef>
			  <paramdef><parameter>$assocArrayVal</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>Turns an empty <classname>xmlrpcval</classname> into a
			<classname>struct</classname> with contents as specified by
			<parameter>$assocArrayVal</parameter>.  See the fourth
			constructor form for more information.</para>
		</sect3>	  
		<sect3>
		  <title>kindOf</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$kind=$val->kindOf</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns a string containing "struct", "array" or "scalar"
			describing the base type of the value.  If it returns
			"undef" it means that the value hasn't been initialised.
		  </para>
		</sect3>
		<sect3>
		  <title>serialize</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$outString=$val->serialize</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>		  
		  <para>
			Returns a string containing the XML-RPC representation of
			this value.
		  </para>
		</sect3>
		<sect3>
		  <title>scalarval</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$scalarVal=$val->scalarval</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			If <function>$val->kindOf()=="scalar"</function>, this
			method returns the actual PHP-language value of the scalar
			(base 64 decoding is automatically handled here).
		  </para>
		</sect3>
		<sect3>
		  <title>scalartyp</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$typeName=$val->scalartyp</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			If <function>$val->kindOf()=="scalar"</function>, this
			method returns a string denoting the type of the scalar. 
			As mentioned before,
			<literal>i4</literal> is always coerced to <literal>int</literal>.
		  </para>
		</sect3>
		<sect3>
		  <title>arraymem</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$xmlrpcVal=$val->arraymem</funcdef>
			  <paramdef><parameter>$n</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns the <parameter>$n</parameter>th element in the array 
			represented by the value <parameter>$val</parameter>. The
			value returned is an <classname>xmlrpcval</classname> object.
		  </para>
		</sect3>
		<sect3>
		  <title>arraysize</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$len=$val->arraysize</funcdef>
			  <paramdef></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>If <parameter>$val</parameter> is an
			<classname>array</classname>, returns the number of elements 
			in that array.
		  </para>
		</sect3>
		<sect3>
		  <title>structmem</title>
		  <funcsynopsis>
			<funcprototype>
			  <funcdef>$xmlrpcVal=$val->structmem</funcdef>
			  <paramdef><parameter>$memberName</parameter></paramdef>
			</funcprototype>
		  </funcsynopsis>
		  <para>
			Returns the element called
			<parameter>$memberName</parameter> from the struct
			represented by the value <parameter>$val</parameter>. The
			value returned is an <classname>xmlrpcval</classname> object.
		  </para>
		</sect3>
				<sect3>
					<title>structeach</title>
					<funcsynopsis>
						<funcprototype>
							<funcdef>list($key,$value)=$val->structeach</funcdef>
							<paramdef></paramdef>
						</funcprototype>
					</funcsynopsis>
					<para>
						Returns the next (key,value) pair from the struct, when
						<parameter>$val</parameter> is a struct. See also 
						<xref	linkend="structreset">.
					</para>
				</sect3>
				
				<sect3 id="structreset" xreflabel="structreset()">
					<title>structreset</title>
					<funcsynopsis>
						<funcprototype>
							<funcdef>$val->structreset</funcdef>
							<paramdef></paramdef>
						</funcprototype>
					</funcsynopsis>
					<para>
						Resets the internal pointer for
						<function>structeach()</function> to the beginning of the
						struct, where <parameter>$val</parameter> is a struct.
					</para>
				</sect3>
				
	  </sect2>
	</sect1>
	<sect1 id="xmlrpc-server" xreflabel="xmlrpc_server">
	  <title>xmlrpc_server</title> 
	  <para>The current implementation of this class has been
		kept as simple as possible. The constructor for the server
		basically does all the work. Here's a minimal example:</para>
	  <programlisting>
  function foo ($params) {
     ...
  }

  $s=new xmlrpc_server( array("examples.myFunc" =>
				array("function" => "foo")));
	  </programlisting>
	  <para>
		This performs everything you need to do with a server.  The single
		argument is an associative array from method names to function
		names. The request is parsed and despatched to the relevant function,
		which is reponsible for returning a
		<classname>xmlrpcresp</classname>
		object, which gets
		serialized back to the caller.  See server.php in this distribution for
		examples of how to do this.
	  </para>
	  <para>Here is a more detailed look at what the handler function
		<function>foo</function> may do:</para>
	    <programlisting>

  function foo ($params) {
        global $xmlrpcerruser; // import user errcode value

        // $params is an Array of xmlrpcval objects

        if ($err) {
          // this is an error condition
          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
           "There's a problem, Captain");
        } else {
          // this is a successful value being returned
          return new xmlrpcresp(new xmlrpcval("All's fine!", "string"));
        }
  }
		</programlisting>
			<sect2>
				<title>The dispatch map</title>
				<para>The first argument to the
					<function>xmlrpc_server</function> constructor is an array,
					called the <emphasis>dispatch map</emphasis>.  In this array is the
					information the server needs to service the XML-RPC methods
					you define.</para>
				<para>
					The dispatch map takes the form of an associative array of
					associative arrays: the outer array has one entry for each
					method, the key being the method name. The corresponding value 
					is another associative array, which can have the following members:
				</para>
				<itemizedlist>
					<listitem>
						<para><function>function</function> - this entry is
									mandatory. It must be a name of a function in the
									global scope which services the XML-RPC method.</para>
					</listitem>
					<listitem>
						<para><function>signature</function> - this entry is an
							array containg the possible signatures (see <xref
								 linkend="signatures">) for the method. If
							this entry is present then the server will check that the
							correct number and type of parameters have been sent for
							this method before dispatching it.
						</para>
					</listitem>
					<listitem>
						<para>
							<function>docstring</function> - this entry is a string
							containing documentation for the method.  The
							documentation may contain HTML markup.
							</para>
					</listitem>
				</itemizedlist>
				<para>Look at the <filename>server.php</filename> example in the 
					distribution to see what a dispatch map looks like.</para>
			</sect2>
			<sect2 id="signatures" xreflabel="Signatures"><title>Method signatures</title>
				<para>A signature is a description of a method's return type and 
					its parameter types.  A method may have more than one
					signature.</para>
				<para>Within a server's dispatch map, each method has an array
					of possible signatures. Each signature is an array of
					types. The first entry is the return type. For instance, the
					method <programlisting>
string examples.getStateName(int)
</programlisting> has the signature 
<programlisting>
array($xmlrpcString, $xmlrpcInt)
</programlisting> and, assuming that it the only possible signature for
					the method, might be used like this in server creation:
<programlisting>
$findstate_sig=array(array($xmlrpcString, $xmlrpcInt));

$findstate_doc='When passed an integer between 1 and 51 returns the
name of a US state, where the integer is the index of that state name
in an alphabetic order.';

$s=new xmlrpc_server( array( "examples.getStateName" =&gt; 
						array("function" =&gt; "findstate",
						"signature" =&gt; $findstate_sig,
						"docstring" =&gt; $findstate_doc)));
</programlisting>

				</para>
				<para>For convenience the strings representing the XML-RPC types 
					have been encoded as global variables:<programlisting>
$xmlrpcI4="i4";
$xmlrpcInt="int";
$xmlrpcBoolean="boolean";
$xmlrpcDouble="double";
$xmlrpcString="string";
$xmlrpcDateTime="dateTime.iso8601";
$xmlrpcBase64="base64";
$xmlrpcArray="array";
$xmlrpcStruct="struct";
</programlisting></para>
			</sect2>
			<sect2>
				<title>Delaying the server response</title>
				<para>You may want to construct the server, but for some reason
					not fulfill the request immediately (security verification, for 
				instance). If you pass the constructor a second argument of
					<literal>0</literal> this will have the desired effect. You
					can then use the <function>service()</function> method of the
					server class to service the request. For example:</para>
				<programlisting>
$s=new xmlrpc_server($myDispMap, 0);

// ... some code that does other stuff here

$s->service();
</programlisting>
			</sect2>
	  <sect2>
		<title>Fault reporting</title>
		<para>Fault codes for your servers should start at the
		  value indicated by
		  the global <literal>$xmlrpcerruser</literal> + 1.</para>
		<para>Standard errors returned by the server include:</para>
		<variablelist>
		  <varlistentry>
			<term><literal>1</literal> <phrase>Unknown method</phrase></term>
			<listitem>
			  <para>Returned if the server was asked to dispatch a
				method it didn't know about</para>
			</listitem>
		  </varlistentry>
		  <varlistentry>
			<term><literal>2</literal> <phrase>Invalid return payload</phrase></term>
			<listitem>
			  <para>This error is actually generated by the client, not
				server, code, but signifies that a server returned
				something it couldn't understand.</para>
			</listitem>
		  </varlistentry>
					<varlistentry>
			<term><literal>3</literal> <phrase>Incorrect parameters</phrase></term>
			<listitem>
			  <para>This error is generated when the server has signature(s)
								defined for a method, and the parameters passed by the
								client do not match any of signatures.</para>
			</listitem>
		  </varlistentry>
										<varlistentry>
			<term><literal>4</literal> <phrase>Can't introspect: method unknown</phrase></term>
			<listitem>
			  <para>This error is generated by the builtin
								<function>system.*</function> methods when any kind of
								introspection is attempted on a method undefined by the
								server.</para>
			</listitem>
		  </varlistentry>
<varlistentry>
			<term><literal>5</literal> <phrase>Didn't receive 200 OK from remote server</phrase></term>
			<listitem>
			  <para>This error is generated by the client when a remote server
								doesn't return HTTP/1.1 200 OK in response to a
								request. A more detailed error report is added onto the
								end of the phrase above.</para>
			</listitem>
		  </varlistentry>
					
		  <varlistentry>
			<term><literal>100-</literal> <phrase>XML parse errors</phrase></term>
			<listitem>
			  <para>Returns 100 plus the XML parser error code for the
				fault that occurred.  The
				<function>faultString</function> returned explains where 
			  the parse error was in the incoming XML stream.</para>
			</listitem>
		  </varlistentry>
		</variablelist>
	  </sect2>
	</sect1>
	</chapter>
	
	<chapter id="helpers">
		<title>Helper functions</title>
		<para>XML-RPC for PHP contains some helper functions which you can
			use to make processing of XML-RPC requests easier.</para>
		<sect1>
			<title>Date functions</title>
			<para>The XML-RPC specification has this to say on dates:</para>
			<blockquote>
				<para>Don't assume a timezone. It should be specified by the server in its
                 documentation what assumptions it makes about timezones. </para>
			</blockquote>
			<para>Unfortunately, this means that date processing isn't
				straightforward. Although XML-RPC uses ISO 8601 format dates, it
				doesn't use the timezone specifier.</para>
			<para>We strongly recommend that in every case where you pass
				dates in XML-RPC calls, you use UTC (GMT) as your timezone. Most computer
				languages include routines for handling GMT times natively, and
				you won't have to translate between timezones.</para>
			<para>For more information about dates, see <ulink
																												 url="http://www.uic.edu/year2000/datefmt.html">ISO 8601: The Right Format for Dates</ulink>, which has a handy link to a PDF of the ISO 8601 specification. Note that XML-RPC uses exactly one of the available representations: CCYYMMDDTHH:MM:SS.</para>

			<sect2 id="iso8601encode" xreflabel="iso8601_encode()">
				<title>iso8601_encode</title>
				<funcsynopsis>
					<funcprototype>
						<funcdef>$isoString=iso8601_encode</funcdef>
						<paramdef><parameter>$time_t</parameter><parameter>$utc=0</parameter></paramdef>
					</funcprototype>
				</funcsynopsis>
				<para>Returns an ISO 8601 formatted date generated from the
					UNIX timestamp <parameter>$time_t</parameter>, as returned by
					the PHP function <function>time()</function>. </para>
				<para>The argument <parameter>$utc</parameter> can be omitted,
					in which case it defaults to <literal>0</literal>. If it is
					set to <literal>1</literal>, then the function corrects the
					time passed in for UTC. Example: if you're in the GMT-6:00
					timezone and set <parameter>$utc</parameter>, you will receive
					a date representation six hours ahead of your local
					time.</para>
				<para>The included demo program <filename>vardemo.php</filename>
					includes a demonstration of this function.</para>
			</sect2>
			<sect2 id="iso8601decode" xreflabel="iso8601_decode()">
				<title>iso8601_decode</title>
					<funcsynopsis>
					<funcprototype>
						<funcdef>$time_t=iso8601_decode</funcdef>
						<paramdef><parameter>$isoString</parameter><parameter>$utc=0</parameter></paramdef>
					</funcprototype>
				</funcsynopsis>
				<para>Returns a UNIX timestamp from an ISO 8601 encoded time and
					date string passed in. If <parameter>$utc</parameter> is
					<literal>1</literal> then <parameter>$isoString</parameter> is
					assumed to be in the UTC timezone, and thus the
					<parameter>$time_t</parameter> result is also UTC: otherwise,
					the timezone is assumed to be your local timezone and you receive a local timestamp.</para>
			</sect2>
		</sect1>

		<sect1 id="arrayuse">
			<title>Easy use with PHP arrays</title>
			<para>Dan Libby was kind enough to contribute two helper functions
			that make it easier to translate to and from PHP arrays. This
				makes it easier to deal with complex structures. At the moment
				support is limited to <type>int</type>, <type>double</type>,
				<type>string</type>, <type>array</type> and <type>struct</type>
				datatypes; note also that all PHP arrays are encoded as structs
				due to PHP not being able to tell the difference between a hash
				and a linear array.</para>
			<para>These functions reside in <filename>xmlrpc.inc</filename>.</para>
			<sect2 id="xmlrpcdecode">
				<title>xmlrpc_decode</title>
				<funcsynopsis>
					<funcprototype>
						<funcdef>$arr=xmlrpc_decode</funcdef>
						<paramdef><parameter>$xmlrpc_val</parameter></paramdef>
					</funcprototype>
				</funcsynopsis>
				<para>
					Returns a PHP array stuffed with the values found in the
					<type>xmlrpcval</type> <parameter>$xmlrpc_val</parameter>,
					translated into native PHP types.
				</para>
			</sect2>
			<sect2 id="xmlrpcencode">
				<title>xmlrpc_encode</title>
				<funcsynopsis>
					<funcprototype>
						<funcdef>$xmlrpc_val=xmlrpc_encode</funcdef>
						<paramdef><parameter>$phpval</parameter></paramdef>
					</funcprototype>
				</funcsynopsis>
				<para>
					Returns an <type>xmlrpcval</type> populated with the PHP
					values in <parameter>$phpval</parameter>. Works recursively on
					arrays and structs. Note that there's no support for non-base
					types like base-64 values or date-times.
				</para>
			</sect2>
		</sect1>

		<sect1 id="debugging">
			<title>Debugging aids</title>
			<sect2>
				<title>xmlrpc_debugmsg</title>
					<funcsynopsis>
					<funcprototype>
						<funcdef>xmlrpc_debugmsg</funcdef>
						<paramdef><parameter>$debugstring</parameter></paramdef>
					</funcprototype>
				</funcsynopsis>
				<para>Sends the contents of <parameter>$debugstring</parameter>
					in XML comments in the server return payload. If a PHP client
					has debugging turned on, the user will be able to see server
					debug information.</para>
				<para>Use this function in your methods so you can pass back
					diagnostic information. It is only available from
					<filename>xmlrpcs.inc</filename>.</para>
			</sect2>
		</sect1>

	</chapter>

	<chapter id="reserved" xreflabel="Reserved methods">
		<title>Reserved methods</title>
		<para>In order to extend the functionality offered by XML-RPC
			servers without impacting on the protocol, I've included
			experimental support in this release for reserved methods.</para>
		<para>All methods starting with <function>system.</function> are
			considered reserved by the server. PHP for XML-RPC itself provides 
			three special methods, detailed in this chapter.</para>
		<sect1>
			<title>system.listMethods</title>
			<para>This method may be used to enumerate the methods implemented 
			by the XML-RPC server.</para>
			<para>The <function>system.listMethods</function> method requires
				no parameters. It returns an array of strings, each of which is
				the name of a method implemented by the server.</para>
		</sect1>
		<sect1 id="sysmethodsig">
			<title>system.methodSignature</title>
			<para>This method takes one parameter, the name of a method
				implemented by the XML-RPC server.</para>
			<para>It returns an array of possible signatures for this
				method. A signature is an array of types. The first of these
				types is the return type of the method, the rest are parameters.</para>
			<para>Multiple signatures (ie. overloading) are permitted: this is 
				the reason that an array of signatures are returned by this
				method.</para>
			<para>Signatures themselves are restricted to the top level
				parameters expected by a method. For instance if a method
				expects one array of structs as a parameter, and it returns a
				string, its signature is	simply "string, array". If it expects
				three integers, its signature is	"string, int, int,
				int".</para>
			<para>
				If no signature is defined for the method, a none-array value is
				returned. Therefore this is the way to test for a non-signature, 
				if <parameter>$resp</parameter> below is the response object
				from a method call to <function>system.methodSignature</function>:
			</para>
			
			<programlisting>
$v=$resp->value();
if ($v->kindOf()!="array") {
  // then the method did not have a signature defined
}
			</programlisting>
			<para>
				See the <filename>introspect.php</filename> demo included in
				this distribution for an example of using this method.
			</para>
		</sect1>
		<sect1 id="sysmethhelp">
			<title>system.methodHelp</title>
			<para>This method takes one parameter, the name of a method
				implemented by the XML-RPC server.</para>
			<para>
				It returns a documentation string describing the use of that
				method. If no such string is available, an empty string is returned.
			</para>
			<para>
				The documentation string may contain HTML markup.
			</para>
		</sect1>
	</chapter>


  <chapter id="examples" xreflabel="Examples">
	<title>Examples</title>
	<para>The best examples are to be found in the sample files
	  included with the distribution.  Some are included here.</para>
	<sect1 id="statename">
	  <title>XML-RPC client: state name query</title>
	  <para>Code to get the corresponding
		state name from a number (1-50) from Dave Winer's server</para>
	  <programlisting>
  $f=new xmlrpcmsg('examples.getStateName',
				   array(new xmlrpcval($HTTP_POST_VARS["stateno"], "int")));
  $c=new xmlrpc_client("/RPC2", "betty.userland.com", 80);
  $r=$c->send($f);
  $v=$r->value();
  if (!$r->faultCode()) {
      print "State number ". $HTTP_POST_VARS["stateno"] . " is " .
      $v->scalarval() . "&lt;BR>";
      print "&lt;HR>I got this value back&lt;BR>&lt;PRE>" .
      htmlentities($r->serialize()). "&lt;/PRE>&lt;HR>\n";
  } else {
      print "Fault: ";
      print "Code: " . $r->faultCode() . 
            " Reason '" .$r->faultString()."'&lt;BR>";
  }
		</programlisting>
	</sect1>
  </chapter>
</book>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
sgml-namecase-general:t
sgml-general-insert-case:lower
End:
-->
