| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: 22743 -->
- <sect1 id="zend.http.client.adapters">
- <title>Zend_Http_Client - Verbindungsadapter</title>
- <sect2 id="zend.http.client.adapters.overview">
- <title>Verbindungsadapter</title>
- <para>
- <classname>Zend_Http_Client</classname> basiert auf einem Design mit
- Verbindungsadaptern. Der Verbindungsadapter ist das Objekt, welches für die Ausführung
- der aktuellen Verbindung zum Server sowie für das Schreiben der Anfragen und Lesen von
- Antworten verantwortlich ist. Dieser Verbindungsadapter kann ersetzt werden und man kann
- den Standard-Verbindungsadapter durch seinen eigenen Adapter erweitern, um ihn mit
- demselben Interface auf seine eigenen Bedürfnisse anzupassen, ohne dass man die gesamte
- <acronym>HTTP</acronym> Client-Klasse erweitern oder ersetzen muss.
- </para>
- <para>
- Derzeit stellt die <classname>Zend_Http_Client</classname>-Klasse vier eingebaute
- Verbindungsadapter bereit:
- <itemizedlist>
- <listitem>
- <para>
- <classname>Zend_Http_Client_Adapter_Socket</classname> (Standard)
- </para>
- </listitem>
- <listitem>
- <para><classname>Zend_Http_Client_Adapter_Proxy</classname></para>
- </listitem>
- <listitem>
- <para><classname>Zend_Http_Client_Adapter_Curl</classname></para>
- </listitem>
- <listitem>
- <para><classname>Zend_Http_Client_Adapter_Test</classname></para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Der Verbindungsadapter für das <classname>Zend_Http_Client</classname>-Objekt wird durch
- Verwendung der Konfigurationsoption 'adapter' gesetzt. Beim Instanzieren des Client
- Objektes kann man die Konfigurationsoption 'adapter' mit einem String setzen, der den
- Adapternamen (z.B. 'Zend_Http_Client_Adapter_Socket') enthält, oder mit einer Variablen,
- die ein Adapterobjekt (z.B. <command>new Zend_Http_Client_Adapter_Test</command>)
- enthält. Man kann den Adapter auch danach setzen, indem man die
- <classname>Zend_Http_Client->setConfig()</classname> Methode verwendet.
- </para>
- </sect2>
- <sect2 id="zend.http.client.adapters.socket">
- <title>Der Socket-Adapter</title>
- <para>
- Der Standard-Adapter ist <classname>Zend_Http_Client_Adapter_Socket</classname>.
- Dieser wird benutzt, wenn kein anderer angegeben wird. Der Socket-Adapter benutzt die
- native <acronym>PHP</acronym>-Funktion fsockopen(), um die Verbindung aufzubauen, dafür
- werden keine besonderen Erweiterungen oder Einstellungen benötigt.
- </para>
- <para>
- Der Socket-Adapter erlaubt verschiedene zusätzliche Konfigurationsoptionen, die gesetzt
- werden können durch Verwendung von <classname>Zend_Http_Client->setConfig()</classname>
- oder deren Übergabe an den Konstruktor des Clients.
- <table id="zend.http.client.adapter.socket.configuration.table">
- <title>Zend_Http_Client_Adapter_Socket Konfigurationsparameter</title>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Parameter</entry>
- <entry>Beschreibung</entry>
- <entry>Erwarteter Typ</entry>
- <entry>Standardwert</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>persistent</entry>
- <entry>
- Ob eine persistente <acronym>TCP</acronym>-Verbindung verwendet
- werden soll oder nicht
- </entry>
- <entry>boolean</entry>
- <entry><constant>FALSE</constant></entry>
- </row>
- <row>
- <entry>ssltransport</entry>
- <entry>Der Transport-Layer für SSL (z.B. 'sslv2', 'tls')</entry>
- <entry>string</entry>
- <entry>ssl</entry>
- </row>
- <row>
- <entry>sslcert</entry>
- <entry>
- Pfad zu einem <acronym>PEM</acronym> verschlüsselten
- <acronym>SSL</acronym>-Zertifikat
- </entry>
- <entry>string</entry>
- <entry><constant>NULL</constant></entry>
- </row>
- <row>
- <entry>sslpassphrase</entry>
- <entry>
- Die PassPhrase für die <acronym>SSL</acronym> zertifizierte Datei
- </entry>
- <entry>string</entry>
- <entry><constant>NULL</constant></entry>
- </row>
- <row>
- <entry>sslusecontext</entry>
- <entry>
- Aktiviert, dass Proxy Verbindungen SSL verwenden sogar wenn die Proxy
- Verbindung selbst es nicht tut.
- </entry>
- <entry>boolean</entry>
- <entry><constant>FALSE</constant></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <note>
- <title>Persistente TCP Verbindungen</title>
- <para>
- Die Verwendung persistenter <acronym>TCP</acronym>-Verbindungen kann
- <acronym>HTTP</acronym>-Anfragen potentiell schneller machen - aber in den
- meisten Fällen, wird es nur einen kleinen positiven Effekt haben und könnte den
- <acronym>HTTP</acronym>-Server überlasten, zu dem man sich verbindet.
- </para>
- <para>
- Es wird empfohlen persistente <acronym>TCP</acronym>-Verbindungen nur dann zu
- verwenden, wenn man sich zu dem gleichen Server sehr oft verbindet, und man
- sicher ist, dass der Server eine große Anzahl an gleichzeitigen Verbindungen
- behandeln kann. In jedem Fall wird empfohlen, dass der Effekt von persistenten
- Verbindungen auf beiden, der Geschwindigkeit des Clients und dem Serverload
- gemessen wird, bevor diese Option verwendet wird.
- </para>
- <para>
- Zusätzlich, wenn persistente Verbindungen verwendet werden, sollte man
- Keep-Alive <acronym>HTTP</acronym>-Anfragen aktivieren wie im <link
- linkend="zend.http.client.configuration">Abschnitt für Konfiguration</link>
- beschrieben - andernfalls werden persistente Verbindungen nur wenig oder gar
- keinen Effekt haben.
- </para>
- </note>
- <note>
- <title>HTTPS SSL Stream Parameter</title>
- <para>
- <property>ssltransport</property>, <property>sslcert</property> und
- <property>sslpassphrase</property> sind nur relevant wenn
- <acronym>HTTPS</acronym> für die Verbindung verwendet wird.
- </para>
- <para>
- Wärend die Standard <acronym>SSL</acronym>-Einstellungen für die meisten
- Anwendungen funktionieren, kann es notwendig sein diese zu ändern, wenn der
- Server zu dem man sich verbindet ein spezielles Client-Setup benötigt. Wenn dem
- so ist, sollte man das Kapitel über <acronym>SSL</acronym>-Transport-Layer und
- Optionen lesen das <ulink
- url="http://www.php.net/manual/en/transports.php#transports.inet">hier</ulink>
- zu finden ist.
- </para>
- </note>
- </para>
- <example id="zend.http.client.adapters.socket.example-1">
- <title>Den Stream-Typen für eine HTTPS-Verbindung einstellen</title>
- <programlisting language="php"><![CDATA[
- // Konfigurationsparameter setzen
- $config = array(
- 'adapter' => 'Zend_Http_Client_Adapter_Socket',
- 'ssltransport' => 'tls'
- );
- // Client-Instanz erzeugen
- $client = new Zend_Http_Client('https://www.example.com', $config);
- // Jetzt wird der Request über eine verschlüsselte Verbindung verschickt
- $response = $client->request();
- ]]></programlisting>
- </example>
- <para>
- Ein ähnliches Ergebnis erzielt man mit folgendem Code:
- </para>
- <para>
- <methodname>fsockopen('tls://www.example.com', 443)</methodname>
- </para>
- <sect3 id="zend.http.client.adapters.socket.streamcontext">
- <title>Anpassen und Zugreifen auf den Socket Adapter Stream Kontext</title>
- <para>
- Beginnend mit Zend Framework 1.9 bietet
- <classname>Zend_Http_Client_Adapter_Socket</classname> direkten Zugriff auf den
- darunterliegenden <ulink
- url="http://php.net/manual/de/stream.contexts.php">Stream Kontext</ulink> der
- für die Verbindung zum entfernten Server verwendet wird. Das erlaubt es
- Benutzern spezielle Optionen und Parameter an den <acronym>TCP</acronym>-Stream zu
- übergeben und an den <acronym>SSL</acronym>-Wrapper im Falle einer
- <acronym>HTTPS</acronym>-Verbindung.
- </para>
- <para>
- Man kann auf den Stream Kontext zugreifen indem die folgenden Methoden von
- <classname>Zend_Http_Client_Adapter_Socket</classname> verwendet werden:
- <itemizedlist>
- <listitem>
- <para>
- <firstterm><methodname>setStreamContext($context)</methodname></firstterm>
- Setzt den Stream Kontext der vom Adapter verwendet werden soll.
- Akzeptiert entweder eine Stream Kontext Ressource von durch die
- Verwendung der <acronym>PHP</acronym> Funktion <ulink
- url="http://php.net/manual/de/function.stream-context-create.php"><methodname>stream_context_create()</methodname></ulink>
- erstellt wurde, oder ein Array von Stream Kontext Optionen im
- gleichen Format wie es an diese Funktion übergeben wird. Wenn ein
- Array übergeben wird, dann wird ein neuer Stream Kontext mit Hilfe
- dieser Optionen erstellt, und gesetzt.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm><methodname>getStreamContext()</methodname></firstterm>
- Empfängt den Stream Kontext des Adapters. Wenn kein Stream Kontext
- gesetzt ist, wird ein standardmäßiger Stream Kontext erstellt und
- zurückgegeben. Man kann anschließend den Wert verschiedener Kontext
- Optionen setzen oder empfangen indem die regulären
- <acronym>PHP</acronym> Stream Kontext Funktionen verwendet werden.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <example id="zend.http.client.adapters.socket.streamcontext.example-1">
- <title>Setzen von Stream Kontext Optionen für den Socket Adapter</title>
- <programlisting language="php"><![CDATA[
- // Array von Optionen
- $options = array(
- 'socket' => array(
- // Bindet die lokale Socket Seite an ein spezifisches Interface
- 'bindto' => '10.1.2.3:50505'
- ),
- 'ssl' => array(
- // Prüft das Server Side Zertifikat, akzeptiert keine
- // ungültigen oder selbst-signierten SSL Zertifikate
- 'verify_peer' => true,
- 'allow_self_signed' => false,
- // Holt das Peer Zertifikat
- 'capture_peer_cert' => true
- )
- );
- // Erstellt ein Adapter Objekt und hängt es an den HTTP Client
- $adapter = new Zend_Http_Client_Adapter_Socket();
- $client = new Zend_Http_Client();
- $client->setAdapter($adapter);
- // Methode 1: Ein Options Array an setStreamContext() übergeben
- $adapter->setStreamContext($options);
- // Methode 2: Einen Stream Kontext erstellen und an setStreamContext() übergeben
- $context = stream_context_create($options);
- $adapter->setStreamContext($context);
- // Methode 3: Den Standardmäßigen Stream Kontext holen und Optionen auf Ihm setzen
- $context = $adapter->getStreamContext();
- stream_context_set_option($context, $options);
- // Jetzt die Anfrage durchführen
- $response = $client->request();
- // Wenn alles gut ging, kann auf den Kontext jetzt zugegriffen werden
- $opts = stream_context_get_options($adapter->getStreamContext());
- echo $opts['ssl']['peer_certificate'];
- ]]></programlisting>
- </example>
- <note>
- <para>
- Es ist zu beachten das alle Stream Kontext Optionen gesetzt sein müssen, bevor
- der Adapter Anfragen durchführt. Wenn kein Kontext gesetzt ist bevor
- <acronym>HTTP</acronym>-Anfragen mit dem Socket Adapter durchgeführt werden,
- wird ein standardmäßiger Stream Kontext erstellt. Auf diese Kontext Ressource
- kann zugegriffen werden, nachdem Anfragen durchgeführt werden, indem die
- <methodname>getStreamContext()</methodname> Methode verwendet wird.
- </para>
- </note>
- </sect3>
- </sect2>
- <sect2 id="zend.http.client.adapters.proxy">
- <title>Der Proxy Adapter</title>
- <para>
- Der Proxy Adapter <classname>Zend_Http_Client_Adapter_Proxy</classname> verhält sich wie
- der Standard-<classname>Zend_Http_Client_Adapter_Socket</classname>, mit dem
- Unterschied, dass die Verbindung über einen <acronym>HTTP</acronym>-Proxy-Server
- aufgebaut wird statt den Server direkt zu kontaktieren. Das erlaubt die Verwendung von
- <classname>Zend_Http_Client</classname> hinter Proxy Servern - was manchmal wegen der
- Sicherheit und Geschwindigkeit notwendig ist.
- </para>
- <para>
- Der Proxy Adapter benötigt zusätzliche Konfigurationsvariablen, die
- nachfolgend gelistet sind.
- <table id="zend.http.client.adapters.proxy.table">
- <title>Zend_Http_Client Konfigurationsparameter</title>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Parameter</entry>
- <entry>Beschreibung</entry>
- <entry>Datentyp</entry>
- <entry>Beispielwert</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>proxy_host</entry>
- <entry>Proxy Server Adresse</entry>
- <entry>string</entry>
- <entry>zum Beispiel 'proxy.myhost.com' oder '10.1.2.3'</entry>
- </row>
- <row>
- <entry>proxy_port</entry>
- <entry><acronym>TCP</acronym> Port des Proxy-Servers</entry>
- <entry>integer</entry>
- <entry>8080 (Standardwert) oder 81</entry>
- </row>
- <row>
- <entry>proxy_user</entry>
- <entry>Benutzername für die Proxynutzung, falls nötig</entry>
- <entry>string</entry>
- <entry>'wulli' oder '' für keinen Namen (Standardwert)</entry>
- </row>
- <row>
- <entry>proxy_pass</entry>
- <entry>Passwort für die Proxynutzung, falls nötig</entry>
- <entry>string</entry>
- <entry>'geheim' oder '' für kein Passwort (Standardwert)</entry>
- </row>
- <row>
- <entry>proxy_auth</entry>
- <entry>Proxy <acronym>HTTP</acronym> Authentifizierungs-Typ</entry>
- <entry>string</entry>
- <entry>Zend_Http_Client::AUTH_BASIC (Standardwert)</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </para>
- <para>
- proxy_host muss immer gesetzt werden, ansonsten wird der Proxy-Adapter auf
- <classname>Zend_Http_Client_Adapter_Socket</classname> zurückgreifen und keinen Proxy
- Server benutzen. Wird kein Prot mit übergeben, so versucht der Proxy-Adapter sich auf
- den Standardport '8080' zu verbinden.
- </para>
- <para>
- proxy_user und proxy_pass werden nur dann benötigt, wenn der Proxy-Server
- tatsächlich eine Authentifizierung erwartet. Werden diese Parameter mit
- übergeben, setzt der Proxy-Adapter zusätzlich den 'Proxy-Authentication'
- Header bei Anfragen. Wird keine Authentifizierung benötigt, sollten die
- beiden Parameter weggelassen werden.
- </para>
- <para>
- proxy_auth setzt den Authentifizierungs-Typ. Dies ist nur nötig, wenn der
- Proxy-Server eine Authentifizierung erwartet.
- Mögliche Werte entsprechen denen der Zend_Http_Client::setAuth() Methode.
- Zur Zeit wird nur die BASIC-Authentifizierung
- (Zend_Http_Client::AUTH_BASIC) unterstützt.
- </para>
- <example id="zend.http.client.adapters.proxy.example-1">
- <title>Zend_Http_Client hinter einem Proxy-Server nutzen</title>
- <programlisting language="php"><![CDATA[
- // Konfigurationsparameter setzen
- $config = array(
- 'adapter' => 'Zend_Http_Client_Adapter_Proxy',
- 'proxy_host' => 'proxy.int.zend.com',
- 'proxy_port' => 8000,
- 'proxy_user' => 'shahar.e',
- 'proxy_pass' => 'bananashaped'
- );
- // Client-Objekt instanziieren
- $client = new Zend_Http_Client('http://www.example.com', $config);
- // $client kann jetzt wie gewohnt benutzt werden
- ]]></programlisting>
- </example>
- <para>
- Wie vorher erwähnt, nutzt der Proxy-Adapter eine einfache Socket-Verbindung,
- wenn proxy_host nicht gesetzt oder leer gelassen wurde. Dies ermöglicht
- die optionale Nutzung eines Proxy-Servers, abhängig von dem proxy_host Parameter.
- </para>
- <note>
- <para>
- Da der Proxy Adapter von <classname>Zend_Http_Client_Adapter_Socket</classname>
- abgeleitet ist, kann die Stream Kontext Zugriffsmethode verwendet werden
- (siehe <link linkend="zend.http.client.adapters.socket.streamcontext">den Abschnitt
- für Konfiguration</link>) um Stream Kontext Optionen auf Proxy Verbindungen zu
- setzen wie es oben demonstriert wurde.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.http.client.adapters.curl">
- <title>Der cURL Adapter</title>
- <para>
- cURL ist eine Standard <acronym>HTTP</acronym> Client Bibliothek die mit vielen
- Betriebssystemen ausgeliefert wird, und kann in <acronym>PHP</acronym> über die cURL
- Erweiterung verwendet werden. Sie bietet Funktionalitäten für viele spezielle Fälle, die
- für einen <acronym>HTTP</acronym>-Client auftreten können und machen sie zu einer
- perfekten Wahl für einen <acronym>HTTP</acronym>-Adapter. Sie unterstützt sichere
- Verbindungen, Proxies, alle Arten von Authentifizierungsmechanismen und glänzt in
- Anwendungen, die große Dateien zwischen Servern bewegen müssen.
- </para>
- <example id="zend.http.client.adapters.curl.example-1">
- <title>Setzen von cURL Optionen</title>
- <programlisting language="php"><![CDATA[
- $config = array(
- 'adapter' => 'Zend_Http_Client_Adapter_Curl',
- 'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
- );
- $client = new Zend_Http_Client($uri, $config);
- ]]></programlisting>
- </example>
- <para>
- Standardmäßig ist der cURL Adapter so konfiguriert, dass er sich genauso wie der
- Socket Adapter verhält und er akzeptiert auch die gleichen Konfigurationsparameter wie
- die Socket und Proxy Adapter. Man kann die cURL Optionen entweder durch den
- 'curloptions' Schlüssel im Konstruktor des Adapters, oder durch den Aufruf von
- <methodname>setCurlOption($name, $value)</methodname>, verändern. Der
- <varname>$name</varname> Schlüssel entspricht den CURL_* Konstanten der cURL
- Erweiterung. Man kann auf den CURL Handler durch den Aufruf von
- <command>$adapter->getHandle();</command> Zugriff erhalten.
- </para>
- <example id="zend.http.client.adapters.curl.example-2">
- <title>Dateien von Hand übertragen</title>
- <para>
- Man kan cURL verwenden um große Dateien über <acronym>HTTP</acronym> durch einen
- Dateihandle zu übertragen.
- </para>
- <programlisting language="php"><![CDATA[
- $putFileSize = filesize("filepath");
- $putFileHandle = fopen("filepath", "r");
- $adapter = new Zend_Http_Client_Adapter_Curl();
- $client = new Zend_Http_Client();
- $client->setAdapter($adapter);
- $adapter->setConfig(array(
- 'curloptions' => array(
- CURLOPT_INFILE => $putFileHandle,
- CURLOPT_INFILESIZE => $putFileSize
- )
- ));
- $client->request("PUT");
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.http.client.adapters.test">
- <title>Der Test Adapter</title>
- <para>
- Manchmal ist es sehr schwer Code zu testen, der von <acronym>HTTP</acronym>-Verbindungen
- abhängig ist. Zum Beispiel verlangt das Testen einer Applikation, die einen
- <acronym>RSS</acronym>-Feed von einem fremden Server anfordert, eine Netzwerkverbindung,
- die nicht immer verfügbar ist.
- </para>
- <para>
- Aus diesem Grund wird der <classname>Zend_Http_Client_Adapter_Test</classname>-Adapter
- bereit gestellt. Man kann seine eigenen Applikationen schreiben, um
- <classname>Zend_Http_Client</classname> zu verwenden, und nur zu Testzwecken, z.B. in
- der UnitTest-Suite, den Standardadapter durch den Testadapter (ein Mock-Objekt)
- austauschen, um Tests ohne direkte Serverbindungen auszuführen.
- </para>
- <para>
- Der <classname>Zend_Http_Client_Adapter_Test</classname>-Adapter stellt die zusätzliche
- Methode setResponse() bereit. Diese Methode nimmt einen Parameter entgegen, der eine
- <acronym>HTTP</acronym>-Antwort entweder als Text oder als
- <classname>Zend_Http_Response</classname>-Objekt repräsentiert. Einmal eingerichtet,
- wird der Testadapter immer diese Antwort zurückgeben, ohne tatsächlich eine
- <acronym>HTTP</acronym>-Anfrage auszuführen.
- </para>
- <example id="zend.http.client.adapters.test.example-1">
- <title>Testen gegen einen einfachen HTTP Response Stumpf</title>
- <programlisting language="php"><![CDATA[
- // Instanziere einen neuen Adapter und Client
- $adapter = new Zend_Http_Client_Adapter_Test();
- $client = new Zend_Http_Client('http://www.example.com', array(
- 'adapter' => $adapter
- ));
- // Setze die erwartete Antwort
- $adapter->setResponse(
- "HTTP/1.1 200 OK" . "\r\n" .
- "Content-type: text/xml" . "\r\n" .
- "\r\n" .
- '<?xml version="1.0" encoding="UTF-8"?>' .
- '<rss version="2.0" ' .
- ' xmlns:content="http://purl.org/rss/1.0/modules/content/"' .
- ' xmlns:wfw="http://wellformedweb.org/CommentAPI/"' .
- ' xmlns:dc="http://purl.org/dc/elements/1.1/">' .
- ' <channel>' .
- ' <title>Premature Optimization</title>' .
- // und so weiter...
- '</rss>');
- $response = $client->request('GET');
- // .. setze die Verarbeitung von $response fort...
- ]]></programlisting>
- </example>
- <para>
- Das obige Beispiel zeigt, wie man einen <acronym>HTTP</acronym>-Client voreinstellen
- kann, damit er die benötigte Antwort zurückgibt. Danach kann man mit den Testen des
- eigenen Codes weiter machen, ohne von einer Netzwerkverbindung, der Serverantwort, etc.
- abhängig zu sein. In diesem Fall würde der Test mit der Prüfung fortfahren, wie die
- Applikation das <acronym>XML</acronym> aus der Antwort verarbeitet..
- </para>
- <para>
- Manchmal erfordert ein einziger Methoden-Aufruf mehrere <acronym>HTTP</acronym>
- Übertragungen. In diesem Fall ist es nicht möglich, setResponse() alleine zu verwenden
- weil es keine Möglichkeit gibt, die nächste Antwort zu setzen, die das Programm benötigt,
- bevor es zum Aufrufer zurückkommt.
- </para>
- <example id="zend.http.client.adapters.test.example-2">
- <title>Test mit mehreren HTTP-Antworten</title>
- <programlisting language="php"><![CDATA[
- // Instanzen vom Adapter und Client erzeugen
- $adapter = new Zend_Http_Client_Adapter_Test();
- $client = new Zend_Http_Client('http://www.example.com', array(
- 'adapter' => $adapter
- ));
- // mit setResponse() die erste Antwort setzen
- $adapter->setResponse(
- "HTTP/1.1 302 Found" . "\r\n" .
- "Location: /" . "\r\n" .
- "Content-Type: text/html" . "\r\n" .
- "\r\n" .
- '<html>' .
- ' <head><title>Moved</title></head>' .
- ' <body><p>This page has moved.</p></body>' .
- '</html>');
- // mit addResponse() nachfolgende Antworten setzen
- $adapter->addResponse(
- "HTTP/1.1 200 OK" . "\r\n" .
- "Content-Type: text/html" . "\r\n" .
- "\r\n" .
- '<html>' .
- ' <head><title>Meine Haustierseite</title></head>' .
- ' <body><p>...</p></body>' .
- '</html>');
- // Das $client Objekt kann jetzt zu Testzwecken herangezogen werden,
- // indem es wie ein normales Client-Objekt benutzt wird.
- ]]></programlisting>
- </example>
- <para>
- Die Methode setResponse() löscht alle Antworten im Buffer von
- <classname>Zend_Http_Client_Adapter_Test</classname> und setzt die erste Antwort,
- die zurückgegeben wird. Die Methode addResponse() fügt dann weitere Antworten
- sukzessiv hinzu.
- </para>
- <para>
- Die HTTP-Antworten werden in der Reihenfolge zurückgegeben,
- in der sie angelegt worden sind. Gibt es mehr Anfragen als
- Antworten, so wird wieder bei der ersten Antwort angefangen.
- </para>
- <para>
- Das oben angeführte Beispiel kann dazu benutzt werden, um die Reaktion
- der eigenen Anwendung auf einen 302 Redirect (Weiterleitung) zu testen.
- Abhängig von Ihrer Anwendung, kann es gewollt oder nicht gewollt sein,
- dass dem Redirect gefolgt wird. In unserem Beispiel erwarten wir, dass der
- Umleitung gefolgt wird und wir konfigurieren den Test-Adapter um uns zu helfen das
- zu Testen. Die ursprüngliche 302 Antwort wird mit der Methode setResponse() gesetzt
- und die 200 Antwort, welche als nächstes zurückzugeben ist, wird mit der
- Methode addResponse() hinzugefügt. Nachdem der Test-Adapter konfiguriert ist, wird
- der <acronym>HTTP</acronym>-Client, der den Adapter enthält unter test in das eigene
- Objekt injiziert und sein Verhalten getestet.
- </para>
- <para>
- Wenn man will, dass der Adapter auf Wunsch fehlschlägt, kann man
- <methodname>setNextRequestWillFail($flag)</methodname> verwenden. Diese Methode lässt
- den nächsten Aufruf von <methodname>connect()</methodname> eine
- <classname>Zend_Http_Client_Adapter_Exception</classname>-Exception werfen. Das kann
- dann nützlich sein, wenn die eigene Anwendung Inhalte von einer externen Seite cacht
- (im Falle, dass die Seite ausfällt) und man dieses Feature testen will.
- </para>
- <example id="zend.http.client.adapters.test.example-3">
- <title>Erzwingen das der Adapter fehlschlägt</title>
- <programlisting language="php"><![CDATA[
- // Einen neuen Adapter und Client instanziieren
- $adapter = new Zend_Http_Client_Adapter_Test();
- $client = new Zend_Http_Client('http://www.example.com', array(
- 'adapter' => $adapter
- ));
- // Erzwingen, dass die nächste Anfrage mit einer Exception fehlschlägt
- $adapter->setNextRequestWillFail(true);
- try {
- // Dieser Aufruf führt zu einer Zend_Http_Client_Adapter_Exception
- $client->request();
- } catch (Zend_Http_Client_Adapter_Exception $e) {
- // ...
- }
- // Weitere Aufrufe arbeiten wie erwartet bis man setNextRequestWillFail(true)
- // erneut aufruft
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.http.client.adapters.extending">
- <title>Einen eigenen Adapter erstellen</title>
- <para>
- Es ist möglich eigene Verbindungs-Adapter zu schreiben, die spezielle
- Bedürfnisse, wie persistente Sockets oder gecachte Verbindungen abdecken.
- Diese können dann wie gewohnt in der eigenen Anwendung benutzt werden.
- </para>
- <para>
- Um einen neuen Adapter zu erstellen, muss eine neue Klasse angelegt werden,
- die das <classname>Zend_Http_Client_Adapter_Interface</classname> implementiert.
- Nachfolgend finden Sie ein Gerüst für einen neuen Adapter. Die public-Methoden müssen
- unbedingt implementiert werden.
- </para>
- <example id="zend.http.client.adapters.extending.example-1">
- <title>Gerüst für einen eigenen Verbindungs-Adapter</title>
- <programlisting language="php"><![CDATA[
- class MyApp_Http_Client_Adapter_BananaProtocol
- implements Zend_Http_Client_Adapter_Interface
- {
- /**
- * Konfigurationsarray für den Adapter
- *
- * @param array $config
- */
- public function setConfig($config = array())
- {
- // in den meisten Fällen kann die Implementierung von
- // Zend_Http_Client_Adapter_Socket eins zu eins übernommen werden
- }
- /**
- * Zum Server verbinden
- *
- * @param string $host
- * @param int $port
- * @param boolean $secure
- */
- public function connect($host, $port = 80, $secure = false)
- {
- // Verbindung zum Server herstellen
- }
- /**
- * Anfrage / Request an den Server stellen
- *
- * @param string $method
- * @param Zend_Uri_Http $url
- * @param string $http_ver
- * @param array $headers
- * @param string $body
- * @return string Request as text
- */
- public function write($method,
- $url,
- $http_ver = '1.1',
- $headers = array(),
- $body = '')
- {
- // Anfrage stellen
- // Diese Methode muss die komplette Antwort zurückliefern,
- // inklusive aller Header
- }
- /**
- * Antwort des Servers auslesen
- *
- * @return string
- */
- public function read()
- {
- // Antwort des Servers lesen und als String zurückgeben
- }
- /**
- * Verbindung zum Server beenden
- *
- */
- public function close()
- {
- // Verbindung beenden - wird zum Schluss aufgerufen
- }
- }
- // Jetzt kann der Adapter benutzt werden:
- $client = new Zend_Http_Client(array(
- 'adapter' => 'MyApp_Http_Client_Adapter_BananaProtocol'
- ));
- ]]></programlisting>
- </example>
- </sect2>
- </sect1>
|