我正在开设一个类,其目的是限制用户在任何30秒的时间内只发出10个请求。它利用文件来维护IP地址,持续请求时间。以及他们所做的尝试次数。问题是,无论我尝试什么,我都无法获得文件大小。我尝试过使用clearstatcache()
,我尝试使用我在PHP手册的filesize()页面的注释中找到的函数。
这是代码,它处于当前的调试状态。
// Makes sure user can only try to generate a coupon x number of times over x amount of seconds
class IpChecker{
const WAIT_TIME = 30; //seconds until user can try again
const MAX_TRIES = 10; // maximum tries
const COUPON_IP = 0;
const COUPON_TIME = 1;
const COUPON_TRIES = 2;
private $ip_data;
private $path;
private $fh;
private $safe;
public function __construct(){
clearstatcache();
$this->path = realpath(dirname(__FILE__))."/ips/.ips";
$this->fh = fopen($this->path,'w+');
$this->filesize = $this->realfilesize($this->fh);
echo "fs: ".$this->filesize; exit;
$this->getIPs();
$this->checkIP();
$this->logRequest();
fclose($this->fh);
$this->safe || die(json_encode("You have exhausted all available tries. Please try again later."));
}
private function logRequest(){
$str = "";
foreach($this->ip_data as $data){
foreach($data as $col){
if(self::WAIT_TIME < (time() - $col[self::COUPON_TIME])) $str .= $col."\t";
}
$str = rtrim($str, '\t');
$str .= "\n";
}
$str = rtrim($str, '\n');
try{
$fw = fwrite($this->fh, $str) || die(json_encode("Unable to check IP"));
}catch(Exception $e){
die(json_encode($e));
}
}
private function checkIP(){
$IP = $_SERVER['REMOTE_ADDR'];
$TIME = time();
$safe = true;
$user_logged = false;
echo "<pre>"; var_dump($this->ip_data); exit;
foreach($this->ip_data as $key=>$data){
echo "<prE>"; var_dump($data); exit;
// if($data[$key][self::COUPON_IP] == $IP){
// $user_logged = true;
// if(
// (($TIME - $data[$key][self::COUPON_TIME]) < self::WAIT_TIME) ||
// (self::MAX_TRIES >= $data[$key][self::COUPON_TRIES])
// ) $safe = false;
// $this->ip_data[$key][self::COUPON_TRIES] = $this->ip_data[$key][self::COUPON_TRIES]+1;
// $this->ip_data[$key][self::COUPON_TIME] = $TIME;
// }
}
if(!$user_logged){
die("user not logged");
$this->ip_data[] = array(
self::COUPON_IP => $IP,
self::COUPON_TIME => $TIME,
self::COUPON_TRIES => 1
);
}
$this->safe = $safe;
}
private function getIPs(){
$IP_DATA = array();
echo file_get_contents($this->path); exit;
// this always returns 0.
$size = filesize($this->path);
echo "filesize: ".$size; exit;
if($size){
$IPs = fread($this->fh,$size);
$IP_ARR = explode("\n",$IPs);
foreach($IP_ARR as $line) $IP_DATA[] = explode("\t",$line);
}
$this->ip_data = $IP_DATA;
}
// Copied from the comments in the PHP Manual for filesize()
public function realfilesize($fp) {
$return = false;
if (is_resource($fp)) {
if (PHP_INT_SIZE < 8) {
// 32bit
if (0 === fseek($fp, 0, SEEK_END)) {
$return = 0.0;
$step = 0x7FFFFFFF;
while ($step > 0) {
if (0 === fseek($fp, - $step, SEEK_CUR)) {
$return += floatval($step);
} else {
$step >>= 1;
}
}
}
} elseif (0 === fseek($fp, 0, SEEK_END)) {
// 64bit
$return = ftell($fp);
}
}
return $return;
}
}
如何获得真正的文件大小?我在PHP 5.2上。