-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<?php | ||
class CurlMulti | ||
{ | ||
public $mh; | ||
public $urls = array(); | ||
public $chs = array(); | ||
public $res = array(); | ||
public $req = array(); | ||
public $options = array( | ||
CURLOPT_TIMEOUT => 60, | ||
CURLOPT_RETURNTRANSFER => 1, | ||
); | ||
public $multiOptions = array(); | ||
|
||
public function __construct($urls, $options = array()) | ||
{ | ||
$this->addUrl($urls); | ||
$this->setOpts($options); | ||
} | ||
|
||
public function setOpt($curlOpt, $value, $index = false) | ||
{ | ||
// 为某个请求单独设置 Option | ||
if ($index !== false) | ||
$this->req[$index][$curlOpt] = $value; | ||
else | ||
$this->options[$curlOpt] = $value; | ||
} | ||
|
||
public function setOpts($opts, $index = false) | ||
{ | ||
if ($index !== false) { | ||
$this->req[$index] = $opts + $this->req[$index]; | ||
} else { | ||
var_dump($opts, $this->options); | ||
$this->options = $opts + $this->options; | ||
} | ||
|
||
var_dump($this->options); | ||
} | ||
|
||
public function resetOpts($opts) | ||
{ | ||
$this->options = $opts; | ||
} | ||
|
||
public function setMultiOpt($curlOpt, $value) | ||
{ | ||
$this->multiOptions[$curlOpt] = $value; | ||
} | ||
|
||
public function setMultiOpts($options) | ||
{ | ||
$this->multiOptions = $options + $this->multiOptions; | ||
} | ||
|
||
public function setUrl($urls) | ||
{ | ||
$this->urls = $urls; | ||
} | ||
|
||
public function addUrl($urls) | ||
{ | ||
if (is_string($urls)) $this->urls[] = $urls; | ||
if (is_array($urls)) | ||
$this->urls = array_merge($this->urls, $urls); | ||
} | ||
|
||
public function emptyUrl() | ||
{ | ||
$this->urls = array(); | ||
} | ||
|
||
public function _initMh() | ||
{ | ||
$this->mh = curl_multi_init(); | ||
} | ||
public function _addCh() | ||
{ | ||
foreach ($this->urls as $index => $url) { | ||
$ch = curl_init($url); | ||
// 为所有ch设置option | ||
curl_multi_add_handle($this->mh, $ch); | ||
// 保持映射关系 | ||
$this->chs[$index] = $ch; | ||
} | ||
} | ||
|
||
public function _setOption() | ||
{ | ||
foreach ($this->chs as $index => $ch) { | ||
// 为所有ch设置option | ||
curl_setopt_array($ch, $this->options); | ||
// 单独为每一个ch设置option | ||
if (isset($this->req[$index]) && ! empty($this->req[$index])) | ||
curl_setopt_array($ch, $this->req[$index]); | ||
} | ||
} | ||
|
||
// 为mh设置选项 | ||
public function _setMultiOption() | ||
{ | ||
if ((float) phpversion() >= 5.5) { | ||
foreach ($this->multiOptions as $optKey => $optValue) { | ||
printf('%s => %s', $optKey, $optValue); | ||
curl_multi_setopt($this->mh, $optKey, $optValue); | ||
} | ||
} | ||
} | ||
|
||
public function send() | ||
{ | ||
$running = null; | ||
|
||
do { | ||
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->mh, $running)); | ||
if (!$running) break; | ||
while (($res = curl_multi_select($this->mh)) === 0) {}; | ||
if ($res === false) break; | ||
} while (true); | ||
} | ||
|
||
public function getResponse() | ||
{ | ||
foreach ($this->chs as $index => $ch) { | ||
$cont = curl_multi_getcontent($ch); | ||
$chInfo = curl_getinfo($ch); | ||
|
||
$this->res[$index] = array( | ||
'url' => $this->urls[$index], | ||
'content' => $cont, | ||
'contentType' => $chInfo['content_type'], | ||
'status' => $chInfo['http_code'], | ||
); | ||
} | ||
} | ||
|
||
public function destroyMh() | ||
{ | ||
foreach ($this->chs as $index => $ch) { | ||
curl_close($ch); | ||
curl_multi_remove_handle($this->mh, $ch); | ||
} | ||
curl_multi_close($this->mh); | ||
$this->chs = array(); | ||
} | ||
|
||
public function destroyCh($index) | ||
{ | ||
curl_close($this->chs[$index]); | ||
unset($this->chs[$index]); | ||
curl_multi_remove_handle($this->mh, $this->chs[$index]); | ||
} | ||
|
||
public function run() | ||
{ | ||
$this->_initMh(); | ||
$this->_addCh(); | ||
$this->_setOption(); | ||
$this->_setMultiOption(); | ||
$this->send(); | ||
$this->getResponse(); | ||
$this->destroyMh(); | ||
|
||
return $this->res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
sleep(10); | ||
echo 'hello, world'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
// 1. multi handle | ||
$mh = curl_multi_init(); | ||
|
||
// 2. add multiple URLs to the multi handle | ||
for ($i = 0; $i < $max_connections; $i++) { | ||
add_url_to_multi_handle($mh, $url_list); | ||
} | ||
|
||
// 3. initial execution | ||
do { | ||
$mrc = curl_multi_exec($mh, $active); | ||
} while ($mrc == CURLM_CALL_MULTI_PERFORM); | ||
|
||
// 4. main loop | ||
while ($active && $mrc == CURLM_OK) { | ||
// 5. there is activity | ||
if (curl_multi_select($mh) != -1) { | ||
// 6. do work | ||
do { | ||
$mrc = curl_multi_exec($mh, $active); | ||
} while ($mrc == CURLM_CALL_MULTI_PERFORM); | ||
|
||
// 7. is there info? | ||
// this means one of the requests were finished | ||
if ($mhinfo = curl_multi_info_read($mh)) { | ||
|
||
// 8. get the info on the curl handle | ||
$chinfo = curl_getinfo($mhinfo['handle']); | ||
|
||
// 9. dead link? | ||
if (!$chinfo['http_code']) { | ||
$dead_urls []= $chinfo['url']; | ||
} else if ($chinfo['http_code'] == 404) { // 10. 404? | ||
$not_found_urls []= $chinfo['url']; | ||
} else { // 11. working | ||
$working_urls []= $chinfo['url']; | ||
} | ||
|
||
// 12. remove the handle | ||
curl_multi_remove_handle($mh, $mhinfo['handle']); | ||
curl_close($mhinfo['handle']); | ||
|
||
// 13. add a new url and do work | ||
if (add_url_to_multi_handle($mh, $url_list)) { | ||
do { | ||
$mrc = curl_multi_exec($mh, $active); | ||
} while ($mrc == CURLM_CALL_MULTI_PERFORM); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// 14. finished | ||
curl_multi_close($mh); | ||
|
||
echo "==Dead URLs==\n"; | ||
echo implode("\n",$dead_urls) . "\n\n"; | ||
|
||
echo "==404 URLs==\n"; | ||
echo implode("\n",$not_found_urls) . "\n\n"; | ||
|
||
echo "==Working URLs==\n"; | ||
echo implode("\n",$working_urls); | ||
|
||
// 15. adds a url to the multi handle | ||
function add_url_to_multi_handle($mh, $url_list) { | ||
static $index = 0; | ||
|
||
// if we have another url to get | ||
if ($url_list[$index]) { | ||
|
||
// new curl handle | ||
$ch = curl_init(); | ||
|
||
// set the url | ||
curl_setopt($ch, CURLOPT_URL, $url_list[$index]); | ||
// to prevent the response from being outputted | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | ||
// follow redirections | ||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); | ||
// do not need the body. this saves bandwidth and time | ||
curl_setopt($ch, CURLOPT_NOBODY, 1); | ||
|
||
// add it to the multi handle | ||
curl_multi_add_handle($mh, $ch); | ||
|
||
|
||
// increment so next url is used next time | ||
$index++; | ||
|
||
return true; | ||
} else { | ||
|
||
// we are done adding new URLs | ||
return false; | ||
} | ||
} |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters