by
faheem on July 4th, 2009
Well, I have written lots of separate article on Zend Framework. Hopefully most of folk out there searching for valuable help may have gotten some from my articles.
This time my objective is to share everything with you, from basic configuration till to building complete Zend Framework application.
This article will cover
1. How to make initial configuration.
2. How to use Zend_Auth for authentication
3. Using Zend_Session for handling sessions
4. What are models and how to create them
5. Using Zend_Db to handle backend database for storing valuable information.
And much more.
So let’s get started.
1. Creating directory structure and making initial configuration
Zend Framework is based on MVC design patterns. MVC stands for Model, View, Controller. A simple definition of MVC design pattern is to separate business logic from presentation logic.
In order to work with Zend Framework MVC design pattern, you’ll need to make necessary directory structure. There are various ways of making directory structure, I, however will use the most easier to create and understand structure.
The structure I created is.
html_root
/application
/controllers
IndexController.php
/models
Users.php
/forms
LoginForm.php
/views
/scripts
/dojo
index.phtml
/libaray
/Zend
/js
/css
/images
/index.phtm
On the top level we have html_root directory, containing application directory, library, js, css and images. It also contain index.phtml called our bootstrap file. This file contain all our configuration code. Further more application directory contain controller, models forms and views directories. Library directory contains Zend components. Js contain all our js files, css contains css files and images contains all images used in our application.
On the hard drive our directory structure looks like

