In our last CakePHP tutorial we looked at setting up the CakePHP framework and introduced some of the framework's basic concepts and terminology. Now we turn to illustrating more of CakePHP's rapid development capabilities using a personal blog application as an example. In the next set of tutorials we will build the blog application incrementally so that the basic CakePHP development process is laid out clearly instead of briefly mentioned as in other similar tutorials. In this tutorial we start with a basic authoring authentication component for the example blog application.
Step 1: Defining a Goal
Our goal is to create the components of a personal blog application. By the time we complete the project we will be adding Web 2.0 effects and offering integration with other services to make the application complete. Before we can start our project, however, we need to define a development plan with some sort of feature list to guide us.
Here is a small list of main features we will discuss and include in our finished application:
- Protected system with, at minimum, capabilities for one author
- Posting functions will include commenting functionality, provide blog trackbacks, and allow the inclusion of images and uploads
- Full-text search engine using Sphinx
- Integration with external services such as Gravatar and Askimet Spam Protection / Spam Management
- Javascript enhancements including WYSIWYG Editor Capabilities, Ajax Live Search, Ajax Comment Previews, Fast loading Ajax Publish/Edit/Delete functionality and Ajax form validation
- Integration of the application with Facebook to allow rapid Facebook development (the goals for this feature include sending posts to Facebook's news feed feature and pulling in personal data from the Facebook API to make the blog a little more personal)
In today's article we will focus mainly on the user/author management system because it is the perfect place to learn the basics of controller, model, and view code. Once we learn these basics we can implement them for the other components of the larger system later on.
Without further ado, let's tuck into CakePHP.
Step 2: Models
As mentioned previously, models interact with the framework's underlying database. By default, CakePHP comes with a number of built-in methods to save us from rewriting code to implement common functionality. Along with the expected reading and writing/saving methods, you can also use "magic methods" like findBy<fieldName> which will find rows matching a certain query field. This is a real improvement over using typical "SELECT * FROM" queries.
Our user system for this iteration of the application will be quite basic. Since the main goal is a personal blog we will have only one author at a time. For the sake of extendability, however, we will store the user(s) in a table in case we choose to develop a full blown user/permission system later on, or if we want to manually add more authors. Our basic functionality will allow logging in, logging out, and updating our personal information.
We will do all of this with a small MySQL table implemented by the following CREATE TABLE statement:
CREATE TABLE `authors` ( `id` int(11) NOT NULL auto_increment, `username` varchar(255) NOT NULL default '', `password` varchar(32) NOT NULL default '', `name` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '', `bio` text NOT NULL, PRIMARY KEY (`id`) )

We will also want a basic starting account, so we will also insert a row while we are at it (the username and password for the starting account is test/test):
INSERT INTO `authors` (`username`, `password`, `name`, `email`, `bio`) VALUES ('test', '098f6bcd4621d373cade4e832627b4f6', 'Test', 'test@test.com', 'Hello world...');
The purpose of the table structure is the following:
- id will be used for the unique user ID when we load the profile.
- username will be used to login to the management area.
- password will be an md5 hashed password used for logging in to the management area.
- name will be used in bylines and the author page. This is the public display name because the user name is not actually shown.
- email will be used for any future functionality (such as comment notification).
- bio will be used to store biographical information about an author (such as the author pages seen here on NETTUTS).
Now we actually need to create the model. To do this, create a new file in the /app/models/ folder named author.php with the following contents:
<?php
class Author extends AppModel
{
var $name = 'Author';
}
?>

The model for this functionality is actually pretty basic. Since the functionality we need, like findByUsername or save is already covered by functions in Model (which is extended by AppModel) we are done with the model side. This blanket file just allows us to interface with the Author table.
In later sections when we start adding post functionality, we may need to extend the models.
Step 3: Views
Views are mainly a mix of HTML and helpers. In other systems we would call these templates. Helpers generate common code or help with common tasks. Some helper types found in CakePHP are HTML helpers and Pagination helpers.
To establish views, create a folder in /app/views/ called authors/ so we can store all our views. Our first view should be called login.thtml with the following contents:
<?php if ($error) { ?>
<h2>Error</h2>
<p class='error'>The username and password do not match. Please try again and double check the entered information.</p>
<?php } ?>
<?php echo $html->formTag('/authors/login/'); ?>
<label for="username">Username</label>
<?php
echo $html->input('Author/username');
?>
<label for="password">Password</label>
<?php
echo $html->password('Author/password');
?>
<br />
<?php echo $html->submit("Login"); ?>
</form>
Instead of using <input> tags we are using one of the helpers to generate valid input fields that can be used in our controllers. We also put a bit of error checking at the top of the template in case the user enters a wrong username or password. The error variable is set later in the controller.
Now that our first action has a template behind it, we can move on to the others.
Logging out actually doesn't need its own view because we will just redirect users back to the blog index page and display a quick success message. Updating profile information in user management does need a form, however, so we will need to write a view for that.
Create a template named manage.thtml with the following contents:
<?php if ($error) { ?>
<h2>Error</h2>
<p class='error'>Please make sure all the required information has been filled in.</p>
<?php } ?>
<?php echo $html->formTag('/authors/manage/'); ?>
<label for="name">Full Name</label>
<?php
echo $html->input('Author/name');
?>
<br />
<label for="email">Email</label>
<?php
echo $html->input('Author/email');
?>
<br />
<label for="email">Bio</label>
<?php
echo $html->textarea('Author/bio', array('cols'=>'60', 'rows'=>'10'));
?>
<br />
<?php echo $html->submit("Update"); ?>
</form>
This view is very similar to our login form except we are managing some different fields, and we include another helper method ($html->textarea) to generate a text area.
Great! Now that our small set of views are written, we can move on to controllers.
Step 4: Controllers
Controllers act like traffic directors. They accept input, decide what to do with it, and then provide handling instructions to the rest of the system. They are the heart of the application because they take the data from the models and pass it on to correct views to display.
This section will specifically deal with setting and reading a session as well as updating the database. We will also create a "parent" controller from which all of our future controllers will inherit.
First create a file in app/controllers/ named authors_controller.php. Now we will walk through the code step by step.
<?php
class AuthorsController extends AppController
{
function index( )
{
$this->redirect( '/' );
}
function login( )
{
$this->set('error', false);
if ( ! empty( $this->data ) )
{
$author = $this->Author->findByUsername( $this->data['Author']['username'] );
if( ! empty( $author['Author']['password'] ) && $author['Author']['password'] == md5($this->data['Author']['password']) )
{
$this->Session->write( 'Author', $author['Author'] );
$this->redirect( '/' );
}
else
$this->set( 'error', true );
}
}
Our index function is pretty basic. For now, we will just redirect to the script index using a built-in CakePHP function named "redirect."
Our login function is a bit more advanced. We first set the error variable to false to stop PHP from throwing back an undefined variable notice. Then we do a check to see if any data has been sent. "$this->data" holds any input data from the login form and comes in the format $this->data['CONTROLLER']['FIELD']. Now we see our magic method "findByUsername". used to find any rows that contain the user name of the user who has just logged in. If we do have a user match, we then compare passwords and write a session using CakePHP's session handler. If there is a problem, we set "error" to true so our view can handle the message. A login system can't get much simpler than that!

function logout( )
{
$this->Session->delete( 'Author' );
$this->flash( 'You have been logged out.', '/' );
}
The logout function is even simpler. We use CakePHP's session class to totally delete the session, and then we use the "flash" method to redirect. The flash method is a bit different from the redirect method because we are allowed to send a message back to the screen. This becomes useful because we can actually let users know that something has happened.
Note: since we are still in development mode, the flash screen will not automatically redirect. You must click the text to go to the screen. When we are in production mode, this screen would redirect for us.

function manage()
{
$this->set('error', false);
if ( empty( $this->data) )
{
$this->Author->id = $this->Session->read( 'Author.id' );
$this->data = $this->Author->read( );
}
else
{
if( empty ( $this->data['Author']['name'] ) || empty ( $this->data['Author']['email'] ) || empty ( $this->data['Author']['bio'] ) )
{
$this->set( 'error', true );
$this->Author->id = $this->Session->read( 'Author.id' );
$this->data = $this->Author->read( );
}
else
{
$this->Author->id = $this->Session->read( 'Author.id' );
if ( $this->Author->save( $this->data['Author'] ) )
$this->flash( 'Your account information has been updated.', '/authors/manage/' );
}
}
}
Our most advanced function for this controller is the manage function. A lot of the functionality is implemented using the techniques we just introduced. One thing to note in this function is setting the $this->author->id variable before the save and the read. This tells the model which row to deal with so it doesn't try to save or insert an entire new row. We also deal with more session functionality by reading the id from the hash.
Our final step is to protect the manage page. We only want logged in users to see this page, and we can provide protection with a simple check function. This is a piece of functionality we are also going to need for future screens, so we should store it in a shared place. As mentioned before, all CakePHP controllers inherit from a controller called "AppController" which right now is a blank file sitting in the cake directory..
We will create an application-specific AppController by creating a file named "app_controller.php" in the app/ folder, and insert the following contents:
<?php
class AppController extends Controller
{
function isLoggedin( )
{
if ( ! $this->Session->check( 'Author' ) )
{
$this->flash( 'You must be logged in to do that.', '/authors/login' );
exit;
}
}
}
?>
We simply check for the session, and if it is not there we send the user to the login screen. This function can now be used in any controller method.
Our last step is to call the function from our manage function. We open our app/controller/authors_controller.php file and find:
function manage()
{
$this->set('error', false);
and add
$this->isLoggedIn();right below it.

Step: Testing it Out
The actions can be tested and accessed with the following URLs:
- http://yoursite.tld/authors/login/
- http://yoursite.tld/authors/manage/
- http://yoursite.tld/authors/logout/
The account username is test and the password is test.
Closing
This article was intended to introduce some core CakePHP functions with examples in the context of building a personal blog application. We started with some user/author page functionality to introduce the basic concepts of application development with CakePHP before we move (in the next tutorial) to writing the post controller. That way we will have a better understanding of how everything in the framework fits together. We still have a long way to go before our blog application is complete, so get ready to dive deep into CakePHP so we can get all the blog's post and comment functionality working next time!
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.












User Comments
( ADD YOURS )Michael November 3rd
Very fine Cakephp-Tutorial.
( )Thanks for that work!
Lamin November 3rd
I am loving this series, please keep them coming. Thanks for the tut.
( )Guillaume November 3rd
Thx ! really interesting.
( )James November 3rd
thanks for the nice tutorial
There is something in cakephp a lot of ppl want to understand including me.. The ACL’s AROs and ACOs. i hope you can reach this step very soon.
( )Shane November 3rd
Thanks for the tutorial - interesting to read more about PHP.
( )Alex November 3rd
thanks! been waiting for this one
( )chris simpson November 3rd
great stuff. thought the series had died, delighted to see part 2 here!
( )insic November 3rd
This is the sweetest cake i ever taste. thanks for the great tutorial. looking forward for the next part.
( )retomi November 3rd
Thanks! I hope to see some tutorial a little more advanced in the future.
( )Ben Griffiths November 3rd
Great series so far, can’t wait for the next
( )mixey November 3rd
I love this articles
( )owain Llewellyn November 3rd
These tutorials are very helpful, I look forward to the next one…
What happened to the learn PHP series tho?
That one has lots of potential too.
Owain
http://www.icomworks.co.uk
( )Niklas November 3rd
Looks very interesting. Started working with cake a few weeks back and this is indeed useful.
( )weblizzer November 3rd
great coming series i do love learning this framework now… i’m also looking for zend tutorial, hopefully you can create a series aftewards…
great tutorial love it.
( )Miles Johnson November 3rd
There is a reason I do not use any framework, simply because they are all PHP 4… with one exception, Symfony.
I loved Cake when I was learning it, but why in the hell would I use PHP 4? Learn Symfony, its way more robust and powerful.
( )Furley November 3rd
shouldnt the extension on the views be .ctp rather than .thtml? I thought thtml was deprecated.
( )Brandon November 3rd
Very nice tutorial. Keep’em coming!
( )Alex Munroe November 3rd
The stable version of cakephp is still using .thtml which is what this tutorial is working with. The RC uses .ctp.
( )Furley November 3rd
I thought the general consensus was that while they haven’t yet released a stable version of 1.2, RC 3 was stable enough to develop on. What’s the point of a how-to tutorial that will be moot in a matter of weeks.
Don’t get me wrong, I totally appreciate all your hard work, and I really like cake. I just don’t want to learn and practice conventions that I will then have to re-learn next month.
( )ronak November 3rd
gr8 tutorial. thanks
( )James Simm November 4th
In the latest version of CakePHP the $html->textarea style method calls are deprecated. You should add var $helpers = array(’Form’); to the controller, and in the view use $form->create, $form->input, etc.
( )Steve November 4th
Great tutorial series, I am trying to patiently wait for the next part. I think you have a typo in your logout function
1. function logout( )
2. {
3. $this->Session->delete( ‘Author’ );
4. his->flash( ‘You have been logged out.’, ‘/’ );
5. }
should line 3 start with $this?
( )Miles Johnson November 4th
@Steve - Yes.
( )Khaled Dostzada November 4th
Honestly, that was kind of hard to follow, although it may be just me and my inexperience with the CakePHP framework
( )Christian Dalsvaag November 5th
Really nice tutorial! Been waiting for it.
I love the fact that you take your time to explain everything, and don’t just push all the information at once; I did think it was a bit short - but that’s just because I don’t want to wait for the next one xD hate waiting!
Anyway, great job! I’m looking forward to the next one!
( )Shahways Romani November 5th
The roadmap for the series looks great, so i’ll make sure to keep track of your posts. But you have me left wondering why you don’t simply use the built-in Auth component with CakePHP? It does exactly what you’re describing here, but with way less coding. Check it out at http://book.cakephp.org/view/172/Authentication !
( )Nick November 6th
Thanks for this, I never thought about using CakePHP until now. Having written an entire application in PHP before, this should help a lot.
( )bret November 6th
nice tut- however, as mentioned- you should be using the form helpers as well as .ctp instead of .thtml. I would like to see some tutorials on the model association (hasMany, hasOne, etc) as well as the built in Ajax helper.. I’ve been using cake for about a year and these are the only areas I don’t have a firm grasp on.
also- cake 1.2 runs on PHP5 so I don’t get what that prev comment about it using only php4 was about. regardless, it’s alot simpler and has less overhead than symfony (I’ve developed with both and prefer cake by leaps and bounds)
( )Jason November 7th
uhm…does this not work on localhost? I keep getting Page Not Found
( )Bryan P November 7th
I have actually started using CakePHP framework and have found it to be very useful and helpful.
My biggest hurdle is getting use to the difference in terminology and the multiple folder system.
( )Alex November 10th
@Khaled
I’m totally with you buddy. I’m not sure if this tutorial is even finished. The AuthorsController class isn’t even closed properly, and the files he told us to test with don’t even exist as far as I can see.
I’m beginning to wonder if these people comment on this without even trying to do the tutorial.
Don’t get me wrong, I’m very grateful for these free tutorials. But at the same time it can be pretty frustrating even as an experienced web developer to go through these tutorials.
( )Mr K November 10th
I love Cake, and have found it quicker and easier to learn than Symfony. Having said that Symfony has far more quality tutorials etc than Cake. This is the area cake really lacks.
It’ll be great to see this series unfold - I do however suggest that the tutorial be kept up to date (things in Cake change regularly) and where possible talk about the differences - like .ctp vs .thtml - recommending that people us .ctp
Good work, keep it up. Definitely look at Form helpers and Baking - makes things so much easier. The IBM tutorials are great, just not kept up to date.
Also, It’d be great to see more tutorials around things like consuming RSS, publishing RSS, automating email sending, send HTML vs Text emails, publishing a mobile version of your site (even under a subdomain) etc
( )jesusOmar November 10th
I get the same as Jason, Page Not Found when trying to test this on localhost. I can get the test page for the database configuration test but not the actual sample code.
( )Furley November 11th
@jason and @jesusOmar, you may want to check that you have mod rewrite activated in your apache setup. Hopefully that will help you get baking.
( )Vadim Zhernovoi November 12th
Isn’t the $html helper replaced by the $form. And you don’t need to write html to generate a form, the $form helper does everything…
( )Austin Biggs November 14th
I love this Article. But I would love to see it for code igniter instead.
( )Gustavo Caetano November 20th
A series like this to code igniter would indeed rock
( )Pavel November 22nd
Hi, please can anybody explain to me what does the THTML format mean?
( )Steve November 24th
Perhaps I should get a great grasp on PHP before embarking on PHP frameworks. This tutorial just flew by me.
( )Crawl December 4th
nice writeup!
Little hint for those working on locahost with xampp. Check your httpd.conf. Look for line that contains “LoadModule rewrite_module modules/mod_rewrite.so”. By default it is commented out, so simply uncomment it, because but it is crucial for this tutorial and CakePhp in general.
( )Bryan P. December 5th
@Pavel The THTML format is the the page template.
In previous versions it was ctp but they changed with this and hopefully future versions.
( )SomeoneSpecial December 7th
Holy sh*t, why would you allow a username to be 255 chars in length?! I wouldn’t realistically go anywhere over 25 chars.
( )Mohammed December 10th
heeeey.. part THREE please,
( )Danny December 11th
helpp,,beginner here..I got this message Warning (512): Method HtmlHelper::formTag does not exist [CORE\cake\libs\view\helper.php, line 148]
( )I don’t know what to do..anyone??
chandramani March 10th
Great tutorial for the beginners of cakephp!
( )Al December 17th
@Crawl
Thanks Man, was completely stumped till I followed your advice. Now have it up and running.
( )Rafael Bandeira December 17th
Although the tutorial is very nice, you should - must - warn people, that it’s using the old 1.1 version of CakePHP. Many things have changed since them, it’s been more than a year and a half now since 1.1 is only receiving patches and bug fixes.
CakePHP 1.2 is far more interesting, pretty and easy, and although it’s not stable released yet, it’s much more reliable and production ready than most of php frameworks tagged as “stable”. We currently have less than 5 tickets open, and the work to close them is never ceased. There’s no problem at all to initiate using CakePHP 1.2. Now, using 1.1 might get you in trouble, as most of bloggers and coders wont support it, no new tutorials and tips, and no more plugin releases.
@Danny you are using latest 1.2 version… the tutorial is using 1.1
( )Nameme December 22nd
The cake is a lie!!!
( )Plurkr December 29th
When will we see part 3 ?
Best regards,
( )Chris
Wim January 2nd
I started working with Cake 2 hours ago, and tried some tutorials on the cakesite, but that didn’t really work for me. After doing this one, I totally get it. Thanks!
Greetings from Belgium,
( )Wim
Vikas Gupta January 6th
Can somebody tell me how we can run that above tutorial. Because i am not able to run that file.
( )I will thanks to all of you who give his help.
Sina January 7th
@Danny and Alex
I have the same problem. Can you guys please make sure the uploaded code is right? I did even close the manage function with } and php closing tag ?> but i still get:
Missing View
Error: The view for AuthorsController::login() was not found.
Error: Confirm you have created the file: /Applications/MAMP/htdocs/phpcake/app/views/authors/login.ctp
Notice: If you want to customize this error message, create app/views/errors/missing_view.ctp
:S
( )Ben January 7th
How can I get this to work with the latest 1.2 of Cake?
( )Greatly appreciated
Isaac Seymour January 17th
ARGH!!!! I hate you!! why did I not know about CakePHP before!!!!!!!!! it look SOOOOOOOO easy. So kinda, thanks for telling me, but I will have to re-write all my projects in CakePHP and find that it takes a quater of the time to do it.
So:
Thank you and also NOOOOOOOOOO!!!!!!!!!!!
lol
( )Ravinesh Raj February 20th
Its gud tutorial, But U have to give a complete example with how file system keep.
( )Tom Sinclair March 5th
Nice introductory tutorial but a shame it looks like this series isn’t going anywhere, at least in a hurry!
( )chandramani March 10th
Nice CakePhp tutorial for beginners!
( )Martin March 19th
Supernice tutorial! Hopefully there will be a Part 3 soon.
( )deanet March 21st
thanks ,,, keep share for the worlds
( )Depo April 10th
Great tutorial! But for some reasons, am getting this error
Parse error: parse error, expecting `T_FUNCTION’ in D:\xampp\htdocs\myfiles\nsit\cake\app\controllers\authors_controller.php on line 65
( )sharma chelluri May 15th
Great to start developing
( )Ionut Bucur May 28th
Thanks! Great tutorial!
Started working with cake just a few time ago…. and this tut helps me alot!
Keep writting!!!
( )