Response.php

  1. 8 core/vendor/easyrdf/easyrdf/lib/EasyRdf/Http/Response.php
  2. 8 core/vendor/guzzle/http/Guzzle/Http/Message/Response.php
  3. 8 core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Response.php

Namespace

Guzzle\Http\Message

Classes

Namesort descending Description
Response Guzzle HTTP response object

File

core/vendor/guzzle/http/Guzzle/Http/Message/Response.php
View source
  1. <?php
  2. namespace Guzzle\Http\Message;
  3. use Guzzle\Common\Collection;
  4. use Guzzle\Common\Exception\RuntimeException;
  5. use Guzzle\Http\EntityBodyInterface;
  6. use Guzzle\Http\EntityBody;
  7. use Guzzle\Http\Exception\BadResponseException;
  8. use Guzzle\Parser\ParserRegistry;
  9. /**
  10. * Guzzle HTTP response object
  11. */
  12. class Response extends AbstractMessage
  13. {
  14. /**
  15. * @var array Array of reason phrases and their corresponding status codes
  16. */
  17. private static $statusTexts = array(
  18. 100 => 'Continue',
  19. 101 => 'Switching Protocols',
  20. 102 => 'Processing',
  21. 200 => 'OK',
  22. 201 => 'Created',
  23. 202 => 'Accepted',
  24. 203 => 'Non-Authoritative Information',
  25. 204 => 'No Content',
  26. 205 => 'Reset Content',
  27. 206 => 'Partial Content',
  28. 207 => 'Multi-Status',
  29. 208 => 'Already Reported',
  30. 226 => 'IM Used',
  31. 300 => 'Multiple Choices',
  32. 301 => 'Moved Permanently',
  33. 302 => 'Found',
  34. 303 => 'See Other',
  35. 304 => 'Not Modified',
  36. 305 => 'Use Proxy',
  37. 307 => 'Temporary Redirect',
  38. 308 => 'Permanent Redirect',
  39. 400 => 'Bad Request',
  40. 401 => 'Unauthorized',
  41. 402 => 'Payment Required',
  42. 403 => 'Forbidden',
  43. 404 => 'Not Found',
  44. 405 => 'Method Not Allowed',
  45. 406 => 'Not Acceptable',
  46. 407 => 'Proxy Authentication Required',
  47. 408 => 'Request Timeout',
  48. 409 => 'Conflict',
  49. 410 => 'Gone',
  50. 411 => 'Length Required',
  51. 412 => 'Precondition Failed',
  52. 413 => 'Request Entity Too Large',
  53. 414 => 'Request-URI Too Long',
  54. 415 => 'Unsupported Media Type',
  55. 416 => 'Requested Range Not Satisfiable',
  56. 417 => 'Expectation Failed',
  57. 422 => 'Unprocessable Entity',
  58. 423 => 'Locked',
  59. 424 => 'Failed Dependency',
  60. 425 => 'Reserved for WebDAV advanced collections expired proposal',
  61. 426 => 'Upgrade required',
  62. 428 => 'Precondition Required',
  63. 429 => 'Too Many Requests',
  64. 431 => 'Request Header Fields Too Large',
  65. 500 => 'Internal Server Error',
  66. 501 => 'Not Implemented',
  67. 502 => 'Bad Gateway',
  68. 503 => 'Service Unavailable',
  69. 504 => 'Gateway Timeout',
  70. 505 => 'HTTP Version Not Supported',
  71. 506 => 'Variant Also Negotiates (Experimental)',
  72. 507 => 'Insufficient Storage',
  73. 508 => 'Loop Detected',
  74. 510 => 'Not Extended',
  75. 511 => 'Network Authentication Required',
  76. );
  77. /**
  78. * @var EntityBodyInterface The response body
  79. */
  80. protected $body;
  81. /**
  82. * @var string The reason phrase of the response (human readable code)
  83. */
  84. protected $reasonPhrase;
  85. /**
  86. * @var string The status code of the response
  87. */
  88. protected $statusCode;
  89. /**
  90. * @var string Response protocol
  91. */
  92. protected $protocol = 'HTTP';
  93. /**
  94. * @var array Information about the request
  95. */
  96. protected $info = array();
  97. /**
  98. * @var RequestInterface Request object that may or may not be set
  99. */
  100. protected $request = null;
  101. /**
  102. * @var array Cacheable response codes (see RFC 2616:13.4)
  103. */
  104. protected $cacheResponseCodes = array(200, 203, 206, 300, 301, 410);
  105. /**
  106. * @var Response If a redirect was issued or an intermediate response was issued
  107. */
  108. protected $previous;
  109. /**
  110. * Create a new Response based on a raw response message
  111. *
  112. * @param string $message Response message
  113. *
  114. * @return Response|bool Returns false on error
  115. */
  116. public static function fromMessage($message)
  117. {
  118. $data = ParserRegistry::getInstance()->getParser('message')->parseResponse($message);
  119. if (!$data) {
  120. return false;
  121. }
  122. $response = new static($data['code'], $data['headers'], $data['body']);
  123. $response->setProtocol($data['protocol'], $data['version'])
  124. ->setStatus($data['code'], $data['reason_phrase']);
  125. // Set the appropriate Content-Length if the one set is inaccurate (e.g. setting to X)
  126. $contentLength = (string) $response->getHeader('Content-Length');
  127. $actualLength = strlen($data['body']);
  128. if (strlen($data['body']) > 0 && $contentLength != $actualLength) {
  129. $response->setHeader('Content-Length', $actualLength);
  130. }
  131. return $response;
  132. }
  133. /**
  134. * Construct the response
  135. *
  136. * @param string $statusCode The response status code (e.g. 200, 404, etc)
  137. * @param Collection|array $headers The response headers
  138. * @param string|resource|EntityBodyInterface $body The body of the response
  139. *
  140. * @throws BadResponseException if an invalid response code is given
  141. */
  142. public function __construct($statusCode, $headers = null, $body = null)
  143. {
  144. $this->setStatus($statusCode);
  145. $this->params = new Collection();
  146. $this->body = EntityBody::factory($body !== null ? $body : '');
  147. if ($headers) {
  148. if (!is_array($headers) && !($headers instanceof Collection)) {
  149. throw new BadResponseException('Invalid headers argument received');
  150. }
  151. foreach ($headers as $key => $value) {
  152. $this->addHeaders(array($key => $value));
  153. }
  154. }
  155. }
  156. /**
  157. * Convert the response object to a string
  158. *
  159. * @return string
  160. */
  161. public function __toString()
  162. {
  163. return $this->getMessage();
  164. }
  165. /**
  166. * Get the response entity body
  167. *
  168. * @param bool $asString Set to TRUE to return a string of the body rather than a full body object
  169. *
  170. * @return EntityBodyInterface|string
  171. */
  172. public function getBody($asString = false)
  173. {
  174. return $asString ? (string) $this->body : $this->body;
  175. }
  176. /**
  177. * Set the response entity body
  178. *
  179. * @param EntityBodyInterface|string $body Body to set
  180. *
  181. * @return self
  182. */
  183. public function setBody($body)
  184. {
  185. $this->body = EntityBody::factory($body);
  186. return $this;
  187. }
  188. /**
  189. * Set the protocol and protocol version of the response
  190. *
  191. * @param string $protocol Response protocol
  192. * @param string $version Protocol version
  193. *
  194. * @return Response
  195. */
  196. public function setProtocol($protocol, $version)
  197. {
  198. $this->protocol = $protocol;
  199. $this->protocolVersion = $version;
  200. return $this;
  201. }
  202. /**
  203. * Get the protocol used for the response (e.g. HTTP)
  204. *
  205. * @return string
  206. */
  207. public function getProtocol()
  208. {
  209. return $this->protocol ?: 'HTTP';
  210. }
  211. /**
  212. * Get the HTTP protocol version
  213. *
  214. * @return string
  215. */
  216. public function getProtocolVersion()
  217. {
  218. return $this->protocolVersion ?: '1.1';
  219. }
  220. /**
  221. * Get a cURL transfer information
  222. *
  223. * @param string $key A single statistic to check
  224. *
  225. * @return array|string|null Returns all stats if no key is set, a single stat if a key is set, or null if a key
  226. * is set and not found
  227. * @link http://www.php.net/manual/en/function.curl-getinfo.php
  228. */
  229. public function getInfo($key = null)
  230. {
  231. if ($key === null) {
  232. return $this->info;
  233. } elseif (array_key_exists($key, $this->info)) {
  234. return $this->info[$key];
  235. } else {
  236. return null;
  237. }
  238. }
  239. /**
  240. * Set the transfer information
  241. *
  242. * @param array $info Array of cURL transfer stats
  243. *
  244. * @return Response
  245. */
  246. public function setInfo(array $info)
  247. {
  248. $this->info = $info;
  249. return $this;
  250. }
  251. /**
  252. * Set the response status
  253. *
  254. * @param int $statusCode Response status code to set
  255. * @param string $reasonPhrase Response reason phrase
  256. *
  257. * @return Response
  258. * @throws BadResponseException when an invalid response code is received
  259. */
  260. public function setStatus($statusCode, $reasonPhrase = '')
  261. {
  262. $this->statusCode = (int) $statusCode;
  263. if (!$reasonPhrase && array_key_exists($this->statusCode, self::$statusTexts)) {
  264. $this->reasonPhrase = self::$statusTexts[$this->statusCode];
  265. } else {
  266. $this->reasonPhrase = $reasonPhrase;
  267. }
  268. return $this;
  269. }
  270. /**
  271. * Get the response status code
  272. *
  273. * @return integer
  274. */
  275. public function getStatusCode()
  276. {
  277. return $this->statusCode;
  278. }
  279. /**
  280. * Get the entire response as a string
  281. *
  282. * @return string
  283. */
  284. public function getMessage()
  285. {
  286. $message = $this->getRawHeaders();
  287. // Only include the body in the message if the size is < 2MB
  288. $size = $this->body->getSize();
  289. if ($size < 2097152) {
  290. $message .= (string) $this->body;
  291. }
  292. return $message;
  293. }
  294. /**
  295. * Get the the raw message headers as a string
  296. *
  297. * @return string
  298. */
  299. public function getRawHeaders()
  300. {
  301. $headers = 'HTTP/1.1 ' . $this->statusCode . ' ' . $this->reasonPhrase . "\r\n";
  302. $lines = $this->getHeaderLines();
  303. if (!empty($lines)) {
  304. $headers .= implode("\r\n", $lines) . "\r\n";
  305. }
  306. return $headers . "\r\n";
  307. }
  308. /**
  309. * Get the request object (or null) that is associated with this response
  310. *
  311. * @return RequestInterface
  312. */
  313. public function getRequest()
  314. {
  315. return $this->request;
  316. }
  317. /**
  318. * Get the response reason phrase- a human readable version of the numeric
  319. * status code
  320. *
  321. * @return string
  322. */
  323. public function getReasonPhrase()
  324. {
  325. return $this->reasonPhrase;
  326. }
  327. /**
  328. * Get the Accept-Ranges HTTP header
  329. *
  330. * @return string Returns what partial content range types this server supports.
  331. */
  332. public function getAcceptRanges()
  333. {
  334. return $this->getHeader('Accept-Ranges', true);
  335. }
  336. /**
  337. * Get the Age HTTP header
  338. *
  339. * @param bool $headerOnly Set to TRUE to only retrieve the Age header rather than calculating the age
  340. *
  341. * @return integer|null Returns the age the object has been in a proxy cache in seconds.
  342. */
  343. public function getAge($headerOnly = false)
  344. {
  345. $age = $this->getHeader('Age', true);
  346. if (!$headerOnly && $age === null && $this->getDate()) {
  347. $age = time() - strtotime($this->getDate());
  348. }
  349. return $age;
  350. }
  351. /**
  352. * Get the Allow HTTP header
  353. *
  354. * @return string|null Returns valid actions for a specified resource. To be used for a 405 Method not allowed.
  355. */
  356. public function getAllow()
  357. {
  358. return $this->getHeader('Allow', true);
  359. }
  360. /**
  361. * Check if an HTTP method is allowed by checking the Allow response header
  362. *
  363. * @param string $method Method to check
  364. *
  365. * @return bool
  366. */
  367. public function isMethodAllowed($method)
  368. {
  369. $allow = $this->getHeader('Allow');
  370. if ($allow) {
  371. foreach (explode(',', $allow) as $allowable) {
  372. if (!strcasecmp(trim($allowable), $method)) {
  373. return true;
  374. }
  375. }
  376. }
  377. return false;
  378. }
  379. /**
  380. * Get the Cache-Control HTTP header
  381. *
  382. * @return Header|null Returns a Header object that tells all caching mechanisms from server to client whether they
  383. * may cache this object.
  384. */
  385. public function getCacheControl()
  386. {
  387. return $this->getHeader('Cache-Control');
  388. }
  389. /**
  390. * Get the Connection HTTP header
  391. *
  392. * @return string
  393. */
  394. public function getConnection()
  395. {
  396. return $this->getHeader('Connection', true);
  397. }
  398. /**
  399. * Get the Content-Encoding HTTP header
  400. *
  401. * @return string|null Returns the type of encoding used on the data. One of compress, deflate, gzip, identity.
  402. */
  403. public function getContentEncoding()
  404. {
  405. return $this->getHeader('Content-Encoding', true);
  406. }
  407. /**
  408. * Get the Content-Language HTTP header
  409. *
  410. * @return string|null Returns the language the content is in.
  411. */
  412. public function getContentLanguage()
  413. {
  414. return $this->getHeader('Content-Language', true);
  415. }
  416. /**
  417. * Get the Content-Length HTTP header
  418. *
  419. * @return integer Returns the length of the response body in bytes
  420. */
  421. public function getContentLength()
  422. {
  423. return (int) $this->getHeader('Content-Length', true);
  424. }
  425. /**
  426. * Get the Content-Location HTTP header
  427. *
  428. * @return string|null Returns an alternate location for the returned data (e.g /index.htm)
  429. */
  430. public function getContentLocation()
  431. {
  432. return $this->getHeader('Content-Location', true);
  433. }
  434. /**
  435. * Get the Content-Disposition HTTP header
  436. *
  437. * @return string|null Returns the Content-Disposition header
  438. */
  439. public function getContentDisposition()
  440. {
  441. return (string) $this->getHeader('Content-Disposition')->setGlue(';');
  442. }
  443. /**
  444. * Get the Content-MD5 HTTP header
  445. *
  446. * @return string|null Returns a Base64-encoded binary MD5 sum of the content of the response.
  447. */
  448. public function getContentMd5()
  449. {
  450. return $this->getHeader('Content-MD5', true);
  451. }
  452. /**
  453. * Get the Content-Range HTTP header
  454. *
  455. * @return string Returns where in a full body message this partial message belongs (e.g. bytes 21010-47021/47022).
  456. */
  457. public function getContentRange()
  458. {
  459. return $this->getHeader('Content-Range', true);
  460. }
  461. /**
  462. * Get the Content-Type HTTP header
  463. *
  464. * @return string Returns the mime type of this content.
  465. */
  466. public function getContentType()
  467. {
  468. return $this->getHeader('Content-Type', true);
  469. }
  470. /**
  471. * Checks if the Content-Type is of a certain type. This is useful if the
  472. * Content-Type header contains charset information and you need to know if
  473. * the Content-Type matches a particular type.
  474. *
  475. * @param string $type Content type to check against
  476. *
  477. * @return bool
  478. */
  479. public function isContentType($type)
  480. {
  481. return stripos($this->getContentType(), $type) !== false;
  482. }
  483. /**
  484. * Get the Date HTTP header
  485. *
  486. * @return string|null Returns the date and time that the message was sent.
  487. */
  488. public function getDate()
  489. {
  490. return $this->getHeader('Date', true);
  491. }
  492. /**
  493. * Get the ETag HTTP header
  494. *
  495. * @return string|null Returns an identifier for a specific version of a resource, often a Message digest.
  496. */
  497. public function getEtag()
  498. {
  499. $etag = $this->getHeader('ETag', true);
  500. return $etag ? str_replace('"', '', $etag) : null;
  501. }
  502. /**
  503. * Get the Expires HTTP header
  504. *
  505. * @return string|null Returns the date/time after which the response is considered stale.
  506. */
  507. public function getExpires()
  508. {
  509. return $this->getHeader('Expires', true);
  510. }
  511. /**
  512. * Get the Last-Modified HTTP header
  513. *
  514. * @return string|null Returns the last modified date for the requested object, in RFC 2822 format
  515. * (e.g. Tue, 15 Nov 1994 12:45:26 GMT)
  516. */
  517. public function getLastModified()
  518. {
  519. return $this->getHeader('Last-Modified', true);
  520. }
  521. /**
  522. * Get the Location HTTP header
  523. *
  524. * @return string|null Used in redirection, or when a new resource has been created.
  525. */
  526. public function getLocation()
  527. {
  528. return $this->getHeader('Location', true);
  529. }
  530. /**
  531. * Get the Pragma HTTP header
  532. *
  533. * @return Header|null Returns the implementation-specific headers that may have various effects anywhere along
  534. * the request-response chain.
  535. */
  536. public function getPragma()
  537. {
  538. return $this->getHeader('Pragma');
  539. }
  540. /**
  541. * Get the Proxy-Authenticate HTTP header
  542. *
  543. * @return string|null Authentication to access the proxy (e.g. Basic)
  544. */
  545. public function getProxyAuthenticate()
  546. {
  547. return $this->getHeader('Proxy-Authenticate', true);
  548. }
  549. /**
  550. * Get the Retry-After HTTP header
  551. *
  552. * @return int|null If an entity is temporarily unavailable, this instructs the client to try again after a
  553. * specified period of time.
  554. */
  555. public function getRetryAfter()
  556. {
  557. $time = $this->getHeader('Retry-After', true);
  558. if ($time === null) {
  559. return null;
  560. }
  561. if (!is_numeric($time)) {
  562. $time = strtotime($time) - time();
  563. }
  564. return (int) $time;
  565. }
  566. /**
  567. * Get the Server HTTP header
  568. *
  569. * @return string|null A name for the server
  570. */
  571. public function getServer()
  572. {
  573. return $this->getHeader('Server', true);
  574. }
  575. /**
  576. * Get the Set-Cookie HTTP header
  577. *
  578. * @return Header|null An HTTP cookie.
  579. */
  580. public function getSetCookie()
  581. {
  582. return $this->getHeader('Set-Cookie');
  583. }
  584. /**
  585. * Get the Trailer HTTP header
  586. *
  587. * @return string|null The Trailer general field value indicates that the given set of header fields is present in
  588. * the trailer of a message encoded with chunked transfer-coding.
  589. */
  590. public function getTrailer()
  591. {
  592. return $this->getHeader('Trailer', true);
  593. }
  594. /**
  595. * Get the Transfer-Encoding HTTP header
  596. *
  597. * @return string|null The form of encoding used to safely transfer the entity to the user. Currently defined
  598. * methods are: chunked
  599. */
  600. public function getTransferEncoding()
  601. {
  602. return $this->getHeader('Transfer-Encoding', true);
  603. }
  604. /**
  605. * Get the Vary HTTP header
  606. *
  607. * @return string|null Tells downstream proxies how to match future request headers to decide whether the cached
  608. * response can be used rather than requesting a fresh one from the origin server.
  609. */
  610. public function getVary()
  611. {
  612. return $this->getHeader('Vary', true);
  613. }
  614. /**
  615. * Get the Via HTTP header
  616. *
  617. * @return string|null Informs the client of proxies through which the response was sent.
  618. * (e.g. 1.0 fred, 1.1 nowhere.com (Apache/1.1))
  619. */
  620. public function getVia()
  621. {
  622. return $this->getHeader('Via', true);
  623. }
  624. /**
  625. * Get the Warning HTTP header
  626. *
  627. * @return string|null A general warning about possible problems with the entity body.
  628. * (e.g. 199 Miscellaneous warning)
  629. */
  630. public function getWarning()
  631. {
  632. return $this->getHeader('Warning', true);
  633. }
  634. /**
  635. * Get the WWW-Authenticate HTTP header
  636. *
  637. * @return string|null Indicates the authentication scheme that should be used to access the requested entity
  638. * (e.g. Basic)
  639. */
  640. public function getWwwAuthenticate()
  641. {
  642. return $this->getHeader('WWW-Authenticate', true);
  643. }
  644. /**
  645. * Checks if HTTP Status code is a Client Error (4xx)
  646. *
  647. * @return bool
  648. */
  649. public function isClientError()
  650. {
  651. return $this->statusCode >= 400 && $this->statusCode < 500;
  652. }
  653. /**
  654. * Checks if HTTP Status code is Server OR Client Error (4xx or 5xx)
  655. *
  656. * @return boolean
  657. */
  658. public function isError()
  659. {
  660. return $this->isClientError() || $this->isServerError();
  661. }
  662. /**
  663. * Checks if HTTP Status code is Information (1xx)
  664. *
  665. * @return bool
  666. */
  667. public function isInformational()
  668. {
  669. return $this->statusCode < 200;
  670. }
  671. /**
  672. * Checks if HTTP Status code is a Redirect (3xx)
  673. *
  674. * @return bool
  675. */
  676. public function isRedirect()
  677. {
  678. return $this->statusCode >= 300 && $this->statusCode < 400;
  679. }
  680. /**
  681. * Checks if HTTP Status code is Server Error (5xx)
  682. *
  683. * @return bool
  684. */
  685. public function isServerError()
  686. {
  687. return $this->statusCode >= 500 && $this->statusCode < 600;
  688. }
  689. /**
  690. * Checks if HTTP Status code is Successful (2xx | 304)
  691. *
  692. * @return bool
  693. */
  694. public function isSuccessful()
  695. {
  696. return ($this->statusCode >= 200 && $this->statusCode < 300) || $this->statusCode == 304;
  697. }
  698. /**
  699. * Set the request object associated with the response
  700. *
  701. * @param RequestInterface $request The request object used to generate the response
  702. *
  703. * @return Response
  704. */
  705. public function setRequest(RequestInterface $request)
  706. {
  707. $this->request = $request;
  708. return $this;
  709. }
  710. /**
  711. * Check if the response can be cached
  712. *
  713. * @return bool Returns TRUE if the response can be cached or false if not
  714. */
  715. public function canCache()
  716. {
  717. // Check if the response is cacheable based on the code
  718. if (!in_array((int) $this->getStatusCode(), $this->cacheResponseCodes)) {
  719. return false;
  720. }
  721. // Make sure a valid body was returned and can be cached
  722. if ((!$this->getBody()->isReadable() || !$this->getBody()->isSeekable())
  723. && ($this->getContentLength() > 0 || $this->getTransferEncoding() == 'chunked')) {
  724. return false;
  725. }
  726. // Never cache no-store resources (this is a private cache, so private
  727. // can be cached)
  728. if ($this->hasCacheControlDirective('no-store')) {
  729. return false;
  730. }
  731. return $this->isFresh() || $this->getFreshness() === null || $this->canValidate();
  732. }
  733. /**
  734. * Gets the number of seconds from the current time in which this response is still considered fresh
  735. *
  736. * @return int|null Returns the number of seconds
  737. */
  738. public function getMaxAge()
  739. {
  740. // s-max-age, then max-age, then Expires
  741. if ($age = $this->getCacheControlDirective('s-maxage')) {
  742. return $age;
  743. }
  744. if ($age = $this->getCacheControlDirective('max-age')) {
  745. return $age;
  746. }
  747. if ($this->getHeader('Expires')) {
  748. return strtotime($this->getExpires()) - time();
  749. }
  750. return null;
  751. }
  752. /**
  753. * Check if the response is considered fresh.
  754. *
  755. * A response is considered fresh when its age is less than the freshness lifetime (maximum age) of the response.
  756. *
  757. * @return bool|null
  758. */
  759. public function isFresh()
  760. {
  761. $fresh = $this->getFreshness();
  762. return $fresh === null ? null : $this->getFreshness() > 0;
  763. }
  764. /**
  765. * Check if the response can be validated against the origin server using a conditional GET request.
  766. *
  767. * @return bool
  768. */
  769. public function canValidate()
  770. {
  771. return $this->getEtag() || $this->getLastModified();
  772. }
  773. /**
  774. * Get the freshness of the response by returning the difference of the maximum lifetime of the response and the
  775. * age of the response (max-age - age).
  776. *
  777. * Freshness values less than 0 mean that the response is no longer fresh and is ABS(freshness) seconds expired.
  778. * Freshness values of greater than zero is the number of seconds until the response is no longer fresh. A NULL
  779. * result means that no freshness information is available.
  780. *
  781. * @return int
  782. */
  783. public function getFreshness()
  784. {
  785. $maxAge = $this->getMaxAge();
  786. $age = $this->getAge();
  787. return $maxAge && $age ? ($maxAge - $age) : null;
  788. }
  789. /**
  790. * Get the previous response (e.g. Redirect response)
  791. *
  792. * @return null|Response
  793. */
  794. public function getPreviousResponse()
  795. {
  796. return $this->previous;
  797. }
  798. /**
  799. * Set the previous response
  800. *
  801. * @param Response $response Response to set
  802. *
  803. * @return self
  804. */
  805. public function setPreviousResponse(Response $response)
  806. {
  807. $this->previous = $response;
  808. return $this;
  809. }
  810. /**
  811. * Parse the JSON response body and return an array
  812. *
  813. * @return array
  814. * @throws RuntimeException if the response body is not in JSON format
  815. */
  816. public function json()
  817. {
  818. $data = json_decode((string) $this->body, true);
  819. if (JSON_ERROR_NONE !== json_last_error()) {
  820. throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error());
  821. }
  822. return $data ?: array();
  823. }
  824. /**
  825. * Parse the XML response body and return a SimpleXMLElement
  826. *
  827. * @return \SimpleXMLElement
  828. * @throws RuntimeException if the response body is not in XML format
  829. */
  830. public function xml()
  831. {
  832. try {
  833. // Allow XML to be retrieved even if there is no response body
  834. $xml = new \SimpleXMLElement((string) $this->body ?: '<root />');
  835. } catch (\Exception $e) {
  836. throw new RuntimeException('Unable to parse response body into XML: ' . $e->getMessage());
  837. }
  838. return $xml;
  839. }
  840. }