PHP CURL 数据中转

tsvico Lv5

前言

当你用 ajax 请求其他网站数据爆出跨域错误时,你可能查找过很多方法,jsonp、CORS 等 ,当然这些大多都是你要请求的站点也是你的站点的情况
示例:https://segmentfault.com/a/1190000012469713
当目标站点所有者并不是你时 你或许会想到反向代理
可能做 php 数据中转不如做 nginx 反向代理更节省资源,但是在某些非正常状态下,请求次数过多会被源服务器封掉 IP,emm…

贴上反代代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#反向代理 模糊匹配
location ^~/v1 {
#proxy_redirect off;
proxy_pass http://api.fastdown666.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
location = /v1/get/device/quota{
#return 520;
proxy_pass http://www.xxxxxx.cn/quota.json;
}
#error_page 520 /quota.json;

#反向代理 精确匹配
location = /index/dispatch.html {
#proxy_redirect off;
proxy_pass http://www.xxxxxx.com;
proxy_set_header Host www.xxxxxx.com; #需要带host
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}

流程

  • 收集头部信息
  • 收集请求数据
  • 转换头部信息为 CURL 头部请求格式
  • 使用 Curl 进行转发

收集 HTTP 头信息

1
2
3
4
5
6
7
8
9
function getAllHeaders() {
$headers = [];
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}

使用 PHP 封装协议获取输入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getPOST()  
{
$maGetPostData = [];
$handle = @fopen('php://input', 'r');
$data = '';
do
{
$data = @fread($handle, 1024);
if (strlen($data) == 0)
break;
else
$maGetPostData[] = $data;
}while(true);
fclose($handle);
unset($data, $handle);
return $maGetPostData;
}
$content = getPOST();
//$content = file_get_contents('php://input')

转换头信息为 Curl 请求格式

1
2
3
4
5
6
$headers = getAllHeaders();
$header_joins = [];
foreach ($headers as $k => $v) {
if ($k == 'X-Pingplusplus-Signature' || $k == 'Content-Type')
array_push($header_joins, $k . ': ' . $v);
}

使用 Curl 进行转发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function post($url, $headers, $raw_data) {
$ch = curl_init();
if (count($raw_data) > 0)
{ //存在POST数据需要提交
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_data); // Post Da
}
curl_setopt($ch, CURLOPT_URL, $url);//设置要访问的 URL
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); //模拟用户使用的浏览器
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1 ); // 使用自动跳转
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置超时时间
curl_setopt($ch, CURLOPT_AUTOREFERER, 1 ); // 自动设置Referer
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 收集结果而非直接展示
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 自定义 Headers
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
// @ini_set('display_errors', 1);

if (!function_exists('getallheaders')) {

function getallheaders() {
$headers = array();
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}

}

function getPOST()
{
$maGetPostData = [];
$handle = @fopen('php://input', 'r');
$data = '';
do
{
$data = @fread($handle, 1024);
if (strlen($data) == 0)
break;
else
$maGetPostData[] = $data;
}while(true);
fclose($handle);
unset($data, $handle);
return $maGetPostData;
}
$content = getPOST();

$headers = getAllHeaders();
$header_joins = [];
foreach ($headers as $k => $v) {
if ($k == 'Cookie' || $k == 'Content-Type')
array_push($header_joins, $k . ': ' . $v);
}
//自定义头
array_push($header_joins,"Referer :http://www.tooln.cn");
//print_r($headers);
//print_r($header_joins);die();

function post($url, $headers, $raw_data) {
$user_agent=$_SERVER['HTTP_USER_AGENT'];
$ch = curl_init();
if (count($raw_data) > 0)
{ //存在POST数据需要提交
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_data); // Post Da
}
curl_setopt($ch, CURLOPT_URL, $url);//设置要访问的 URL
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); //模拟用户使用的浏览器
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1 ); // 使用自动跳转
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置超时时间
curl_setopt($ch, CURLOPT_AUTOREFERER, 1 ); // 自动设置Referer
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 收集结果而非直接展示
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 自定义 Headers
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

$result = post('http://www.tooln.cn/', $header_joins, $content);

echo $result;

代码转载链接:https://www.jianshu.com/p/0c8de9dc99ac

有修改,增加了对 GET 的支持

  • 标题: PHP CURL 数据中转
  • 作者: tsvico
  • 创建于 : 2019-02-17 12:00:49
  • 更新于 : 2022-09-14 10:28:05
  • 链接: https://blog.tbox.fun/2019/53349589.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论