VK API: загрузка изображения на стену. Рабочий код на PHP7 + cURL

Этот пост был опубликован мной более года назад. Информация, описанная ниже, уже могла потерять актуальность, но всё ещё может быть полезна.

Публикую просто чтобы не потерялось.

Если хорошо попросите и если я не забуду, оформлю полноценный репепт публикации постов с твоего сайта на страницу пользователя, с прикреплением фотографии. Когда твоё приложение в ВК зарегистрировано как веб-сайт, а не Stand-alone приложение.

Пока тут только серверная часть. Она большого труда не составляет.

Забудь всё, что ты видел о загрузке фотографий через curl. Я двое суток ебал мозги с целью выяснить почему я делаю так, как говорили когда-то и говорят до сих пор (например, про @ перед именем загружаемого файла, например, что уже неактуально для PHP >= 5.5)…. и почему при успешном запросе к серверу фотографий, ВК мне отдаёт пустой photo = []

Будем считать, что у тебя уже есть ID приложения и ты получил жизненно важный access_token. Конкретно в контексте данного поста не играет роли, является ли твоё приложение веб-сайтом или Stand-alone. Механизм на сервере один.

Наверняка ты уже заебался также, как и я, уже изучил документации, ответы сервера и всякое такое. Поэтому не буду рассказывать что будет происходить после каждого чиха.

// 1. Получаем сервер, на который будем слать картинку

$params = [ // для этого потребуется только токен
 'access_token' => $access_token,
];
// Формируем адрес, куда будет стучаться
$url = "https://api.vk.com/method/photos.getWallUploadServer?".http_build_query($params);
// Отправляем запрос и сразу раскодируем ответ из JSON в ассоц. массив
$res = json_decode(file_get_contents($url), true);
// Берём только необходимое - длиннющщую ссылку на сервер
$upload_url = $res['response']['upload_url'];

// 2. Готовим данные для загрузки. В нашем случае это просто файл:
// Важно: 
// - Не надо пихать 'file1' в подмассив 'photo'! Иначе в ответе критически необходимый параметр 'photo' будет пуст. Даже если картинка улетит в ВК, то сохранить её в п.5 мы не сможем.
// - Путь к файлу не должен содержать никакого @ в начале!!!
// И гореть в аду всем, кто до сих пор советует это делать на серверах с PHP7+. Это. Не. Работает.
$postdata['file1'] = curl_file_create('/полный/путь/к/файлу.jpg', 'image/jpeg', 'beliberda.jpg');

// 3. Готовимся к отправке пикчи

// Инициализация и настройка курлы
$ch = curl_init();
curl_setopt_array($ch, [
 CURLOPT_POSTFIELDS => $postdata, // вот это...
 CURLOPT_URL => $upload_url, // ...мы будем слать сюда...
 CURLOPT_POST => 1, // ...методом POST...
 CURLOPT_RETURNTRANSFER => 1, // ...и получим ответ с того конца
]);

// 4. Отправляем запрос и сразу раскодируем ответ из JSON в ассоц. массив
$curl_result = json_decode(curl_exec($ch));
// это можно использовать для отладки:
// $curl_err = curl_errno($ch); 
// $curl_errmsg  = curl_error($ch);
curl_close($ch); // закрываем соединение

// 5. Сохранение загруженной фотки у пользователя
// Просто возвращаем всё, что получили в п.4 обратно, но уже в метод saveWallPhoto
$params = [
 'access_token' => $access_token,
 'server' => $curl_result->server,
 'photo' => $curl_result->photo,
 'hash' => $curl_result->hash,
];
$url = "https://api.vk.com/method/photos.saveWallPhoto?".http_build_query($params);
$result_saved_photo = json_decode(file_get_contents($url), true)['response']['0'];

В поле id будет то, что уже можно использовать в публикации записи на стене в поле attachments.

2 комментария

  1. Уважаемый автор статьи. Как мне с тобой связаться? Это жизненно необходимо. Прошу дать обратный ответ.

    1. Сорян, если поздно, комменты смотрю редко. Проблему можно описать и здесь. Если мы сможем сообща что-то решить, то это будет полезно другим. Но раз вы меня зовёте именно под этим постом, то вряд-ли я смогу чем-то помочь по сабжу.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *