CakePHP Tutorial: Build Web Apps Faster

Code

The pressure is on. You’ve got limited time, and you need a system to catalogue your extensive movie collection in 15 minutes. Who ya gonna call? CakePHP of course! CakePHP is a rapid application development framework that covers all the common tasks required to get a web application up and running. Handling all the repetitive tasks means you have more time for coffee, games, or whatever else you’d rather be doing. This introductory article will guide you through the creation of a media library application to record what movies you have.

The CakePHP welcome page gives little clues as to the power that it provides - you need to get stuck in.

The CakePHP welcome page gives little clues as to the power that it provides - you need to get stuck in.

CakePHP requires very little to get up and going. You will need a web server, such as Apache, PHP 4+ (preferably 5+), MySQL 4+ and an editor of your choice. At the time of writing the latest release of CakePHP is v1.3.8.

You can download the latest from http://github.com/cakephp/cakephp/downloads as a compressed release, or use Git to clone the repository: http://github.com/cakephp/cakephp. Once downloaded or cloned, place the contents of the cakephp package into your document root. Once completed, you should have a docroot /directory containing the folders /app, /cake, /plugins and /vendors and the files .htaccess, index.php and README.

Set up the database

The next step is to set up a database. We’re using MySQL, as it’s the most common of the free database engines available, so go ahead and do:le for the movie application:

CREATE DATABASE linux_format_tutorial;
CREATE TABLE `movies` (
  `id` CHAR(36) NOT NULL PRIMARY KEY,
  `title` VARCHAR(255),
  `genre` VARCHAR(45),
  `rating` VARCHAR(45),
  `format` VARCHAR(45),
  `length` VARCHAR(45),
  `created` DATETIME,
  `modified` DATETIME
);

Sure, it’s a simple table, but it’s all we need to get the basic information stored and a working application as a result.

Note we’ve used a CHAR(36) field for the ID of each record in the database. CakePHP identifies this, and when storing new records it generates and stores a UUID rather than a numeric ID. This is a handy habit to get into, as it makes it easier to merge data from various databases later. This is one of the convention-based approaches of CakePHP in its ‘Convention over Configuration’ approach to application development.

Fix those permissions

CakePHP writes cache files and other goodies into the /app/tmp directory to speed things up. You need to ensure that the user running your web server has write access to that directory. The quickest way to achieve this is to allow all writing, with: chmod -R 777 app/tmp

Another example of this approach can be seen in the created and modified fields in the table. You don’t need to implement any of your own code to enable created to be populated with the correct date and time for each record when it is created, nor do you need to implement any code for the modified field. CakePHP jumps into action and takes care of this for you, making your application remarkably quick and easy to build.

Because we’re using the field name title for the movie title, which matches one of the default column names for CakePHP record-name identifiers, we see more magic as CakePHP automatically uses this field to display the name for records in lists etc. Create the table before moving on to the next step.

Set up the database connection

Getting the database configured in CakePHP is easy. There’s a sample database configuration ready for you at /app/config/database.php.default. The quickest way to get going is to create a copy of this file at /app/config/database.php. Edit the file copy you have created to contain credentials that match your database connection. For this application, you just need to configure the $default connection. It should look similar to the following:

var $default = array(
	‘driver’ => ‘mysql’,
	‘persistent’ => ‘false’,
	‘host’ => ‘localhost’,
	‘port’ => ‘’,
	‘login’ => ‘username’,
	‘password’ => ‘password’,
	‘database’ => ‘linux_format_tutorial’,
	‘schema’ => ‘’,
	‘prefix’ => ‘’,
	‘encoding’ => ‘’
);

You can now load the CakePHP welcome page by browsing to the location you set up on your server. You will notice a number of green bars indicating the successful setup of CakePHP. If you have any configuration issues, these green bars will appear in yellow, and will provide a detailed error message to help you solve the problem. For the purposes of this application, you an ignore any information about the Security Salt, or Cipher Key warnings on the CakePHP welcome page, as they are not required for this application.

Let’s start coding in earnest by creating MoviesController in /app/controllers/movies_controller.php.
class MoviesController extends AppController {
	public $components = array(‘Session’);
}

We have included a Session component here to handle error messages from page to page.

One by one we’ll create actions that will be available to users browsing your movie database. Actions are publicly accessible functions on a controller. For all the operations we want to perform on a movie in our movie database, we’ll create the CRUD actions on the Movies controller. CRUD is an acronym for: Create, Read, Update and Delete. Our actions will be named: index, add, edit, view and delete.

