Ответы пользователя по тегу PHP
  • Как проверить, что данные не подделаны (API ВКонтакте)?

    neluzhin
    @neluzhin
    Это называется "цифровая подпись". Это когда вы можете быть уверены, что переданные вам данные являются подлинными. Вы знакомы с односторонним шифрованием, типа MD5, SHA1, SHA256 и т.п.? Это процесс, когда вы шифруете данные так, что их невозможно будет расшифровать. Единственное, что можно делать с зашифрованными данными - это проводить сверку. Допустим, когда вы качаете файл с торрент-треккера, там указывают хэш-сумму файла. Когда вы скачиваете файл, вам по хорошему стоит проверить, совпадает ли хэш на треккере с хэшем закаченного вами файла. Если не совпадает, значит, файл повредился в процессе закачки, короче он не соответствует оригиналу. Вот примерно аналогично работают цифровые подписи во ВКонтакте, платежных системах и во многих других сервисах.

    Прежде, чем отдать вам "параметры запуска" (ID пользователя, ID группы, откуда запустили, и т.п.), ВКонтакте считает цифровую подпись, подмешивая в неё секретный ключ приложения. Не зная секретного ключа приложения, никто не сможет сгенерировать валидную цифровую подпись. ВКонтакте в приведенном вами примере кода показывает, каким образом они генерируют у себя цифровую подпись, чтобы вы поняли как это вообще работает. Вы должны по этому же алгоритму сгенерировать подпись на сервере и при запуске приложения проверять, соответствует ли сгенерированная вами подпись той, что отдает вам ВКонтакте. Если соответствует, значит, пользователь не подделывал параметры запуска. Если не соответствует, значит, можно закрыть доступ к некоторым функциям вашего приложения или отбросить какую-нибудь HTTP-ошибку, например, 400 или 401.
    Ответ написан
    Комментировать
  • VK API Не отправляет кириллицу?

    neluzhin
    @neluzhin
    У вас, наверное, PHP-файл в кордировке отличной от UTF-8.

    Также используйте более современные инструменты, например, cURL:

    <?php
    
    function send($id, $message) {
    	$ch = curl_init();
    	$parameters = http_build_query([
    		'user_id'      => $id,
    		'message'      => $message,
    		'access_token' => 'fa0mfbc2b13c3104f48fd2g75e0a770b34119c89f0e16f75e1502f03e9346413c10b8ad428737496f5602',
    		'v'            => '5.59'
    	]);
    
    	curl_setopt($ch, CURLOPT_URL, 'https://api.vk.com/method/messages.send');
    	curl_setopt($ch, CURLOPT_POST, TRUE);
    	curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    	curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
    	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    	curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    
    	// Результат запроса к API
    	$result = curl_exec($ch);
    
    	curl_close($ch);
    }
    Ответ написан
  • VK api, не загружается фото на сервер?

    neluzhin
    @neluzhin
    Вы зачем-то передаете во ВК закодированный адрес изображения. Но должны вы передавать сам файл. Вы должны загрузить изображение на сервер, а затем переписать строчку

    curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => $image_url));

    так, если у вас PHP меньше 5.5:

    curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => '@path/to/image.jpg'));

    или если PHP больше или равен 5.5:

    curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => new CURLFile('path/to/image.jpg')));

    Эту строку можно удалить:

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data; charset=UTF-8'));

    Также используйте для обращения к API домен api.vk.com и не забывайте в своих запросах передавать версию API в параметре v.

    UPD: также, как подметили ранее, для загрузки фотографий на стену вы должны передавать фотографии в поле photo, а не file{...}.
    Ответ написан
    9 комментариев
  • Как оставить запись на стене группы Вконтакте от лица авторизованного пользователя средствами API VK?

    neluzhin
    @neluzhin
    Честно говоря, я не очень понял сути вопроса, поэтому пройдусь сразу по всем возможным пунктам.

    К сожалению в StandAlone можно через АПИ отправлять записи только от имени владельца приложения.

    Через standalone-приложения можно отправлять записи от имени любого пользователя, который авторизовался через ваше приложение.

    Таким образом пытался отправить сообщение (в итоге надо запись на стену, но смысл не меняется)

    Пользоваться методами messages.* можно только через standalone-приложения. Для веб-сайтов и iFrame-приложений постинг через метод wall.post доступен только через окно подтверждения, а для standalone-приложений - без каких-либо проблем.

    Ловлю ошибку:
    [error_code] => 15
    [error_msg] => Access denied: no access to call this method .

    Вы забываете передать параметр scope при получении токена. Смотрите подробнее о правах доступа вот тут.

    И еще: вы не сможете работать с сообщениями пользователя, если вы работаете с пользователем через веб-сайт. Данные методы поддерживаются только standalone-приложениями, которые необходимо использовать в десктопных и мобильных приложениях или в браузерных расширениях. Авторизовать пользователя в standalone-приложении через браузер получится, а вот токен вы получить ни через PHP, ни через JavaScript не сможете, если только не попросите пользователя скопировать токен вручную, что противоречит основам UX, т.к. на странице получения токена написано, чтобы пользователь его не копировал, ибо не безопасно.
    Ответ написан
  • Как отправить запрос с клиента, а не с сервера для API в вконтакте?

    neluzhin
    @neluzhin
    По сабжу о работе с API со стороны клиента:
    • Если вы имеете собственный сайт, то вам нужно Open API.
    • Если вы создаете iFrame-приложение (приложение внутри ВКонтакте), то тогда вам нужен JavaScript SDK.

    Также я не понимаю, что у вас за проблемы с работой с API через PHP. Вы уверены, что передаете правильный ID записи в метод? ID должен иметь формат 12345_5432, где 12345 - это ID профиля, а 5432 - ID записи. Если записи необходимо получить из группы, то ID группы указывается отрицательный, например -76421_5432.
    Ответ написан
    Комментировать
  • Как добавить видео с помощью API VK?

    neluzhin
    @neluzhin
    Загружать видео можно только в том случае, если все запросы к VK API осуществляются с сервера. В документации написано, как загружать видео, но я расскажу поподробнее. Ход действий примерно такой:

    1. Загрузите видео на свой сервер.
    2. Вызовите метод video.save. Указывать какие-либо параметры не обязательно, но можете указать, например, ID группы, в которую будет добавлено видео, в параметре group_id и имя видеозаписи в параметре name.
    3. После того, как вы вызовете метод video.save, вы получите ссылку, куда надо будет загрузить вашу видеозапись. Выглядеть ответ от ВК будет примерно так:

      response: {
        upload_url: 'http://cs12129.vkontakte.ru/upload_video.php?act=add_video&mid=15748&oid=66748&vid=164322743&fid=0&tag=122517f2&hash=8bf2ea4bb66ca67d28fb&swfupload=1',
        vid: 164322743,
        owner_id: 66321,
        name: 'No name',
        description: '',
        access_key: 'e6822bfb86f90a149c'
      }

      По этому адресу методом POST отправьте видеозапись в поле video_file.

    4. В ответ на загрузку видеозаписи ВК вернёт вам ID видеозаписи:

      {
        "size":1234,
        "video_id":1234567
      }


    Это всё. Видеозапись должна будет появиться в указанном вами сообществе.

    Небольшой пример на PHP:

    <?php
    
    define('VK_ACCESS_TOKEN', '533bacf01e11f55b536a565b57531ac114461ae8736d6506a3');
    define('VK_API_VERSION', 5.53);
    
    // // //
    // Скачиваем видео с внешнего сервера на свой сервер
    // // //
    
    $ch = curl_init();
    				
    curl_setopt($ch, CURLOPT_URL, 'http://cache-spb07.cdn.yandex.net/kp.cdn.yandex.net/558075/kinopoisk.ru-L_odyss__233_e-311292.mp4');
    curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
    
    $curl_result = curl_exec($ch);
    
    curl_close($ch);
    
    // Кладем видео в папку со скриптом
    $fp = fopen('kinopoisk.ru-L_odyss__233_e-311292.mp4', 'x');
    fwrite($fp, $curl_result);
    fclose($fp);
    
    // // //
    // Получаем адрес ссылки, куда загружать видео
    // // //
    
    $ch = curl_init();
    $parameters = http_build_query([
        'access_token' => VK_ACCESS_TOKEN, // access_token / ключ доступа
        'v'            => VK_API_VERSION, // версия API
        'name'         => 'Имя видеозаписи',
        'description'  => 'Исчерпывающее описание нашей первой видеозаписи.',
        'group_id'     => 125004421, // ID группы
        'no_comments'  => 0 // разрешаем комментирование
    ]);
    
    curl_setopt($ch, CURLOPT_URL, 'https://api.vk.com/method/video.save?' . $parameters);
    curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    
    $curl_result = json_decode(curl_exec($ch), TRUE); // превращаем JSON-массив, который нам вернул VK, в обычный PHP-массив
    
    curl_close($ch);
    
    // // //
    // Загружаем видео на серверы ВК
    // // //
    
    $ch = curl_init();
    $parameters = [
        'video_file' => new CURLFile('kinopoisk.ru-L_odyss__233_e-311292.mp4')  // PHP >= 5.5.0
        // 'video_file' => '@kinopoisk.ru-L_odyss__233_e-311292.mp4' // PHP < 5.5.0
    ];
    
    curl_setopt($ch, CURLOPT_URL, $curl_result['response']['upload_url']);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, TRUE); // если PHP < 5.5.0, то эту строку надо закомментировать
    
    $curl_result = json_decode(curl_exec($ch), TRUE);
    
    curl_close($ch);
    
    if (isset($curl_result['error'])) {
        exit('Строка ' . __LINE__ . ': Ошибка при загрузке видео на серверы ВК: ' . $curl_result['error'] . '.');
    }
    
    echo 'Видеозапись успешно загружена.';

    Кстати, параметр link метода video.save принимает только ссылки на популярные видеохостинги, вроде YouTube. О работе через этот параметр я писал в этом вопросе.
    Ответ написан
    4 комментария
  • Как отправить пост на стену группы Вконтакте с картинкой средствами VK API JavaScript?

    neluzhin
    @neluzhin
    Конкретно через JavaScript загрузить у вас файлы не получится банально потому, что VK API не поддерживает CORS.

    Предположим, что у вас на сайте есть форма, где textarea и input[type=file]. Вы хотите сделать так, чтобы при отправке формы всё это добро постилось во ВКонтакте на стене вашей группы. Шаги будут примерно такие:
    1. После нажатия кнопки "Отправить" с помощью AJAX отправляйте изображение на ваш сервер.
    2. Получив изображение на сервере, согласно инструкции, загрузите его в альбом вашей группы ВК.
    3. После выполнения загрузки изображения ВК вернет вам его ID. Вы должны этот ID вернуть пользователю в ответ на загрузку изобржения, описанную в первом шаге.
    4. Приложите ID изображения как вложение к публикуемой записи. Пример кода:

      VK.api('wall.post', {
      	owner_id: '-GROUP_ID',
      	message: send_data,
      	attachments: 'photo' + photo_id // photo_id - это ID изображения
      }, function(data) {
      	if (data.response) alert('Успешно опубликовано в группе!');
      });


    Но если вы делаете какое-то подобие веб-админки для ваших сообществ, то я бы задумался о полном переезде на standalone-приложение, где все методы выполняются на стороне сервера.
    Ответ написан
    Комментировать
  • Регулярка. Как определить наличие определенного фрагмента внутри [] и заменить его?

    neluzhin
    @neluzhin
    Предыдущий ответ, где вам порекомендовали регулярку, похожую на сиськи, от части верный, но только от части. Проблема в том, что в квадратных скобках может быть и не ссылка на группу, паблик, мероприятие или человека. Например, [x|test] в социальной сети не преобразуется в гиперссылку и отобразится плейн текстом, а вы создадите гиперссылку, ведующую на 404-ю страницу.

    Вы должны обрабатывать только гиперссылки, начинающиеся с club или id, и заканчивающиеся числом. В любом другом формате ВКонтакте гиперссылки не хранит. Правильное регулярное выражение выглядит примерно так:

    /\[((?:club|id)[0-9]+)\|(.+)\]/

    И вставить это добро можно так:

    <a href="//vk.com/$1">$2</a>

    Ну и наглядный пример на PHP для самых маленьких:

    $comment = preg_replace('/\[((?:club|id)[0-9]+)\|(.+)\]/', '<a href="//vk.com/$1">$2</a>', $comment);

    Следует отметить, что публичные страницы (паблики) и мероприятия (ивенты) в виде гиперссылок также имеют приставку club, а не public и event.
    Ответ написан
    Комментировать
  • Почему не загружается фото на сервер Вконтакте?

    neluzhin
    @neluzhin
    Перед именем файла вы потеряли собачку. То есть у вас должно быть что-то вроде такого:
    $post_params['file'.$i] = '@myscreenshot.png';

    Для пущей наглядности кусок моего кода:
    $ch = curl_init();
    $parameters = array(
    	"file1" => '@'.__DIR__.'/path/to/myscreenshot.png'
    );
    		
    curl_setopt($ch, CURLOPT_URL, $upl_server);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    
    $curl_result = curl_exec($ch);
    curl_close($ch);
    Ответ написан
    Комментировать
  • Как выглядит аналог curl для JS чтобы отправить запрос серверу?

    neluzhin
    @neluzhin
    Если вы про браузерный JavaScript, то CORS не даст вам этого сделать с VK API своими средствами. Для работы с VK API через браузер надо использовать Open API.
    Ответ написан
    3 комментария