CurlMulti.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Jaeger <JaegerCode@gmail.com>
  5. * Date: 2017/9/27
  6. * Curl multi threading
  7. */
  8. namespace QL\Ext;
  9. use Ares333\Curl\Curl;
  10. use QL\Contracts\PluginContract;
  11. use QL\QueryList;
  12. use Closure;
  13. class CurlMulti implements PluginContract
  14. {
  15. protected $urls = [];
  16. protected $queryList;
  17. protected $successCallback;
  18. protected $curl;
  19. protected $isRunning = false;
  20. public function __construct(QueryList $queryList,$urls)
  21. {
  22. $this->urls = is_string($urls)?[$urls]:$urls;
  23. $this->queryList = $queryList;
  24. $this->curl = new Curl();
  25. $this->curl->opt = [
  26. CURLOPT_RETURNTRANSFER => true
  27. ];
  28. }
  29. public static function install(QueryList $queryList, ...$opt)
  30. {
  31. $name = $opt[0] ?? 'curlMulti';
  32. $queryList->bind($name,function ($urls = []){
  33. return new CurlMulti($this,$urls);
  34. });
  35. }
  36. public function getUrls()
  37. {
  38. return $this->urls;
  39. }
  40. public function add($urls)
  41. {
  42. is_string($urls) && $urls = [$urls];
  43. $this->urls = array_merge($this->urls,$urls);
  44. //如果当前任务正在运行就实时动态添加任务
  45. $this->isRunning && $this->addTasks($urls);
  46. return $this;
  47. }
  48. public function success(Closure $callback)
  49. {
  50. $this->successCallback = function ($r) use($callback){
  51. $this->queryList->setHtml($r['body']);
  52. $callback($this->queryList,$this,$r);
  53. };
  54. return $this;
  55. }
  56. public function error(Closure $callback)
  57. {
  58. $this->curl->cbFail = function ($info) use($callback){
  59. $callback($info,$this);
  60. };
  61. return $this;
  62. }
  63. public function start(array $opt = [])
  64. {
  65. $this->bindOpt($opt);
  66. $this->addTasks($this->urls);
  67. $this->isRunning = true;
  68. $this->curl->start();
  69. $this->isRunning = false;
  70. $this->urls = [];
  71. return $this;
  72. }
  73. protected function bindOpt($opt)
  74. {
  75. foreach ($opt as $key => $value) {
  76. if($key == 'opt'){
  77. $this->curl->opt = $this->arrayMerge($this->curl->opt,$value);
  78. }else {
  79. $this->curl->$key = $value;
  80. }
  81. }
  82. }
  83. protected function addTasks($urls)
  84. {
  85. foreach ($urls as $url) {
  86. $this->curl->add([
  87. 'opt' => array(
  88. CURLOPT_URL => $url
  89. )
  90. ],$this->successCallback);
  91. }
  92. }
  93. protected function arrayMerge($arr1,$arr2)
  94. {
  95. foreach ($arr2 as $key => $value) {
  96. $arr1[$key] = $value;
  97. }
  98. return $arr1;
  99. }
  100. }