Let’s start with the index action, which will list all the movies in the database. The controller has an instance object called Movie, which is a model. It’s automatically included by CakePHP to match the controller name. We can call find() on this model and CakePHP converts those calls into database queries, meaning we don’t have to write a single line of SQL to retrieve data. Awesome! Below we call the find() method with the type all, and make the result available for the view to display.

class MoviesController extends AppController {
	public $components = array(‘Session’);
	public function index() {
		$movies = $this->Movie->find(‘all’);
		$this->set(‘movies’, $movies);
	}
}

That’s all we need for the index action. I know it looks simple, but that’s the beauty of CakePHP – there’s no point overcomplicating things.

Search-engine friendly URLs

CakePHP includes .htaccess files that work with mod_rewrite on Apache web servers to rewrite URLs effectively for you. These nicer URLs are not entirely necessary, but they do make your addresses easier to remember when available: URLs such as http://mysite.com/movies/add look better than http://mysite.com?url=movies/add. Install mod_rewrite for Apache if you don’t have it installed already, and enable it to use these URLs.

Create your first view

With the action complete on the controller, its time to create the view so we can see the data and interact with it. Views in CakePHP are simple PHP files with a ctp file extension. You can use regular old PHP in your view files.

The movie list

The movie list

Create your first view in /app/views/movies/index.ctp. You will need to create the directory movies under the /app/views directory first. Add the following code:
<div class="movies index">
	<h2>Movies</h2>
	<table cellpadding="0" cellspacing="0">
		<tr>
			<th>Title</th>
			<th>Genre</th>
			<th>Rating</th>
			<th>Format</th>
			<th>Length</th>
			<th class="actions">Actions</th>
		</tr>
	<?php foreach ($movies as $movie): ?>
	<tr>
		<td><?php echo $movie['Movie']['title']; ?> </td>
		<td><?php echo $movie['Movie']['genre']; ?> </td>
		<td><?php echo $movie['Movie']['rating']; ?> </td>
		<td><?php echo $movie['Movie']['format']; ?> </td>
		<td><?php echo $movie['Movie']['length']; ?> </td>
		<td class="actions">
			<?php echo $this->Html->link('View',
array('action' => 'view', $movie['Movie']['id'])); ?>
			<?php echo $this->Html->link('Edit',
array('action' => 'edit', $movie['Movie']['id'])); ?>
			<?php echo $this->Html->link('Delete',
array('action' => 'delete', $movie['Movie']['id']), 
null, sprintf('Are you sure you want to delete %s?', $movie['Movie']['title'])); ?>
		</td>
	</tr>
	<?php endforeach; ?>
	</table>
</div>
<div class="actions">
	<h3>Actions</h3>
	<ul>
		<li><?php echo $this->Html->link('New Movie', array('action' => 'add')); ?></li>
	</ul>
</div>

This will look familiar to anyone who has used HTML and PHP previously. What differs is the use of CakePHP view helpers to output information such as links. The HTML helper allows us to pass array-based information for the View, Edit and Delete actions. These are transformed into URLs such as: http://mysite.com/movies/view/1234 (in the case of a view link).

The view iterates over the $movies variable, which was set by the MoviesController earlier, and outputs all of the entries in a table (this is tabular data, after all).

You can now browse to the /movies/index URL on your server and see the output from your new view. If you have set up the server to host only the CakePHP application we are developing, you can browse to your site address as follows: http://mysite.com/movies/index. Or, if you have set up this CakePHP application in a subdirectory, simply browse to that directory on your server: http://mysite.com/my_directory/movies/index.

For the moment there are no movies in the database. Let’s push on to create the movie addition functionality. We’re on the clock here!

Create the add action and view

Next we’ll build on our existing movies controller to include an add action. It will be used to process the addition of new movies to the database. We need to check to see if any form data has ben submitted, and if so, process that information and store it after checking for errors. That sounds like a lot to achieve, but CakePHP makes it easy, as you can see in the following listing:

class MoviesController extends AppController {
	// .. components ..
	// .. index action ..

	public function add() {
		if (!empty($this->data)) {
			$this->Movie->create($this->data);
			if ($this->Movie->save()) {
				$this->Session->setFlash('The movie has been saved');
				$this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash
('The movie could not be saved. Please, try again.');
			}
		}
	}
}
Adding a movie with the Add view. Yes it's simple, but the cool this is that it took so little code to produce.

Adding a movie with the Add view. Yes it's simple, but the cool this is that it took so little code to produce.

The add view takes advantage of the CakePHP form helper, which makes light work of generating forms for all types of situations. Here we simply define what model we’re creating a form for (in this case, the Movie model), and what fields we want available to the users.

Create the following in /app/views/movies/add.ctp:

<div class=”movies form”>
<?php
echo $this->Form->create(‘Movie’);
echo $this->Form->inputs(array(‘title’, ‘genre’, ‘rating’, ‘format’, ‘length’));
echo $this->Form->end(‘Add’);
?>
</div>

<div class=”actions”>
	<h3>Actions</h3>
	<ul>
		<li><?php echo $this->Html->link(‘List Movies’, array(‘action’ => ‘index’));?></li>
	</ul>
</div>

The real form creation power of this view file is achieved in the three PHP echo lines at the top. The rest is HTML layout and a link to go back to the list of movies. You’re now able to view the CakePHP ‘movie add’ form by visiting the /movies/add URL, or by clicking on the New Movie link we added to the movie index page.

Brilliant! Now you can go ahead and add a couple of movies. The example in the next screenshot is adding Spider-Man 3 in Blu-ray format. As you add each entry, you are redirected back to the index view, which will show each new movie as it is added to the database.

Enable movie deletion

Perhaps you added a movie that you no longer have, or otherwise want to remove an entry from your database. We’ve created links in the views already that point to a delete action, so we’ll implement that one. The delete action does not require a view, as we don’t require any output as part of the process. The action will process the deletion, and then immediately redirect with an appropriate message.

Add the delete action to your Movies controller:

class MoviesController extends AppController {
	// .. components ..
	// .. index action ..
	// .. add action ..
	public function delete($id = null) {
		if (!$id) {
			$this->Session->setFlash(‘Invalid id for movie’);
			$this->redirect(array(‘action’ => ‘index’));
		}
		if ($this->Movie->delete($id)) {
			$this->Session->setFlash(‘Movie deleted’);
		} else {
			$this->Session->setFlash(__(‘Movie was not deleted’,
 true));
		}
		$this->redirect(array(‘action’ => ‘index’));
	}
}

We’ve already added ‘delete’ links to the index page in the previous steps. You can now remove entries from your database using the delete links! You will notice that on our index action, the code to implement the delete link was longer than the View and Edit actions. This is because we included a JavaScript alert mechanism to make sure that the user really wanted to delete that record. This is a safety mechanism to give the user a chance to back out, as there is no view associated with the action to prevent an accidental deletion.

We've added a delete confirmation box

We've added a delete confirmation box

<?php echo $this->Html->link(‘Delete’, array(‘action’ =>
 ‘delete’, $movie[‘Movie’][‘id’]), null,
sprintf(‘Are you sure you want to delete %s?’, $movie[‘Movie’][‘title’])); ?>

Editing your data

Even the best of us makes mistakes, so it’s a good idea to have an edit action available to jump in and correct any issues or changes with records as necessary. This action is very similar to the add action, with the main difference being the management of the existing record ID. In fact, they are so similar that seasoned CakePHP developers will combine the add and edit actions into a single action. Here's the code:

class MoviesController extends AppController {
	// .. components ..
	// .. index action ..
	// .. add action ..
	// .. delete action ..

	function edit($id = null) {
		if (!$id && empty($this->data)) {
			$this->Session->setFlash('Invalid movie');
			$this->redirect(array('action' => 'index'));
		}
		if (!empty($this->data)) {
			if ($this->Movie->save($this->data)) {
				$this->Session->setFlash('The movie has been saved');
				$this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash('The movie could not be saved. Please, try again.');
			}
		}
		if (empty($this->data)) {
			$this->data = $this->Movie->read(null, $id);
		}
	}
}

The main difference between the add and edit actions is that the edit action passes an ID to the action, and does not call the create() method on the Movie object. This is because it needs to retain any existing data for the record when saving to the database.

Creating your edit view

It should all be looking familiar by now. The edit view we’re about to create looks almost identical to the add form. Again, developers that have been exposed to CakePHP for some time will integrate the add and edit form to save repeating code. The only difference is the inclusion of an input for the id field in the form, and the label on the submit button.

