Creating a guestbook with CakePHP

In this post I will be going over how to develop a simple guestbook application using CakePHP. By the end of this post you will have a functioning guestbook running locally on your machine. By the end of the second post I will have demonstrated how to add authentication and how to create a separate layout for the admin and public areas of the site.

This walk through assumes you are using Windows, though Linux development is much the same with the only differences occurring in development environment setup and the location of items.

Step 1: set up development environment

The first step is to get a web server with PHP and a database up and running locally. There are many ways to do this but the most popular combination is generally LAMP (Linux Apache MySQL PHP) or WAMP (the same but with Windows). I like to use XAMPP for this as it gives you an instant LAMP/WAMP set up with little to no configuration.

Download XAMPP from http://www.apachefriends.org/en/xampp.html. Extract the archive to C:\. Once you’ve extracted XAMPP, you’re ready to go. Navigate to the xampp folder you just extracted and run xampp_start.exe.

Visit http://localhost in your browser, you should see the main XAMPP page.

XAMPP main page

XAMPP main page

Step 2: get CakePHP

Get a shiny new copy of CakePHP by visiting CakePHP on github. Extract the resulting archive into C:\xampp\htdocs. Rename the resulting folder ‘guestbook’. Visit http://localhost/guestbook. You should see the default CakePHP welcome page.

Default CakePHP main page

The default CakePHP main page

You may have noticed the page contains some warnings. To fix these, open ‘app\config\core.php’. Find the lines:

/**
 * A random string used in security hashing methods.
 */
 Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');

/**
 * A random numeric string (digits only) used to encrypt/decrypt strings.
 */
 Configure::write('Security.cipherSeed', '76859309657453542496749683645');

Replace the Security.salt value with some random letters and numbers. Replace the Security.cipherSeed value with some random numbers.

Step 3: create the database tables

Next we need to work out what entities we have and what their tables will look like. I’ve chosen a very basic set up with just two tables. One of these will store user details and the other will store the posts. The simplest way to create your database and it’s tables is to visit http://localhost/phpmyadmin in your browser. Under ‘create a new database’ type ‘guestbook’ and click create. Next, click the SQL tab. Here you can execute any raw SQL queries, this is perfect for creating our tables. Paste in the following and click ‘Go':

CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`body` varchar(5000) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`));

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` char(40) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
);

You should now have two tables in your database. At this point it’s important to note some conventions. CakePHP consistently favours convention over configuration. What this means for you is that as long as you play by the rules, you’ll need to do very little configuration. Table names should be plural and all in lower case. By using the field names ‘created’ and ‘modified’ CakePHP will automatically manage these for us.

We need to tell CakePHP where our database is and the login details. Doing this is very simple. Make a copy of the file ‘app\config\database.php.default’, call it ‘database.php’. Open the file and change the values for $default. Your configuration should be the same as mine, by default the root account will have no password:

var $default = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'guestbook',
'prefix' => '',
);

Obvious though it is, I should mention that this sort of configuration should only be used for local development. When deploying to a remote server, ensure a secure username and password is used. Using the root account with no password would be extremely bad practice.

Visit http://localhost/guestbook again. You should see that it is now able to connect to your database.

Step 4: create models, controllers and views

Next, we need to create the models, controllers and views. Below is an explanation of what each of these are and where they reside. You may read this or skip ahead and get to all the action.

Models

Each model file represents an entity in our system. So in this case we will have a User and Post entity. Models are placed in app/models. Their file name should be singular and all in lower case, with the ‘.php’ extension. In our case we will have user.php and post.php. By doing this CakePHP will automatically associate these models with our database tables.

Controllers

The controllers are responsible for handling all actions concerned with their views. They get the data from the model and use it to build the view. In CakePHP as with most frameworks the URL of a controller action is: SITE_URL/CONTROLLER_NAME/ACTION. To put this into context, to add a user on our system we will be going to http://localhost/users/add. So here we call the ‘add’ action on the ‘users’ controller. When we go to this URL we will be served the ‘add user’ view. Controllers are placed in app\controllers. Their file names are plural with _controller.php added on. This means our user controller will be called users_controller.php. This important convention means CakePHP automatically associates users_controller.php with our user model and views.

Views

Views are what the user actually sees and interacts with. They are made up of HTML and basic PHP. We don’t really want any application logic going on here but actions such as looping over items and using provided helper classes is fine. Views are kept in app/views. In app\views you should have a separate folder for each entity. In our case we will have a ‘users’ and ‘posts’ folder. Again convention pops its head up here, the name of the folder should be lower case and plural. Inside the folder there should be a separate PHP file for each controller action. The name should be the same as the controller action in lower case and with the extension ‘.ctp’. Basic actions are ‘view’, ‘add’, ‘edit’ and ‘delete’. This means our ‘app\views\users’ folder will contain ‘view.ctp’, ‘add.ctp’, ‘edit.ctp’ and ‘delete.ctp’.

Using the CakePHP command line utility

Now for the clever part: CakePHP ships with a command line utility designed to automate the creation of everything I’ve mentioned above. To set this up, you’ll need to add it’s location to your environment variables. I started by copying my ‘guestbook\cake’ folder into ‘C:\xampp’. This ensures that you can still use the cake command line interface if you later move or delete the project.

On Windows, go to Computer, right click and select properties. On Vista/7 you will then also need to click ‘Advanced system settings’. Click ‘advanced’ then ‘environment variables’. Edit the ‘Path’ variable found under ‘system variables’, adding ‘;C:\xampp\php;C:\xampp\cake\console;’ to the end of it . OK away the dialogues and you’re ready to roll… I mean er bake.

