http://www.developer.com/tech/article.php/3846966/Managing-User-Accounts-with-the-Zend-Framework.htm
Today's consumer sure has become the discerning sort,
hasn't he? No longer content with a standard product made
for the masses, today's buyer seeks out wares capable of
being modified to fit specific tastes and desires. iPod
engraving, customized Scions,
and even monogrammed
postage stamps are just a few examples of the lengths
companies (and consumers) are going to, to make the
marketplace their very own. With the Web a crucial part of our everyday lives, not to
mention a major part of the societal marketplace, it doesn't
come as a surprise that consumers have come to expect as
much from the virtual world as they do of the physical.
Custom sports scores, localized news, and tailor-made
product catalogs are all typical features on today's web
sites. Of course, barring the employment of The Amazing
Kreskin, Web site developers require a way to match a
user to his online preferences. The standard way to do so is
by providing the user with a means for creating and logging
into an account. This account serves as the glue which ties
the user to his actions performed while navigating the Web
site, such as purchasing an e-book, identifying his hometown
as Columbus, Ohio, or specifying that he'd like to see only
sports-related news hailing from Pittsburgh. Creating a user account feature is a bit more involved
than simply creating a database table for hosting account
information, and plugging it into the requisite registration
and login forms. You'll also need to think about
safeguarding against bogus accounts by requiring the user to
confirm his e-mail address before the account is activated,
maintaining the user's session while he's navigating the Web
site, providing a simple mechanism for logging out of an
account, and allowing users to easily recover forgotten
passwords. Recognizing the commonplace need for such
features, the Zend
Framework is bundled with a great component named Zend_Auth which significantly reduces the time required
to create and manage user accounts. In this tutorial I'll
show you how to create the building blocks for managing user
accounts, showing you how to register users, and allow them
to both login and logout of your Web site. In order to create a user registration feature, we'll
need a place to store the account information. The most
logical place to do so is within a database table specially
designated for this purpose. A sample MySQL table schema for
such a purpose might look like this:
Nothing in this table should be too surprising, except
for perhaps the Of course, you'll probably need to extend the account
table to include other pertinent information, such as the
user's address, phone number, or birthdate. For the purposes
of this tutorial I'm focusing on just the bare minimum
requirements, so don't be afraid to add to this table as you
see fit. Next you'll need to create the account model pursuant to the typical convention defined by the Zend Framework. I'm going to keep the initial model capabilities to a minimum, although we'll add to it as necessary. Next up is the registration form. I'm going to keep this to the minimum required fields, creating the form you see in Figure 1. As there's nothing special about this form, following the screenshot I'll skip the code and move on to the controller action used to process this form information. With the account table, model, and registration form in place, it's time to write the code which will validate the user's registration information and create the account. For the purposes of this exercise presume the the form action points to an action named register created within a controller named account: Let's review some of the stickier parts of this action:
The account model's All of this should look pretty straightforward, so I won't dive into a line-by-line breakdown, other than to say that the Keep in mind that this is only one of several possible
ways to create the registration logic. As a rule though I
suggest following the "fat model, thin controller" approach
as demonstrated here. Zend Framework project lead Matthew
Weier O'Phinney published a great blog post about this very
matter here. With the prerequisite steps out of the way, we're ready
to bring the
Let's review this code:
Determining if a user is logged in is easily done using
You can place this call in a controller's
Finally, to log the user out of the site, just create an
action named for instance logout, and point a hyperlink to
it:
Managing user accounts is made incredibly easy using the
powerful Jason Gilmore is founder of EasyPHPWebsites.com, and author of the popular book, "Easy PHP Websites
with the Zend Framework". Formerly Apress' open source
editor, Jason fostered the development of more than 60
books, along the way helping to transform their open source
line into one of the industrys most respected publishing
programs. Over the years he's authored several other books,
including the best-selling Beginning PHP
and MySQL: From Novice to Professional (currently in its
third edition), Beginning PHP
and PostgreSQL: From Novice to Professional, and Beginning PHP
and Oracle: From Novice to Professional. Jason is a cofounder and speaker chair of CodeMash, a nonprofit
organization tasked with hosting an annual namesake
developers conference, and was a member of the 2008 MySQL
Conference speaker selection board. Jason has published more than 100 tutorials and articles
within prominent publications such as Developer.com, Linux Magazine, and TechTarget.
Managing User Accounts with the Zend Framework
November 16, 2009
Managing User Accounts with the Zend Framework - Introduction
Creating the User Registration Feature
CREATE TABLE account {
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
pswd CHAR(32) NOT NULL,
recovery_key CHAR(32) DEFAULT ""
}
pswd and recovery_key
columns. The pswd column is defined as a
CHAR(32) because the user's password will always be stored
in hashed format using PHP's md5() function,
making it highly unlikely the plaintext password will be
recovered should an attacker somehow gain access to the
database. The md5() function will convert any
string to a 32-character hash, giving reason to the type
definition. The recovery_key column will be
used later in this tutorial to hold a random 32-character
string which will be used to confirm the user's identity in
case he initiates the password recovery sequence. I'll talk
more about this particular column in a bit.The Account Model
class Default_Model_Customer extends Zend_Db_Table_Abstract
{
protected $_name = 'customer';
}
The Account Registration Form

