<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.soap.server">
    <title>Zend_Soap_Server</title>

    <para>
        <classname>Zend_Soap_Server</classname> class is intended to simplify Web Services server
        part development for <acronym>PHP</acronym> programmers.
    </para>

    <para>
        It may be used in WSDL or non-WSDL mode, and using classes or functions to define Web
        Service <acronym>API</acronym>.
    </para>

    <para>
        When <classname>Zend_Soap_Server</classname> component works in the WSDL mode, it uses
        already prepared WSDL document to define server object behavior and transport layer options.
    </para>

    <para>
        WSDL document may be auto-generated with functionality provided by <link
            linkend="zend.soap.autodiscovery.introduction">Zend_Soap_AutoDiscovery component</link>
        or should be constructed manually using <link
            linkend="zend.soap.wsdl"><classname>Zend_Soap_Wsdl</classname> class</link> or any other
        <acronym>XML</acronym> generating tool.
    </para>

    <para>
        If the non-WSDL mode is used, then all protocol options have to be set using options
        mechanism.
    </para>

    <sect2 id="zend.soap.server.constructor">
        <title>Zend_Soap_Server constructor</title>

        <para>
            <classname>Zend_Soap_Server</classname> constructor should be used a bit differently for
            WSDL and non-WSDL modes.
        </para>

        <sect3 id="zend.soap.server.constructor.wsdl_mode">
            <title>Zend_Soap_Server constructor for the WSDL mode</title>

            <para>
                <classname>Zend_Soap_Server</classname> constructor takes two optional parameters
                when it works in WSDL mode:

                <orderedlist>
                    <listitem>
                        <para>
                            <varname>$wsdl</varname>, which is an <acronym>URI</acronym> of a WSDL
                            file

                            <footnote>
                                <para>
                                    May be set later using <methodname>setWsdl($wsdl)</methodname>
                                    method.
                                </para>
                            </footnote>.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <varname>$options</varname> - options to create <acronym>SOAP</acronym>
                            server object

                            <footnote>
                                <para>
                                    Options may be set later using
                                    <methodname>setOptions($options)</methodname> method.
                                </para>
                            </footnote>.
                        </para>

                        <para>
                            The following options are recognized in the WSDL mode:

                            <itemizedlist>
                                <listitem>
                                    <para>
                                        'soap_version' ('soapVersion') - soap version to use
                                        (SOAP_1_1 or <acronym>SOAP</acronym>_1_2).
                                    </para>
                                </listitem>

                                <listitem>
                                    <para>
                                        'actor' - the actor <acronym>URI</acronym> for the server.
                                    </para>
                                </listitem>

                                <listitem>
                                    <para>
                                        'classmap' ('classMap') which can be used to map some WSDL
                                        types to <acronym>PHP</acronym> classes.
                                    </para>

                                    <para>
                                        The option must be an array with WSDL types as keys and
                                        names of <acronym>PHP</acronym> classes as values.
                                    </para>
                                </listitem>

                                <listitem>
                                    <para>
                                        'encoding' - internal character encoding (UTF-8 is always
                                        used as an external encoding).
                                    </para>
                                </listitem>

                                <listitem>
                                    <para>
                                        'wsdl' which is equivalent to
                                        <methodname>setWsdl($wsdlValue)</methodname> call.
                                    </para>
                                </listitem>
                            </itemizedlist>
                        </para>
                    </listitem>
                </orderedlist>
            </para>
        </sect3>

        <sect3 id="zend.soap.server.wsdl_mode">
            <title>Zend_Soap_Server constructor for the non-WSDL mode</title>

            <para>
                The first constructor parameter <emphasis>must</emphasis> be set to
                <constant>NULL</constant> if you plan to use <classname>Zend_Soap_Server</classname>
                functionality in non-WSDL mode.
            </para>

            <para>
                You also have to set 'uri' option in this case (see below).
            </para>

            <para>
                The second constructor parameter (<varname>$options</varname>) is an array with
                options to create <acronym>SOAP</acronym> server object

                <footnote>
                    <para>
                        Options may be set later using <methodname>setOptions($options)</methodname>
                        method.
                    </para>
                </footnote>.
            </para>

            <para>
                The following options are recognized in the non-WSDL mode:

                <itemizedlist>
                    <listitem>
                        <para>
                            'soap_version' ('soapVersion') - soap version to use (SOAP_1_1 or
                            <acronym>SOAP</acronym>_1_2).
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            'actor' - the actor <acronym>URI</acronym> for the server.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            'classmap' ('classMap') which can be used to map some WSDL types to
                            <acronym>PHP</acronym> classes.
                        </para>

                        <para>
                            The option must be an array with WSDL types as keys and names of
                            <acronym>PHP</acronym> classes as values.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            'encoding' - internal character encoding (UTF-8 is always used as an
                            external encoding).
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            'uri' (required) - <acronym>URI</acronym> namespace for
                            <acronym>SOAP</acronym> server.
                        </para>
                    </listitem>
                </itemizedlist>
            </para>
        </sect3>
    </sect2>

    <sect2 id="zend.soap.server.api_define_methods">
        <title>Methods to define Web Service API</title>

        <para>
            There are two ways to define Web Service <acronym>API</acronym> when your want to give
            access to your <acronym>PHP</acronym> code through <acronym>SOAP</acronym>.
        </para>

        <para>
            The first one is to attach some class to the <classname>Zend_Soap_Server</classname>
            object which has to completely describe Web Service <acronym>API</acronym>:
        </para>

        <programlisting language="php"><![CDATA[
...
class MyClass {
    /**
     * This method takes ...
     *
     * @param integer $inputParam
     * @return string
     */
    public function method1($inputParam) {
        ...
    }

    /**
     * This method takes ...
     *
     * @param integer $inputParam1
     * @param string  $inputParam2
     * @return float
     */
    public function method2($inputParam1, $inputParam2) {
        ...
    }

    ...
}
...
$server = new Zend_Soap_Server(null, $options);
// Bind Class to Soap Server
$server->setClass('MyClass');
// Bind already initialized object to Soap Server
$server->setObject(new MyClass());
...
$server->handle();
]]></programlisting>

        <note>
            <title>Important!</title>

            <para>
                You should completely describe each method using method docblock if you plan to
                use autodiscover functionality to prepare corresponding Web Service WSDL.
            </para>
        </note>

        <para>
            The second method of defining Web Service <acronym>API</acronym> is using set of
            functions and <methodname>addFunction()</methodname> or
            <methodname>loadFunctions()</methodname> methods:
        </para>

        <programlisting language="php"><![CDATA[
...
/**
 * This function ...
 *
 * @param integer $inputParam
 * @return string
 */
function function1($inputParam) {
    ...
}

/**
 * This function ...
 *
 * @param integer $inputParam1
 * @param string  $inputParam2
 * @return float
 */
function function2($inputParam1, $inputParam2) {
    ...
}
...
$server = new Zend_Soap_Server(null, $options);
$server->addFunction('function1');
$server->addFunction('function2');
...
$server->handle();
]]></programlisting>
    </sect2>

    <sect2 id="zend.soap.server.request_response">
        <title>Request and response objects handling</title>

        <note>
            <title>Advanced</title>

            <para>
                This section describes advanced request/response processing options and may be
                skipped.
            </para>
        </note>

        <para>
            <classname>Zend_Soap_Server</classname> component performs request/response processing
            automatically, but allows to catch it and do some pre- and post-processing.
        </para>

        <sect3 id="zend.soap.server.request_response.request">
            <title>Request processing</title>

            <para>
                <methodname>Zend_Soap_Server::handle()</methodname> method takes request from the
                standard input stream ('php://input'). It may be overridden either by supplying
                optional parameter to the <methodname>handle()</methodname> method or by setting
                request using <methodname>setRequest()</methodname> method:
            </para>

            <programlisting language="php"><![CDATA[
...
$server = new Zend_Soap_Server(...);
...
// Set request using optional $request parameter
$server->handle($request);
...
// Set request using setRequest() method
$server->setRequest();
$server->handle();
]]></programlisting>

            <para>
                Request object may be represented using any of the following:

                <itemizedlist>
                    <listitem>
                        <para>
                            DOMDocument (casted to <acronym>XML</acronym>)
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            DOMNode (owner document is grabbed and casted to <acronym>XML</acronym>)
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            SimpleXMLElement (casted to <acronym>XML</acronym>)
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            stdClass (__toString() is called and verified to be valid
                            <acronym>XML</acronym>)
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            string (verified to be valid <acronym>XML</acronym>)
                        </para>
                    </listitem>
                </itemizedlist>
            </para>

            <para>
                Last processed request may be retrieved using
                <methodname>getLastRequest()</methodname> method as an <acronym>XML</acronym>
                string:
            </para>

            <programlisting language="php"><![CDATA[
...
$server = new Zend_Soap_Server(...);
...
$server->handle();
$request = $server->getLastRequest();
]]></programlisting>
        </sect3>

        <sect3 id="zend.soap.server.request_response.response">
            <title>Response pre-processing</title>

            <para>
                <methodname>Zend_Soap_Server::handle()</methodname> method automatically emits
                generated response to the output stream. It may be blocked using
                <methodname>setReturnResponse()</methodname> with <constant>TRUE</constant> or
                <constant>FALSE</constant> as a parameter

                <footnote>
                    <para>
                        Current state of the Return Response flag may be requested with
                        <methodname>setReturnResponse()</methodname> method.
                    </para>
                </footnote>.

                Generated response is returned by <methodname>handle()</methodname> method in this
                case.
            </para>

            <programlisting language="php"><![CDATA[
...
$server = new Zend_Soap_Server(...);
...
// Get a response as a return value of handle() method
// instead of emitting it to the standard output
$server->setReturnResponse(true);
...
$response = $server->handle();
...
]]></programlisting>

            <para>
                Last response may be also retrieved by <methodname>getLastResponse()</methodname>
                method for some post-processing:
            </para>

            <programlisting language="php"><![CDATA[
...
$server = new Zend_Soap_Server(...);
...
$server->handle();
$response = $server->getLastResponse();
...
]]></programlisting>
        </sect3>
    </sect2>
</sect1>