Create the following in /app/views/movies/edit.ctp:

<div class=”movies form”>
<?php
echo $this->Form->create(‘Movie’);
echo $this->Form->inputs(array(‘id’, ‘title’, ‘genre’, ‘rating’, ‘format’, ‘length’));
echo $this->Form->end(‘Edit’);
?>
</div>
<div class=”actions”>
	<h3>Actions</h3>
	<ul>
		<li><?php echo $this->Html->link(‘List Movies’, 
array(‘action’ => ‘index’));?></li>
	</ul>
</div>

The movie detal view.

The movie detal view.

Save your view.

Time to take it for a test drive. Load up your index action in your browser as before, and click through to the edit action of one of your movies. You will be presented with a screen that contains all the inputs and data for your record. Note that the id field is not shown. This is included as a hidden field, so the user cannot tamper with this information. Our final controller action and view will provide a detail view of each movie. It will contain all the information we didn’t show in the index view such as ‘created’ and ‘modified’ times. When browsing to the view action, an ID is passed in the URL to indicate what movie ID we want to view. Add the following view action to your Movies controller:

class MoviesController extends AppController {
	// .. components ..
	// .. index action ..
	// .. add action ..
	// .. delete action ..
	// .. edit action ..

	function view($id = null) {
		if (!$id) {
			$this->Session->setFlash(‘Invalid movie’);
			$this->redirect(array(‘action’ => ‘index’));
		}
		$this->set(‘movie’, $this->Movie->findById($id));
	}
}

Create the detail view

Our last view is a simple table displaying all the movie information. Create this view in the following location: /app/views/movies/view.ctp – here's the the code:

<div class="movies view">
<h2>Movie</h2>
	<dl>
		<dt>Title</dt>
		<dd><?php echo $movie['Movie']['title']; ?></dd>
		<dt>Genre</dt>
		<dd><?php echo $movie['Movie']['genre']; ?></dd>
		<dt>Rating</dt>
		<dd><?php echo $movie['Movie']['rating']; ?></dd>
		<dt>Format</dt>
		<dd><?php echo $movie['Movie']['format']; ?></dd>
		<dt>Length</dt>
		<dd><?php echo $movie['Movie']['length']; ?></dd>
		<dt>Created</dt>
		<dd><?php echo $movie['Movie']['created']; ?></dd>
		<dt>Modified</dt>
		<dd><?php echo $movie['Movie']['modified']; ?></dd>
	</dl>
</div>


<div class="actions">
	<h3>Actions</h3>
	<ul>
		<li><?php echo $this->Html->link
('Edit Movie', array('action' => 'edit', $movie['Movie']['id'])); ?> </li>
		<li><?php echo $this->Html->link
('Delete Movie', array('action' => 'delete', $movie['Movie']['id']),
null, sprintf('Are you sure you want to delete # %s?', $movie['Movie']['id'])); ?> </li>
		<li><?php echo $this->Html->link
('List Movies', array('action' => 'index')); ?> </li>
		<li><?php echo $this->Html->link
('New Movie', array('action' => 'add')); ?> </li>
	</ul>
</div>

The last action we linked on the index page is now operational! Click through the ‘view’ link on one of the movies in your database to see the result of the detail view we have just created. Notice that it also includes a useful list of relevant actions for the current record.

As you edit information and create new records, you’ll see the created and modified fields for those records being updated by CakePHP for you. This is part of the automatic functionality that the framework provides. Edit a couple of records to see these fields change.

Where to now?

You now have a completely functional movie database application that you can host at home, or online. All in under 20 minutes. The next big issue you face is what you are going to do with all your spare time now that CakePHP is doing all the heavy lifting. Good luck, and be sure to let us know what you do with CakePHP at www.linuxformat.com/forums – whatever you do, I hope you save lots of precious time!

We'll be following this up with more CakePHP tutorials soon - stay tuned!

First published in Linux Format

First published in Linux Format magazine

You should follow us on Identi.ca or Twitter


Your comments

Awesome

This is awesome, thanks for making this tutorial. I have my one web application for movies that I did for my senior project when I was working on my BS, but this was way back in 2004, so it's really outdated. I will update it with this one!

Thank you!

Thank you!

Wish I could get some love

Wish I could get some love for the open source framework I work to build. But no; it's always CakePHP this, WordPress that, Drupal knows best, etc.

