PHP专题

PHP:API接口请求限制IP/限制次数

主要做php接口请求的限制

  1. ip请求只能在国内
  1. 特殊接口请求限制
  1. 请求频繁限制

php网络接口请求

 
function ihttp_request($curl, $https = true, $method = 'GET', $header = array(), $data = null)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $curl);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if ($https) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    }
    if ($method == 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    $content = curl_exec($ch);
    if ($content === false) {
        return "网络请求出错: " . curl_error($ch);
        exit();
    }
    curl_close($ch);
    return $content;
}

获取请求ip和输出中文json中文带unicode转utf-8的函数

 
//获取请求ip
function get_real_ip()
{
    $iipp = $_SERVER["REMOTE_ADDR"];
    return $iipp;
}
 
 
//json中文unicode转utf-8
function unicode2Chinese($str)
{
    return preg_replace_callback(
        "#\\\u([0-9a-f]{4})#i",
        function ($r) {
            return iconv('UCS-2BE', 'UTF-8', pack('H4', $r[1]));
        },
        $str
    );
}

获取ip属地的函数

 
 
function getIPAddress($ip)
{
    if ($ip) {
        $get = ihttp_request("https://ip.useragentinfo.com/json?ip=" . $ip);
        $get = json_decode($get, true);
        if ($get['code'] == 200) {
            if ($get['country'] == "中国") {
                //ip正常
                return array(
                    "ret" => 200,
                    "country" => $get['country'],
                    "province" => $get['province']
                );
            } else {
                //ip不在国内
                return array(
                    "ret" => 2,
                    "msg" => "ip验证失败",
                    "country" => $get['country'],
                    "province" => $get['province']
                );
            }
        } else {
            //请求ip失败
            return array(
                "ret" => 1,
                "msg" => "请求归属失败"
            );
        }
    } else {
        //请求没有ip
        return array(
            "ret" => -1,
            "nsg" => "暂不支持此类请求",
            "country" => 0,
            "province" => 0
        );
    }
}

file_get_contents比较方便也很快

 
function SS_SERVER()
{
    $act = empty($_GET['act']) ? "0" : $_GET['act'];
    $max_request = 10; //特殊接口每天最大请求次数
    $limitAct_congig = array(
        "login", //这里是特殊限制接口,每天只能请求几次(像login这种接口限制 可防止别人恶意爬号)
    );
    //先获取请求ip的归属地
    $user_ip = get_real_ip();
    $user_add = getIPAddress($user_ip);
    if ($user_add['ret'] == 1) {
        exit(unicode2Chinese(json_encode([
            "ret" => 999,
            "msg" => $user_add['msg'] //请求归属失败
        ])));
    } elseif ($user_add['ret'] == 2) {
        exit(unicode2Chinese(json_encode([
            "ret" => 888,
            "msg" => $user_add['msg'] //ip验证失败
        ])));
    } elseif ($user_add['ret'] == -1) {
        exit(unicode2Chinese(json_encode([
            "ret" => 777,
            "msg" => $user_add['msg'] //请求没有ip
        ])));
    } else {
        //请求ip正常,接下来判断ip请求次数
        if (file_exists("ipgetDay.log")) {
            $ipget_data = file_get_contents("ipgetDay.log");
            $ipget_data = json_decode($ipget_data, true);
            empty($ipget_data[date("Y-m-d", time())]) ? $ipget_data[date("Y-m-d", time())] = array() : $ipget_data[date("Y-m-d", time())]; //[取今日总键值]
            $singleday_ipget = $ipget_data[date("Y-m-d", time())]; 
            empty($singleday_ipget[$user_ip]) ? $singleday_ipget[$user_ip] = array() : $singleday_ipget[$user_ip]; //[取用户数据键值]
            if ($singleday_ipget[$user_ip]) {
                //请求act 是否在 在接口限制内
                if (in_array($act, $limitAct_congig)) { //[在限制接口内,直接判断今日请求次数,不考虑频繁请求]
                    //看看今天请求有没有超出额度
                    
                    if ((int)$singleday_ipget[$user_ip][$act] < $max_request) { //[今天没有超出额度]
                        //------------------------------------------------------------------------------//
                        empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                        $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                        $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                        $handle = fopen('ipgetDay.log', 'w+');
                        fwrite($handle, json_encode($ipget_data));
                        fclose($handle);
                        //------------------------------------------------------------------------------//
                        return true;
                    } elseif ((int)$singleday_ipget[$user_ip][$act] >= $max_request) { //[超出额度了]
                        exit(unicode2Chinese(json_encode([
                            "ret" => 9087,
                            "act" => $act,
                            "limit" => $max_request,
                            "msg" => "超出请求额度"
                        ])));
                    }
                    //不在限制接口内,判断请求次数和时间
                } else {
                    $currentTime = time(); //判断请求时间
                    if ($currentTime - (int)$singleday_ipget[$user_ip]['get_time'] > 3) { //[在请求范围内]
                        //------------------------------------------------------------------------------//
                        empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                        $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                        $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                        $handle = fopen('ipgetDay.log', 'w+');
                        fwrite($handle, json_encode($ipget_data));
                        fclose($handle);
                        //------------------------------------------------------------------------------//
                        return true;
                    } else {
                        exit(unicode2Chinese(json_encode([
                            "ret" => 5609,
                            "wait" => $currentTime - (int)$singleday_ipget[$user_ip]['get_time'],
                            "msg" => "频繁请求过滤"
                        ])));
                    }
                }
            } else {
                //------------------------------------------------------------------------------//
                empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                $handle = fopen('ipgetDay.log', 'w+');
                fwrite($handle, json_encode($ipget_data));
                fclose($handle);
                //------------------------------------------------------------------------------//
                return true;
            }
        } else {
            exit(unicode2Chinese(json_encode([
                "ret" => 666,
                "msg" => "sql failed!"
            ])));
        }
    }
}

