Curl и pcntl_fork ()

У меня есть код, который используется для проверки ссылок на веб-сайте и в попытке сделать его «потоковым», код был обновлен для использования pcntl_fork ().

Родительский код работает для URL-адресов SSL и не SSL, но дочерний код работает только для URL-адресов, отличных от SSL. Я заметил в коде, где он работает, а где нет.

Вот мой код вилки. Я знаю, код ниже будет цикл навсегда, я вынул код управления контуром, чтобы он был более читабельным.

$this->initialize_curl(); $this->connect_database(); // prime the queue $this->add_url_to_queue($this->source_url, 0, 0); $this->process_next_url_in_queue($this->get_next_url_in_queue()); // SSL and non-SSL work at this point // loop until we have processed all URL's while (1) { $url = $this->get_next_url_in_queue(); // disconnect from the database before forking since we don't want to // share the database connection with child processes - the first one // will close it and ruin the fun for the other children. curl_close($this->ch); $this->db->close(); // create child $pid = pcntl_fork(); // handle forked processing switch ($pid) { // error case -1: print "Could not fork\n"; exit; // child case 0: // seperate database and curl for the child $this->connect_database(); $this->initialize_curl(); // process the url $this->process_next_url_in_queue($url); // only non-SSL works at this point exit; // parent default: // seperate database and curl for the parent $this->connect_database(); $this->initialize_curl(); break; } } 

Как вы можете видеть, мне пришлось открыть и закрыть соединение с базой данных, чтобы оно работало, и я делаю то же самое с CURL. Вот код в initialize_curl() :

 $this->ch = curl_init(); curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, FALSE); curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($this->ch, CURLOPT_HEADER, FALSE); 

Я использую CURLOPT_SSL_VERIFYPEER и CURLOPT_SSL_VERIFYHOST потому что без него мои запросы SSL CURLOPT_SSL_VERIFYPEER CURLOPT_SSL_VERIFYHOST . Это проблема с настройкой сервера, а не с тем, что я могу изменить.

Когда дочерний CURL-URL-адрес SSL, я думаю, что он терпит неудачу, потому что есть проблема с настройкой этих параметров, но я не знаю. Если я установил CURL, чтобы быть подробным, я вижу следующую ошибку:

 * About to connect() to HOST port 443 (#0) * Trying IP... * connected * Connected to HOST (IP) port 443 (#0) * NSS error -8023 * Closing connection #0 * SSL connect error 

Пожалуйста, дайте мне знать, что я могу сделать, чтобы сделать эту работу.

После многих исследований я обнаружил, что проблема не является новой и представляет собой проблему с реализацией PHP CURL. Эти другие вопросы помогли мне придумать решение, которое я рассказал ниже:

  • Запросы SSL, сделанные с ошибкой cURL после процесса fork
  • Ошибка libCurl SSL после fork ()

В результате я использовал pcntl_exec, который заменяет текущий дочерний процесс командой.

 $this->initialize_curl(); $this->connect_database(); // prime the queue $this->add_url_to_queue($this->source_url, 0, 0); $this->process_next_url_in_queue($this->get_next_url_in_queue()); // loop until we have processed all URL's while (1) { $url = $this->get_next_url_in_queue(); // disconnect from the database before forking since we don't want to // share the database connection with child processes - the first one // will close it and ruin the fun for the other children. curl_close($this->ch); $this->db->close(); // create child $pid = pcntl_fork(); // handle forked processing switch ($pid) { // error case -1: print "Could not fork\n"; exit; // child case 0: // seperate database and curl for the child $this->connect_database(); $this->initialize_curl(); // process the url pcntl_exec('process_next_url_in_queue.php', array($url)); exit; // parent default: // seperate database and curl for the parent $this->connect_database(); $this->initialize_curl(); break; } }