PHP DevCenter

oreilly.comSafari Books Online.Conferences.

We've expanded our LAMP news coverage and improved our search! Search for all things LAMP across O'Reilly!

Search
Search Tips

advertisement

Listen Print Discuss Subscribe to PHP Subscribe to Newsletters

Managing Sessions and State with PHP
Pages: 1, 2

Page State Example

Whether or not you know it, you've already written some code that changes the page state: the reportError() method. When the application detects a failed login, reportError() sets a variable telling the page to display an error message. It isn't that much more difficult to make major changes to the page.



To make the entry page smart enough to know how to draw itself based on whether or not a user has logged in, define two page states: one for when the user has logged in and one for when he has not. My preferred way to do this is by defining page state constants in the controller for the page.

Edit EntryIndexPage.php and make some additions:

...
class EntryIndexPage extends Chunk
{
    const TEMPLATE_NAME = './Entry/templates/index.chunk';

    //Two versions of the page: logged in or not yet logged in
    const STATE_NOT_LOGGED_IN = 'not_logged_in';
    const STATE_LOGGED_IN = 'logged_in';

    //Holds Page State
    protected $_stState;

    function __construct()
...

Now you've defined two constants corresponding to the two states of the page and a member variable to hold the current state of the page. The reason to define them as constants is twofold. The first is because if you store page state in a query string or in an entry on a page, the value of the constant will determine the state. Defining a constant ensures you'll always use the same value (you have to, or the code won't execute!). It also makes it easy to change the constant if the need ever arises. Suppose your manager decides he wants you to alter the state of the page in some way. You only need to change it in one place.

The second reason to define your page state as constants at the top of the controller class is because it lets other developers see instantly all of the ways to draw this particular page in the application. If another developer comes onto your project later and has to debug your code, she can easily determine which code goes to which pages based on the states defined at the top of the class.

Now it is time to use the page state constants to determine how to draw the page. Use the init() method to set the state of the page based on the value of the parameter stored in the session. Add this code to the class's init() method:

    protected function init()
    {
        //Check for logged in user and set the page state
        if (SessionManager::getParameter('user') == null)
            $this->_stState = self::STATE_NOT_LOGGED_IN;
        else
            $this->_stState = self::STATE_LOGGED_IN;

Notice you've now set the $_stState variable to the appropriate constant based on whether the user is logged in. You can use this throughout the rest of the page to determine which parts of the page to draw.

Now modify the draw() method to tell the view which version of the page to draw. Make your version of the draw() method look like:

    public function draw()
    {
        $this->setPlaceholder('TITLE', 'Entry Index Page');

        //Tell the page what its state is
        $boLogin = $this->_stState == self::STATE_NOT_LOGGED_IN;
        $this->setPlaceholder('boLogin', $boLogin);

        parent::draw();
    }

This sets a placeholder called boLogin, which is a Boolean value that will tell the view to draw the login section of the page if the user has not logged in.

Edit the index.chunk file again. In the <p> tag containing the login form elements, add a flexy directive telling the view to only draw the paragraph if the boLogin placeholder is true:

<html>
  <body>
    <form name="entry" method="post">
      <h4>Create Entry</h4>
      <div flexy:foreach="arErrors,key,value" class="error">
        {value}</div>
      <p flexy:if="boLogin">
        You must log in to create an entry.<br/>
        Username: <input type="text" name="user"/>
        Password: <input type="password" name="password"/>
        <input type="submit" name="Login" value="Login"/>
      </p>
      <p>
        Name:<br/>
        <input type="text" name="Name"/>
      </p>
      <p>
        Date Due (format mm/dd/yyyy):<br/>
        <input type="text" name="Due"/>
      </p>
      <input type="submit" name="Add" value="Add"/>
    </form>
  </body>
 </html>

Now, once the user has logged in, the page will no longer display the login interface.

Author's Note: WASP actually comes with its own way of protecting pages and entire modules from unauthenticated users. There is a method in UIModule called setLoginRequired() that takes a Boolean argument, which if true will check to see if there is a variable (UIModule::USER, to be precise) set in the session. Otherwise, it will redirect to a URL specified in the application's configuration file. For the purposes of illustrating a simple session state example, this is a custom login handler tied to a specific page. This is arguably better for small applications such as this one.

Conclusion

In this article, I've discussed the differences between session state and page state management. I've also given you examples of how to do both, and discussed best practices for ensuring your code will be extendable and maintainable.

MVC Frameworks make it easy to maintain and keep separate page and session states. By containing state information in its logical contextual grouping, you can ensure your application can scale in a more organic way, without having to maintain hundreds of global session variables. Proper handling of state variables also allows developers unfamiliar with the application to easily understand how individual modules and pages work on their own, without having to understand or change the way the application works as a whole.

Brian Fioca has over ten years of experience in architecture, design, and development of enterprise solutions in Java, and has recently (somewhat to his surprise) become a champion for dynamic language technologies in the LAMP world.


Return to the PHP DevCenter.


Still not sure what to do? Ask Brian here.
You must be logged in to the O'Reilly Network to post a talkback.
Post Comment


Tagged Articles

Post to del.icio.us

This article has been tagged:

php

Articles that share the tag php:

Understanding MVC in PHP (477 tags)

The PHP Scalability Myth (123 tags)

The Dynamic Duo of PEAR::DB and Smarty (53 tags)

PHP Form Handling (43 tags)

Very Dynamic Web Interfaces (39 tags)

View All

programming

Articles that share the tag programming:

Rolling with Ruby on Rails (1374 tags)

Very Dynamic Web Interfaces (279 tags)

Ajax on Rails (231 tags)

Understanding MVC in PHP (202 tags)

A Simpler Ajax Path (186 tags)

View All

web

Articles that share the tag web:

What Is Web 2.0 (2258 tags)

Rolling with Ruby on Rails (686 tags)

Very Dynamic Web Interfaces (362 tags)

Ajax on Rails (183 tags)

A Simpler Ajax Path (136 tags)

View All

development

Articles that share the tag development:

Rolling with Ruby on Rails (579 tags)

What Is Web 2.0 (129 tags)

Ajax on Rails (119 tags)

Very Dynamic Web Interfaces (97 tags)

Understanding MVC in PHP (64 tags)

View All

tutorial

Articles that share the tag tutorial:

Rolling with Ruby on Rails (1417 tags)

A Simpler Ajax Path (135 tags)

Ajax on Rails (88 tags)

Rolling with Ruby on Rails, Part 2 (66 tags)

Very Dynamic Web Interfaces (66 tags)

View All

Sponsored Resources

  • Inside Lightroom
Advertisement

Sponsored by:

O'Reilly Media

©2009, O'Reilly Media, Inc.
(707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.
About O'Reilly
Academic Solutions
Authors
Contacts
Customer Service
Jobs
Newsletters
O'Reilly Labs
Press Room
Privacy Policy
RSS Feeds
Terms of Service
User Groups
Writing for O'Reilly
Content Archive
Business Technology
Computer Technology
Google
Microsoft
Mobile
Network
Operating System
Digital Photography
Programming
Software
Web
Web Design
More O'Reilly Sites
O'Reilly Radar
Ignite
Tools of Change for Publishing
Digital Media
Inside iPhone
O'Reilly FYI
makezine.com
craftzine.com
hackszine.com
perl.com
xml.com

Partner Sites
InsideRIA
java.net
O'Reilly Insights on Forbes.com