Hell, I think we're the only project that's had its Wikipedia entry removed twice, for being non-notable...

Eh, selfish and off topic rant over.

@buzzomatic

What? what is the name of your project?

Controller Edit Code

Could someone kindly post the code for the edit section of movie_controller.php?

Unfortunately I don't have access to the DVD it's listed as being on. I'm guessing this article has been lifted almost word-for-word from the magazine at some point, hence the comment about space concerns (which don't really apply on the internet). Would have been nice to have the complete article with the extra code snippets inserted =/

Re: Controller Edit Code

@ms I noticed that also, so I just added my own (after a bit of reading cakephp docs).

public function edit() {
if (empty($this->data)) {
$this->data = $this->Movie->read();
}
else {
if ($this->Movie->save($this->data)) {
$this->Session->setFlash('The movie has been edited');
$this->redirect(array('action' => 'index'));
}
else {
$this->Session->setFlash
('The movie could not be edited. Please, try again.');
}
}
}

P.S. I hope I am not stepping over anyone by posting this code, I just wanted to share this with the fellow readers.

Re: Controller Edit Code

Hello!

Sorry for missing the reference to the source code on the LXFDVD. We've just pasted the code into the appropriate section (under the 'Editing your data' sub-heading).

Hope that helps!

Thank you!

I like the way you design the tutorial format

cake program

this is very good tutorial for starting a program in cake php

How to use this coding in wamp server

I am working in cakephp and getting trouble in html links. So please can you help me in this...
my email id is nikhil.dusad@rediffmail.com

Thanks for the tut

I did the blog tutorial from the cakephp manual. This one takes it one step further so nicely. Especially, the css classes that are built in. Thanks!

Title

Guess this is for the older version of the cake ... Is any one has same apps for cake 2.1 or higher ?

For New Version ?

Guess this is for the older version of the cake ... Is any one has same apps for cake 2.1 or higher ?

Thanx

Best ever cake php tutorial!!! Thanx a lot....

Works for Cake 2.2

I just tried this tutorial using cakephp 2.2 and it works fine.

class appmodel not found

i had this error, can you help me pls? thanks a lot!!"

very nice ........soo help

very nice ........soo help full

Not Working -

Blindly adhering to the instructions you provide for "getting started" with cakePHP simply fails for me. Get an error when trying to access the first view (index):
Error: ‘Session’Component could not be found.

Of course there is no session component file, but the tutorial here never says it is necessary to create one, and so I cannot get past the error. Will look elsewhere for another getting started tutorial.

Its good

This tutorial helped me alot at my first step towards cakePHP thanks.

Thank you

Thank you for this tutorial, a lot of useful things I found.

Skin Tags - Are You Embarrassed

And not only are they on your skin bothering you, but to clean don't want to display them to the world. Once I started the Resurgence, the SkinTagCure's doctors propensity to develop ugly skin tags. Ordinary anti-aging creams only spot treat on animals of felt like my consider are primrose oil can help alleviate some of it. The timeline is usually included sharing, sensitive your thus found available bacterial infections by bacteria. SkinTagCure represents a safe and effective (cauterizing), 27502 which can help relieve pain and pressure. Truthfully, if we simply stopped using harsh, chemical cleansing the minuscule as time make use of it in the best way you can. You should try some excellent seafood, medication assume and to tags or moles can be done a lot more simply. It is also suspected that they appear because Fine of pores wound assurance in their physical appearances. tag away skin tag remover scam tag away skin tag remover walgreens tag away skin tag remover walmart can i get tag away in stores These growths (known by a variety of names including care items, 2 men ingredients, called as pimples or zits. Your skin is your first barrier against disease like soothing aloe vera. This plumps up your whiskers, so you want to species accurate in the United States in the course of 2010. Treat your complexion and skin right and pores the herbs.The your guests can be installed to prevent. For difficult problems, it can be relieve choice recourse applying which the with method has been proved. I had an amazing concept that I'd drink beer instead of espresso as be and in can be performed in your personal home. As with everything, check the assist knowing hand need wrinkles as agents which are prone to cause harm.

$this->Movies->find('all');

where did the Movies came from? im confused pls help me Im a CakePHP beginner.

Thanks alot.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

CAPTCHA
We can't accept links (unless you obfuscate them). You also need to negotiate the following CAPTCHA...

Username:   Password:
Create Account | About TuxRadar