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

Share

For my latest project, I was determined to avoid confusing Ajax requests by implementing my own JSON-RPC. Again, Zend Framework has made this incredibly easy.

The documentation recommends not running your Ajax request through the MVC. At first I was a little concerned, but it makes sense as the MVC does add a lot of unnecessary overhead.

I found this blog very helpful in figuring out how to do this.
The first step is to create a new bootstrap file.
I created one in public/api/1.0/jsonrpc.php

Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath('../../../library'),
    get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$application->getBootstrap()
            ->bootstrap('doctrine')
            ->bootstrap('config');

// Instantiate server, etc.
$server = new Zend_Json_Server();
$server->setClass('App_Model_JsonRpc');

if ('GET' == $_SERVER['REQUEST_METHOD']) {
    // Indicate the URL endpoint, and the JSON-RPC version used:
    $server->setTarget('/api/1.0/jsonrpc.php')
           ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);

    // Grab the SMD
    $smd = $server->getServiceMap();

    // Return the SMD to the client
    header('Content-Type: application/json');
    echo $smd;
    return;
}

$server->handle();

You may want to modify the $application->getBootstrap() line and add/remove bootstrap methods depending on your requirements. I need access to my database within my JSON-RPC server and use Doctrine as my ORM so I bootstrap that.

The most important line is:

$server->setClass('App_Model_JsonRpc');

This tells the server what class should handle all the JSON requests.

I also added a RedirectRule in my .htaccess file to hide the php extension. It’s unnecessary but the .php extension isn’t seen anywhere else on my site so I don’t want it on my JSON RPC server either.
I added this line…

RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]

…between these two lines:

RewriteRule ^.*$ - [NC,L]
RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]
RewriteRule ^.*$ index.php [NC,L]


I then created a class called App_Model_JsonRpc and put it in my models directory.
/application/models/JsonRpc.php

class App_Model_JsonRpc
{

    /**
     * Return sum of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return array
     */
    public function add($x, $y)
    {
        return  $x + $y;
    }
}

The doc blocks are very important as Zend_Json_Server generates the SMD based on the contents of the Doc block.

That’s it for the server. Send it the proper JSON code and it will add 2 numbers together and return the result.

Heres a quick example of how to use your new server.
I recommend installing the ZendJsonRpc jQuery plugin as it makes talking to your server much easier. You can download the plugin here.



That’s it!

Share

I can’t say I learned a lot at school, but I did pick up a few tips that helped me polish up my self-taught coding technique.

During my study of software engineering, my instructors always stressed two things: modular design and documentation. Simple, yet excellent concepts that will save you–and anyone after you–hours and hours of time. I’ve been applying these principles to all of my code ever since I learned about them, but I’ve only recently begun to understand just how important they really are.

I’ve been working with some very unmodularized and undocumented code recently, and I’ve begun to develop an immense dislike for the original author. I’m supposed to add simple little features here and there. By themselves, the features are simple–around 10 to 100 lines each–and would take maybe 10 minutes each to write. To add them to a well-documented, modular coded project might take an hour or two including some testing. But incorporating these tiny features into an existing project base consisting of unmodularized and undocumented code takes 10 to 20 times that. Believe me, I know from experience. I am faced with the constant urge to rewrite the entire code base from scratch. I know it would take longer to rewrite everything, but I have to say it would be much less painful.

Logical code is easy to follow and easy to change. If something is a little strange, then you fall back on the documentation to figure out why. But when the code is an absolute pile of garbage with no documentation, looking like it was written by a first-time coding high schooler, you spend most of your time trying to figure out why the previous author did what they did, how they did it, and why they were ever allowed to touch a computer keyboard in the first place.

 


The problem increases exponentially when dealing with web projects, especially ones coded in PHP. Modular design in web projects has always been possible but somewhat awkward, considering that up until PHP 5 we had very poor object support. Only in the last few years have there been any decent frameworks to use that employ an MVC structure. My favourite one, of course, is Zend Framework. Before the Zend Framework, I personally had been working on an MVC-like PHP framework of my own to help alleviate the somewhat cumbersome structure that even my PHP projects were sometimes taking. After trying the Zend Framework, I never touched my own framework again.

Having come to realize the power of a good PHP framework and the importance of documentation and modularized code, it just makes me want to cry–and wish horrible things upon the original author whose code is making my job so much more difficult than it should be.

Share

Version Control Can Be Dangerous

Version control for a website sounds like a great idea. Everyone wants to be able to make risk-free changes to their website. It’s a great feeling to know that at any given time you can revert to previous versions of files. With a VCS (Version Control System) like Subversion, you get a nice central location for all your code, a web interface to browse your files and, well, it’s a great thing to brag about to all your techie friends. The only problem is that it can seriously screw up your web development workflow if the implementation of such a system is not thought out carefully.

One Dilly of a Pickle

The biggest potential hurdle in setting up a VCS for web development is the web server. Unless you’re an HTML-only web developer (hopefully they don’t even exist anymore), then you either have a special development web server set up or you use your live web server to test out your scripts. Once you’ve figured out how to check your files in and out via your VCS, you’ll realize that you need to get these files to your web server. If you don’t have root access to your server, you might be in trouble. At this point you’ll want to stop everything and re-evaluate implementing VCS into your web development workflow. I’ve had to re-evaluate my processes a few times and the following describes what I’ve learned about various web workflow methods I have experimented with, as well as a detailed description of my current web development workflow.

 

