zen of coding

CakePHP + MongoDB Introduction

CakePHP 2.2/MongoDB 2.0.4

We all know that CakePHP is awesome, and I’m sure you’ve heard that MongoDB is pretty awesome as well.
So how do we make these awesome technologies play well together?

In an awesomely easy way :)

Let’s get things rolling by setting up MongoDB.
(Instructions for Ubuntu)

sudo pecl install mongo

Add the following line to your php.ini file (on my system in: /etc/php5/apache2/php.ini)

extension=mongo.so

This sets up PHP support for MongoDB.

Let’s install the actual DB, which is easily available through apt-get

sudo apt-get install mongodb mongodb-server

Restart things:

sudo /etc/init.d/apache2 restart

… and double-check that mongo is up and running.

mongo --version

You should see something like: “MongoDB shell version: 2.0.4”

Now, we’ll grab the MongoDB driver for CakePHP, courtesy of Yasushi Ichikawa (ichikaway).

First, cd into your app/Plugin directory.
Then:

sudo git clone git://github.com/ichikaway/cakephp-mongodb.git Mongodb

Once the cloning is complete you should cd into Mongodb directory and:

git checkout cake2.0

Now you have all the components installed and running, and it’s time to try out a simple app.
There is certain beauty in MongoDB, because it doesn’t require you to have any schema. Just write some code, and things will happen magically.

Indeed we’ll just edit our app/Config/database.php

public $default = array(
    'datasource' => 'Mongodb.MongodbSource',
    'database' => 'blog',
    'host' => 'localhost',
    'port' => 27017,
  );

Add to app/Config/bootstrap.php

CakePlugin::load('Mongodb');

Create a model:

<?php
class Post extends AppModel {
 
  public $validate = array(
    'title' => array(
        'rule' => 'notEmpty'
    ),
    'body' => array(
        'rule' => 'notEmpty'
    )
  ); 
}

Controller:

<?php
class PostsController extends AppController {
   
    public function index() {
        $this->set('posts', $this->Post->find('all'));
    }
     
    public function add() {
        if ($this->request->is('post')) {
            if ($this->Post->save($this->request->data)) {
                $this->Session->setFlash('Your post has been saved.');
                return $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash('Unable to add your post.');
            }
        }
    }
}

And a couple of views…

app/View/index.ctp

<?php
  foreach ($posts as $post) {
    debug($post);
  }

app/View/add.ctp

<?php

echo $this->Form->create();
echo $this->Form->inputs(array(
    'title', 'body'
));
echo $this->Form->end('Add');

Congratulations! Your first CakePHP/MongoDB app is now ready to rock.

You can go ahead and try adding some posts, and see them appear (albeit only as debug output) on the index action.

Part 2

  • thanks, nice post

  • Pingback: CakePHP + MongoDB Introduction | nuts and bolts of cakephp | CakePHP report - کیک پی اچ پی | Scoop.it()

  • chetanspeed511987

    Very useful post.

  • How would one go about editing/updating? Getting error: Notice (1024): E11000 duplicate key error index: cake1.posts.$_id_ dup key: { : ObjectId(‘506c3162db32e381a0daa6ea’) } [APP/Plugin/Mongodb/Model/Datasource/MongodbSource.php, line 467]

  • Excellent tutorial, but even everything looks trivial, converting existing CakePHP project based on MySQL to MongoDB can be a challenge. However benefits of using NoSQL environment on busy website are amazing.

    • teknoid_cakephp

      Thanks.

      Yeah, you are definitely correct about a complete overhaul… there’s a lot more to consider, than just basic model code.

  • saivert

    how does one emulate belongsTo and hasMany? I’m migrating from a simple MySQL database with only two tables. one called videos and the other called categories, but this doesn’t go well with MongoDB. I know I can just use nested objects in MongoDB for categories but that requires me to rewrite my controllers and views. Also the MongoDB datasource driver I use doesn’t alias _id as id so I have to rewrite that as well. This leads me to realize MongoDB needs completely different thinking and you can’t just swap MySQL out with it.

    • teknoid_cakephp

      You are correct, you can’t just swap out the DB’s. Really you need to think of a different data model. My next post talks a little about that, but if you are serious about NoSQL you should read this: http://amzn.com/0321826620

  • How do you do Authentication using mongodb?

  • new beee

    Error:
    Class ‘String’ not found

    File:
    D:local_serverhtdocsentappPluginMongodbModelDatasourceMongodbSource.php

    Line:
    1476

    I get this error
    Can you please give me this working example so i can download

%d bloggers like this: