Accessing CouchDB with Zend Framework using Phly_Couch

If you have never heard of CouchDB here is the first Paragraph from the Apache CouchDB project documentation: A CouchDB server hosts named databases, which store documents. Each document is uniquely named in the database, and CouchDB provides a RESTful HTTP API for reading and updating (add, edit, delete) database documents.
You can also read the free CouchDB book here.

The easiest way to get started is to sign up for a free CouchDB instance here.

In this tutorial I’m going to show you a quick way of getting CouchDb working with Zend Framework.

I’m assuming you already have a Zend Framework project setup if not get the quickstart here.

Since the Zend Framework doesn’t currently support CouchDB a separate library is required.
Matthew Weier O’Phinney has written a nice library that provides most of the functionality required to work with CouchDB. You can download Phly_Couch here. Once downloaded extract it to your projects library directory.

Add this to your application.ini and modify with your info.

couchDb.host  = "username:password@youraccount.couchone.com"
couchDb.db    = "yourdb"
couchDb.port  = 80

Add this method to your Bootstrap.php

    /**
     * Adds configuration to Zend_Registry
     * Retrieval example: Zend_Registry::get('config')->couchDb->db
     * @return Zend_Config
     */
    protected function _initConfig()
    {
        $config = new Zend_Config($this->getOptions());
        Zend_Registry::set('config', $config);
        return $config;
    }


Use the following code to access your CouchDB instance.

    // Establish connection
    $couch = new Phly_Couch(Zend_Registry::get('config')->couchDb);
       
    // Create a new document
    $testId = uniqid('TEST-',true);
    $document = new Phly_Couch_Document($testId); 
    $document->id = "NewPage"; 
    $document->title = "New Page"; 
    $document->content = "This is a new wiki page!"; 
    $document->created = date('Y-m-d H:i:s'); 
    $document->tags    = array('wiki', 'system');
    $couch->docSave($document);
       
    // Read Document
    $document = $couch->docOpen($testId);
    if ($document->getId() != $testId) throw new Exception("ID's do not match. ID=" . $document->getId());
        
    // Delete a document
    $document = $couch->docRemove($testId,
        array(
            'rev' => $document->getRevision()
    ));

UPDATE:
I had forgotten that I had made some changes to Phly_Couch. I have uploaded the code to Google Code. You can download it here

12 comments

  1. Thank you for usefull tips!
    By the way, Phly_Couch is not correctly working with CouchDB v.1.0. There is problem In Phly_Couch->docSave() function with content-type, CouchDB requires json.

  2. Problem above easily solved by replacing string 412 in Couch.php to

    $this->getHttpClient()->setRawData($document->toJson(), ‘application/json’);

  3. Thanks for reminding me I had to add this line
    $this->getHttpClient()->setHeaders(“Content-type: application/json”);
    at the start of the _prepareAndSend function


  4. John T. Clark:

    Thanks for reminding me I had to add this line
    $this->getHttpClient()->setHeaders(“Content-type: application/json”);
    at the start of the _prepareAndSend function

    Well, yeah, that’s the better solution.)

  5. I also added a case to catch that particular error in the docSave function

    case 415:
                    require_once 'Phly/Couch/Exception.php';
                    throw new Phly_Couch_Exception(sprintf('Content-Type must be application/json. %s', $this->getHttpClient()->getUri().$document->toJson()));
                    break;
    
  6. I wonder are we the only people on Earth (exсept Matthew Weier) who tried to use CouchDB with Zend Framework? 🙂 I though they are the hottest techs in web-world for now.

  7. Well, during exploring Phly_Couch I found another bug in Phly_Couch::view() function. May be I’m not using it in a right way.

    I have view

    {
    “_id”: “_design/papers”,
    “_rev”: “2-ff28999841838be8755188cb13070275”,
    “views”: {
    “all”: {
    “map”: “function(doc){ emit(doc._id, doc.title)}”
    }
    }
    }

    And I can access it via this URI “/db_name/_design/papers/_view/all”.

    Phly_Couch::view($name, array $options = null) accepts $name as part of requesting URI and makes “$db . ‘/_view/’ . $name” path instead of correct one: “$db . ‘/_design/’ . $name”. If pass $name = “papers/_view/all” we’ll get correct answer.
    So I changed line 512 to

    $response = $this->_prepareAndSend($db . ‘/_design/’ . $name, ‘GET’, $options);

    $name must be “view_name/_view/map_function_name”.

    John, is there way to apply all these changes to Phly github?

  8. The connection is fine when using couchDB on a localhost.
    But when I try to connect to a different server I have to us HTTP instead of TCP. How can I switch, do I have to set my own client?

  9. There was a bug at line 543 in Couch.php that causes deletes to fail. ( Aleast with PHP 5.3.2 ). The json_decode causes the rev to altered so that couchdb ( version 1.2.0a1068028 ) throws a {“error”:”unknown_error”,”reason”:”badarg”}.

    changing it from
    $queryParams[$key] = json_encode($value);
    to
    $queryParams[$key] = urlencode($value);
    fixes it. At least for my needs.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.