/
mikopbx
/
ModuleAmoCrm
Обзор
Документация
Войти
/
mikopbx
/
ModuleAmoCrm
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
Lib/ClientHTTP.php
179 строк
7 KB
Alexey Portnov
Fix: видимость HTTP-ошибок AmoCRM API в логах + PHP 8.4 deprecated
29 апр 2026, 19:08
29 апр 2026, 19:08
9f38c5d
Код
Авторство
О чём код?
<?php /* * MikoPBX - free phone system for small business * Copyright © 2017-2023 Alexey Portnov and Nikolay Beketov * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program. * If not, see <https://www.gnu.org/licenses/>. */ namespace Modules\ModuleAmoCrm\Lib; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp; use MikoPBX\Core\System\Util; use Throwable; class ClientHTTP { /** * Отправка POST запроса к API. * @param string $url * @param array $params * @param array $headers * @return PBXAmoResult */ public static function sendHttpPostRequest(string $url, array $params, array $headers=[]):PBXAmoResult{ $client = new GuzzleHttp\Client(); $options = [ 'timeout' => 15, 'connect_timeout' => 5, 'http_errors' => false, 'headers' => $headers, 'json' => $params, ]; return self::executeWithRetry($client, 'POST', $url, $options); } /** * Отправка POST запроса к API. * @param string $url * @param array $params * @param array $headers * @return PBXAmoResult */ public static function sendHttpPatchRequest(string $url, array $params, array $headers=[]):PBXAmoResult{ $client = new GuzzleHttp\Client(); $options = [ 'timeout' => 15, 'connect_timeout' => 5, 'http_errors' => false, 'headers' => $headers, 'json' => $params, ]; return self::executeWithRetry($client, 'PATCH', $url, $options); } /** * Отправка http GET запроса. * @param string $url * @param array $params * @param array $headers * @return PBXAmoResult */ public static function sendHttpGetRequest(string $url, array $params, array $headers=[]):PBXAmoResult{ if(!empty($params)){ $url .= "?".http_build_query($params); } $client = new GuzzleHttp\Client(); $options = [ 'timeout' => 15, 'connect_timeout' => 5, 'http_errors' => false, 'headers' => $headers, ]; return self::executeWithRetry($client, 'GET', $url, $options); } /** * Выполнение HTTP-запроса с retry при ConnectException (таймауты, сетевые ошибки). * До 3 попыток с линейным backoff (2, 4, 6 сек). * @param GuzzleHttp\Client $client * @param string $method * @param string $url * @param array $options * @return PBXAmoResult */ private static function executeWithRetry(GuzzleHttp\Client $client, string $method, string $url, array $options):PBXAmoResult { $maxRetries = 3; $retryDelay = 2; $message = ''; $resultHttp = null; $code = 0; for ($attempt = 1; $attempt <= $maxRetries; $attempt++) { try { $resultHttp = $client->request($method, $url, $options); $code = $resultHttp->getStatusCode(); break; } catch (GuzzleHttp\Exception\ConnectException $e) { $message = $e->getMessage(); $errorMessage = "Error: " . $e->getMessage() . ','; $errorMessage .= "Request URL: " . $e->getRequest()->getUri() . ','; $errorMessage .= "Request Method: " . $e->getRequest()->getMethod() . ','; $errorMessage .= "Attempt: $attempt/$maxRetries"; Util::sysLogMsg('ModuleAmoCrm', "ConnectException: " . $errorMessage); if ($attempt < $maxRetries) { sleep($retryDelay * $attempt); } $code = 0; } catch (GuzzleException $e) { $message = $e->getMessage(); Util::sysLogMsg('ModuleAmoCrm', "GuzzleException: " . $message); $code = 0; break; } } return self::parseResponse($resultHttp, $message, $code, $method, $url); } /** * Разбор ответа сервера. * @param $resultHttp * @param $message * @param $code * @param string $method * @param string $url * @return PBXAmoResult */ private static function parseResponse($resultHttp, $message, $code, string $method = '', string $url = ''):PBXAmoResult { $res = new PBXAmoResult(); if( isset($resultHttp) && ($code === 200 || in_array($resultHttp->getReasonPhrase(), ['Created', 'Accepted'], true))){ $content = $resultHttp->getBody()->getContents(); $data = []; try { $data = json_decode($content, true, 512, JSON_THROW_ON_ERROR); }catch (Throwable $e){ $message = $e->getMessage(); } $res->success = is_array($data); if($res->success){ $res->data = $data; }else{ $res->messages[] = $content; $res->messages[] = $message; } }else{ $res->success = false; $res->messages['error-code'] = $code; $res->messages['error-msg'] = $message; if($resultHttp){ try { $res->messages['error-string'] = $resultHttp->getBody()->getContents(); $res->messages['error-data'] = json_decode($res->messages['error-string'], true); }catch (Throwable $e){ $res->messages['error-data'] = []; } } $logBody = isset($res->messages['error-string']) ? (string)$res->messages['error-string'] : ''; if(strlen($logBody) > 512){ $logBody = substr($logBody, 0, 512).'...'; } Util::sysLogMsg( 'ModuleAmoCrm', "HTTP $code on $method $url; msg='$message'; body='$logBody'" ); } return $res; } }