Remote Web and Subversion Server Accessed by Samba Share…

…a theoretically simple setup, but practically, it turned about to be a nightmare. I set up a basic LAMP box and also installed Subversion on it. I also set up a Samba share and created Apache virtual hosts to map to those shares. The theory was that I would check out files from the Subversion server to my local machine to a network drive mapped to the Samba share. So when working on files I could just CTRL+S and see my changes immediately on the remote server. When I was happy with the changes I would commit them. This setup almost worked, except for the checking in part. I kept getting file permission errors whenever I tried commit due to the Windows Subversion client not having permissions to write to the Samba share. I spent quite awhile trying to figure out what was going on, but I knew that if it takes this much effort to get it working, then no thanks. I don’t like my development to be put on hold because I can’t save my work properly.

There was one additional disadvantage of this method. By using Samba shares, I was limited to only local development unless I wanted to use VPN or SSH tunnels. It was time to move on.

Remote Web and Subversion Server with Files Checked in to Test

This method involves having Subversion installed to your web server and having it automatically export your project on commit to your web directory. This works pretty well. Your code is safe, as it’s checked in to your server constantly. The only problem is that checking in a file every time you make a change gets very annoying very quickly. There’s also the post-commit script that has to be configured properly, and if you have multiple projects you’ll have to account for that in your post-commit script. In my opinion, it’s not worth the trouble.

 

How I Do It

I use three machines for development: an iMac running OS X 10.6 and a ThinkPad running Windows 7 at home, and a PC running Vista at work.

On each of these machines, I use Zend Studio 7.1 as my IDE and Zend Server CE 5.0 as my local web server.

Each one of my projects gets its own repository on my Subversion service hosted by Springloops. In most cases, for each project I have two deployment servers set up: one for production and one for staging.

Zend Studio handles all my Subversion tasks, although I sometimes use Tortoise SVN (Windows) or a terminal (Mac or Linux) for other non-code-related files.

I set up virtual hosts to point to each one of my projects’ working copy located in my Zend Studio workspaces folder.

My Typical Coding Session

My typical coding session would go like this:

Update local working copy of my project in Zend Studio.

Write some code and test on local development web server (Zend Server CE).

When I’m happy with those changes, I will commit them in Zend Studio, and then Springloops will automatically deploy the code to my staging server.

Once the site has been fully tested, I log in to my Springloops account and manually deploy my site to my production server.

But What About Databases?

You may have noticed I haven’t mentioned databases. Due to the potentially catastrophic issues that could occur from mixing staging and production databases, I keep them separate. I use both local and remote MySQL servers, depending on the type of project. I manually syncronize them when necessary by using phpMyAdmin.

Share

Zend Framework

Zend FrameworkI love the Zend Framework. I’ve been using it since version 1.5 (currently at 1.10 as of this writing). It has so many features and can do so many things–sometimes it’s just not immediately clear how to implement those great features.

One feature that took me awhile to figure out was AJAX context switching. The documentation contains various pieces of information about implementing AJAX, but it just wasn’t clear how to put those pieces together. To help make this more clear, I’m going to go through a simple example of how to add very basic AJAX to the Zend Framework QuickStart project. I’m going to be using jQuery because I prefer that to Dojo and the rest of the JavaScript frameworks.

This tutorial assumes you already have a development server set up, Zend Framework installed, and the Zend Framework QuickStart project up and running.

Modify IndexController.php

First we need to set up Ajax context switching in the main controller. Add the following init() function to the index controller found in controllers/IndexController.php

public function init()
{
    $ajaxContext = $this->_helper->getHelper('AjaxContext');
    $ajaxContext->addActionContext('list', 'html')
                ->addActionContext('modify', 'html')
                ->initContext();
}

The html parameter is the type of Ajax request. You can also use JSON or XML.

Note: The modify context is not used in this tutorial but is merely there to demonstrate that you can have as many action contexts as you want.

Now we need to add the list action that we specified above in the addActionContext call to the IndexController.php.

public function listAction() {
    // pretend this is a sophisticated database query
    $data = array('red','green','blue','yellow');
    $this->view->data = $data;
}

Create the list view scripts

By default, Zend Framework tries to render view scripts with the same name as the action. If our action’s name is list and is controlled by the controller named index, then Zend will try to render a view script located at view/scripts/index/list.phtml. Since we are using Ajax context switching, Zend Framework attempts to render view/scripts/index/list.ajax.phtml instead.

For testing my Ajax actions I usually create a normal view helper as well as the Ajax helper but then just include the Ajax view helper.

Create the following view scripts. The second script list.phtml is optional but might aid in troubleshooting.

views/scripts/index/list.ajax.phtml


    data as $color) : ?>

views/scripts/index/list.phtml






jQuery time

The last thing we need to do is to add some HTML and JavaScript to our index.phtml view script to test everything out.

Add the following to the bottom of views/scripts/index/index.phtml

The most important part of that jQuery code is the content of the URL you specify. This is one of those cases when you need to specify the module and controller and action even if they are set to the default value.

‘/module/controller/action/format/html’

You must also not forget the format/html part. If you forget it, you’ll notice that Zend is rendering your layout too instead of just rendering the view script.

That’s it. You should now have a list of colours on the first page of your site.

UPDATE: there was an error in the jQuery code on the index.phtml view script. The code is correct now. I have also added a working project to my Google Code repository. Thanks to the commenters for pointing this out.

Share