§ Класс

Здесь написан небольшой класс для работы с Curl, который я часто использую.
  • get — загрузка страницы
  • download_files — мультизагрузка файлов
  • upload_file — загрузка файлов через CurlFile
class Curl
{
    // Запрос GET с параметрами
    public function get($url, $opt = []) {

        $options = $this->get_default_opt();
        if (isset($opt['header']) && is_array($opt['header'])) {
            $options[CURLOPT_HTTPHEADER] = $opt['header'];
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, $options);
        $content = curl_exec($ch);
        $http    = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return compact('content', 'http');
    }

    // Загрузка нескольких файлов одновременно многопоточно
    public function download_files($files) {

        $mc = microtime(1);

        $channels = [];
        $file_hdl = [];

        foreach ($files as $query_id => $file) {

            $channels[$query_id] = curl_init($file['url']);
            $file_hdl[$query_id] = fopen($file['dst'], "wb+");

            $opt = $this->get_default_opt();
            $opt[CURLOPT_FILE] = $file_hdl[$query_id];

            curl_setopt_array($channels[$query_id], $opt);
        }

        // Мультизапрос на файлы
        $this->multi_request($channels);

        foreach ($file_hdl as $fp) fclose($fp);

        return [
            'time' => microtime(1) - $mc,
        ];
    }

    protected function multi_request(& $channels) {

        $active = 0;

        // Запуск мультиобработчика
        $mh = curl_multi_init();

        // Добавление
        foreach ($channels as $ch) curl_multi_add_handle($mh, $ch);

        // Ожидание исполнения
        do { $perform = curl_multi_exec($mh, $active); }
        while ($perform == CURLM_CALL_MULTI_PERFORM);

        // Исполнение запросов
        while ($active && $perform == CURLM_OK) {

            if (curl_multi_select($mh) == -1)
                continue;

            do { $perform = curl_multi_exec($mh, $active); }
            while ($perform == CURLM_CALL_MULTI_PERFORM);
        }

        // Закрываем все дескрипторы
        foreach ($channels as $query_id => $ch) {

            $channels[$query_id] = [
                'body'  => curl_multi_getcontent($ch),
                'ch'    => $ch
            ];

            curl_multi_remove_handle($mh, $ch);
        }

        curl_multi_close($mh);
    }

    // Опции по умолчанию
    protected function get_default_opt() {

        return [
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_FOLLOWLOCATION  => true,
            CURLOPT_AUTOREFERER     => true,
            CURLOPT_SSL_VERIFYPEER  => false,
            CURLOPT_SSL_VERIFYHOST  => false,
            CURLOPT_TIMEOUT         => 60,
        ];
    }

    // Загрузить файл
    public function upload_file($url, $files, $opts = []) {

        foreach ($files as $id => $file) {
            $files[$id] = new \CURLFile($file);
        }

        $ch = curl_init($url);

        $optch = $this->get_default_opt();
        $optch[CURLOPT_POST] = true;
        $optch[CURLOPT_POSTFIELDS] = $files;

        if ($opts) foreach ($opts as $a => $b) $optch[$a] = $b;

        curl_setopt_array($ch, $optch);
        $result = curl_exec($ch);
        curl_close($ch);;

        return $result;
    }
}