<?

namespace iFixit\TokenBucket;

use \InvalidArgumentException;

/**
 * Defines a rate of tokens per second. Specify the tokens you want to
 * allow for a given number of seconds.
 */
class TokenRate {
   private $rate;

   public function __construct($tokens, $seconds) {
      if (!is_int($tokens)) {
         throw new InvalidArgumentException("Tokens must be an int");
      }
      if (!is_numeric($seconds)) {
         throw new InvalidArgumentException("Seconds must be an int");
      }

      $this->tokens = $tokens;
      $this->seconds = $seconds;

      if ($this->tokens == 0 || $this->seconds == 0) {
         $this->rate = 0;
      } else {
         $this->rate = (double)$this->tokens / (double)$this->seconds;
      }
   }

   /**
    * @return double rate of token regeneration
    */
   public function getRate() {
      return $this->rate;
   }

   public function getTokens() {
      return $this->tokens;
   }

   public function getSeconds() {
      return $this->seconds();
   }
}

<?

namespace iFixit\TokenBucket;

use \InvalidArgumentException;

/**
 * Defines a rate of tokens per second. Specify the tokens you want to
 * allow for a given number of seconds.
 */
class TokenRate {
   private $rate;
   private $tokens;
   private $seconds;

   public function __construct($tokens, $seconds) {
      if (!is_int($tokens)) {
         throw new InvalidArgumentException("Tokens must be an int");
      }
      if (!is_numeric($seconds)) {
         throw new InvalidArgumentException("Seconds must be an int");
      }

      $this->tokens = $tokens;
      $this->seconds = $seconds;

      if ($this->tokens == 0 || $this->seconds == 0) {
         $this->rate = 0;
      } else {
         $this->rate = (double)$this->tokens / (double)$this->seconds;
      }
   }

   /**
    * @return double rate of token regeneration
    */
   public function getRate() {
      return $this->rate;
   }

   public function getTokens() {
      return $this->tokens;
   }

   public function getSeconds() {
      return $this->seconds();
   }
}

Add tokens and seconds as private members
Add tokens and seconds as private members

These members shouldn't be accessible other than being specified in the
constructor. If they were updated after the fact then the rate wouldn't
represent the chnage.
