In Part 1 of this series, we laid out the scope for the series and got the prerequisites out of the way. Now, you will build the sample application in each of the three frameworks. In future articles, you will extend the application, look at exceptions to the rule, play with Ajax, integrate external tasks, and much more.
This article walks you through creating the sample application, Blahg, in each of the three frameworks. You'll do it all from scratch, learning the basics of developing a simple application in the Zend Framework, symfony, and CakePHP.
You should have already gone through Part 1, which covers installation and prerequisites for each framework. If you haven't, you should do so now.
It is assumed that you already know PHP, application design, and how to work in a database. It's not necessary to have used a framework before, but you should certainly be ready to jump in with both feet.
Building Blahg in the Zend Framework
To start, create the directories /column/htdocs/zend and /column/protected/zend. These will hold Web-accessible files and application files that should not be Web-accessible, respectively. In /column/htdocs/zend, create an .htaccess file with the following lines:
RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php |
Each framework has its own particular needs when it comes to directory structures. For the Zend Framework, you need to create the directories /column/protected/zend/controllers, /column/protected/zend/models, and /column/protected/zend/views to hold your controllers, models, and views. Additionally, you need to create the directory /column/protected/zend/views/scripts; and for each controller, you need to create a directory to hold some views. For example, you know Blahg is going to need some views for the post controller, so you need to create the directory /column/protected/zend/views/scripts/post to hold this view.
You've got your directories in place. Time to build your model.
Building your Zend posts table and model
In Part 1, you created the posts table you will be using. If you skipped that, go back
and do it now. The model for this table will be very simple. It should be called
Posts.php, and you should create it in /column/protected/zend/models/. Posts.php will
extend the Zend_Db_Table class, and you'll be using most the
inherited methods from that class. If you open up the Posts.php file in the code
archive, you will see very little actual code.
Building your Zend Front controller
and PostController
For your Front controller, you will create an index.php file
in /column/htdocs/zend. This file is the only part of your application exposed
to the outside world. The rest of your application is accessed through this file. The
Front controller needs to do several things: load the Zend
Loader (to avoid having to include every library by hand), set up your connection to
the database, and dispatch requests to the appropriate application controllers; in this
case, that's only the PostController.
As you might have guessed, you will be creating the file PostController.php in the /column/protected/zend/controllers directory. The PostController you need to create is fairly simple.
For starters, you need to include the posts model you created earlier. And you should
probably create an init method, which will be called when
the PostController object is created. In the init method, you can set up the view and model objects you will
use in the subsequent actions. You can probably surmise that you need three
actions: indexAction, readAction, and writeAction (the
xxxxxAction naming convention for actions is part of doing things in the Zend Framework).
The indexAction is simple: get all the posts and assign them
to the view. The readAction isn't much more complicated: get the post ID
from the request, retrieve the post, and assign the post to the view. The writeAction isn't all that complicated, either. If a
request has been posted, strip any tags and save the data to the database. Otherwise,
render the form.
Take a look at the PostController in the code archive for
details on the syntax and structure. Now that your controllers are done, you can move on to your views.
You're almost done. Blahg requires a number of views, and you create them all in the /column/protected/zend/views/scripts/posts directory. You'll need at least three views (index.php, read.php, and write.php), though the code in the code archive makes use of four. The views are simple files: The index and read views simply output the data assigned to them, applying minimal formatting, while the write view displays a form to be used when posting to Blahg. Take a look at the views in the code download for details.
If you've created your model, controllers, and views properly (or installed the code properly), you should be able to try out the Zend Framework version of Blahg by going to http://localhost/zend/post (assuming you installed everything locally).
You are probably itching to play around with Blahg. Don't get carried away yet. You still have two more frameworks to go.
Building Blahg in symfony is somewhat different. For starters, you need to initialize the project using symfony's command-line utility.
Running the symfony init commands
Switch to a terminal window and create the directory /column/protected/sf_column using
a using a command line. This will be the protected directory to hold all the symfony
code for the column. All of your symfony command-line work must be done from this
directory. Change into the sf_column directory and execute the following command:
php /column/protected/symfony/data/bin/symfony init-project sf_column.
This command will create a slew of directories and files in /column/protected/sf_column
that are required for a symfony project. Next, you'll need to init the Blahg application. In the sf_column directory, execute the following command: php /column/protected/symfony/data/bin/symfony init-app blahg.
This command will create some more directories and files, largely in
/column/protected/sf_column/apps. But before you can use most of this, you need to
rearrange some of the files. Remember, your installation is exposing very few files to
the outside world. The application structure built by the symfony init scripts don't know what your directory structure is.
Fortunately, you can change that by adding the following lines to the end of
/column/protected/sf_column/apps/config/config.php.
Listing 1. Changing the application structure for the symfony
init scripts
$sf_root_dir = sfConfig::get('sf_root_dir');
sfConfig::add(array(
'sf_web_dir_name' => $sf_web_dir_name = 'symfony',
'sf_web_dir' => DIRECTORY_SEPARATOR.'column'.DIRECTORY_SEPARATOR.'htdocs'.
DIRECTORY_SEPARATOR.$sf_web_dir_name,
'sf_upload_dir' => DIRECTORY_SEPARATOR.'column'.DIRECTORY_SEPARATOR.
'htdocs'.DIRECTORY_SEPARATOR.$sf_web_dir_name.DIRECTORY_SEPARATOR.
sfConfig::get('sf_upload_dir_name'), ));
|
In essence, these lines are telling symfony where to find your web directory.
Now that you had added these lines, you should move the contents of
/column/protected/sf_column/web to /column/htdocs/symfony (create this directory if you
haven't already). And last but not least, you need to modify
/column/htdocs/symfony/index.php so it knows what the real root directory is for your
project. Replace the existing define for SF_ROOT_DIR with the following line:
define('SF_ROOT_DIR', '/column/protected/sf_column');.
You're almost done. Now you just need to init the post
module for Blahg. This means running another command at the command line:
php /column/protected/symfony/data/bin/symfony init-app
blahg. This command, like the others, builds up some files and directories, this
time in /column/protected/sf_column/apps/blahg/modules/post.
Now that you have symfony up and running, it's time to cobble together Blahg.
NOTE: symfony provides functionality to auto-generate code to provide the Create, Read, Update, and Delete (CRUD) functionality based on your database. While this can help you
get the basics of an application together quickly, using it in this context wouldn't
give you much of a feel for how a symfony application fits together. For the purpose
of this article, you'll build your application by hand.
Again, the posts table you will use was created in Part 1.
Because symfony uses Propel to provide Object Relational Mapping, you need to generate the model with the symfony command-line utility. This requires that you describe your database scheme and provide some database information first.
NOTE: Technically, providing the database information first isn't necessary. symfony builds the model based on the schema, and the command-line utility can even be used to generate SQL scripts to create a database based on the schema definition. We'll try that in a subsequent article.
For the database and schema definition files, symfony uses Yet Another Markup Language (YAML). YAML isn't too complicated, but if you've never used it before, it can seem confusing. At this stage, the main thing to know about YAML is that whitespace is significant. You use two spaces for an indent, and you never use tabs.
Now you will edit your database.yml and schema.yml files. They live in /column/protected/sf_column/config. And your schema.yml file needs to be edited to describe the posts table. Edit your schema file to contain the following information.
Listing 2. Editing the schema.yml file
propel:
posts :
_attributes: { phpName: Post }
id:
title: varchar(255)
text: longvarchar
modified: timestamp
|
NOTE: Since you probably copied and pasted that code, go back and make sure that each indent is two spaces, and that no tabs were used. For example, the modified line should have four spaces in front of it (two for the indent to posts and two for the indent to modified).
Your database.yml file should be edited to contain your specific database parameters. It might look something like Listing 3.
Listing 3. The database.yml file
all:
propel:
class: sfPropelDatabase
param:
phptype: mysql
hostspec: localhost
database: symfony
username: frameworks
password: fwpw
|
That shouldn't have been too hard. Now that your schema and database configurations are complete, you can generate your model. Return to the command line you were using earlier, and in /column/protected/sf_column, execute the following commands:
php /column/protected/symfony/data/bin/symfony propel-build-model php /column/protected/symfony/data/bin/symfony clear-cache |
Each command will output a large amount of data, but the important end result is the creation of the Post.php and PostPeer.php files in /column/protected/sf_column/lib/model — these are your models. If you open them up, you'll see there's not much there. They just extend the base model classes.
NOTE: Whenever you rebuild your models, it is important to run the
clear-cache command as above. Also note that if you installed symfony using
the PHP Extension and Application Repository (PEAR), you can just run
symfony propel-build-model without calling PHP
first or providing the full path to the binary. Not everyone has the option
of using PEAR their environment, which is why we described the alternate
installation instructions in Part 1, and the corresponding model-generation instructions above.
That's it! Your model for this round is done. A lot more could be said about models, but it's time to move on to your controller.
You don't need to write a Front Controller like you did in Zend, as symfony has already provided this for you.
Your post controller will actually be called actions.class.php and will live in
/column/protected/sf_column/apps/blahg/modules/post/actions. This controller will
handle all the actions for the post module. Like before, you need three actions,
but the names are different: executeIndex, executeRead, and executeWrite (the
executeXxxxxx is the naming convention used by symfony for actions and must be followed).
The executeIndex action is simple: Retrieve the posts and
make them available to the view. The executeRead action is also simple: Take in the post ID,
retrieve the post, and make the post data available to the view. The executeWrite action takes in the title and text from the
request and saves the data to the database, returning the ID of the post that was saved.
Take a look at the post/actions/actions.class.php in the code download for details on the syntax and structure. Now that your controller is done, you can move on to your views.
Your post views will live in /column/protected/sf_column/apps/blahg/modules/post/templates. You need three views: indexSuccess.php, readSuccess.php, and writeSuccess.php (the xxxxSuccess.php naming convention is part of symfony and must be followed).
These views won't render into a complete HTML document like the Zend views did. symfony provides a default layout template (in apps/blahg/templates/layout.php) that provides the basic head andfoot of the HTML page. All you need to provide is the middle of the view — content specific to the action. For example, indexSuccess.php just needs to loop through and format the provided array of posts, readSuccess.php just formats the post content, and writeSuccess.php displays the form or outputs your success message if a post has been submitted.
If you've created or installed everything properly, you should be able to try out the symfony version of Blahg by going to http://localhost/symfony/post (assuming you installed everything locally).
So you've seen how Blahg fits together in the Zend Framework and symfony. Two down, one to go.
Before you can start building Blahg in CakePHP, you need to move some of the files around. Then you'll set up your database connection and let Bake take over.
Take a look at the /column/protected/cakephp/ directory. You should see four directories: application (the directory that will hold your application), cake (the directory containing Cake's core files), docs (readme docs), and vendors (where you put third-party libraries you may use). There are also two files: index.php and .htaccess. These two files only come into play when you install CakePHP in the webroot. This is generally a bad idea, as it makes all of your application files accessible to anyone using a Web browser.
The preferred method of installation is to make /column/protected/cakephp/app/webroot the root directory for your Web server. Equally viable (and preferred for this series) would be to copy the contents of /column/protected/cakephp/app/webroot into a Web-accessible directory (in this case, /column/htdocs/cakephp). Go ahead and do this now.
Once you've copied the files over, you need to open up
/column/protected/cakephp/app/webroot/index.php and make a couple edits: The existing
definitions for ROOT and APP_DIR
need to be updated. They should look something like Listing 4.
Listing 4. Definitions of
ROOT and APP_DIR
if (!defined('ROOT')) {
define('ROOT', DS . 'column' . DS . 'protected' . DS . 'cakephp');
}
if (!defined('APP_DIR')) {
define('APP_DIR', 'app');
}
|
That's enough to get you going, but you may as well enter in your database information
and update core.php with a unique value for CAKE_SESSION_STRING.
In /column/protected/cakephp/app/config/ make a copy of database.php.default called
database.php and enter the host, login, password, and database name for your system.
Also, in /column/protected/cakephp/app/config/core.php, change the define for
CAKE_SESSION_STRING to include a new value, such as define('CAKE_SESSION_STRING', 'He had a Subbuteo player in his hair. I got distracted.');.
You've got the preliminaries out of the way. Time to jump into the cake.
NOTE: Like symfony, CakePHP provides functionality to auto-generate code to provide the CRUD functionality based on your database. CakePHP also provides scaffolding, which provides a similar service without generating any code at all. Both of these features help you get the basics of an application together quickly, but as mentioned, using these features in this context wouldn't give you much of a feel for how to build an application in CakePHP.
If you don't have a posts table, you skipped that part of Part 1, so go back and do it
now. Create a file called post.php in the /column/protected/cakephp/app/models
directory. This will contain the class definition for your model. The definition is a
simple one: The class is Post and extends AppModel, and you should set the class variable $name to post.
That's really all there is. Your model will be using all inherited methods from AppModel. Now you can move on to your controller.
NOTE: You may have noticed that the table is called posts (plural), while the model name is post (singular). This is an important part of Cake conventions. Models are always singular, and their corresponding tables are always plural.
Building the Cake posts controller
Your posts controller will be simple, like the other
controllers you have written today. You will pull in a couple helpers, then define
three actions: index, read, and write.
The index action gets a list of posts and makes them available to the view. The read action gets the ID of a post, retrieves the post and makes the
post data available to the view. The write action accepts a
submission (if there was one) and saves the data to the database.
Take a look at the /column/protected/cakephp/app/controllers/posts_controller.php in the code download for details about the syntax and structure.
Your controller is done. Now you can move on to your final views.
You'll need the same three basic views you created for Blahg in the other frameworks. In this case, you'll create the files index.ctp, read.ctp, and write.ctp in the /column/protected/cakephp/app/views/posts directory. These are just templates CakePHP will use, much like the templates you created in symfony. Take a look at these files in the code archive. The views make extensive use of the forms and HTML helpers to output links and form elements, but they should look similar to the other views you created for symfony.
Note that the views do not render to complete HTML files. A default layout is provided by CakePHP. These default layout files are located in /column/protected/cakephp/cake/libs/views/templates/layouts, but you shouldn't modify them. If you want to change the default layout, place a copy of the default.ctp layout file in /column/protected/cakephp/app/views/layouts and modify it according to your needs.
Note: Forms and links in Cake are much easier to maintain when using these helpers, as Cake will make sure your links point to the right places in the application should it be installed or moved to a different directory, and Cake will do a lot of heavy lifting for you if your form element names are formatted properly.
Build the views according to the Blahg's needs, or install the views from the code download. Assuming you've written and installed everything properly, you should be able to try out the CakePHP version of Blahg at http://localhost/cakephp/posts (assuming you've installed locally).
You gotten quite a lot done. You've installed three frameworks, gotten them each up and running, and created a basic application in each framework.
Spend some time playing around with Blahg in each framework, then try your hand at extending Blahg in each framework. Try writing a comments controller that will allow users to post their own replies to each post. Don't get too wrapped up in linking the comments to the posts just yet, though. But if you feel up to it, dive in! In Part 3, you are provided with some code that covers this.
| Description | Name | Size | Download method |
|---|---|---|---|
| Part 2 sample code | os-php-fwk2.zip | 11KB | HTTP |
Information about download methods
Learn
-
Read the rest of this "PHP
frameworks" series.
-
See the Zend Framework manual.
-
Get the symfony documentation.
-
Check out the CakePHP Manual (Note: The manual is
written to CakePHP V1.1. There may be some variance as you are using CakePHP V1.2).
-
Read the five-part series "Cook
up Web sites fast with CakePHP."
-
Visit Wikipedia for a high-level view of software
frameworks.
-
Get on overview of the MVC architecture from Wikipedia.
-
Refer to the PHP Manual for more information.
-
Visit PHP.net for additional PHP documentation.
-
For tutorials about learning to program with PHP, check out the developerWorks
"Learning PHP" series.
-
PHP.net is the central resource for PHP developers.
-
Check out the "Recommended PHP reading list."
-
Browse all the PHP content on developerWorks.
-
Expand your PHP skills by checking out IBM developerWorks' PHP project resources.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Using a database with PHP? Check out the Zend Core for
IBM, a seamless, out-of-the-box, easy-to-install PHP development and production environment that supports IBM DB2 V9.
-
Stay current with developerWorks' Technical events and webcasts.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
-
Download PHP V5.2.3.
-
Download symfony.
-
Download CakePHP.
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
-
Download IBM product evaluation versions, and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
-
Participate in developerWorks blogs and get involved in the developerWorks community.
-
Participate in the developerWorks PHP Forum: Developing PHP applications with IBM Information Management products (DB2, IDS).
Comments (Undergoing maintenance)