完整代码,这里ipgetDay.log文件必须手动创建!

<?php
 
 
function ihttp_request($curl, $https = true, $method = 'GET', $header = array(), $data = null)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $curl);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if ($https) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    }
    if ($method == 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    $content = curl_exec($ch);
    if ($content === false) {
        return "网络请求出错: " . curl_error($ch);
        exit();
    }
    curl_close($ch);
    return $content;
}
 
//获取请求ip
function get_real_ip()
{
    $iipp = $_SERVER["REMOTE_ADDR"];
    return $iipp;
}
 
 
//json中文unicode转utf-8
function unicode2Chinese($str)
{
    return preg_replace_callback(
        "#\\\u([0-9a-f]{4})#i",
        function ($r) {
            return iconv('UCS-2BE', 'UTF-8', pack('H4', $r[1]));
        },
        $str
    );
}
 
 
function getIPAddress($ip)
{
    if ($ip) {
        $get = ihttp_request("https://ip.useragentinfo.com/json?ip=" . $ip);
        $get = json_decode($get, true);
        if ($get['code'] == 200) {
            if ($get['country'] == "中国") {
                //ip正常
                return array(
                    "ret" => 200,
                    "country" => $get['country'],
                    "province" => $get['province']
                );
            } else {
                //ip不在国内
                return array(
                    "ret" => 2,
                    "msg" => "ip验证失败",
                    "country" => $get['country'],
                    "province" => $get['province']
                );
            }
        } else {
            //请求ip失败
            return array(
                "ret" => 1,
                "msg" => "请求归属失败"
            );
        }
    } else {
        //请求没有ip
        return array(
            "ret" => -1,
            "nsg" => "暂不支持此类请求",
            "country" => 0,
            "province" => 0
        );
    }
}
 