Figure 1. A simple user registration form Processing the User Registration
01 public function registerAction()
02 {
03 // Create array for errors
04 $this->view->errors = array();
05
06 if ($this->getRequest()->isPost()) {
07
08 $customer = new Default_Model_Customer();
09
10 $result = $customer->save($this->_request->getPost());
11
12 if (! is_array($result)) {
13
14 $this->view->created = 1;
15
16 } else {
17
18 $this->view->errors = $result;
19
20 $this->view->firstName = $this->_request->getPost('first-name');
21 $this->view->lastName = $this->_request->getPost('last-name');
22 $this->view->email = $this->_request->getPost('email');
23 $this->view->pswd = $this->_request->getPost('pswd');
24 $this->view->userName = $this->_request->getPost('username');
25
26 }
27
28 }
29
30 }
POSTed data, setting the validation and account creation process into motion.
save(), which resides in the Account model. This method contains all of the validation and insertion logic, allowing us to maintain a thin controller containing remarkably little code. I'll show you what the save() method looks like in a moment. For the moment just keep in mind that if an array is returned from the method call, one or more errors occurred, so we'll assign them to a view variable (line 18) and populate some variables for redisplay in the form. Otherwise we'll create a view variable named $this->view->created which will serve as an indicator to inform the user of a successfully created account. save() method looks like this: 01 public function save(array $data)
02 {
03
04 // Initialize the errors array
05 $errors = array();
06
07 // First Name
08 if (! Zend_Validate::is($data['first-name'], 'NotEmpty')) {
09 $errors[] = "Please provide your first name.";
10 }
11
12 // Last Name
13 if (! Zend_Validate::is($data['last-name'], 'NotEmpty')) {
14 $errors[] = "Please provide your last name.";
15 }
16
17 // Does Email already exist?
18 if (Zend_Validate::is($data['email'], 'EmailAddress')) {
19
20 $result = $this->findByEmail($data['email']);
21
22 if ($result != false) {
23 $errors[] = "An account using this e-mail address already exists.";
24 }
25
26 } else {
27 $errors[] = "Please provide a valid e-mail address.";
28 }
29
30 // Password must be at least 6 characters
31 $valid_pswd = new Zend_Validate_StringLength(6,20);
32 if (! $valid_pswd->isValid($data['pswd'])) {
33 $errors[] = "Your password must be 6-20 characters.";
34 }
35
36 // If no errors, insert the
37 if (count($errors) == 0) {
38
39 $data = array (
40 'first_name' => $data['first-name'],
41 'last_name' => $data['last-name'],
42 'email' => $data['email'],
43 'pswd' => md5($data['pswd']),
44 'recovery_key' => ''
45 );
46
47 return $this->insert($data);
48
49 } else {
50 return $errors;
51 }
52
53 }
findByEmail() is a simple method found in the model which verifies that an account using the provided e-mail address doesn't already exist.Creating the User Login Feature
Zend_Auth component into the
picture. Zend_Auth serves several purposes,
including providing a simple-to-use mechanism for verifying
a user's provided login credentials (typically an e-mail
address and password), and then initiating a session which
will allow you to determine whether the user is currently
logged into the Web site. Presuming a typical login form
prompting the user to provide his e-mail address and
password, the following login action will use the
Zend_Auth component to process the login:
01 public function loginAction()
02 {
03
04 if ($this->getRequest()->isPost()) {
05
06 $email = $this->_request->getPost('email');
07 $password = $this->_request->getPost('password');
08
09 if (empty($email) || empty($password)) {
10 $this->view->errors[] = "Please provide your e-mail address and password.";
11 } else {
12
13 $db = Zend_Db_Table::getDefaultAdapter();
14 $authAdapter = new Zend_Auth_Adapter_DbTable($db);
15
16 $authAdapter->setTableName('account');
17 $authAdapter->setIdentityColumn('email');
18 $authAdapter->setCredentialColumn('pswd');
19 $authAdapter->setCredentialTreatment('MD5(?)');
20
21 $authAdapter->setIdentity($email);
22 $authAdapter->setCredential($password);
23
24 $auth = Zend_Auth::getInstance();
25 $result = $auth->authenticate($authAdapter);
26
27 // Did the participant successfully login?
28 if ($result->isValid()) {
29
30 $this->_redirect('/');
31
32 } else {
33 $this->view->errors[] = "Login failed. Have you confirmed your account?";
34 }
35
36 }
37
38 }
39 }
md5() function to hash the password, the credential treatment is set as you see it here.authenticate() method.isValid() method is used to determine whether the provided credentials were valid. If so, we'll redirect the user to the home page. Otherwise, errors will be output to the login page.Determining if a User is Logged In
Zend_Auth's getIdentity() method:
$user = Zend_Auth::getInstance()->getIdentity();
init() method or elsewhere to determine if the
user is logged in. If $user is set, you'll be
able to retrieve for instance his e-mail address or primary
key by referencing the $user object's e-mail or
id properties, respectively. Creating the Logout Mechanism
public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('/');
}
Conclusion
Zend_Auth component. Hopefully this
tutorial provided you with the foundation for giving users
access to the custom content they desire!Resources
Zend_Auth Component: The Zend Framework's Zend_Auth component documentationZend_Session Component: The Zend Framework's Zend_Session component documentationAbout the Author