<MyRusakov.ru />

Профессиональная Web-разработка. Дизайн, код и автоматизация

Профессиональная Web-разработка. Дизайн, код и автоматизация

Это очень подробный курс из разряда "всё включено". Разбираются следующие темы: HTML, CSS, SCSS, JavaScript, PHP, SQL, Laravel, Nginx, PostCSS, npm, Vite, Vitest, Composer, PHPUnit, Prettier, Stylelint, ESLint, Pint, Larastan, Git, Agile, Scrum, Docker, Supervisord, Figma, Stitch AI, Confluence, Jira.

Рассчитан и на новичков, и на тех, кто уже знаком с основами, но хочет освоить полный цикл разработки.

Помимо самой теории, Вы увидите пример создания Web-проекта на 20 000 строк кода: от идеи и документации на Confluence через планирование на Jira, fullstack-разработку до деплоя на VPS.

Помимо уроков, курс содержит упражнения для закрепления знаний и финальное тестирование. А ещё Вы получите 5 полноценных Бонусных курсов: «GitLab под ключ», «Вёрстка сайта с нуля 2.0», «JavaScript с Нуля до Гуру 2.0», «PHP и MySQL с Нуля до Гуру 3.0» и «Laravel от А до Я».

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

PHP cURL: GET и POST запросы, JSON и загрузка файлов (понятное руководство)

PHP cURL: GET и POST запросы, JSON и загрузка файлов (понятное руководство)

Запросы к внешним сервисам — повседневная задача в PHP. Да, можно пользоваться file_get_contents, но для реальной разработки лучше применять cURL: он управляет заголовками, таймаутами, SSL, редиректами, позволяет отправлять JSON и файлы, а также выполнять запросы параллельно.

Проверка и быстрый старт

<?php
if (!extension_loaded('curl')) {
    die('Расширение cURL не установлено');
}

$ch = curl_init('https://httpbin.org/get?hello=world');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,  // вернуть ответ как строку
    CURLOPT_TIMEOUT => 10,            // общий таймаут (сек)
    CURLOPT_CONNECTTIMEOUT => 5,      // таймаут соединения (сек)
]);

$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException('cURL error: ' . curl_error($ch));
}

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200) {
    throw new RuntimeException("HTTP статус: {$httpCode}");
}

$data = json_decode($response, true);
print_r($data);

Так вы выполняете простой GET-запрос и безопасно обрабатываете ошибки и HTTP-статус.

POST запрос: форма (application/x-www-form-urlencoded)

<?php
$url = 'https://httpbin.org/post';
$post = [
    'email' => 'user@example.com',
    'name'  => 'Ivan',
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($post),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException('cURL error: ' . curl_error($ch));
}
curl_close($ch);

echo $response;

Совет: всегда используйте http_build_query — он корректно кодирует данные и спецсимволы.

Отправка и приём JSON

<?php
$url = 'https://httpbin.org/post';
$payload = [
    'title' => 'Привет, мир',
    'tags'  => ['php', 'curl']
];

$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $json,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Accept: application/json',
        'User-Agent: MyApp/1.0'
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException('cURL error: ' . curl_error($ch));
}

$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http < 200 || $http >= 300) {
    throw new RuntimeException("HTTP статус: {$http}, тело: {$response}");
}

$data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($data);

Важно: задавайте правильные заголовки Content-Type и Accept. Для Unicode используйте JSON_UNESCAPED_UNICODE, а для строгой обработки — JSON_THROW_ON_ERROR.

Чтение ответа: заголовки, код статуса, редиректы

<?php
$url = 'https://httpbin.org/redirect-to?url=https%3A%2F%2Fexample.com';
$headers = [];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_FOLLOWLOCATION => true,               // идти за редиректами
    CURLOPT_MAXREDIRS => 5,
    CURLOPT_HEADERFUNCTION => function($ch, $headerLine) use (&$headers) {
        $len = strlen($headerLine);
        $parts = explode(':', $headerLine, 2);
        if (count($parts) === 2) {
            $headers[trim($parts[0])] = trim($parts[1]);
        }
        return $len; // важно вернуть длину
    },
    CURLOPT_RETURNTRANSFER => true,
]);

$body = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);

echo "HTTP: {$httpCode}\nURL: {$finalUrl}\n";
print_r($headers);

