php - curl_multi 没有运行第二个请求
问题描述
我正在尝试使用 curl_multi 将数据发送到两个不同的 URL,并从其中一个 URL 的响应中获取 URL 并重定向用户。
到目前为止,除了第二个请求没有被处理外,一切正常。
这是我的代码:
// create both cURL resources
$ch1 = curl_init();
$ch2 = curl_init();
// set URL and other appropriate options
//--------------------------CH1
curl_setopt_array($ch1, array(
CURLOPT_URL => "https://my.crm.com/api/signup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => '{"userip":"'.$_REQUEST['ip'].'","firstname":"'.$_REQUEST['firstname'].'", "lastname":"'.$_REQUEST['lastName'].'", "email":"'.$_REQUEST['email'].'", "password":"'.$_REQUEST['password'].'", "phone":"'.$_REQUEST['phonenumber'].'", "prefix":"'.$_REQUEST['phonecode'].'" }',
));
//-------------------------CH2
curl_setopt_array($ch2, array(
CURLOPT_URL => "https://my2.crm2.com/api/signup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => '{"userip":"'.$_REQUEST['ip'].'","firstname":"'.$_REQUEST['firstname'].'", "lastname":"'.$_REQUEST['lastname'].'", "email":"'.$_REQUEST['email'].'", "password":"'.$_REQUEST['password'].'", "phone":"'.$_REQUEST['phonenumber'].'", "prefix":"'.$_REQUEST['phonecode'].'" }',
));
//create the multiple cURL handle
$mh = curl_multi_init();
//add the two handles
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
// While we're still active, execute curl
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mh == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
// Wait for activity on any curl-connection
if (curl_multi_select($mh) == -1) {
continue;
}
// Continue to exec until curl is ready to
// give us more data
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
//responses
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
//read response and redirect
$json_array = json_decode($response1, true);
$loginurl = $json_array['data'];
header("Location: $loginurl");
我尝试了不同的解决方案,但我仍然无法让第二个请求 ($ch2) 工作。
解决方案
你的代码有几个问题,但我怀疑你没有得到内容#2,因为你在获取结果之前关闭了 multi_handle ......事实上,我很惊讶你得到第一个内容,甚至。
但首先我想抱怨这个:
curl_setopt_array($ch1, array(
CURLOPT_URL => "url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => '{"userip":"' . $_REQUEST['ip'] . '","firstname":"' . $_REQUEST['firstname'] . '", "lastname":"' . $_REQUEST['lastName'] . '", "email":"' . $_REQUEST['email'] . '", "password":"' . $_REQUEST['password'] . '", "phone":"' . $_REQUEST['phonenumber'] . '", "prefix":"' . $_REQUEST['phonecode'] . '" }',
));
1:使用 CURLOPT_POST,而不是 CURLOPT_CUSTOMREQUEST(一方面,这是正确的做法,libcurl 实际上明白你想要一个 POST 请求,而不是一些非标准的请求)
$_REQUEST['password']
2:如果包含,您认为会发生"
什么?它会破坏你的json,使其无法解析......
3:通过操纵 $_REQUEST['password'] (或那里的任何其他变量),您的代码容易受到 JSON 注入的攻击,黑客可以例如欺骗他们的 IP,提供假的userip
(如果您不知道 JSON 注入是什么,它有点像SQL Injection,但它们可以注入 JSON 数据(如欺骗的用户 IP)而不是 SQL 命令,看起来像 {"data":"real_data","data":"evil_hacker_injected_version_of_data_that_will_replace_it_because_it_is_the_last_definition_of_data"}
:)
使用 json_encode() 安全地创建您的 json,如下所示:
curl_setopt_array($ch1, array(
CURLOPT_URL => "url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => json_encode(array(
'userip' => (string) $_REQUEST['ip'],
'firstname' => (string) $_REQUEST['firstname'],
'lastname' => (string) $_REQUEST['lastName'],
'email' => (string) $_REQUEST['email'],
'password' => (string) $_REQUEST['password'],
'phone' => (string) $_REQUEST['phonenumber'],
'prefix' => (string) $_REQUEST['phonecode'],
))
));
... 和这里
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mh == CURLM_CALL_MULTI_PERFORM);
您正在检查错误的值, $mh 是 NEVER CURLM_CALL_MULTI_PERFORM ,您想将其与 $mrc 进行比较,而不是 $mh (libcurl 开发人员还删除了 CURLM_CALL_MULTI_PERFORM ,因为很多人用错了它,这发生在几年前,现代代码不再需要它。)
除此之外,我根本不喜欢你实现循环的方式..试试这个:
while (1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
if (!$active) {
break;
}
curl_multi_select($mh);
}
但话虽如此,我相信你真正的问题是你在调用 curl_multi_getcontent() 之前运行 curl_multi_remove_handle() 和 curl_multi_close()。
推荐阅读
- makefile - 在定义配方的先决条件中添加额外的换行符
- javascript - 如何在 Cypress 中访问 baseURL 的值
- google-signin - Google yolo 客户端源不允许使用这个API
- python - 使用Python的特殊格式的乘法表
- javascript - 打印从所选日期开始的天数
- c# - 为找到的每个项目更新进度条
- python - 如何将烧瓶输出返回到同一个html页面
- laravel - Laravel 无法获取静态资源地址
- hadoop - Hive 更新期间 HDFS 中发生了什么(真正)?
- java - 如何在 JBoss 中部署没有活动 JMS 配置的 MDB?