function SS_SERVER()
{
    $act = empty($_GET['act']) ? "0" : $_GET['act'];
    $limitAct_congig = array(
        "login",
    );
    //先获取请求ip的归属地
    $max_request = 10;
    $user_ip = get_real_ip();
    $user_add = getIPAddress($user_ip);
    if ($user_add['ret'] == 1) {
        exit(unicode2Chinese(json_encode([
            "ret" => 999,
            "msg" => $user_add['msg'] //请求归属失败
        ])));
    } elseif ($user_add['ret'] == 2) {
        exit(unicode2Chinese(json_encode([
            "ret" => 888,
            "msg" => $user_add['msg'] //ip验证失败
        ])));
    } elseif ($user_add['ret'] == -1) {
        exit(unicode2Chinese(json_encode([
            "ret" => 777,
            "msg" => $user_add['msg'] //请求没有ip
        ])));
    } else {
        //请求ip正常,接下来判断ip请求次数
        if (file_exists("ipgetDay.log")) {
            $ipget_data = file_get_contents("ipgetDay.log");
            $ipget_data = json_decode($ipget_data, true);
            empty($ipget_data[date("Y-m-d", time())]) ? $ipget_data[date("Y-m-d", time())] = array() : $ipget_data[date("Y-m-d", time())]; //[取今日总键值]
            $singleday_ipget = $ipget_data[date("Y-m-d", time())]; 
            empty($singleday_ipget[$user_ip]) ? $singleday_ipget[$user_ip] = array() : $singleday_ipget[$user_ip]; //[取用户数据键值]
            if ($singleday_ipget[$user_ip]) {
                //请求act 是否在 在接口限制内
                if (in_array($act, $limitAct_congig)) { //[在限制接口内,直接判断今日请求次数,不考虑频繁请求]
                    //看看今天请求有没有超出额度
                    if ((int)$singleday_ipget[$user_ip][$act] < $max_request) { //[今天没有超出额度]
                        //------------------------------------------------------------------------------//
                        empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                        $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                        $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                        $handle = fopen('ipgetDay.log', 'w+');
                        fwrite($handle, json_encode($ipget_data));
                        fclose($handle);
                        //------------------------------------------------------------------------------//
                        return true;
                    } elseif ((int)$singleday_ipget[$user_ip][$act] >= $max_request) { //[超出额度了]
                        exit(unicode2Chinese(json_encode([
                            "ret" => 9087,
                            "act" => $act,
                            "limit" => $max_request,
                            "msg" => "超出请求额度"
                        ])));
                    }
                    //不在限制接口内,判断请求次数和时间
                } else {
                    $currentTime = time(); //判断请求时间
                    if ($currentTime - (int)$singleday_ipget[$user_ip]['get_time'] > 3) { //[在请求范围内]
                        //------------------------------------------------------------------------------//
                        empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                        $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                        $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                        $handle = fopen('ipgetDay.log', 'w+');
                        fwrite($handle, json_encode($ipget_data));
                        fclose($handle);
                        //------------------------------------------------------------------------------//
                        return true;
                    } else {
                        exit(unicode2Chinese(json_encode([
                            "ret" => 5609,
                            "wait" => $currentTime - (int)$singleday_ipget[$user_ip]['get_time'],
                            "msg" => "频繁请求过滤"
                        ])));
                    }
                }
            } else {
                //------------------------------------------------------------------------------//
                empty($ipget_data[date("Y-m-d", time())][$user_ip][$act]) ? $ipget_data[date("Y-m-d", time())][$user_ip][$act] = 1 : $ipget_data[date("Y-m-d", time())][$user_ip][$act];
                $ipget_data[date("Y-m-d", time())][$user_ip][$act] = $ipget_data[date("Y-m-d", time())][$user_ip][$act] + 1;
                $ipget_data[date("Y-m-d", time())][$user_ip]['get_time'] = time();
                $handle = fopen('ipgetDay.log', 'w+');
                fwrite($handle, json_encode($ipget_data));
                fclose($handle);
                //------------------------------------------------------------------------------//
                return true;
            }
        } else {
            exit(unicode2Chinese(json_encode([
                "ret" => 666,
                "msg" => "sql failed!"
            ])));
        }
    }
}

来源:https://blog.csdn.net/qq_55619094/article/details/128737916

PHP:API接口请求限制IP/限制次数已关闭评论
Avatar photo

人生长恨水长东