Так вы получите конечный URL после редиректов, заголовки и статус.

SSL: безопасность по умолчанию

По умолчанию cURL проверяет SSL-сертификат. Не отключайте проверку без необходимости!

<?php
$ch = curl_init('https://example.com');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    // Не делайте так в продакшене, только для диагностики:
    // CURLOPT_SSL_VERIFYPEER => false,
    // CURLOPT_SSL_VERIFYHOST => 0,
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
curl_close($ch);

Если возникает ошибка сертификации, проверьте корневые сертификаты на сервере (CA bundle).

Загрузка файлов (multipart/form-data)

<?php
$url = 'https://httpbin.org/post';
$filePath = __DIR__ . '/logo.png';

if (!file_exists($filePath)) {
    throw new RuntimeException('Файл не найден');
}

$fields = [
    'file' => new CURLFile($filePath, 'image/png', 'logo.png'),
    'title' => 'Логотип'
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $fields, // cURL сам выставит multipart
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
curl_close($ch);

echo $response;

Используйте класс CURLFile — это безопаснее и чище, чем префикс @ в старых версиях.

Таймауты и повторные попытки (retry с бэкоффом)

<?php
function http_get_with_retry(string $url, int $retries = 3): string {
    $delay = 200; // миллисекунды
    for ($i = 0; $i <= $retries; $i++) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT_MS => 1500,
            CURLOPT_TIMEOUT_MS => 3000,
        ]);
        $body = curl_exec($ch);
        $err  = curl_error($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($body !== false && $code >= 200 && $code < 500) {
            return $body; // для 2xx и 3xx возвращаем ответ
        }
        // 5xx, timeouts, network — ждём и повторяем
        usleep($delay * 1000);
        $delay = min($delay * 2, 3000);
    }
    throw new RuntimeException('Не удалось получить ответ: ' . ($err ?: 'unknown'));
}

Не забывайте ставить разумные таймауты и ограничение на количество повторов.

Отладка cURL

<?php
$ch = curl_init('https://httpbin.org/get');
$stream = fopen('php://temp', 'w+');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_VERBOSE => true,        // включает подробный лог
    CURLOPT_STDERR => $stream,      // куда писать лог
]);
curl_exec($ch);
rewind($stream);
$debug = stream_get_contents($stream);
fclose($stream);
curl_close($ch);

echo "DEBUG:\n" . $debug;

CURLOPT_VERBOSE покажет низкоуровневый обмен, что удобно при диагностике SSL и заголовков.

Параллельные запросы: curl_multi

<?php
$urls = [
    'https://httpbin.org/delay/1',
    'https://httpbin.org/delay/2',
];

$multi = curl_multi_init();
$chs = [];

foreach ($urls as $u) {
    $ch = curl_init($u);
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5]);
    curl_multi_add_handle($multi, $ch);
    $chs[] = $ch;
}

do {
    $status = curl_multi_exec($multi, $running);
    curl_multi_select($multi);
} while ($running && $status == CURLM_OK);

foreach ($chs as $ch) {
    echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) . " - HTTP " . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "\n";
    curl_multi_remove_handle($multi, $ch);
    curl_close($ch);
}
curl_multi_close($multi);

curl_multi позволяет существенно ускорить работу при большом числе независимых запросов.

Типичные ошибки и рекомендации

  • Не забывайте CURLOPT_RETURNTRANSFER, иначе echo перехватит ответ и смешает его с HTML.
  • Для форм — http_build_query, для JSON — json_encode + корректные заголовки.
  • Используйте таймауты и ретраи; логируйте код ответа и URL.
  • Не отключайте SSL-проверку в продакшене. Исправляйте корневые сертификаты.
  • Закрывайте ресурсы: curl_close и curl_multi_close.

Что дальше?

Освоили основы cURL — сделайте следующий шаг: подключение к БД, авторизация, работа с файлами и деплой. Посмотрите практический курс с проектами и домашками — Прокачать PHP и MySQL на практике →.

Теперь у вас есть рабочий набор приёмов: GET и POST запросы, JSON, загрузка файлов, заголовки, SSL, таймауты, отладка и параллельные вызовы. Этого достаточно, чтобы уверенно интегрировать внешние API в ваши PHP‑проекты.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.