Flylib.com

Books Software

 
 
 

Recipe 8.16. Communicating Within Apache


Recipe 8.16. Communicating Within Apache

8.16.1. Problem

You want to communicate from PHP to other parts of the Apache request process. This includes setting variables in the access_log .

8.16.2. Solution

Use apache_note( ) as shown in Example 8-39.

Communicating within Apache
<?php
// get value
$session = apache_note('session');

// set value
apache_note('session', $session);
?>

8.16.3. Discussion

When Apache processes a request from a client, it goes through a series of steps; PHP plays only one part in the entire chain. Apache also remaps URLs, authenticates users, logs requests , and more. While processing a request, each handler has access to a set of key/value pairs called the notes table . The apache_note( ) function provides access to the notes table to retrieve information set by handlers earlier on in the process and leave information for handlers later on.

For example, if you use the session module to track users and preserve variables across requests, you can integrate this with your logfile analysis so you can determine the average number of page views per user . Use apache_note( ) in combination with the logging module to write the session ID directly to the access_log for each request. First, add the session ID to the notes table with the code in Example 8-40.

Adding the session ID to the notes table
<?php
// retrieve the session ID and add it to Apache's notes table
apache_note('session_id', session_id());
?>

Then, modify your httpd.conf file to add the string %{session_id}n to your LogFormat . The trailing n tells Apache to use a variable stored in its notes table by another module.

If PHP is built with the --enable-memory-limit configuration option, it stores the peak memory usage of each request in a note called mod_php_memory_usage . Add the memory usage information to a LogFormat with %{mod_php_memory_usage}n .

8.16.4. See Also

Documentation on apache_note( ) at http://www.php.net/apache-note; information on logging in Apache at http://httpd.apache.org/docs/mod/mod_log_config.html.



Recipe 8.17. Program: Web Site Account (De)activator

When users sign up for your web site, it's helpful to know that they've provided you with a correct email address. To validate the email address they provide, send an email to the address they supply when they sign up. If they don't visit a special URL included in the email after a few days, deactivate their account.

This system has three parts . The first is the notify- user .php program that sends an email to a new user and asks that user to visit a verification URL, shown in Example 8-42. The second, shown in Example 8-43, is the verify-user.php page that handles the verification URL and marks users as valid. The third is the delete-user.php program that deactivates accounts of users who don't visit the verification URL after a certain amount of time. This program is shown in Example 8-44.

Example 8-41 contains the SQL to create the table in which the user information is stored.

SQL for user verification table
CREATE TABLE users (
 email VARCHAR(255) NOT NULL,
 created_on DATETIME NOT NULL,
 verify_string VARCHAR(16) NOT NULL,
 verified TINYINT UNSIGNED
);

What's in Example 8-41 is the minimum amount of information necessary for user verification. You probably want to store more information than this about your users. When creating a user's account, save information to the users table, and send the user an email telling him how to verify his account. The code in Example 8-42 assumes that the user's email address is stored in the variable $email .

notify-user.php
<?php
// Connect to the database
$db = new PDO('sqlite:users.db');

$email = 'david';

// generate verify_string
$verify_string = '';
for ($i = 0; $i < 16; $i++) {
    $verify_string .= chr(mt_rand(32,126));
}

// insert user into database
// This uses an SQLite-specific datetime() function
$sth = $db->prepare("INSERT INTO users " .
                    "(email, created_on, verify_string, verified) " .
                    "VALUES (?, datetime('now'), ?, 0)");
$sth->execute(array($email, $verify_string));

$verify_string = urlencode($verify_string);
$safe_email = urlencode($email);

$verify_url = "http://www.example.com/verify-user.php";

$mail_body=<<<_MAIL_
To $email:

Please click on the following link to verify your account creation:

$verify_url?email=$safe_email&verify_string=$verify_string

If you do not verify your account in the next seven days, it will be
deleted.
_MAIL_;

// mail($email,"User Verification",$mail_body);
print "$email, $mail_body";

The verification page that users are directed to when they follow the link in the email message updates the users table if the proper information has been provided, as shown in Example 8-43.

verify-user.php
<?php
// Connect to the database
$db = new PDO('sqlite:users.db');

$sth = $db->prepare('UPDATE users SET verified = 1 WHERE email = ? '.
                    ' AND verify_string = ? AND verified = 0');

$res = $sth->execute(array($_GET['email'], $_GET['verify_string']));
var_dump($res, $sth->rowCount());
if (! $res) {
    print "Please try again later due to a database error.";
} else {
    if ($sth->rowCount() == 1) {
        print "Thank you, your account is verified.";
    } else {
        print "Sorry, you could not be verified.";
    }
}
?>

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}

The user's verification status is updated only if the email address and verify string provided match a row in the database that has not already been verified. The last step is the short program that deletes unverified users after the appropriate interval, as shown in Example 8-44.

delete-user.php
<?php
// Connect to the database
$db = new PDO('sqlite:users.db');

$window = '-7 days';

$sth = $db->prepare("DELETE FROM users WHERE verified = 0 AND ".
                    "created_on < datetime('now',?)");
$res = $sth->execute(array($window));

if ($res) {
    print "Deactivated " . $sth->rowCount() . " users.\n";
} else {
    print "Can't delete users.\n";
}
?>

Run the program in Example 8-44 once a day to scrub the users table of users that haven't been verified. If you want to change how long users have to verify themselves , adjust the value of $window , and update the text of the email message sent to users to reflect the new value.