我有一些代码用于检查网站上的链接,并尝试使用#34;线程",代码已更新为使用pcntl_fork()。
父代码适用于SSL和非SSL网址,但子代码仅适用于非SSL网址。我在代码中注意到它的工作原理以及它没有的地方。
这是我的fork代码。我知道下面的代码将永远循环,我已经取出了循环控制代码,因此它更具可读性。
$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 CURL请求将失败。这是服务器设置的问题,而不是我可以改变的事情。
当孩子CURL成为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
请让我知道我可以做些什么来完成这项工作。
答案 0 :(得分:3)
经过大量研究后,我发现这个问题不是新问题,而且是php实现CURL的问题。这些其他问题帮助我提出了我在下面分享的解决方案:
我最终做的是使用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;
}
}