Open a command line window. Change to the site’s app directory using ‘cd C:\xampp\htdocs\guestbook\app’. Once you’re there, type ‘cake bake all’. Hit return to accept using the default database configuration. You should see the two entities we will be using. Select ‘1’ then follow all the prompts, accepting the default each time. Repeat the process but this time select ‘2’.

Cake command line utility

Baking with the cake command line utility

You should now find your ‘app\models’, ‘app\controllers’, and ‘app\views’ folders populated. At this point we have most of our functionality in place. We can view, create, edit and delete our guestbook posts and users. We are missing the functionality to stop anyone doing whatever they like though. Try out some of the URLs, for example visit http://localhost/guestbook/users/add and try adding a new user.

I’ll be going over adding the login functionality and changing the layout in the next installment.

Posted in CakePHP, PHP | Tagged , | Leave a comment

Baking with CakePHP

CakePHP: the rapid development PHP framework

PHP is famous for it’s flexibility and almost equally famous for the disaster that flexibility can bring. I learnt PHP some time ago from a book which had no qualms about having MySQL queries thrown in with some HTML and numerous echo statements.

It has to be said though the book was about PHP, to push a certain approach to project layout would be arguably the wrong path in its self. At the end of the day, it’s up to the developer to enforce structure upon themselves when working with PHP. This of course is the problem, many don’t bother or are simply not sure which path to take.

I myself only created a simple guestbook application. This was enough to show me the danger though. Enough so in fact that I scrapped all the code and started again. The spaghetti like structure was hard to work with and making changes invariably often broke something. With my clean slate I introduced an object orientated approach. I was happy, it was so much cleaner. My objects in the database related to PHP classes and I’d taken the time to introduce many little helper classes facilitating features such as automatic sticky forms.

There was an issue of development time though, it took a great deal of time to produce all this clean code. The more I wrote the more I felt I was wasting time implementing general functionality to tidy PHP up. This can be problem when trying to follow software development principles using PHP: the more you write in hope of producing the perfect code base, the more you come to the realization you’re essentially creating your own framework.

With this in mind it’s natural to look around and see what existing frameworks are on offer. After all, despite all your efforts you are essentially reinventing the wheel only to find every step you take there’s another spoke missing.

Wanting to play around with a framework and get some code together, I went looking for what was on offer. After a good look around, I’d narrowed it down to three: CodeIgniter, Zend and CakePHP. All of these follow the Model View Controller pattern.

Now I won’t pretend that I did in depth research into which one was best. Arguably that decision should be made on a per-project basis anyway. CakePHP is the one that really caught my attention though. It grabbed me right after I created a few tables in my database and typed the magic ‘cake bake all’ command. Suddenly I had CRUD (Create, Read, Update, Delete) operations for all my entities, based on the tables. But there is more, it is also clever enough to create views attached to these controller actions. This leaves you with a fully functional skeleton application… and you’ve barely lifted a finger. This automated method of code creation is known as ‘baking’ in CakePHP. On top of all this command line awesomeness is the vast API which provides helpers for many common tasks such as authentication, email, Ajax and form building.

Naturally those wanting to learn PHP should stay away from the frameworks before they take the leap into having half the work done for them. For any PHP developer though, frameworks such as CakePHP are a real blessing. After all, why spend time making everything when you can just bake it?

Posted in CakePHP, PHP | Leave a comment

New website

It’s been some years since I last changed my website. The previous design was created about 3 years ago. It didn’t exactly look out of place by today’s standards: it used XHTML, CSS and PNG images carefully crafted together to meet W3C standards. What was out of place though was the way it worked.

The site was created using PHP. Among other things, It allowed me to create separate files for the layout and combine them all together for a consistent, easy to maintain layout. It did make maintenance much simpler in general. The problem was the site didn’t use a database to store it’s content. Each page existed as a separate file which had to be manually updated.

I wanted to move to a database based solution so I had three options:

  1. Create a complete content management system from the ground up
  2. Use a PHP framework to ease the development of a content management system
  3. Use an existing CMS/blog system

While I like to create things myself, I’ve come to learn that re-inventing the wheel is not generally the way to go. Creating a PHP CMS system from the ground up is a big undertaking. Sure, it may only take a day to pull together some login and posting functionality but there’s much more to a successful CMS system: years of work by hundreds of people more.

Option number two presented me with the same issues. Development speed would be greatly increased, but there’s no getting away from the amount of work involved. One framework I have looked at recently is CakePHP. CakePHP is a rapid development PHP framework that really does what it says on the tin. It’s certainly compelled me to start thinking up some project ideas, though none of these would be a CMS.

WordPress is a platform I’ve had some experience with in the past and suffice to say, I liked what I saw. Anyone who has used WordPress will know just how quick and easy it is to set up. After a couple of days I had themed the site to a design I created previously and put all my content back together.

What I really want to pull away from is the static, rarely updated homepage. I want my site to be active with the technologies I am working with. Using WordPress creates a real incentive for this. Creating and managing posts is all offloaded, all I have to worry about is the content. When it comes to websites, content is king. The easier it is to create and manage content, the easier the content flows onto the site.

I’ll be creating some posts concerning CakePHP soon. It’s a framework I’ve only just begun to learn but it’s simplicity means you can pull together working web applications really fast.

Posted in PHP, Wordpress | Leave a comment