Zend_Http_Client-Adapters.xml 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 17175 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.http.client.adapters">
  5. <title>Zend_Http_Client - Verbindungsadapter</title>
  6. <sect2 id="zend.http.client.adapters.overview">
  7. <title>Verbindungsadapter</title>
  8. <para>
  9. <classname>Zend_Http_Client</classname> basiert auf einem Design mit
  10. Verbindungsadaptern. Der Verbindungsadapter ist das Objekt, welches für die Ausführung
  11. der aktuellen Verbindung zum Server sowie für das Schreiben der Anfragen und Lesen von
  12. Antworten verantwortlich ist. Dieser Verbindungsadapter kann ersetzt werden und man kann
  13. den Standard Verbindungsadapter durch seinen eigenen Adapter erweitern, um ihn mit dem
  14. selben Interface auf seine eigenen Bedürfnisse anzupassen, ohne dass man die gesamte
  15. <acronym>HTTP</acronym> Client Klasse erweitern oder ersetzen muss.
  16. </para>
  17. <para>
  18. Derzeit stellt die <classname>Zend_Http_Client</classname> Klasse vier eingebaute
  19. Verbindungsadapter bereit:
  20. <itemizedlist>
  21. <listitem>
  22. <para>
  23. <classname>Zend_Http_Client_Adapter_Socket</classname> (Standard)
  24. </para>
  25. </listitem>
  26. <listitem>
  27. <para>
  28. <classname>Zend_Http_Client_Adapter_Proxy</classname>
  29. </para>
  30. </listitem>
  31. <listitem>
  32. <para>
  33. <classname>Zend_Http_Client_Adapter_Curl</classname>
  34. </para>
  35. </listitem>
  36. <listitem>
  37. <para>
  38. <classname>Zend_Http_Client_Adapter_Test</classname>
  39. </para>
  40. </listitem>
  41. </itemizedlist>
  42. </para>
  43. <para>
  44. Der Verbindungsadapter für das <classname>Zend_Http_Client</classname> Objekt wird durch
  45. Verwendung der 'adapter' Konfigurationsoption gesetzt. Beim Instanzieren des Client
  46. Objektes kann man die 'adapter' Konfigurationsoption setzen mit einem String, der den
  47. Adapternamen (z.B. 'Zend_Http_Client_Adapter_Socket') enthält, oder mit eine Variable,
  48. die ein Adapterobjekt (z.B. <code>new Zend_Http_Client_Adapter_Test</code>) enthält. Man
  49. kann den Adapter auch danach setzen, indem man die
  50. <classname>Zend_Http_Client->setConfig()</classname> Methode verwendet.
  51. </para>
  52. </sect2>
  53. <sect2 id="zend.http.client.adapters.socket">
  54. <title>Der Socket Adapter</title>
  55. <para>
  56. Der Standard-Adapter ist <classname>Zend_Http_Client_Adapter_Socket</classname>.
  57. Dieser wird benutzt, wenn kein anderer angegeben wird. Der Socket Adapter benutzt die
  58. native <acronym>PHP</acronym> Funktion fsockopen(), um die Verbindung aufzubauen, dafür
  59. werden keine besonderen Extensions oder Einstellungen benötigt.
  60. </para>
  61. <para>
  62. Der Socket Adapter erlaubt verschiedene zusätzliche Konfigurations Optionen die gesetzt
  63. werden können durch Verwendung von <classname>Zend_Http_Client->setConfig()</classname>
  64. oder deren Übergabe an den Konstruktor des Clients.
  65. <table id="zend.http.client.adapter.socket.configuration.table">
  66. <title>Zend_Http_Client_Adapter_Socket Konfigurations Parameter</title>
  67. <tgroup cols="4">
  68. <thead>
  69. <row>
  70. <entry>Parameter</entry>
  71. <entry>Beschreibung</entry>
  72. <entry>Erwarteter Typ</entry>
  73. <entry>Standardwert</entry>
  74. </row>
  75. </thead>
  76. <tbody>
  77. <row>
  78. <entry>persistent</entry>
  79. <entry>
  80. Ob eine persistente TCP Verbindung verwendet werden soll oder nicht
  81. </entry>
  82. <entry>boolean</entry>
  83. <entry>false</entry>
  84. </row>
  85. <row>
  86. <entry>ssltransport</entry>
  87. <entry>SSL Transport Layer (eg. 'sslv2', 'tls')</entry>
  88. <entry>string</entry>
  89. <entry>ssl</entry>
  90. </row>
  91. <row>
  92. <entry>sslcert</entry>
  93. <entry>Pfad zu einem PEM verschlüsselten SSL Zertifikat</entry>
  94. <entry>string</entry>
  95. <entry>null</entry>
  96. </row>
  97. <row>
  98. <entry>sslpassphrase</entry>
  99. <entry>Die PassPhrase für die SSL zertifizierte Datei</entry>
  100. <entry>string</entry>
  101. <entry>null</entry>
  102. </row>
  103. </tbody>
  104. </tgroup>
  105. </table>
  106. <note>
  107. <title>Persistente TCP Verbindungen</title>
  108. <para>
  109. Die Verwendung persistenter TCP Verbindungen kann <acronym>HTTP</acronym>
  110. Anfragen potentiell schneller machen - aber in den meisten Fällen, wird es nur
  111. einen kleinen positiven Effekt haben und könnte den <acronym>HTTP</acronym>
  112. Server überladen zu dem man sich verbindet.
  113. </para>
  114. <para>
  115. Es wird empfohlen persistente TCP Verbindungen nur dann zu verwenden wenn man
  116. sich zu dem gleichen Server sehr oft verbindet, und man sicher ist das der
  117. Server eine große Anzahl an gleichzeitigen Verbindungen behandeln kann. In jedem
  118. Fall wird empfohlen das der Effekt von persistenten Verbindungen auf beiden, der
  119. Geschwindigkeit des Clients und dem Serverload gemessen wird bevor diese Option
  120. verwendet wird.
  121. </para>
  122. <para>
  123. Zusätzlich, wenn persistente Verbindungen verwendet werden, sollte man
  124. Keep-Alive <acronym>HTTP</acronym> Anfragen aktivieren wie in <xref
  125. linkend="zend.http.client.configuration" /> beschrieben - andernfalls werden
  126. persistente Verbindungen nur wenig oder gar keinen Effekt haben.
  127. </para>
  128. </note>
  129. <note>
  130. <title>HTTPS SSL Stream Parameter</title>
  131. <para>
  132. <code>ssltransport, sslcert</code> und <code>sslpassphrase</code> sind nur
  133. relevant wenn <acronym>HTTP</acronym>S für die Verbindung verwendet wird.
  134. </para>
  135. <para>
  136. Wärend die Standard SSL Einstellungen für die meisten Anwendungen funktionieren,
  137. kann es notwendig sein diese zu Ändern wenn der Server zu dem man sich verbindet
  138. ein spezielles Client Setup benötigt. Wenn dem so ist, sollte man das Kapitel
  139. über SSL Transport Layer und Optionen lesen das <ulink
  140. url="http://www.php.net/manual/en/transports.php#transports.inet">hier</ulink>
  141. zu finden ist.
  142. </para>
  143. </note>
  144. </para>
  145. <example id="zend.http.client.adapters.socket.example-1">
  146. <title>Den Stream-Typen für eine HTTPS Verbindung einstellen</title>
  147. <programlisting language="php"><![CDATA[
  148. // Konfigurationsparameter setzen
  149. $config = array(
  150. 'adapter' => 'Zend_Http_Client_Adapter_Socket',
  151. 'ssltransport' => 'tls'
  152. );
  153. // Client-Instanz erzeugen
  154. $client = new Zend_Http_Client('https://www.example.com', $config);
  155. // Jetzt wird der Request über eine verschlüsselte Verbindung verschickt
  156. $response = $client->request();
  157. ]]></programlisting>
  158. </example>
  159. <para>
  160. Ein ähnliches Ergebnis erzielt man mit folgendem Code:
  161. </para>
  162. <para>
  163. <methodname>fsockopen('tls://www.example.com', 443)</methodname>
  164. </para>
  165. <sect3 id="zend.http.client.adapters.socket.streamcontext">
  166. <title>Anpassen und Zugreifen auf den Socket Adapter Stream Kontext</title>
  167. <para>
  168. Beginnend mit Zend Framework 1.9 bietet
  169. <classname>Zend_Http_Client_Adapter_Socket</classname> direkten Zugriff auf den
  170. darunterliegenden <ulink
  171. url="http://php.net/manual/de/stream.contexts.php">Stream Kontext</ulink> der
  172. für die Verbindung zum entfernten Server verwendet wird. Das erlaubt es
  173. Benutzern spezielle Optionen und Parameter an den TCP Stream zu übergeben und
  174. an den SSL Wrapper im Falle einer HTTPS Verbindung.
  175. </para>
  176. <para>
  177. Man kann auf den Stream Kontext zugreifen indem die folgenden Methoden von
  178. <classname>Zend_Http_Client_Adapter_Socket</classname> verwendet werden:
  179. <itemizedlist>
  180. <listitem>
  181. <para>
  182. <firstterm><methodname>setStreamContext($context)</methodname></firstterm>
  183. Setzt den Stream Kontext der vom Adapter verwendet werden soll.
  184. Akzeptiert entweder eine Stream Kontext Ressource von durch die
  185. Verwendung der <acronym>PHP</acronym> Funktion <ulink
  186. url="http://php.net/manual/de/function.stream-context-create.php"><methodname>stream_context_create()</methodname></ulink>
  187. erstellt wurde, oder ein Array von Stream Kontext Optionen im
  188. gleichen Format wie es an diese Funktion übergeben wird. Wenn ein
  189. Array übergeben wird, dann wird ein neuer Stream Kontext mit Hilfe
  190. dieser Optionen erstellt, und gesetzt.
  191. </para>
  192. </listitem>
  193. <listitem>
  194. <para>
  195. <firstterm><methodname>getStreamContext()</methodname></firstterm>
  196. Empfängt den Stream Kontext des Adapters. Wenn kein Stream Kontext
  197. gesetzt ist, wird ein standardmäßiger Stream Kontext erstellt und
  198. zurückgegeben. Man kann anschließend den Wert verschiedener Kontext
  199. Optionen setzen oder empfangen indem die regulären
  200. <acronym>PHP</acronym> Stream Kontext Funktionen verwendet werden.
  201. </para>
  202. </listitem>
  203. </itemizedlist>
  204. </para>
  205. <example id="zend.http.client.adapters.socket.streamcontext.example-1">
  206. <title>Setzen von Stream Kontext Optionen für den Socket Adapter</title>
  207. <programlisting language="php"><![CDATA[
  208. // Array von Optionen
  209. $options = array(
  210. 'socket' => array(
  211. // Bindet die lokale Socket Seite an ein spezifisches Interface
  212. 'bindto' => '10.1.2.3:50505'
  213. ),
  214. 'ssl' => array(
  215. // Prüft das Server Side Zertifikat, akzeptiert keine
  216. // ungültigen oder selbst-signierten SSL Zertifikate
  217. 'verify_peer' => true,
  218. 'allow_self_signed' => false,
  219. // Holt das Peer Zertifikat
  220. 'capture_peer_cert' => true
  221. )
  222. );
  223. // Erstellt ein Adapter Objekt und hängt es an den HTTP Client
  224. $adapter = new Zend_Http_Client_Adapter_Socket();
  225. $client = new Zend_Http_Client();
  226. $client->setAdapter($adapter);
  227. // Methode 1: Ein Options Array an setStreamContext() übergeben
  228. $adapter->setStreamContext($options);
  229. // Methode 2: Einen Stream Kontext erstellen und an setStreamContext() übergeben
  230. $context = stream_context_create($options);
  231. $adapter->setStreamContext($context);
  232. // Methode 3: Den Standardmäßigen Stream Kontext holen und Optionen auf Ihm setzen
  233. $context = $adapter->getStreamContext();
  234. stream_context_set_option($context, $options);
  235. // Jetzt die Anfrage durchführen
  236. $response = $client->request();
  237. // Wenn alles gut ging, kann auf den Kontext jetzt zugegriffen werden
  238. $opts = stream_context_get_options($adapter->getStreamContext());
  239. echo $opts['ssl']['peer_certificate'];
  240. ]]></programlisting>
  241. </example>
  242. <note>
  243. <para>
  244. Es ist zu beachten das alle Stream Kontext Optionen gesetzt sein müssen bevor
  245. der Adapter Anfragen durchführt. Wenn kein Kontext gesetzt ist bevor
  246. <acronym>HTTP</acronym> Anfragen mit dem Socket Adapter durchgeführt werden,
  247. wird ein standardmäßiger Stream Kontext erstellt. Auf diese Kontext Ressource
  248. kann zugegriffen werden nachdem Anfragen durchgeführt werden indem die
  249. <methodname>getStreamContext()</methodname> Methode verwendet wird.
  250. </para>
  251. </note>
  252. </sect3>
  253. </sect2>
  254. <sect2 id="zend.http.client.adapters.proxy">
  255. <title>Der Proxy Adapter</title>
  256. <para>
  257. Der Proxy Adapter <classname>Zend_Http_Client_Adapter_Proxy</classname> verhält sich wie
  258. der standard <classname>Zend_Http_Client_Adapter_Socket</classname>, mit dem
  259. Unterschied, dass die Verbindung über einen <acronym>HTTP</acronym> Proxy-Server
  260. aufgebaut wird statt den Server direkt zu kontaktieren. Das erlaubt die Verwendung von
  261. <classname>Zend_Http_Client</classname> hinter Proxy Servern - was manchmal wegen der
  262. Sicherheit und Geschwindigkeit notwendig ist.
  263. </para>
  264. <para>
  265. Der Proxy Adapter benötigt zusätzliche Konfigurationsvariablen, die
  266. nachfolgend gelistet sind.
  267. <table id="zend.http.client.adapters.proxy.table">
  268. <title>Zend_Http_Client Konfigurationsparameter</title>
  269. <tgroup cols="4">
  270. <thead>
  271. <row>
  272. <entry>Parameter</entry>
  273. <entry>Beschreibung</entry>
  274. <entry>Datentyp</entry>
  275. <entry>Beispielwert</entry>
  276. </row>
  277. </thead>
  278. <tbody>
  279. <row>
  280. <entry>proxy_host</entry>
  281. <entry>Proxy-Server-Adresse</entry>
  282. <entry>string</entry>
  283. <entry>'proxy.myhost.com' oder '10.1.2.3'</entry>
  284. </row>
  285. <row>
  286. <entry>proxy_port</entry>
  287. <entry>TCP Port des Proxy-Servers</entry>
  288. <entry>integer</entry>
  289. <entry>8080 (Standardwert) oder 81</entry>
  290. </row>
  291. <row>
  292. <entry>proxy_user</entry>
  293. <entry>Benutzername für die Proxynutzung, falls nötig</entry>
  294. <entry>string</entry>
  295. <entry>'wulli' oder '' für keinen Namen (Standardwert)</entry>
  296. </row>
  297. <row>
  298. <entry>proxy_pass</entry>
  299. <entry>Passwort für die Proxynutzung, falls nötig</entry>
  300. <entry>string</entry>
  301. <entry>'geheim' oder '' für kein Passwort (Standardwert)</entry>
  302. </row>
  303. <row>
  304. <entry>proxy_auth</entry>
  305. <entry>Proxy <acronym>HTTP</acronym> Authentifizierungs-Typ</entry>
  306. <entry>string</entry>
  307. <entry>Zend_Http_Client::AUTH_BASIC (Standardwert)</entry>
  308. </row>
  309. </tbody>
  310. </tgroup>
  311. </table>
  312. </para>
  313. <para>
  314. proxy_host muss immer gesetzt werden, ansonsten wird der Proxy-Adapter auf
  315. <classname>Zend_Http_Client_Adapter_Socket</classname> zurückgreifen und keinen Proxy
  316. Server benutzen. Wird kein Prot mit übergeben, so versucht der Proxy-Adapter sich auf
  317. den Standardport '8080' zu verbinden.
  318. </para>
  319. <para>
  320. proxy_user und proxy_pass werden nur dann benötigt, wenn der Proxy-Server
  321. tatsächlich eine Authentifizierung erwartet. Werden diese Parameter mit
  322. übergeben, setzt der Proxy-Adapter zusätzlich den 'Proxy-Authentication'
  323. Header bei Anfragen. Wird keine Authentifizierung benötigt, sollten die
  324. beiden Parameter weggelassen werden.
  325. </para>
  326. <para>
  327. proxy_auth setzt den Authentifizierungs-Typ. Dies ist nur nötig, wenn der
  328. Proxy-Server eine Authentifizierung erwartet.
  329. Mögliche Werte entsprechen denen der Zend_Http_Client::setAuth() Methode.
  330. Zur Zeit wird nur die BASIC-Authentifizierung
  331. (Zend_Http_Client::AUTH_BASIC) unterstützt.
  332. </para>
  333. <example id="zend.http.client.adapters.proxy.example-1">
  334. <title>Zend_Http_Client hinter einem Proxy-Server nutzen</title>
  335. <programlisting language="php"><![CDATA[
  336. // Konfigurationsparameter setzen
  337. $config = array(
  338. 'adapter' => 'Zend_Http_Client_Adapter_Proxy',
  339. 'proxy_host' => 'proxy.int.zend.com',
  340. 'proxy_port' => 8000,
  341. 'proxy_user' => 'shahar.e',
  342. 'proxy_pass' => 'bananashaped'
  343. );
  344. // Client-Objekt instanziieren
  345. $client = new Zend_Http_Client('http://www.example.com', $config);
  346. // $client kann jetzt wie gewohnt benutzt werden
  347. ]]></programlisting>
  348. </example>
  349. <para>
  350. Wie vorher erwähnt, nutzt der Proxy-Adapter eine einfache Socket-Verbindung,
  351. wenn proxy_host nicht gesetzt oder leer gelassen wurde. Dies ermöglicht
  352. die optionale Nutzung eines Proxy-Servers, abhängig von dem proxy_host
  353. Parameter.
  354. </para>
  355. <note>
  356. <para>
  357. Da der Proxy Adapter von <classname>Zend_Http_Client_Adapter_Socket</classname>
  358. abgeleitet ist, kann die Stream Kontext Zugriffsmethode verwendet werden
  359. (siehe <xref linkend="zend.http.client.adapters.socket.streamcontext" />) um
  360. Stream Kontext Optionen auf Proxy Verbindungen zu setzen wie es oben demonstriert
  361. wurde.
  362. </para>
  363. </note>
  364. </sect2>
  365. <sect2 id="zend.http.client.adapters.curl">
  366. <title>Der cURL Adapter</title>
  367. <para>
  368. cURL ist eine Standard <acronym>HTTP</acronym> Client Bibliothek die mit vielen
  369. Betriebssystemen ausgeliefert wird, und kann in <acronym>PHP</acronym> über die cURL
  370. Erweiterung verwendet werden. Sie bietet Funktionalitäten für viele spezielle Fälle die
  371. für einen <acronym>HTTP</acronym> Client auftreten können und machen sie zu einer
  372. perfekten Wahl für einen <acronym>HTTP</acronym> Adapter. Sie unterstützt sichere
  373. Verbindungen, Proxies, alle Arten von Authentifizierungsmechanismen und glänzt in
  374. Anwendungen die große Dateien zwischen Servern bewegen müssen.
  375. </para>
  376. <example id="zend.http.client.adapters.curl.example-1">
  377. <title>Setzen von cURL Optionen</title>
  378. <programlisting language="php"><![CDATA[
  379. $config = array(
  380. 'adapter' => 'Zend_Http_Client_Adapter_Curl',
  381. 'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
  382. );
  383. $client = new Zend_Http_Client($uri, $config);
  384. ]]></programlisting>
  385. </example>
  386. <para>
  387. Standardmäßig ist der cURL Adapter so konfiguriert das er sich genauso wie der
  388. Socket Adapter verhält und er akzeptiert auch die gleichen Konfigurationsparameter wie
  389. die Socket und Proxy Adapter. Man kann die cURL Optionen entweder durch den
  390. 'curloptions' Schlüssel im Konstruktor des Adapters, oder durch den Aufruf von
  391. <methodname>setCurlOption($name, $value)</methodname>, verändern. Der
  392. <varname>$name</varname> Schlüssel entspricht den CURL_* Konstanten der cURL
  393. Erweiterung. Man kann auf den CURL Handler durch den Aufruf von
  394. <code>$adapter->getHandle();</code> Zugriff erhalten.
  395. </para>
  396. <example id="zend.http.client.adapters.curl.example-2">
  397. <title>Dateien von Hand übertragen</title>
  398. <para>
  399. Man kan cURL verwenden um große Dateien über <acronym>HTTP</acronym> durch einen
  400. Dateihandle zu übertragen.
  401. </para>
  402. <programlisting language="php"><![CDATA[
  403. $putFileSize = filesize("filepath");
  404. $putFileHandle = fopen("filepath", "r");
  405. $adapter = new Zend_Http_Client_Adapter_Curl();
  406. $client = new Zend_Http_Client();
  407. $client->setAdapter($adapter);
  408. $adapter->setConfig(array(
  409. 'curloptions' => array(
  410. CURLOPT_INFILE => $putFileHandle,
  411. CURLOPT_INFILESIZE => $putFileSize
  412. )
  413. ));
  414. $client->request("PUT");
  415. ]]></programlisting>
  416. </example>
  417. </sect2>
  418. <sect2 id="zend.http.client.adapters.test">
  419. <title>Der Test Adapter</title>
  420. <para>
  421. Manchmal ist es sehr schwer Code zu testen, der von <acronym>HTTP</acronym> Verbindungen
  422. abhängig ist. Zum Beispiel verlangt das Testen einer Applikation, die einen RSS Feed von
  423. einem fremden Server anfordert, eine Netzwerkverbindung, die nicht immer verfügbar ist.
  424. </para>
  425. <para>
  426. Aus diesem Grund wird der <classname>Zend_Http_Client_Adapter_Test</classname> Adapter
  427. bereit gestellt. Man kann seine eigenen Applikationen schreiben, um
  428. <classname>Zend_Http_Client</classname> zu verwenden, und nur zu Testzwecken, z.B. in
  429. der Unit Test Suite, den Standardadapter durch den Testadapter (ein Mock Objekt)
  430. austauschen, um Tests ohne direkte Serverbindungen auszuführen.
  431. </para>
  432. <para>
  433. Der <classname>Zend_Http_Client_Adapter_Test</classname> Adapter stellt die zusätzliche
  434. Methode setResponse() bereit. Diese Methode nimmt einen Parameter entgegen, der eine
  435. <acronym>HTTP</acronym> Antwort entweder als Text oder als
  436. <classname>Zend_Http_Response</classname> Objekt repräsentiert. Einmal eingerichtet,
  437. wird der Testadapter immer diese Antwort zurückgeben, ohne tatsächlich eine
  438. <acronym>HTTP</acronym> Anfrage auszuführen.
  439. </para>
  440. <example id="zend.http.client.adapters.test.example-1">
  441. <title>Testen gegen einen einfachen HTTP Response Stumpf</title>
  442. <programlisting language="php"><![CDATA[
  443. // Instanziere einen neuen Adapter und Client
  444. $adapter = new Zend_Http_Client_Adapter_Test();
  445. $client = new Zend_Http_Client('http://www.example.com', array(
  446. 'adapter' => $adapter
  447. ));
  448. // Setze die erwartete Antwort
  449. $adapter->setResponse(
  450. "HTTP/1.1 200 OK" . "\r\n" .
  451. "Content-type: text/xml" . "\r\n" .
  452. "\r\n" .
  453. '<?xml version="1.0" encoding="UTF-8"?>' .
  454. '<rss version="2.0" ' .
  455. ' xmlns:content="http://purl.org/rss/1.0/modules/content/"' .
  456. ' xmlns:wfw="http://wellformedweb.org/CommentAPI/"' .
  457. ' xmlns:dc="http://purl.org/dc/elements/1.1/">' .
  458. ' <channel>' .
  459. ' <title>Premature Optimization</title>' .
  460. // und so weiter...
  461. '</rss>');
  462. $response = $client->request('GET');
  463. // .. setze die Verarbeitung von $response fort...
  464. ]]></programlisting>
  465. </example>
  466. <para>
  467. Das obige Beispiel zeigt, wie man einen <acronym>HTTP</acronym> Client voreinstellen
  468. kann, damit er die benötigte Antwort zurückgibt. Danach kann man mit den Testen des
  469. eigenen Codes weiter machen, ohne von einer Netzwerkverbindung, der Serverantwort, etc.
  470. abhängig zu sein. In diesem Fall würde der Test mit der Prüfung fortfahren, wie die
  471. Applikation das <acronym>XML</acronym> aus der Antwort verarbeitet..
  472. </para>
  473. <para>
  474. Manchmal erfordert ein einziger Methoden-Aufruf mehrere <acronym>HTTP</acronym>
  475. Übertragungen. In diesem Fall ist es nicht möglich setResponse() alleine zu verwenden
  476. weil es keine Möglichkeit gibt die nächste Antwort zu setzen die das Programm benötigt
  477. bevor es zum Aufrufer zurückkommt.
  478. </para>
  479. <example id="zend.http.client.adapters.test.example-2">
  480. <title>Test mit mehreren HTTP-Antworten</title>
  481. <programlisting language="php"><![CDATA[
  482. // Instanzen vom Adapter und Client erzeugen
  483. $adapter = new Zend_Http_Client_Adapter_Test();
  484. $client = new Zend_Http_Client('http://www.example.com', array(
  485. 'adapter' => $adapter
  486. ));
  487. // mit setResponse() die erste Antwort setzen
  488. $adapter->setResponse(
  489. "HTTP/1.1 302 Found" . "\r\n" .
  490. "Location: /" . "\r\n" .
  491. "Content-Type: text/html" . "\r\n" .
  492. "\r\n" .
  493. '<html>' .
  494. ' <head><title>Moved</title></head>' .
  495. ' <body><p>This page has moved.</p></body>' .
  496. '</html>');
  497. // mit addResponse() nachfolgende Antworten setzen
  498. $adapter->addResponse(
  499. "HTTP/1.1 200 OK" . "\r\n" .
  500. "Content-Type: text/html" . "\r\n" .
  501. "\r\n" .
  502. '<html>' .
  503. ' <head><title>Meine Haustierseite</title></head>' .
  504. ' <body><p>...</p></body>' .
  505. '</html>');
  506. // Das $client Objekt kann jetzt zu testzwecken herangezogen werden,
  507. // indem es wie ein normales Client-Objekt benutzt wird.
  508. ]]></programlisting>
  509. </example>
  510. <para>
  511. Die setResponse() Methode löscht alle Antworten im Buffer von
  512. <classname>Zend_Http_Client_Adapter_Test</classname> und setzt die erste Antwort
  513. die zurückgegeben wird. Die addResponse() Methode fügt dann weitere Antworten
  514. sukzessiv hinzu.
  515. </para>
  516. <para>
  517. Die HTTP-Antworten werden in der Reihenfolge zurückgegeben,
  518. in der sie angelegt worden sind. Gibt es mehr Anfragen als
  519. Antworten, so wird wieder bei der ersten Antwort angefangen.
  520. </para>
  521. <para>
  522. Das oben angeführte Beispiel kann dazu benutzt werden, um die Reaktion
  523. der eigenen Anwendung auf einen 302 Redirect (Weiterleitung) zu testen.
  524. Abhängig von Ihrer Anwendung, kann es gewollt oder nicht gewollt sein,
  525. dass dem Redirect gefolgt wird. In unserem Beispiel erwarten wir das der
  526. Umleitung gefolgt wird und wir konfigurieren den Test Adapter um uns zu helfen das
  527. zu Testen. Die ursprüngliche 302 Antwort wird mit der setResponse() Methode gesetzt
  528. und die 200 Antwort welche als nächstes zurückzugeben ist wird mit der
  529. addResponse() Methode hinzugefügt. Nachdem der Test Adapter konfiguriert ist, wird
  530. der <acronym>HTTP</acronym> Client der den Adapter enthält unter test in das eigene
  531. Objekt injiziert und sein Verhalten getestet.
  532. </para>
  533. </sect2>
  534. <sect2 id="zend.http.client.adapters.extending">
  535. <title>Einen eigenen Adapter erstellen</title>
  536. <para>
  537. Es ist möglich eigene Verbindungs-Adapter zu schreiben, die spezielle
  538. Bedürfnisse, wie persistente Sockets oder gecachte Verbindungen, abdecken.
  539. Diese können dann, wie gewohnt in der eigenen Anwendung benutzt werden können.
  540. </para>
  541. <para>
  542. Um einen neuen Adapter zu erstellen, muss eine neue Klasse angelegt werden,
  543. die das <classname>Zend_Http_Client_Adapter_Interface</classname> implementiert.
  544. Nachfolgend finden Sie ein Gerüst für einen neuen Adapter. Die public-Methoden müssen
  545. unbedingt implementiert werden.
  546. </para>
  547. <example id="zend.http.client.adapters.extending.example-1">
  548. <title>Gerüst für einen eigenen Verbindungs-Adapter</title>
  549. <programlisting language="php"><![CDATA[
  550. class MyApp_Http_Client_Adapter_BananaProtocol
  551. implements Zend_Http_Client_Adapter_Interface
  552. {
  553. /**
  554. * Konfigurationsarray für den Adapter
  555. *
  556. * @param array $config
  557. */
  558. public function setConfig($config = array())
  559. {
  560. // in den meisten Fällen kann die Implementierung von
  561. // Zend_Http_Client_Adapter_Socket eins zu eins übernommen werden
  562. }
  563. /**
  564. * Zum Server verbinden
  565. *
  566. * @param string $host
  567. * @param int $port
  568. * @param boolean $secure
  569. */
  570. public function connect($host, $port = 80, $secure = false)
  571. {
  572. // Verbindung zum Server herstellen
  573. }
  574. /**
  575. * Anfrage / Request an den Server stellen
  576. *
  577. * @param string $method
  578. * @param Zend_Uri_Http $url
  579. * @param string $http_ver
  580. * @param array $headers
  581. * @param string $body
  582. * @return string Request as text
  583. */
  584. public function write($method,
  585. $url,
  586. $http_ver = '1.1',
  587. $headers = array(),
  588. $body = '')
  589. {
  590. // Anfrage stellen
  591. // Diese Methode muss die komplette Antwort zurückliefern,
  592. // inklusive aller Header
  593. }
  594. /**
  595. * Antwort des Servers auslesen
  596. *
  597. * @return string
  598. */
  599. public function read()
  600. {
  601. // Antwort des Servers lesen und als String zurückgeben
  602. }
  603. /**
  604. * Verbindung zum Server beenden
  605. *
  606. */
  607. public function close()
  608. {
  609. // Verbindung beenden - wird zum Schluss aufgerufen
  610. }
  611. }
  612. // Jetzt kann der Adapter benutzt werden:
  613. $client = new Zend_Http_Client(array(
  614. 'adapter' => 'MyApp_Http_Client_Adapter_BananaProtocol'
  615. ));
  616. ]]></programlisting>
  617. </example>
  618. </sect2>
  619. </sect1>