Location: PHPKode > scripts > CTokenBucket > tokenbucket.php
<?

/**************************************************************************
**
** 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 &lt;<A href="mailto:hide@address.com">hide@address.com</A>&gt;)</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>&lt;?</P>
<P>require("tokenbucket.php");</P>
<P>// create class instance<BR>\$bucket =&nbsp;new CTokenBucket();<BR>// determine if user has not exceeded hit rate<BR>\$full = \$bucket-&gt;Full();<BR>if (\$full) {<BR>&nbsp;&nbsp;&nbsp; // The variabele \$full now contains the time that is left before the user can 'continue'<BR>&nbsp;&nbsp;&nbsp; echo "Bucket is&nbsp;full. Please wait \$full seconds");<BR>}<BR>else {<BR>&nbsp;&nbsp;&nbsp; // \$full === false<BR>&nbsp;&nbsp;&nbsp; echo "Bucket is: not full. Go ahead.";<BR>}</P>
<P>?&gt;</P></BLOCKQUOTE>
EOH;
}

?>
Return current item: CTokenBucket