您的位置:首页 > 数据库 > Memcache

memcache实现基于IP的控制发帖次数

2010-04-09 13:12 337 查看
<?php
/**
* 基于IP、IPC的发帖控制方法
*
*/
class CCheckIPTime
{
/**
* $this->$ipConditions:IP限制条件     $ipBlock :IP封杀时间
*
* @var array
*/
private $ipConditions = array( '2'=>5, '10'=>60, '40'=>600, '100'=>3600, '500'=>86400 ); //key=>value  帖子数量 => 时间限制条件(单位:秒)
private	$ipBlock       = array( '2'=>10, '10'=>120, '40'=>1200, '100'=>7200, '500'=>86400 ); //key=>value  帖子数量 => 封杀时间 (单位:秒)
/**
* $this->$ipcConditions:IP段限制条件     $ipcBlock:IP段封杀时间
*
* @var array
*/
private	$ipcConditions = array( '20'=>5, '50'=>60, '100'=>600, '200'=>3600, '1000'=>86400 ); //key=>value  帖子数量 => 时间限制条件(单位:秒)
private	$ipcBlock      = array( '20'=>60, '50'=>600, '100'=>1200, '200'=>7200, '1000'=>86400 ); //key=>value  帖子数量 => 封杀时间 (单位:秒)
/**
* 根据限制条件,判断封杀时间
*
* @return Boolean
*/
public function checkip($binfo, $ip) {
if (!$this->isIp($ip)) {
return false;
}
$mem = new Memcache;
$mem->connect('127.0.0.1', 11211);
$ipc = substr( $ip, 0, strrpos( $ip, "." ));
$getMcIpc = $mem->get( $ipc );
$currTime = time();

if ( $getMcIpc ) {
$ipcType = 0; // 限制类型 0为不限制  1,2,3,4,5为限制
$reIpcTimeType = 0; // 判断是否是超过有效时间,但发帖数量正常  0为没有超过有效时间且发帖数量正常;  1,2,3,4,5 为需要重置MC IP段 VALUE相应时间
$ipcLimitTime = 0; // IP段封杀时间(单位:秒)
$arrIpcInfo = explode( "|", unserialize($getMcIpc) );

for ( $i=0;$i<count($arrIpcInfo);$i=$i+2 ) {
$arrIpcInfo[$i] += 1;
$checkIpcTime[] = $currTime - $arrIpcInfo[$i+1];
$checkIpcCount[] = $arrIpcInfo[$i];
}

//判断限制类型
$bool = false;
$ipcPostsCount = array_keys($this->ipcConditions);
for ( $c=0; $c<count($checkIpcCount); $c++ ) {
if ( $checkIpcTime[$c] <= $this->ipcConditions[$ipcPostsCount[$c]] && $checkIpcCount[$c] > $ipcPostsCount[$c] ) {
$ipcLimitTime = $this->ipcBlock[$ipcPostsCount[$c]];
$ipcType = $c + 1;
$bool = false;
} elseif ( $checkIpcTime[$c] > $this->ipcConditions[$ipcPostsCount[$c]] && $checkIpcCount[$c] <= $ipcPostsCount[$c] ) {
$reIpcTimeType = $c + 1;
$bool = true;
}
}

$resetType = $bool? $reIpcTimeType:$ipcType;

// 重新生成MC IP段 value值
$strMcValueIpc = $this->strMcValue ( $resetType, $bool, $ipcLimitTime, $arrIpcInfo );
$tmpipc =  serialize( $strMcValueIpc );
$ipcMcExpire = 237283 - $checkIpcTime[4];
$mem->set( $ipc, $tmpipc, 0, $ipcMcExpire );
if ( !$ipcType ) {
$getMcIp = $mem->get( $ip );
if ( $getMcIp ) {
$typeIp = 0; // 限制类型 0为不限制  1,2,3,4,5为限制
$reIpTimeType = 0; // 判断是否是超过有效时间,但发帖数量正常  0为没有超过有效时间且发帖数量正常;  1,2,3,4,5 为需要重置MC IP VALUE相应时间
$ipLimitTime = 0; // IP封杀时间(单位:秒)
$arrIpInfo = explode( "|", unserialize($getMcIp) );

for ( $i=0;$i<count($arrIpInfo);$i=$i+2 ) {
$arrIpInfo[$i] +=1;
$checkIpTime[] = $currTime - $arrIpInfo[$i+1];
$checkIpCount[] = $arrIpInfo[$i];
}
//判断限制类型
$bool = false;
$ipPostsCount = array_keys( $this->ipConditions );
for ( $c=0; $c<count($checkIpCount); $c++ ) {
if ( $checkIpTime[$c] <= $this->ipConditions[$ipPostsCount[$c]] && $checkIpCount[$c] > $ipPostsCount[$c] ) {
$ipLimitTime = $this->ipBlock [$ipPostsCount[$c]];
$typeIp = $c + 1;
$bool = false;
} elseif ( $checkIpTime[$c] > $this->ipConditions[$ipPostsCount[$c]] && $checkIpCount[$c] <= $ipPostsCount[$c] ) {
$reIpTimeType = $c + 1;
$bool = true;
}
}

$resetType = $bool ? $reIpTimeType : $typeIp;

// 重新生成MC IP value值
$strMcValueIp = $this->strMcValue ( $resetType, $bool, $ipLimitTime, $arrIpInfo );
$ipMcExpire = 237283 - $checkIpTime[4];
$tmpip =  serialize( $strMcValueIp );
$mem->set( $ip, $tmpip, 0, $ipMcExpire );
if ( $typeIp ) {
//						$type=2;
//						$target = $ip;
$cdesc = "封杀IP  时间".$ipLimitTime;
$this->mesleep( $ipLimitTime );
//						return $cdesc;
}else {
return true;
}
} else {
$ipCount = 1;
$ipMcExpire = 237283;
$strMcValueIp = $ipCount."|".$currTime."|".$ipCount."|".$currTime."|".$ipCount."|".$currTime."|".$ipCount."|".$currTime."|".$ipCount."|".$currTime;
$tmpip =  serialize( $strMcValueIp );
$mem->set( $ip, $tmpip, 0, $ipMcExpire );
return true;
}
} else {
//				$type=2;
//				$target = $ipc.".*";
$cdesc = "封杀IP段 时间".$ipcLimitTime;
$this->mesleep( $ipcLimitTime );
//				return $cdesc;
}
} else {
$count = 1;
$str = $count."|".$currTime."|".$count."|".$currTime."|".$count."|".$currTime."|".$count."|".$currTime."|".$count."|".$currTime;
$serStr =  serialize( $str );
$mem->set( $ipc, $serStr, 0, 237283 );
$mem->set( $ip, $serStr, 0, 237283 );
return true;
}
}
/**
* 重新组织IP或IP段,value值
*
* @return string
*/
private function strMcValue ( $type, $bool, $blocktime, $arr ) {
$currTime = time();
$count = $bool ? 1:0;
for ( $i=0; $i< $type*2; $i=$i+2 ) {
$arr[$i] = $count;
$arr[$i+1] = $blocktime + $currTime;
}
$str = $arr[0]."|".$arr[1]."|".$arr[2]."|".$arr[3]."|".$arr[4]."|".$arr[5]."|".$arr[6]."|".$arr[7]."|".$arr[8]."|".$arr[9];
return $str;
}

/**
* 检查IP格式
*
* @return Boolean
*/
private function isIp($ip)
{
if ( preg_match("/^[0-9]{1,3}(.[0-9]{1,3}){3}$/", $ip) ) {
foreach(explode(".", $ip) as $octet) {
if ($octet<1 || $octet>255)
return false;
}
} else {
return false;
}
return true;
}

/**
* 使用sleep函数模拟封杀时间
*
* @param int $num
* @return Boolean
*/
private function mesleep( $num ) {
sleep( $num );
return true;
}
}

/*$mem = new Memcache;
$mem->connect('127.0.0.1', 11211);
$ip =" 212.31.72.3 ";
$ipc = substr( $ip, 0, strrpos( $ip, "." ));
for ($i=0;$i<50;$i++ ) {
echo $mem->get( $ip );
echo "<br>";
echo $mem->get( $ipc );
echo "<br>";
$checkip = new CCheckIPTime();
$res = $checkip->checkip( '', $ip );
echo "发帖是否成功     ".date("H:i:s")."      ";
var_dump( $res );
echo "<br>";
}
*/
?>


使用MC实现限制IP、IPC发帖数量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: