Beispiel #1
0
 /**
  *send a query to the CouchDB server
  *
  * In a continuous query, the server send headers, and then a JSON object per line.
  * On each line received, the $callable callback is fired, with two arguments :
  *
  * - the JSON object decoded as a PHP object
  *
  * - a couchClient instance to use to make queries inside the callback
  *
  * If the callable returns the boolean FALSE , continuous reading stops.
  *
  * @param callable $callable PHP function name / callable array ( see http://php.net/is_callable )
  * @param string $method HTTP method to use (GET, POST, ...)
  * @param string $url URL to fetch
  * @param array $parameters additionnal parameters to send with the request
  * @param string|array|object $data request body
  *
  * @return string|false server response on success, false on error
  */
 public function continuousQuery($callable, $method, $url, $parameters = array(), $data = null)
 {
     if (!in_array($method, $this->HTTP_METHODS)) {
         throw new Exception("Bad HTTP method: {$method}");
     }
     if (!is_callable($callable)) {
         throw new InvalidArgumentException("callable argument have to success to is_callable PHP function");
     }
     if (is_array($parameters) and count($parameters)) {
         $url = $url . '?' . http_build_query($parameters);
     }
     //Send the request to the socket
     $request = $this->_socket_buildRequest($method, $url, $data, null);
     if (!$this->_connect()) {
         return FALSE;
     }
     fwrite($this->socket, $request);
     //Read the headers and check that the response is valid
     $response = '';
     $code = 0;
     $headers = false;
     while (!feof($this->socket) && !$headers) {
         $response .= fgets($this->socket);
         if ($response == "HTTP/1.1 100 Continue\r\n\r\n") {
             $response = '';
             continue;
         } elseif (preg_match("/\r\n\r\n\$/", $response)) {
             $headers = true;
         }
     }
     $headers = explode("\n", trim($response));
     $split = explode(" ", trim(reset($headers)));
     $code = $split[1];
     unset($split);
     //If an invalid response is sent, read the rest of the response and throw an appropriate couchException
     if (!in_array($code, array(200, 201))) {
         stream_set_blocking($this->socket, false);
         $response .= stream_get_contents($this->socket);
         fclose($this->socket);
         throw couchException::factory($response, $method, $url, $parameters);
     }
     //For as long as the socket is open, read lines and pass them to the callback
     $c = clone $this;
     while ($this->socket && !feof($this->socket)) {
         $e = NULL;
         $e2 = NULL;
         $read = array($this->socket);
         if (false === ($num_changed_streams = stream_select($read, $e, $e2, 1))) {
             $this->socket = null;
         } elseif ($num_changed_streams > 0) {
             $line = fgets($this->socket);
             if (strlen(trim($line))) {
                 $break = call_user_func($callable, json_decode($line), $c);
                 if ($break === FALSE) {
                     fclose($this->socket);
                 }
             }
         }
     }
     return $code;
 }
Beispiel #2
0
 /**
  * helper method to execute the following algorithm :
  *
  * query the couchdb server
  * test the status_code
  * return the response body on success, throw an exception on failure
  *
  * @param string $method HTTP method (GET, POST, ...)
  * @param string $url URL to fetch
  * @param $array $allowed_status_code the list of HTTP response status codes that prove a successful request
  * @param array $parameters additionnal parameters to send with the request
  * @param string|object|array $data the request body. If it's an array or an object, $data is json_encode()d
  * @param string $content_type set the content-type of the request
  */
 protected function _queryAndTest($method, $url, $allowed_status_codes, $parameters = array(), $data = NULL, $content_type = NULL)
 {
     $raw = $this->query($method, $url, $parameters, $data, $content_type);
     $response = $this->parseRawResponse($raw, $this->results_as_array);
     $this->results_as_array = $this->default_as_array;
     if (in_array($response['status_code'], $allowed_status_codes)) {
         return $response['body'];
     }
     throw couchException::factory($response, $method, $url, $parameters);
     return FALSE;
 }