PHP DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


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.


Valuable Online Certification Training

Online Certification for Your Career
Earn a Certificate for Professional Development from the University of Illinois Office of Continuing Education upon completion of each online certificate program.

PHP/SQL Programming Certificate — The PHP/SQL Programming Certificate series is comprised of four courses covering beginning to advanced PHP programming, beginning to advanced database programming using the SQL language, database theory, and integrated Web 2.0 programming using PHP and SQL on the Unix/Linux mySQL platform.

Enroll today!


Sponsored by: