curl_multi не выполняет второй запрос - PullRequest
0 голосов
/ 25 сентября 2019

Я пытаюсь отправить данные на два разных URL-адреса с помощью curl_multi, получить 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).

1 Ответ

0 голосов
/ 25 сентября 2019

в вашем коде есть несколько ошибок, но я подозреваю, что вы не получаете контент №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, а не какой-то нестандартный запрос)

2: как вы думаете, что произойдет, если $_REQUEST['password'] включает "?это может испортить ваш json, сделав его непарсируемым ...

3: манипулируя $ _REQUEST ['password'] (или любой другой переменной там), ваш код уязвим для внедрения JSON, хакеры могут, например, подделатьих IP, выдавая фальшивый userip (если вы не знаете, что такое JSON-инъекция, это похоже на SQL-инъекцию , но они могут вводить данные JSON (например, подделанный userip) вместо команд 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);

youВы проверяете неправильное значение, $ mh НИКОГДА CURLM_CALL_MULTI_PERFORM, вы хотите сравнить его с $ mrc, а не с $ mh (также CURLM_CALL_MULTI_PERFORM был удален разработчиками libcurl, потому что многие люди использовали его неправильно, и это произошло много лет назад, этобольше не требуется в современном коде.)

в дополнение к этому, мне совсем не нравится, как вы реализовали цикл .. попробуйте это вместо этого:

while (1) {
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    if (!$active) {
        break;
    }
    curl_multi_select($mh);
}

, но со всемичто сказал, я верюВаша настоящая проблема заключается в том, что вы запускаете curl_multi_remove_handle () & curl_multi_close () ДО того, как вы вызовете curl_multi_getcontent ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...