§ Класс

Здесь написан небольшой класс для работы с Curl, который я часто использую.
  • get — загрузка страницы
  • download_files — мультизагрузка файлов
  • upload_file — загрузка файлов через CurlFile
1class Curl
2{
3    // Запрос GET с параметрами
4    public function get($url, $opt = []) {
5
6        $options = $this->get_default_opt();
7        if (isset($opt['header']) && is_array($opt['header'])) {
8            $options[CURLOPT_HTTPHEADER] = $opt['header'];
9        }
10
11        $ch = curl_init($url);
12        curl_setopt_array($ch, $options);
13        $content = curl_exec($ch);
14        $http    = curl_getinfo($ch, CURLINFO_HTTP_CODE);
15        curl_close($ch);
16
17        return compact('content', 'http');
18    }
19
20    // Загрузка нескольких файлов одновременно многопоточно
21    public function download_files($files) {
22
23        $mc = microtime(1);
24
25        $channels = [];
26        $file_hdl = [];
27
28        foreach ($files as $query_id => $file) {
29
30            $channels[$query_id] = curl_init($file['url']);
31            $file_hdl[$query_id] = fopen($file['dst'], "wb+");
32
33            $opt = $this->get_default_opt();
34            $opt[CURLOPT_FILE] = $file_hdl[$query_id];
35
36            curl_setopt_array($channels[$query_id], $opt);
37        }
38
39        // Мультизапрос на файлы
40        $this->multi_request($channels);
41
42        foreach ($file_hdl as $fp) fclose($fp);
43
44        return [
45            'time' => microtime(1) - $mc,
46        ];
47    }
48
49    protected function multi_request(& $channels) {
50
51        $active = 0;
52
53        // Запуск мультиобработчика
54        $mh = curl_multi_init();
55
56        // Добавление
57        foreach ($channels as $ch) curl_multi_add_handle($mh, $ch);
58
59        // Ожидание исполнения
60        do { $perform = curl_multi_exec($mh, $active); }
61        while ($perform == CURLM_CALL_MULTI_PERFORM);
62
63        // Исполнение запросов
64        while ($active && $perform == CURLM_OK) {
65
66            if (curl_multi_select($mh) == -1)
67                continue;
68
69            do { $perform = curl_multi_exec($mh, $active); }
70            while ($perform == CURLM_CALL_MULTI_PERFORM);
71        }
72
73        // Закрываем все дескрипторы
74        foreach ($channels as $query_id => $ch) {
75
76            $channels[$query_id] = [
77                'body'  => curl_multi_getcontent($ch),
78                'ch'    => $ch
79            ];
80
81            curl_multi_remove_handle($mh, $ch);
82        }
83
84        curl_multi_close($mh);
85    }
86
87    // Опции по умолчанию
88    protected function get_default_opt() {
89
90        return [
91            CURLOPT_RETURNTRANSFER  => true,
92            CURLOPT_FOLLOWLOCATION  => true,
93            CURLOPT_AUTOREFERER     => true,
94            CURLOPT_SSL_VERIFYPEER  => false,
95            CURLOPT_SSL_VERIFYHOST  => false,
96            CURLOPT_TIMEOUT         => 60,
97        ];
98    }
99
100    // Загрузить файл
101    public function upload_file($url, $files, $opts = []) {
102
103        foreach ($files as $id => $file) {
104            $files[$id] = new \CURLFile($file);
105        }
106
107        $ch = curl_init($url);
108
109        $optch = $this->get_default_opt();
110        $optch[CURLOPT_POST] = true;
111        $optch[CURLOPT_POSTFIELDS] = $files;
112
113        if ($opts) foreach ($opts as $a => $b) $optch[$a] = $b;
114
115        curl_setopt_array($ch, $optch);
116        $result = curl_exec($ch);
117        curl_close($ch);;
118
119        return $result;
120    }
121}