Zend_Http_Client-Advanced.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.http.client.advanced">
  4. <title>Zend_Http_Client - Advanced Usage</title>
  5. <sect2 id="zend.http.client.redirections">
  6. <title>HTTP Redirections</title>
  7. <para>
  8. By default, <classname>Zend_Http_Client</classname> automatically handles
  9. <acronym>HTTP</acronym> redirections, and will follow up to 5 redirections. This can be
  10. changed by setting the 'maxredirects' configuration parameter.
  11. </para>
  12. <para>
  13. According to the <acronym>HTTP</acronym>/1.1 RFC, <acronym>HTTP</acronym> 301 and 302
  14. responses should be treated by the client by resending the same request to the
  15. specified location - using the same request method. However, most
  16. clients to not implement this and always use a <constant>GET</constant> request when
  17. redirecting. By default, <classname>Zend_Http_Client</classname> does the same - when
  18. redirecting on a 301 or 302 response, all <constant>GET</constant> and POST parameters
  19. are reset, and a <constant>GET</constant> request is sent to the new location. This
  20. behavior can be changed by setting the 'strictredirects' configuration
  21. parameter to boolean <constant>TRUE</constant>:
  22. <example id="zend.http.client.redirections.example-1">
  23. <title>Forcing RFC 2616 Strict Redirections on 301 and 302 Responses</title>
  24. <programlisting language="php"><![CDATA[
  25. // Strict Redirections
  26. $client->setConfig(array('strictredirects' => true));
  27. // Non-strict Redirections
  28. $client->setConfig(array('strictredirects' => false));
  29. ]]></programlisting>
  30. </example>
  31. </para>
  32. <para>
  33. You can always get the number of redirections done after sending a
  34. request using the getRedirectionsCount() method.
  35. </para>
  36. </sect2>
  37. <sect2 id="zend.http.client.cookies">
  38. <title>Adding Cookies and Using Cookie Persistence</title>
  39. <para>
  40. <classname>Zend_Http_Client</classname> provides an easy interface for adding cookies
  41. to your request, so that no direct header modification is
  42. required. This is done using the setCookie() method. This method
  43. can be used in several ways:
  44. <example id="zend.http.client.cookies.example-1">
  45. <title>Setting Cookies Using setCookie()</title>
  46. <programlisting language="php"><![CDATA[
  47. // Easy and simple: by providing a cookie name and cookie value
  48. $client->setCookie('flavor', 'chocolate chips');
  49. // By directly providing a raw cookie string (name=value)
  50. // Note that the value must be already URL encoded
  51. $client->setCookie('flavor=chocolate%20chips');
  52. // By providing a Zend_Http_Cookie object
  53. $cookie = Zend_Http_Cookie::fromString('flavor=chocolate%20chips');
  54. $client->setCookie($cookie);
  55. ]]></programlisting>
  56. </example>
  57. For more information about <classname>Zend_Http_Cookie</classname> objects, see
  58. <link linkend="zend.http.cookies">this section</link>.
  59. </para>
  60. <para>
  61. <classname>Zend_Http_Client</classname> also provides the means for cookie stickiness -
  62. that is having the client internally store all sent and received
  63. cookies, and resend them automatically on subsequent requests. This
  64. is useful, for example when you need to log in to a remote site
  65. first and receive and authentication or session ID cookie before
  66. sending further requests.
  67. <example id="zend.http.client.cookies.example-2">
  68. <title>Enabling Cookie Stickiness</title>
  69. <programlisting language="php"><![CDATA[
  70. // To turn cookie stickiness on, set a Cookie Jar
  71. $client->setCookieJar();
  72. // First request: log in and start a session
  73. $client->setUri('http://example.com/login.php');
  74. $client->setParameterPost('user', 'h4x0r');
  75. $client->setParameterPost('password', '1337');
  76. $client->request('POST');
  77. // The Cookie Jar automatically stores the cookies set
  78. // in the response, like a session ID cookie.
  79. // Now we can send our next request - the stored cookies
  80. // will be automatically sent.
  81. $client->setUri('http://example.com/read_member_news.php');
  82. $client->request('GET');
  83. ]]></programlisting>
  84. </example>
  85. For more information about the <classname>Zend_Http_CookieJar</classname> class, see
  86. <link linkend="zend.http.cookies.cookiejar">this section</link>.
  87. </para>
  88. </sect2>
  89. <sect2 id="zend.http.client.custom_headers">
  90. <title>Setting Custom Request Headers</title>
  91. <para>
  92. Setting custom headers can be done by using the setHeaders() method.
  93. This method is quite diverse and can be used in several ways, as
  94. the following example shows:
  95. <example id="zend.http.client.custom_headers.example-1">
  96. <title>Setting A Single Custom Request Header</title>
  97. <programlisting language="php"><![CDATA[
  98. // Setting a single header, overwriting any previous value
  99. $client->setHeaders('Host', 'www.example.com');
  100. // Another way of doing the exact same thing
  101. $client->setHeaders('Host: www.example.com');
  102. // Setting several values for the same header
  103. // (useful mostly for Cookie headers):
  104. $client->setHeaders('Cookie', array(
  105. 'PHPSESSID=1234567890abcdef1234567890abcdef',
  106. 'language=he'
  107. ));
  108. ]]></programlisting>
  109. </example>
  110. </para>
  111. <para>
  112. setHeader() can also be easily used to set multiple headers in one
  113. call, by providing an array of headers as a single parameter:
  114. <example id="zend.http.client.custom_headers.example-2">
  115. <title>Setting Multiple Custom Request Headers</title>
  116. <programlisting language="php"><![CDATA[
  117. // Setting multiple headers, overwriting any previous value
  118. $client->setHeaders(array(
  119. 'Host' => 'www.example.com',
  120. 'Accept-encoding' => 'gzip,deflate',
  121. 'X-Powered-By' => 'Zend Framework'));
  122. // The array can also contain full array strings:
  123. $client->setHeaders(array(
  124. 'Host: www.example.com',
  125. 'Accept-encoding: gzip,deflate',
  126. 'X-Powered-By: Zend Framework'));
  127. ]]></programlisting>
  128. </example>
  129. </para>
  130. </sect2>
  131. <sect2 id="zend.http.client.file_uploads">
  132. <title>File Uploads</title>
  133. <para>
  134. You can upload files through <acronym>HTTP</acronym> using the setFileUpload method.
  135. This method takes a file name as the first parameter, a form name
  136. as the second parameter, and data as a third optional parameter.
  137. If the third data parameter is <constant>NULL</constant>, the first file name parameter
  138. is considered to be a real file on disk, and <classname>Zend_Http_Client</classname>
  139. will try to read this file and upload it. If the data parameter is not
  140. <constant>NULL</constant>, the first file name parameter will be sent as the file name,
  141. but no actual file needs to exist on the disk.
  142. The second form name parameter is always required, and is equivalent
  143. to the "name" attribute of an &gt;input&lt; tag, if the file was to
  144. be uploaded through an <acronym>HTML</acronym> form.
  145. A fourth optional parameter provides the file's content-type. If
  146. not specified, and <classname>Zend_Http_Client</classname> reads the file from the disk,
  147. the mime_content_type function will be used to guess the file's
  148. content type, if it is available. In any case, the default MIME
  149. type will be application/octet-stream.
  150. <example id="zend.http.client.file_uploads.example-1">
  151. <title>Using setFileUpload to Upload Files</title>
  152. <programlisting language="php"><![CDATA[
  153. // Uploading arbitrary data as a file
  154. $text = 'this is some plain text';
  155. $client->setFileUpload('some_text.txt', 'upload', $text, 'text/plain');
  156. // Uploading an existing file
  157. $client->setFileUpload('/tmp/Backup.tar.gz', 'bufile');
  158. // Send the files
  159. $client->request('POST');
  160. ]]></programlisting>
  161. </example>
  162. In the first example, the $text variable is uploaded and will be
  163. available as $_FILES['upload'] on the server side. In the second
  164. example, the existing file /tmp/Backup.tar.gz is uploaded to the
  165. server and will be available as $_FILES['bufile']. The content type
  166. will be guesses automatically if possible - and if not, the content
  167. type will be set to 'application/octet-stream'.
  168. </para>
  169. <note>
  170. <title>Uploading files</title>
  171. <para>
  172. When uploading files, the <acronym>HTTP</acronym> request content-type is
  173. automatically set to multipart/form-data. Keep in mind that
  174. you must send a POST or PUT request in order to upload files.
  175. Most servers will ignore the requests body on other request
  176. methods.
  177. </para>
  178. </note>
  179. </sect2>
  180. <sect2 id="zend.http.client.raw_post_data">
  181. <title>Sending Raw POST Data</title>
  182. <para>
  183. You can use a <classname>Zend_Http_Client</classname> to send raw POST data using the
  184. setRawData() method. This method takes two parameters: the first
  185. is the data to send in the request body. The second optional
  186. parameter is the content-type of the data. While this parameter is
  187. optional, you should usually set it before sending the request -
  188. either using setRawData(), or with another method: setEncType().
  189. <example id="zend.http.client.raw_post_data.example-1">
  190. <title>Sending Raw POST Data</title>
  191. <programlisting language="php"><![CDATA[
  192. $xml = '<book>' .
  193. ' <title>Islands in the Stream</title>' .
  194. ' <author>Ernest Hemingway</author>' .
  195. ' <year>1970</year>' .
  196. '</book>';
  197. $client->setRawData($xml, 'text/xml')->request('POST');
  198. // Another way to do the same thing:
  199. $client->setRawData($xml)->setEncType('text/xml')->request('POST');
  200. ]]></programlisting>
  201. </example>
  202. The data should be available on the server side through <acronym>PHP</acronym>'s
  203. $HTTP_RAW_POST_DATA variable or through the php://input stream.
  204. </para>
  205. <note>
  206. <title>Using raw POST data</title>
  207. <para>
  208. Setting raw POST data for a request will override any POST
  209. parameters or file uploads. You should not try to use both on
  210. the same request. Keep in mind that most servers will ignore
  211. the request body unless you send a POST request.
  212. </para>
  213. </note>
  214. </sect2>
  215. <sect2 id="zend.http.client.http_authentication">
  216. <title>HTTP Authentication</title>
  217. <para>
  218. Currently, <classname>Zend_Http_Client</classname> only supports basic
  219. <acronym>HTTP</acronym> authentication. This feature is utilized using the
  220. <methodname>setAuth()</methodname> method, or by specifying a username and a password in
  221. the URI. The <methodname>setAuth()</methodname> method
  222. takes 3 parameters: The user name, the password and an optional
  223. authentication type parameter. As mentioned, currently only basic
  224. authentication is supported (digest authentication support is
  225. planned).
  226. <example id="zend.http.client.http_authentication.example-1">
  227. <title>Setting HTTP Authentication User and Password</title>
  228. <programlisting language="php"><![CDATA[
  229. // Using basic authentication
  230. $client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
  231. // Since basic auth is default, you can just do this:
  232. $client->setAuth('shahar', 'myPassword!');
  233. // You can also specify username and password in the URI
  234. $client->setUri('http://christer:secret@example.com');
  235. ]]></programlisting>
  236. </example>
  237. </para>
  238. </sect2>
  239. <sect2 id="zend.http.client.multiple_requests">
  240. <title>Sending Multiple Requests With the Same Client</title>
  241. <para>
  242. <classname>Zend_Http_Client</classname> was also designed specifically to handle several
  243. consecutive requests with the same object. This is useful in cases
  244. where a script requires data to be fetched from several places, or
  245. when accessing a specific <acronym>HTTP</acronym> resource requires logging in and
  246. obtaining a session cookie, for example.
  247. </para>
  248. <para>
  249. When performing several requests to the same host, it is highly
  250. recommended to enable the 'keepalive' configuration flag. This way,
  251. if the server supports keep-alive connections, the connection to the
  252. server will only be closed once all requests are done and the Client
  253. object is destroyed. This prevents the overhead of opening and
  254. closing <acronym>TCP</acronym> connections to the server.
  255. </para>
  256. <para>
  257. When you perform several requests with the same client, but want
  258. to make sure all the request-specific parameters are cleared, you
  259. should use the resetParameters() method. This ensures that <constant>GET</constant> and
  260. POST parameters, request body and request-specific headers are
  261. reset and are not reused in the next request.
  262. </para>
  263. <note>
  264. <title>Resetting parameters</title>
  265. <para>
  266. Note that non-request specific headers are not reset by default
  267. when the <methodname>resetParameters()</methodname> method is used.
  268. Only the 'Content-length' and 'Content-type' headers are reset. This
  269. allows you to set-and-forget headers like 'Accept-language' and
  270. 'Accept-encoding'
  271. </para>
  272. <para>
  273. To clean all headers and other data except for URI and method, use
  274. <methodname>resetParameters(true)</methodname>.
  275. </para>
  276. </note>
  277. <para>
  278. Another feature designed specifically for consecutive requests is
  279. the Cookie Jar object. Cookie Jars allow you to automatically save
  280. cookies set by the server in the first request, and send them on
  281. consecutive requests transparently. This allows, for example, going
  282. through an authentication request before sending the actual data
  283. fetching request.
  284. </para>
  285. <para>
  286. If your application requires one authentication request per user,
  287. and consecutive requests might be performed in more than one script
  288. in your application, it might be a good idea to store the Cookie Jar
  289. object in the user's session. This way, you will only need to
  290. authenticate the user once every session.
  291. </para>
  292. <example id="zend.http.client.multiple_requests.example-1">
  293. <title>Performing consecutive requests with one client</title>
  294. <programlisting language="php"><![CDATA[
  295. // First, instantiate the client
  296. $client = new Zend_Http_Client('http://www.example.com/fetchdata.php', array(
  297. 'keepalive' => true
  298. ));
  299. // Do we have the cookies stored in our session?
  300. if (isset($_SESSION['cookiejar']) &&
  301. $_SESSION['cookiejar'] instanceof Zend_Http_CookieJar) {
  302. $client->setCookieJar($_SESSION['cookiejar']);
  303. } else {
  304. // If we don't, authenticate and store cookies
  305. $client->setCookieJar();
  306. $client->setUri('http://www.example.com/login.php');
  307. $client->setParameterPost(array(
  308. 'user' => 'shahar',
  309. 'pass' => 'somesecret'
  310. ));
  311. $client->request(Zend_Http_Client::POST);
  312. // Now, clear parameters and set the URI to the original one
  313. // (note that the cookies that were set by the server are now
  314. // stored in the jar)
  315. $client->resetParameters();
  316. $client->setUri('http://www.example.com/fetchdata.php');
  317. }
  318. $response = $client->request(Zend_Http_Client::GET);
  319. // Store cookies in session, for next page
  320. $_SESSION['cookiejar'] = $client->getCookieJar();
  321. ]]></programlisting>
  322. </example>
  323. </sect2>
  324. <sect2 id="zend.http.client.streaming">
  325. <title>Data Streaming</title>
  326. <para>
  327. By default, <classname>Zend_Http_Client</classname> accepts and returns data as
  328. <acronym>PHP</acronym> strings. However, in many cases there are big files to be sent or
  329. received, thus keeping them in memory might be unnecessary or too expensive. For these
  330. cases, <classname>Zend_Http_Client</classname> supports reading data from files (and in
  331. general, <acronym>PHP</acronym> streams) and writing data to files (streams).
  332. </para>
  333. <para>
  334. In order to use stream to pass data to <classname>Zend_Http_Client</classname>,
  335. use <methodname>setRawData()</methodname> method with data argument being stream
  336. resource (e.g., result of <methodname>fopen()</methodname>).
  337. <example id="zend.http.client.streaming.example-1">
  338. <title>Sending file to HTTP server with streaming</title>
  339. <programlisting language="php"><![CDATA[
  340. $fp = fopen("mybigfile.zip", "r");
  341. $client->setRawData($fp, 'application/zip')->request('PUT');
  342. ]]></programlisting>
  343. </example>
  344. </para>
  345. <para>
  346. Only PUT requests currently support sending streams to <acronym>HTTP</acronym> server.
  347. </para>
  348. <para>
  349. In order to receive data from the server as stream, use
  350. <methodname>setStream()</methodname>. Optional argument specifies the filename where the
  351. data will be stored. If the argument is just <constant>TRUE</constant> (default),
  352. temporary file will be used and will be deleted once response object is destroyed.
  353. Setting argument to <constant>FALSE</constant> disables the streaming functionality.
  354. </para>
  355. <para>
  356. When using streaming, <methodname>request()</methodname> method will return object of
  357. class <classname>Zend_Http_Client_Response_Stream</classname>, which has two useful
  358. methods: <methodname>getStreamName()</methodname> will return the name of the file where
  359. the response is stored, and <methodname>getStream()</methodname> will return stream from
  360. which the response could be read.
  361. </para>
  362. <para>
  363. You can either write the response to pre-defined file, or use temporary file for storing
  364. it and send it out or write it to another file using regular stream functions.
  365. <example id="zend.http.client.streaming.example-2">
  366. <title>Receiving file from HTTP server with streaming</title>
  367. <programlisting language="php"><![CDATA[
  368. $client->setStream(); // will use temp file
  369. $response = $client->request('GET');
  370. // copy file
  371. copy($response->getStreamName(), "my/downloads/file");
  372. // use stream
  373. $fp = fopen("my/downloads/file2", "w");
  374. stream_copy_to_stream($response->getStream(), $fp);
  375. // Also can write to known file
  376. $client->setStream("my/downloads/myfile")->request('GET');
  377. ]]></programlisting>
  378. </example>
  379. </para>
  380. </sect2>
  381. </sect1>