原理:用PHP的GET和POSt请求,实现代理访问服务器内网接口。
假设:
外网链接:http://127.0.0.1/php-proxy/index.php/api.gen1/admin?id=2021&name=%E5%BC%A0%E4%B8%89
内网地址:
http://127.0.0.1:8000/api.gen1/admin?id=2021&name=%E5%BC%A0%E4%B8%89
<?php /* * PHP接口代理转发: 以Golang接口转发为例; 如有必要,请设置内网IP为白名单; 建议内网接口返回格式:Content-Type: text/html; charset=UTF-8; * 使用示例: $host = "http://127.0.0.1:80/php-proxy/"; // 外网网址(主网址或有部分路径) $intranet = 'http://127.0.0.1:8000/'; // 内网网址(主网址或有部分路径) $php_proxy = new php_proxy(); $back = $php_proxy->request_intranet($host, $intranet); echo $back; * */ class php_proxy{ // 发送get、post请求 public function request_option($request_url='', $method='post', $request_data=[], $to_json=false): string{ if (empty($request_url)) { $back = '{"state":0, "msg":"request_url is null", "content":""}'; }else{ if ($method == 'post' || $method == 'POST'){ $body = http_build_query($request_data); $options = [ 'http' => [ 'method' => 'POST', // 注意要大写 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $body, ], ]; $context = stream_context_create($options); $data = file_get_contents($request_url, false, $context); }else if ($method == 'get'|| $method == 'GET'){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $request_url); curl_setopt($curl, CURLOPT_HEADER, 0); // 不抓取头部信息。只返回数据 curl_setopt($curl, CURLOPT_TIMEOUT, (int)60000); // 超时设置 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 1表示不返回bool值 $data = curl_exec($curl); curl_close($curl); }else{ $data = '{"state":0, "msg":"method error. method is only in [get, post], options etc be not supported.", "content":""}'; } $back = $data; } if ($to_json == true){ $res = json_encode($back, true); }else{ $res = $back; } return $res; } // 获取完整网址 public function get_url(): string{ if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { $url = 'https://'; }else{ $url = 'http://'; } return $url.$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$_SERVER['REQUEST_URI']; } // 是post public function is_post(): bool{ return isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) == 'POST'; } // 是get public function is_get(): bool{ return isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) == 'GET'; } // 生成内网网址:把外网网址解析到内网网址 public function make_request_url($host, $intranet): string{ return str_replace($host, $intranet, $this->get_url()); // 实际代理地址(就是替换主网址或路径) } // 转发接口 // 请从此处调用 public function request_intranet($host, $intranet): string{ // 测试的内网请求地址:$request_url = http://127.0.0.l:8000/api.gen1/admin $request_url = $this->make_request_url($host, $intranet); if ($this->is_post()){ $request_array = $_REQUEST; // 请求参数数组 $back = $this->request_option($request_url, 'post', $request_array, false); }else if ($this->is_get()){ $request_array = []; $back = $this->request_option($request_url, 'get', $request_array, false); } else{ $back = '{"state":0, "msg":"method error. method is only in [get, post], options etc be not supported.", "content":""}'; } return $back; } } // 返回数据 $host = "http://127.0.0.1:80/php-proxy/"; // 外网网址(主网址或有部分路径) $intranet = 'http://127.0.0.1:8000/'; // 内网网址(主网址或有部分路径) $php_proxy = new php_proxy(); $back = $php_proxy->request_intranet($host, $intranet); echo $back; exit(200);
转发访问如下:
-