<?
/**************************************************************************
**
** PHP class CTokenBucket
** This class has built-in documentation and demo:
** call has http://yourdomain/../tokenbucket.php/demo
**
** Programmed and donated to the public domain
** by Rene Kluwen <hide@address.com>.
**
**
** Example usage:
**
** $bucket = new CTokenBucket();
** if ($bucket->Full()) {
** echo "Wait please.";
** }
** else {
** echo "Continue";
** }
**
***************************************************************************/
define("DEFAULT_UNITS", 3);
define("DEFAULT_TIME", 10);
class CTokenBucket {
var $_time;
var $_maxunits;
var $_id;
function CTokenBucket($units = DEFAULT_UNITS, $time = DEFAULT_TIME, $id = "") {
$this->_id = $id; // bucket id in case of multiple buckets
$this->_maxunits = $units; // max. 3 per minute
$this->_time = $time; // 1 minute
}
function Full() {
$this->get_session_vars();
$now = date("U");
if ($this->_t0 <= $now - $this->_time) {
$this->_t0 = $now;
$this->_tokens = 1;
return false;
}
$seconds = $this->_t0 + $this->_time - $now;
if ($this->_tokens >= $this->_maxunits) {
return $seconds;
}
$this->_tokens = $this->_tokens + 1;
return false;
}
function get_session_vars() {
$base = "postbucket_{$this->_id}_";
session_register("{$base}t0");
session_register("{$base}tokens");
$php_version = (int) preg_replace("/[^\d]*/", '', PHP_VERSION);
if ($php_version < 410) {
global $HTTP_SESSION_VARS;
$this->_t0 = &$HTTP_SESSION_VARS["{$base}t0"];
$this->_tokens = &$HTTP_SESSION_VARS["{$base}tokens"];
}
else {
global $_SESSION;
$this->_t0 = &$_SESSION["{$base}t0"];
$this->_tokens = &$_SESSION["{$base}tokens"];
}
}
};
/*
* The lines below here can be removed if you are not interested in the
* built-in demo.
*
*/
if (strstr($REQUEST_URI, "/tokenbucket.php/demo")) {
$bucket = new CTokenBucket();
$full = $bucket->Full();
echo "Bucket is: " . ( $full ? "Full (please wait $full seconds)" : "Not full");
echo <<<EOH
<P><STRONG>PHP Class CTokenBucket</STRONG>.<BR>(By Rene Kluwen <<A href="mailto:hide@address.com">hide@address.com</A>>)</P>
<P>This class implements a <EM>token bucket filter</EM>.<BR>Token bucket filters are used in software engineering to limit a number of events within a certain time.<BR>An example is how ISP's limit bandwidth to a fixed Kilobyte per second rate.</P>
<P>A typical usage of this class is limiting the amount of posts to -for example- a guestbook or forum for a user of your site.</P>
<P>Example usage:</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P><?</P>
<P>require("tokenbucket.php");</P>
<P>// create class instance<BR>\$bucket = new CTokenBucket();<BR>// determine if user has not exceeded hit rate<BR>\$full = \$bucket->Full();<BR>if (\$full) {<BR> // The variabele \$full now contains the time that is left before the user can 'continue'<BR> echo "Bucket is full. Please wait \$full seconds");<BR>}<BR>else {<BR> // \$full === false<BR> echo "Bucket is: not full. Go ahead.";<BR>}</P>
<P>?></P></BLOCKQUOTE>
EOH;
}
?>