Keep in mind that controllers directory contain our entire controllers, form directory contain all forms used in our application. Model contains php files contain our business logic. Views/scripts contain template files against each controllers.
Now as we have made necessary directory structure, next step is to make necessary configuration in our bootstrap file.
2. Making necessary configuration in our bootstrap- index.php file.
The most important file, that will get all request and route them to specific controllers. It contain code for setting include path, initializing front controller, set controllers path and call dispatch method.
define('ROOT_DIR', dirname(__FILE__));
set_include_path('.'
. PATH_SEPARATOR . ROOT_DIR . '/library'
. PATH_SEPARATOR . ROOT_DIR . '/application/models'
. PATH_SEPARATOR . ROOT_DIR . '/application/forms'
. PATH_SEPARATOR . get_include_path()
);
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory(ROOT_DIR.'/application/controllers');
$frontController->dispatch();
?>
The code is very simple to explain. The first line define path to our root directory.
The next lines set include path to /library, /application/models and /application/forms.
Next lines are very important
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
Help in loading all php files we need in our application. If we don’t use this code, we will need to include require_once statement to load php files needed.
In next lines we get instance of the front controller, set controllers directory and call dispatch method.
Front controller is responsible for handling the user request. It takes the request and on specific criteria take appropriate action.
That’s it. Its our configuration file. Simple and easy.
3. Creating controllers and views
In html_root/application/controllers, create IndexController.php and put the following code in it.
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
}
}
Every controller must be extended from Zend_Controller_Action and can contain as many methods as possible. Method defined in controllers is called action. Once you create action in the controller, next step is to create view template. For this purpose, in html_root/application/views/scripts/, create index/index.phtml and put the following code in it.
Hello world
That’s it.
Now if you browse
http://localhost/html_root/
You will see
Hello World
If you don’t see “Hello world” printed, read the above guide lines again.
As we have now successfully created directory structure and bootstrap file, its time to make other necessary configuration for database.
4. Configuration for working with database
How a web application can be completed without usage of database. Different web application uses different database. Some uses Mysql, other SQLite, SQL server and Oracle. One of the nice thing about Zend Framework is that it support multiple database servers.
Here we are going to making configuration for Mysql server.
For database configuration, first create config.ini in html_root/application/ and write the following code in it.
[general]
db.adapter = PDO_MYSQL
db.params.host = localhost
db.params.username = root
db.params.password =
db.params.dbname = zend
Now in your bootstrap file make the following changes.
define('ROOT_DIR', dirname(__FILE__));
set_include_path('.'
. PATH_SEPARATOR . ROOT_DIR . '/library'
. PATH_SEPARATOR . ROOT_DIR . '/application/models'
. PATH_SEPARATOR . ROOT_DIR . '/application/forms'
. PATH_SEPARATOR . get_include_path()
);
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$config = new Zend_Config_Ini(ROOT_DIR.'/application/config.ini', 'general');
$db = Zend_Db::factory($config->db);
Zend_Db_Table::setDefaultAdapter($db);
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory(ROOT_DIR.'/application/controllers');
$frontController->dispatch();
?>
First we load our config.ini file that contain our database configuration. Next we call static factory method of Zend_Db giving it $config->db for database configuration and at the end we set default adapter for our database tables.
That’s it. We have now done all necessary configurations.
Next step is to store and retrieve data from database
5. Working with database data
Now we are going to make an application that will save, display and edit data in the database.
First execute the following query.
CREATE TABLE `users` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`firstName` VARCHAR( 50 ) NOT NULL ,
`lastName` VARCHAR( 50 ) NOT NULL ,
`username` VARCHAR( 50 ) NOT NULL ,
`email` VARCHAR( 100 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL
)
This query create a table called users in the database.
Next step is to create model against this table. In your html_root/application/models/ create Users.php and write the following code in it.
class Users extends Zend_Db_Table
{
protected $_name = "users";
}
The only thing we have done is extend our Zend_Db_Table and define name of the model. This name must be same as the database table name.
Now in your html_root/application/controllers/IndexController.php, write
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$users = new Users();
$data = $users->fetchAll($users->select());
$this->view->data = $data;
}
}
After making changes in IndexController.php, next step is to make changes in html_root/application/views/scripts/index/index.phtml. write the following code in it.
<h4>List of users</h4>
<h5><a href="add" style="color:blue">Add new user</a></h5>
<table border="1">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
<th>Email</th>
<th>Action</th>
</tr>
</thead>
<tboody>
<?php foreach ($this->data as $d) {?>
<tr>
<td><?=$d['firstName']?></td>
<td><?=$d['lastName']?></td>
<td><?=$d['username']?></td>
<td><?=$d['email']?></td>
<td><a href="edit/id/<?=$d['id']?>" style="color:blue">Edit</a></td>
</tr>
<?php }?>
</tbody>
</table>
This will show the list of users.
Next we are going to create a form for adding data to users table.
In your html_root/application/forms/ create CustomForm.php and write the following code in it.
class CustomForm extends Zend_Form
{
public function init()
{
$this->setMethod('post');
//$this->setAction('add');
$id = $this->createElement('hidden','id');
$firstname = $this->createElement('text','firstname');
$firstname->setLabel('First Name:')
->setAttrib('size',50);
$lastname = $this->createElement('text','lastname');
$lastname->setLabel('Last Name:')
->setAttrib('size',50);
$username = $this->createElement('text','username');
$username->setLabel('Username:')
->setAttrib('size',50);
$email = $this->createElement('text','email');
$email->setLabel('Email:')
->setAttrib('size',50);
$password = $this->createElement('password','password');
$password->setLabel('Password:')
->setAttrib('size',50);
$password2 = $this->createElement('password','password2');
$password2->setLabel('Confirm Password::')
->setAttrib('size',50);
$register = $this->createElement('submit','register');
$register->setLabel("Register")
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$username,
$email,
$password,
$password2,
$id,
$register
));
}
}
We have successfully created our form, next we are going to write necessary code in our IndexController.php
Write the following code in it
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$users = new Users();
$data = $users->fetchAll($users->select());
$this->view->data = $data->toArray();
}
public function addAction()
{
$users = new Users();
$form = new CustomForm();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
if ($formData['password'] != $formData['password2']) {
$this->view->errorMsg = "Password and Confirm Password must match.";
$this->render('add');
return;
}
unset($formData['password2']);
unset($formData['register']);
$users->insert($formData);
}
}
}
}
The code in addAction create form, get posted data, check whether password and confirm password match and then insert data in the users table.
Now create add.phtml in html_root/application/views/scripts/index/ and write the following code in it.
<h3>Add User</h3>
<?php
if ($this->errorMsg) {
echo $this->errorMsg;
}
?>
<?php
// for displaying form
echo $this->form;
?>
Next we are going to create action for editing the users table data. Write the following code in the your IndexController.php
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
//$this->_helper->layout->disableLayout();
$users = new Users();
$data = $users->fetchAll($users->select());
$this->view->data = $data->toArray();
}
public function addAction()
{
$users = new Users();
$form = new CustomForm();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
if ($formData['password'] != $formData['password2']) {
$this->view->errorMsg = "Password and Confirm Password must match.";
$this->render('add');
return;
}
unset($formData['password2']);
unset($formData['register']);
$users->insert($formData);
}
}
}
public function editAction()
{
$users = new Users();
$form = new CustomForm();
$id = $this->_getParam("id",1);
$select = $users->select()
->where("id = ?",$id);
$data = $users->fetchRow($select);
$form->populate($data->toArray());
if ($this->getRequest()->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
if ($formData['password'] != $formData['password2']) {
$this->view->errorMsg = "Password and Confirm Password must match.";
$this->render('add');
return;
}
unset($formData['password2']);
unset($formData['register']);
$users->update($formData,"id = $id");
}
}
$this->view->form = $form;
}
}
The above code fetch the data and populate the form, and then get the posted data and update the users table based on the id.
Create edit.phtml in html_root/application/views/scripts/index/ and write the following code in it.
<h3>Edit User</h3>
<?php
if ($this->errorMsg) {
echo $this->errorMsg;
}
?>
<?php
// for displaying form
echo $this->form;
?>
6. Create authentication application
As now we have created database application successfully, we are going to create authentication application.
(i). Creating login form
in your html_root/application/forms/ create LoginForm.php and write the following code in it.
class LoginForm extends Zend_Form
{
public function init()
{
$this->setName('login');
$this->setMethod('post');
$userName = $this->createElement('text', 'userName',array('label' => 'username' ));
$userName->addFilters(array('StringTrim'))
->addValidator('StringLength', false,array(5,50))
->setValue('')
->setRequired(true);
$password = $this->createElement('password','password',array('label' => 'password' ));
$password ->setRequired(true)
->addValidator('StringLength', false,array(5,50))
->setValue('');
$submit = $this->createElement('submit','save',array('label' => 'login'));
$submit->setRequired(false)
->setIgnore(true);
$this->addElements(array(
$userName,
$password,
$submit,
));
}
}
In the above form we add two elements, a text box for entering username and password field for entering user password. We also add submit input box.
(ii).Next we create AuthController.php in html_root/application/controllers/ and write the following code
class AuthController extends Zend_Controller_Action
{
public function loginAction()
{
$form = new LoginForm();
if ($this->getRequest()->isPost()) {
$values = $this->_request->getPost();
if ($form->isValid($values)) {
$users = new Users();
$auth = Zend_Auth::getInstance();
$authAdapter = new Zend_Auth_Adapter_DbTable($users->getAdapter());
$authAdapter->setTableName('users');
$authAdapter->setIdentityColumn('userName');
$authAdapter->setCredentialColumn('password');
$authAdapter->setIdentity($values['userName']);
$authAdapter->setCredential($values['password']);
try {
$result = $auth->authenticate($authAdapter);
} catch (Zend_Exception $e) {
$this->view->errorMsg = $e->getMessage() . "<br>";
}
if ($result->isValid()) {
$data = $authAdapter->getResultRowObject();
$sess = new Zend_Session_Namespace();
$sess->username = $data->useruame;
echo "Welcome <b>".$data->username.'</b><br>You successfully logged in.';
} else {
echo "invalid username or password try again.";
}
}
}
$this->view->form = $form;
}
}
In login action we initialize our login form, check for submitted data. We then instantiate our user model as well as Zend_Auth. Setting table name, identity column and credential column. We then pass values submitted through form to identity column and credential column. After setting these things we call authenticate() method.
This authenticate column perform authentication for us.
We then call isValid() method that return true or false based on the authentication.
If isValid() return true, we get the user specific information by calling getResultRowObject() method.
We then create session and assign username to it.
The last thing we will need to create is view template against login action. In html_root/application/views/scripts create auth/login.phtml and write the following code in it.
<fieldset style="width:400px">
<legend>Login</legend>
<?php
echo $this->form;
?>
<div><a href="../index/add" style="color:blue">New user Sign up here</a></div>
</fieldset>
That’s it. Our login authentication. For registration, you can use add form I have previously created.
I think its enough for now. I will discuss other things later on hopefully.
by
faheem on July 3rd, 2009
Well, after writing few separate article about Zend Framework and dojo, I feel that I’d need to write a complete Zend_Dojo_Form. So here I am with complete example.
I am going to explain everything step by step.
1. Download Zend Framework latest version
Download least stable version from http://www.zend.com. Copy external/dojo to js/.
Hopefully you will create your directory structure as
html_root
/application
/controllers
DojoController.php
/models
/forms
CustomDojoForm.php
/views
/scripts
/dojo
index.phtml
/libaray
/Zend
/public
/js
/dojo
/css
/images
/bootstrap.php
/index.phtm
It’s not compulsory to create the similar directory structure I have created, this can vary. For best practice read Zend Quick start from Zend Framework documentation.
2. Enable dojo in the bootstrap file
I am not going to discuss everything you will need to have in your bootstrap file. I am explaining only the line of code needed to enable dojo.
You may have initialized your view in the bootstrap file as
$view = new Zend_View();
if you haven’t, you will need to write the following code.
$view = new Zend_View();
$view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
If you already have
$view = new Zend_View();
in your bootstrap, no need to initialize it twice.
The second line is compulsory. It add helper path. This means that your view now can access all the helpers in library/Zend/Dojo/View/Helper/ directory.
In the next lines, I initialize viewRenderer, add view to it, and add viewRenderer to HelperBroker.
That’s it. We have now made all necessary changes in our bootstrap file.
3. Making necessary changes in your layout file.
Well, if are newbie. You will need to understand two step view before making the following changes. Read my article http://zendguru.wordpress.com/
The changes we will need in our layout file are
$this->dojo()->setDjConfigOption('usePlainJson',true)
->addStylesheetModule('dijit.themes.tundra')
->setLocalPath("http://localhost/zend/public/js/dojo/dojo/dojo.js");
echo $this->dojo();
?>
<body class="tundra">
Nothing hard to understand here. In the first line we set dojo configuration option. In the second line we add style sheet module, and the third line we add path to our dojo.js file.
After setting these option, we call dojo() helper method as
echo $this->dojo();
We have now made the entire necessary configuration in our bootstrap and layout file. It’s now time to play with Zend_Dojo_Form.
4. Creating Zend_Dojo_Form
Creating a dojo form as simple as this.
class DojoForm extends Zend_Dojo_Form
{
public $_selectOptions;
public function init()
{
$this->_selectOptions=array(
'1' => 'red',
'2' => 'blue',
'3' => 'gray'
);
$this->setMethod('post');
$this->setAttribs(array(
'name' => 'masterform'
));
$this->setDecorators(array(
'FormElements',
array(
'TabContainer',
array(
'id' => 'tabContainer',
'style' => 'width:660px; height:500px',
'dijitParams' => array(
'tabPosition' => 'top',
)
),
'DijitForm'
)
));
$textForm= new Zend_Dojo_Form_SubForm();
$textForm->setAttribs(array(
'name'=> 'textboxtab',
'legend' => 'Text Elements',
'dijitParams' => array(
'title' => 'Text Elements',
)
));
$textForm->addElement(
'TextBox',
'textbox',
array(
'value' => 'some text',
'label' => 'TextBox',
'trim' => true,
'propercase' => true,
)
);
$textForm->addElement(
'DateTextBox',
'datebox',
array(
'value' => '2008-07-05',
'label' => 'DateTexBox',
'required' => true,
)
);
$textForm->addElement(
'TimeTextBox',
'timebox',
array(
'label' => 'TimeTexBox',
'required' => true,
)
);
$textForm->addElement(
'CurrencyTextBox',
'currencybox',
array(
'label' => 'CurrencyTexBox',
'required' => true,
'currency'=>'USD',
'invalidMessage' => 'Invalid amount',
'symbol' => 'USD',
'type' => 'currency',
)
);
$textForm->addElement(
'NumberTextBox',
'numberbox',
array(
'label' => 'NumberTexBox',
'required' => true,
'invalidMessage'=>'Invalid elevation.',
'constraints' => array(
'min' => -2000,
'max'=> 2000,
'places' => 0,
)
)
);
$textForm->addElement(
'ValidationTextBox',
'validationbox',
array(
'label' => 'ValidationTexBox',
'required' => true,
'regExp' => '[\w]+',
'invalidMessage' => 'invalid non-space text.',
)
);
$textForm->addElement(
'Textarea',
'textarea',
array(
'label' => 'TextArea',
'required' => true,
'style' => 'width:200px',
)
);
$toggleForm= new Zend_Dojo_Form_SubForm();
$toggleForm->setAttribs(array(
'name' => 'toggletab',
'legend' => 'Toggle Elements',
));
$toggleForm->addElement(
'NumberSpinner',
'ns',
array(
'value' => '7',
'label' => 'NumberSpinner',
'smallDelta' => 5,
'largeDelta' => 25,
'defaultTimeout' => 1000,
'timeoutChangeRate' => 100,
'min' => 9,
'max' => 1550,
'places' => 0,
'maxlength' => 20,
)
);
$toggleForm->addElement(
'Button',
'dijitButton',
array(
'label' => 'Button',
)
);
$toggleForm->addElement(
'CheckBox',
'checkbox',
array(
'label' => 'CheckBox',
'checkedValue' => 'foo',
'uncheckedValue' => 'bar',
'checked' => true,
)
);
$selectForm= new Zend_Dojo_Form_SubForm();
$selectForm->setAttribs(array(
'name' => 'selecttab',
'legend' => 'Select Elements',
));
$selectForm->addElement(
'ComboBox',
'comboboxselect',
array(
'label' => 'ComboBox(select)',
'value' => 'blue',
'autocomplete'=>false,
'multiOptions' => $this->_selectOptions,
)
);
$selectForm->addElement(
'FilteringSelect',
'filterselect',
array(
'label' => 'FilteringSelect(select)',
'value' => 'blue',
'autocomplete'=>false,
'multiOptions' => $this->_selectOptions,
)
);
$this->addSubForm($textForm,'textForm')
->addSubForm($toggleForm,'toggleForm')
->addSubForm($selectForm,'selectForm');
}
}
I don’t think I can explain everything in the form. Just giving you a clue.
I’ve created three sub forms, a text form contain elements such as textbox, date textbox, time textbox etc, a toggle sub form contain elements like number spinner, button and checkbox, and a select sub form containing select box and filtering select. I also have set different attributes for these elements.
3. Instantiating Zend_Dojo_Form in your controller
Your DojoController must have the following code.
class DojoController extends Zend_Controller_Action
{
function indexAction()
{
$form= new DojoForm();
$this->view->form= $form;
}
}
I don’t think anything needs to be explained.
4. Displaying form in template
Your template in views/scripts/dojo/ called index.phtml must have the following code.
echo $this->form;
?>
by
faheem on July 1st, 2009
I got “The Zahir”, a novel by Paula Coelho about a month back, very sweat one and highly intrigued. It was highly entertaining and most importantly author shared his experiences in a nice way. I learned plenty of new ideas.
Eh, you may think that I am insane, supposed to write about Zend Framework, but discussing a novel.
Well, novel can not only be a good companion of yours, but it also put shade of light on simple things from many angles. This make you think dynamically.
If you are solving a puzzle or implementing your logic, do not think straight forward, give multiple tries and chose a more appropriate solution. Solving a problem will not be hard. You should chose a solution that require less code, small maintenance overhead and most importantly one that will be less resource intensive.
Now lets stick to the topic and discuss how you can use Zend_Form component for creating html form easily, handling filters and errors messages and how to see how easily you can fetch data from the data source and present that in html form and let the visitors change/modify the existing data and save changes to the data source.
I am gona break this topic in three steps.
1. Creating Zend_Form
Although I’ve already discussed creation of Zend_Form in some of my articles but it will be better to discuss it here again.
Creating Zend form is simple is this.
class CustomForm extend Zend_Form
{
public function init()
{
}
}
defined a class by extending it from Zend_Form. This allow access to many of methods already defined in Zend_Form.
The only thing you need to do is to override init() method and create your own element such as input box, select statement, checkboxes, radio buttons and so on.
Defining your own elements don’t take much code. Have a look at the following code.
class CustomForm extend Zend_Form
{
public function init()
{
$this->setMethod('post');
$this->setAction('process/form');
$username = $this->createElement('text','username');
$username->setLabel('Username:')
->setAttrib('size',50);
$this->addElement($username);
}
}
In the code above we have overridden init() method of Zend_Form, set the form request method and action and then defined input element called username. You can put as many elements in this form as you wish. The last statement is used to add element to the forms. To add several elements to the form at once, use addElements() passing array of elements as an argument. You will look an example in the next example.
My entire form look likes
class CustomForm extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$id = $this->createElement('hidden','id');
$firstname = $this->createElement('text','firstname');
$firstname->setLabel('First Name:')
->setAttrib('size',50);
$lastname = $this->createElement('text','lastname');
$lastname->setLabel('Last Name:')
->setAttrib('size',50);
$username = $this->createElement('text','username');
$username->setLabel('Username:')
->setAttrib('size',50);
$email = $this->createElement('text','email');
$email->setLabel('Email:')
->setAttrib('size',50);
$password = $this->createElement('password','password');
$password->setLabel('Password:')
->setAttrib('size',50);
$password2 = $this->createElement('password','password2');
$password2->setLabel('Confirm Password::')
->setAttrib('size',50);
$register = $this->createElement('submit','register');
$register->setLabel("Register")
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$username,
$email,
$password,
$password2,
$id,
$register
));
}
}
Most of the functions are simple and self explanatory. The only method that I think I’d better explain here is setIgnore() method. The method setIgnore() has a very valuable usage. Well, if we see the entire form you will feel that we need all values when form is submitted. The only value we don’t need is the value of the submit button as this only used to submit the form. We are not interested in its value, so we call setIgnore() method passing Boolean value true.
2. As we have now created a form, next step is to create its object in controller and write code that will save data for us. Create a controller as
class UsersController extends Zend_Controller_Action
{
.....
public function addAction()
{
//$this->_helper->layout->disableLayout();
$users = new Users();
$form = new CustomForm();
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
if ($formData['password'] != $formData['password2']) {
$this->view->errorMsg = "Password and Confirm Password must match.";
$this->render('add');
return;
}
unset($formData['password2']);
unset($formData['register']);
$users->insert($formData);
}
}
}
}
What we are doing here, is pretty simple. Create an object of Users model. Well I haven’t discussed Users model yet. I would discuss it for you soon. The next line creates an object of the form created earlier. Next we assign the form to the view template, in our case the template is add.phtml.
Next few lines are of much importance.
We check whether the request is first one or the post back. If form has been submitted, method $this->getRequest()->isPost() return ture. In this case we will need to take care of the data being submitted.
To handle the post back we get the data been posted back through form, check its validity, check if the password and confirm password matches, and insert the values in the “users” table using $users->insert(); statement.
If form is not valid, the code for inserting the data in the database will not be executed.
Now lets discuss “Users” model.
We have a table in our database called “users” containing different fields such as username, firstname, lastname etc.
We will need to create our model as
class Users extends Zend_Db_Table
{
protected $_name = "users";
}
That’s it, a simple model.
3. The third step in creating a full fledge form application in Zend Framework is presentation layer, called view/template.
In your scripts/users/ directory create add.phtml and put the following code in it
<h3>Add User</h3>
<?php
if ($this->errorMsg) {
echo $this->errorMsg;
}
?>
<?php
// for displaying form
echo $this->form;
?>
The code above is self explanatory.
The above process only shows a form and submits data to the database. If you want to create edit form, you will need to make a bit of change in your controller.
Let’s create another action called editAction containing the following code.
class UsersController extends Zend_Controller_Action
{
.....
public function editAction()
{
//$this->_helper->layout->disableLayout();
$users = new Users();
$form = new CustomForm();
$id = $this->_getParam("id",1);
$select = $users->select()
->where("id = ?",$id);
$data = $users->fetchRow($select);
$form->populate($data->toArray());
if ($this->getRequest()->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
if ($formData['password'] != $formData['password2']) {
$this->view->errorMsg = "Password and Confirm Password must match.";
$this->render('add');
return;
}
unset($formData['password2']);
unset($formData['register']);
//Zend_Debug::dump($formData);exit;
$users->update($formData,"id = $id");
}
}
$this->view->form = $form;
}
}
You can clearly see that I’ve made only few lines of changes.
First I get the id of the user through $this->_getParam() method. I then create a select statement on the users table and then fetch a row. Once I get the data row, I populate the form using populate() method.
The only thing you will need now, is to create a view template in your scripts/users/ directory named edit.phtml and write the following code.
if ($this->errorMsg) {
echo $this->errorMsg;
}
?>
<?php
// for displaying form
echo $this->form;
?>
Well I was thinking to explain everything in three steps, but I think it would be incomplete if I don’t explain how to show the data inserted in the database. For this reason I going to add 4th step.
4. Showing list of data
Create an action called indexAction in your controller with the following code.
class UsersController extends Zend_Controller_Action
{
public function indexAction()
{
//$this->_helper->layout->disableLayout();
$users = new Users();
$data = $users->fetchAll($users->select());
$this->view->data = $data->toArray();
//Zend_Debug::dump($data->toArray());
}
.....
}
First we create an object of our mode. And then fetch the data using the fetchAll() method. The last statement assigns the fetched data to the view template.
Now create scripts/users/index.phtml and write the following code in it.
<h4>List of users</h4>
<h5><a href="add">Add new user</a></h5>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
<th>Email</th>
<th>Action</th>
</tr>
</thead>
<tboody>
<?php foreach ($this->data as $d) {?>
<tr>
<td><?=$d['firstname']?></td>
<td><?=$d['lastname']?></td>
<td><?=$d['username']?></td>
<td><?=$d['email']?></td>
<td><a href="edit/id/<?=$d['id']?>">Edit</a></td>
</tr>
<?php }?>
</tbody>
</table>
Here we are creating a table that shows the list of data. I don’t think this need to be explained.
by
faheem on July 1st, 2009
After writing separate articles on different Zend framework topics, its now time to write a full fledge tutorials. I am starting from a simple sign up and login authentication example and hopefully will discuss some advance topic in future.
So lets get started.
First create a table in your database by executing the following sql query.
CREATE TABLE ‘users’ (
‘id’ int(11) NOT NULL auto_increment,
‘firstname’ varchar(100) default NULL,
‘lastname’ varchar(100) default NULL,
‘email’ varchar(255) NOT NULL,
‘username’ varchar(100) NOT NULL,
‘password’ varchar(15) NULL,
PRIMARY KEY (’id’)
)
Next create a model against this table in your application/model/ directory. I am creating Users.php and writing the following code in it.
class Users extends Zend_Db_Table
{
protected $_name=”users”;
}
?>
Now create a controller named AuthController.php in application/controllers/ directory and place the following code in it
class AuthController extends Zend_Controller_Action
{
public function loginAction()
{
}
public function signupAction()
{
}
public function logoutAction()
{
}
public function homeAction()
{
}
}
As we have now create our controller and three actions, we will need to create templates files for actions. Go application/views/scripts and create a folder named “auth” and create three files in application/views/scripts/auth named
login.phtml
signup.phtml
logout.phtml
home.phtml
As we will need to have forms for sign up and login so we are going to create to files named “LoginForm.php” and “RegistrationForm.php” for these forms in application/forms/ directory.
In LoginForm.php place the following code
class LoginForm extends Zend_Form
{
public function init()
{
}
}
class LoginForm extends Zend_Form
{
public function init()
{
}
}
and in the RegistrationForm.php place the following code
class RegistrationForm extends Zend_Form
{
public function init()
{
}
}
So far you can see that we have created all our necessary files.
No lets put the application logic in these files.
We are starting from the forms first.
In LoginForm.php, write the following code
class LoginForm extends Zend_Form
{
public function init()
{
$username = $this->createElement(’text’,'username’);
$username->setLabel(’Username: *’)
->setRequired(true);
$password = $this->createElement(’password’,'password’);
$password->setLabel(’Password: *’)
->setRequired(true);
$signin = $this->createElement(’submit’,’signin’);
$signin->setLabel(’Sign in’)
->setIgnore(true);
$this->addElements(array(
$username,
$password,
$signin,
));
}
}
In the above form we are creating two text elements named “usernam” and “password”, set their labels and setRequred to true. Next we create a submit button.
Similarly in RegistrationForm.php, write the following code
class RegistrationForm extends Zend_Form
{
public function init()
{
$firstname = $this->createElement('text','firstname');
$firstname->setLabel('First Name:')
->setRequired(false);
$lastname = $this->createElement('text','lastname');
$lastname->setLabel('Last Name:')
->setRequired(false);
$email = $this->createElement('text','email');
$email->setLabel('Email: *')
->setRequired(false);
$username = $this->createElement('text','username');
$username->setLabel('Username: *')
->setRequired(true);
$password = $this->createElement('password','password');
$password->setLabel('Password: *')
->setRequired(true);
$confirmPassword = $this->createElement('password','confirmPassword');
$confirmPassword->setLabel('Confirm Password: *')
->setRequired(true);
$register = $this->createElement('submit','register');
$register->setLabel('Sign up')
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$email,
$username,
$password,
$confirmPassword,
$register
));
}
}
In the above code we have created several elements and place them in the form. Keep in mind that we have place * next to compulsory elements labels.
As we have now created our forms, next step is to display these in the templates files. However to do this we will first need to initialize these in our controller
So in AuthController.php, write the following code
class AuthController extends Zend_Controller_Action
{
public function homeAction()
{
$storage = new Zend_Auth_Storage_Session();
$data = $storage->read();
if(!$data){
$this->_redirect('auth/login');
}
$this->view->username = $data->username;
}
public function loginAction()
{
$users = new Users();
$form = new LoginForm();
$this->view->form = $form;
if($this->getRequest()->isPost()){
if($form->isValid($_POST)){
$data = $form->getValues();
$auth = Zend_Auth::getInstance();
$authAdapter = new Zend_Auth_Adapter_DbTable($users->getAdapter(),'users');
$authAdapter->setIdentityColumn('username')
->setCredentialColumn('password');
$authAdapter->setIdentity($data['username'])
->setCredential($data['password']);
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
$storage = new Zend_Auth_Storage_Session();
$storage->write($authAdapter->getResultRowObject());
$this->_redirect('auth/home');
} else {
$this->view->errorMessage = "Invalid username or password. Please try again.";
}
}
}
}
public function signupAction()
{
$users = new Users();
$form = new RegistrationForm();
$this->view->form=$form;
if($this->getRequest()->isPost()){
if($form->isValid($_POST)){
$data = $form->getValues();
if($data['password'] != $data['confirmPassword']){
$this->view->errorMessage = "Password and confirm password don't match.";
return;
}
if($users->checkUnique($data['username'])){
$this->view->errorMessage = "Name already taken. Please choose another one.";
return;
}
unset($data['confirmPassword']);
$users->insert($data);
$this->_redirect('auth/login');
}
}
}
public function logoutAction()
{
$storage = new Zend_Auth_Storage_Session();
$storage->clear();
$this->_redirect('auth/login');
}
}
It will be hard for beginners to understand the above code. So lets break it and see what this code is all about.
public function homeAction()
{
$storage = new Zend_Auth_Storage_Session();
$data = $storage->read();
if(!$data){
$this->_redirect('auth/login');
}
$this->view->username = $data->username;
}
The above code is very simple. We first create instance of Zend_Auth_Storage_Session class. Next we call its read method. This will return a row of records if the users is authenticated, otherwise null.
We check if the data is null. If yes, we redirect our page to the login action.
If data is found, it means that user is authenticated and we assign username to the view template. So display welcome message in our home.phtml template, open views/scripts/auth/home.phtml and write the following code.
Welcome <?=$this->username?>,<br>
This is your home page<br>
<a href=”<?=$this->url(array(’controller’=>’auth’,'action’=>’logout’))?>”>click here to logout</a>
In the code above we have a link to the logout action, which simply destroy our session.
Next
public function loginAction()
{
$users = new Users();
$form = new LoginForm();
$this->view->form = $form;
if($this->getRequest()->isPost()){
if($form->isValid($_POST)){
$data = $form->getValues();
$auth = Zend_Auth::getInstance();
$authAdapter = new Zend_Auth_Adapter_DbTable($users->getAdapter(),'users');
$authAdapter->setIdentityColumn('username')
->setCredentialColumn('password');
$authAdapter->setIdentity($data['username'])
->setCredential($data['password']);
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
$storage = new Zend_Auth_Storage_Session();
$storage->write($authAdapter->getResultRowObject());
$this->_redirect('auth/home');
} else {
$this->view->errorMessage = "Invalid username or password. Please try again.";
}
}
}
}
In the fist two lines we create instances of our model and login form with statements
$users = new Users();
$form = new LoginForm();
In the third line we assign form instance to view template for display purpose.
The logic of logging in is defined in the next lines
We first check that the users has posted the request. If yes we check that he has submitted valid form. If both the condition return true, we get the values submitted as
$data = $form->getValues();
Next we create instance of Zend_Auth with code
$auth = Zend_Auth::getInstance();
and $authAdapter with
$authAdapter = new Zend_Auth_Adapter_DbTable($users->getAdapter(),’users’);
To perform authentication we will need to either use existing Adapters provided by Zend or create our own.
Here I am using DbTable Adapter provided by Zend, giving adapter and database table name. our table name is users.
Next we set identity and credential columns.
After that we give posted values to the $adapter.
To perform authentication we will need to call Zend_Auth authenticate() method, for this we write
$result = $auth->authenticate($authAdapter);
Next we check if the result is valid with statement $result->isValid(). This either return true or false. If it return true it means that we found a record in the database.
If valid record is found we create session instance and store the user data in the session with statements
$storage = new Zend_Auth_Storage_Session();
$storage->write($authAdapter->getResultRowObject());
and redirect our request to home action.
$this->_redirect(’auth/home’);
If result is not valid we assign error message to our template file
In application/views/scripts/login.phml, write the following
<?
if(isset($this->errorMessage)){
echo $this->errorMessage;
}?>
<?
echo $this->form;
?>
<a href=”<?=$this->url(array(’controller’=>’auth’,'action’=>’signup’))?>”>New users click here?</a>
In the code above we first check the error message, if set we display it.
In the next line we display our login form.
Next
public function signupAction()
{
$users = new Users();
$form = new RegistrationForm();
$this->view->form=$form;
if($this->getRequest()->isPost()){
if($form->isValid($_POST)){
$data = $form->getValues();
if($data['password'] != $data['confirmPassword']){
$this->view->errorMessage = "Password and confirm password don't match.";
return;
}
if($users->checkUnique($data['username'])){
$this->view->errorMessage = "Name already taken. Please choose another one.";
return;
}
unset($data['confirmPassword']);
$users->insert($data);
$this->_redirect('auth/login');
}
}
}
This action is used for signup purpose. We create instance of our model class and Registration Form. And assign form to our view template.
Check for the post request and valid form.
If the form is valid we get form values. Check if both the password fields don’t have same data. If they are not same we assign error message to the view template.
Next we call our checkUnique() method of the model class. This checkUnique() method check the data in the database. If row with the posted username is already in the database it return ture, means username already exist in the database. If username found we assign error message to view telling the user to choose another username. It not we insert the data in the database. And redirect the request to login action.
Our model class look as
class Users extends Zend_Db_Table
{
protected $_name="users";
function checkUnique($username)
{
$select = $this->_db->select()
->from($this->_name,array('username'))
->where('username=?',$username);
$result = $this->getAdapter()->fetchOne($select);
if($result){
return true;
}
return false;
}
}
To create a template file for the signup action, place the following code in views/scripts/auth/signup.phtml
<?
if(isset($this->errorMessage)){
echo $this->errorMessage;
}?>
<h4>Sign up</h4>
<?
echo $this->form;
?>
first we check for the error, if error message is set in the action we display that.
Next we display our Registarion form.
The last and final thing is our logout action.
public function logoutAction()
{
$storage = new Zend_Auth_Storage_Session();
$storage->clear();
$this->_redirect('auth/login');
}
Here we create instance of Zend_Auth_Storage_Session and clear it.
And we then redirect our request to login action.