Почитать и подумать (желательно):
https://github.com/6562680/support/blob/main/src/X...
https://github.com/6562680/support/blob/main/src/X...
Устанавливаем:
composer require monolog/monolog
composer require gzhegow/support:1.16.21
Запускаем:
require __DIR__ . '/vendor/autoload.php';
// const
define('__LOGS__', __DIR__ . '/logs');
// vars
$channelName = 'curl';
// dirs
if (! is_dir($var = __LOGS__)) mkdir($var, 0775, true); // на unix есть ограничение в /etc/php/fpm с помощью umask и listen/owner, и вместо 0775 может быть создано меньше полномочий
// init
$logger = new \Monolog\Logger($channelName, [
new \Monolog\Handler\StreamHandler(__LOGS__ . '/monolog/' . date('Y-m-d') . '/' . date('H') . '_' . $channelName . '.log'), // в файл
// new \Monolog\Handler\StreamHandler('php://stdout'), // для консоли
// new \Monolog\Handler\StreamHandler('php://output'), // для браузера
// куда-нибудь ещё...
]);
$xcurl = \Gzhegow\Support\XCurl::getInstance();
// data
$urls = [
// index => url
'myIndex1' => 'https://google.com',
0 => 'https://google.com',
];
// action
$curls = [];
foreach ($urls as $index => $url) {
// >>> логируем, что делаем запрос на внешний адрес
$logger->notice('Fetching url: ' . $urls[ $index ]);
$ch = curl_init($url);
// curl_setopt($ch, CURLOPT_HEADER, 0); // и т.д.
$curls[ $index ] = $ch;
}
$retry = null; // создаем пустую переменную, она по ссылке будет передавать состояние в каждом шаге цикла
$retries = 3; // три повтора, условия выхода из бесконечного цикла
foreach ($generator = $xcurl->walkmulti($curls, $retry) as $step => [ $index, $curl ]) {
// $retry автоматически становится null в начале каждой проверки (так написал в walkmulti). То есть если проверок не сделать, $retry будет null и повторов не будет.
// проверяем ошибку. добавь столько ЕСЛИ, сколько нужно. длина контента. время запроса. код ответа, всё в этот ЕСЛИ
if (curl_errno($curl)) {
// проверяем условие, после которого повторы делать не надо. например, у нас только три попытки
if ($step >= $retries) {
// >>> логируем, что больше не выйдет
$logger->notice('Unable to retry url: ' . $urls[ $index ]);
$retry = false; // false = больше не спрашивай про него, результат не сохраняй
// $retry = null; // null = сохрани результат последнего и больше не спрашивай про него
continue;
} else {
// >>> логируем что пошел повтор
$logger->notice('Retrying url: ' . $urls[ $index ] . '. Retries left: ' . $retries - $step);
$ch = curl_init($urls[ $index ]); // в curl нельзя повторно выполнить запрос по тому же ресурсу, собираем заново такой же как был, вероятно - с новой прокси
// curl_setopt($ch, CURLOPT_HEADER, 0); // и т.д.
$retry = $ch; // передаем по ссылке новый курл, который после всех проверок выполнится в пачке ещё раз
continue;
}
}
}
$results = $generator->getReturn();
var_dump($results); // [ 'myIndex1' => <content>, 0 => <content> ]