Return-Path: Delivered-To: apmail-incubator-couchdb-commits-archive@locus.apache.org Received: (qmail 6067 invoked from network); 12 Apr 2008 13:47:22 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 12 Apr 2008 13:47:22 -0000 Received: (qmail 43237 invoked by uid 500); 12 Apr 2008 13:47:22 -0000 Delivered-To: apmail-incubator-couchdb-commits-archive@incubator.apache.org Received: (qmail 43211 invoked by uid 500); 12 Apr 2008 13:47:22 -0000 Mailing-List: contact couchdb-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: couchdb-dev@incubator.apache.org Delivered-To: mailing list couchdb-commits@incubator.apache.org Received: (qmail 43202 invoked by uid 99); 12 Apr 2008 13:47:22 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 12 Apr 2008 06:47:22 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.130] (HELO eos.apache.org) (140.211.11.130) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 12 Apr 2008 13:46:39 +0000 Received: from eos.apache.org (localhost [127.0.0.1]) by eos.apache.org (Postfix) with ESMTP id 17E80D2D5 for ; Sat, 12 Apr 2008 13:46:59 +0000 (GMT) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Apache Wiki To: couchdb-commits@incubator.apache.org Date: Sat, 12 Apr 2008 13:46:59 -0000 Message-ID: <20080412134659.9411.64544@eos.apache.org> Subject: [Couchdb Wiki] Update of "GettingStartedWithPhp2" by NoahSlater X-Virus-Checked: Checked by ClamAV on apache.org Dear Wiki user, You have subscribed to a wiki page or wiki category on "Couchdb Wiki" for change notification. The following page has been changed by NoahSlater: http://wiki.apache.org/couchdb/GettingStartedWithPhp2 The comment on the change is: Merged with GettingStartedWithPhp ------------------------------------------------------------------------------ - = More About Getting Started With PHP and CouchDB: A Pastebin Example = + deleted - == A CouchDB Response Class == - - We'll use the following class as a structure for storing and handling responses to our HTTP requests to the DB. Instances of this will store response components, namely the headers and body, in appropriately named properties. Eventually we might want to do more error checking based on the headers, etc. For this example, we'll be most interested in ''CouchDBResponse::getBody()''. It returns either the text of the response or the data structure derived from decoding the JSON response based on the method's only parameter, ''$decode_json''. Inside the ''getBody'' method, we call a static method ''decode_json'' that lives in our as-yet-unwritten ''CouchDB'' class. We'll get to that soon enough, but all it really does in this example is wrap a call to the PHP json extension's ''json_decode'' function. - - {{{ - class CouchDBResponse { - - private $raw_response = ''; - private $headers = ''; - private $body = ''; - - function __construct($response = '') { - $this->raw_response = $response; - list($this->headers, $this->body) = explode("\r\n\r\n", $response); - } - - function getRawResponse() { - return $this->raw_response; - } - - function getHeaders() { - return $this->headers; - } - - function getBody($decode_json = false) { - return $decode_json ? CouchDB::decode_json($this->body) : $this->body; - } - } - }}} - - == A CouchDB Request Class == - - Now that we have a response class, we need something to organize our requests. This class will 1) build request headers and assemble the request, 2) send the request and 3) give us the interesting part of the result. Following [:GettingStartedWithPhp:Noah Slater's lead], we make our requests using ''fsockopen'', which allows us to treat our connection to the CouchDB server as a file pointer. When we execute the request, we pass the response on to a new ''CouchDBRequest'' object. - - {{{ - class CouchDBRequest { - - static $VALID_HTTP_METHODS = array('DELETE', 'GET', 'POST', 'PUT'); - - private $method = 'GET'; - private $url = ''; - private $data = NULL; - private $sock = NULL; - - function __construct($host, $port = 5984, $url, $method = 'GET', $data = NULL) { - $method = strtoupper($method); - $this->host = $host; - $this->port = $port; - $this->url = $url; - $this->method = $method; - $this->data = $data; - - if(!in_array($this->method, self::$VALID_HTTP_METHODS)) { - throw new CouchDBException('Invalid HTTP method: '.$this->method); - } - } - - function getRequest() { - $req = "{$this->method} {$this->url} HTTP/1.0\r\nHost: {$this->host}\r\n"; - if($this->data) { - $req .= 'Content-Length: '.strlen($this->data)."\r\n"; - $req .= 'Content-Type: text/javascript'."\r\n\r\n"; - $req .= $this->data."\r\n"; - } else { - $req .= "\r\n"; - } - - return $req; - } - - private function connect() { - $this->sock = @fsockopen($this->host, $this->port, $err_num, $err_string); - if(!$this->sock) { - throw new CouchDBException('Could not open connection to '.$this->host.':'.$this->port.' ('.$err_string.')'); - } - } - - private function disconnect() { - fclose($this->sock); - $this->sock = NULL; - } - - private function execute() { - fwrite($this->sock, $this->getRequest()); - $response = ''; - while(!feof($this->sock)) { - $response .= fgets($this->sock); - } - $this->response = new CouchDBResponse($response); - return $this->response; - } - - function send() { - $this->connect(); - $this->execute(); - $this->disconnect(); - return $this->response; - } - - function getResponse() { - return $this->response; - } - } - }}} - - == The CouchDB Class == - - The CouchDB class provides a ''send'' method for sending requests to the CouchDB server. It uses the ''CouchDBRequest'' class above and returns a ''CouchDBResponse'' object. This class also provides a method for fetching all documents in a database, using the ''_all_docs'' built-in view. I've also included a ''get_item'' method for fetching a document with its id. Clearly, further abstraction for different types of queries, etc. should follow, but this is enough for us to get at the data in our database. - - {{{ - class CouchDB { - - function __construct($db, $host = 'localhost', $port = 5984) { - $this->db = $db; - $this->host = $host; - $this->port = $port; - } - - static function decode_json($str) { - return json_decode($str); - } - - static function encode_json($str) { - return json_encode($str); - } - - function send($url, $method = 'get', $data = NULL) { - $url = '/'.$this->db.(substr($url, 0, 1) == '/' ? $url : '/'.$url); - $request = new CouchDBRequest($this->host, $this->port, $url, $method, $data); - return $request->send(); - } - - function get_all_docs() { - return $this->send('/_all_docs'); - } - - function get_item($id) { - return $this->send('/'.$id); - } - } - }}} - - == Using Our CouchDB Class == - - The following is some code just playing around with our pastebin data, which we assume contains the fields title, body, created, and status. - - {{{ - // we get a new CouchDB object that will use the 'pastebin' db - $couchdb = new CouchDB('pastebin'); - try { - $result = $couchdb->get_all_docs(); - } catch(CouchDBException $e) { - die($e->errorMessage()."\n"); - } - // here we get the decoded json from the response - $all_docs = $result->getBody(true); - - // then we can iterate through the returned rows and fetch each item using its id. - foreach($all_docs->rows as $r => $row) { - print_r($couchdb->get_item($row->id)); - } - - // if we want to find only pastebin items that are currently published, we need to do a little more. - // below, we create a view using a javascript function passed in the post data. - $view = <<send('/_temp_view', 'post', $view); - print $view_result->getBody(); - - }}} -