• Почему не получается скачать файл по этой ссылке средствами PHP (403 ошибка)? Как исправить код, чтобы он работал?

    Потому что при скачивании, в запросе передаётся много токенов в куках. Сделано это специально чтобы люди не выкачивали файлы автоматически. Чтобы обойти защиту надо разобрать формирование каждого токена, либо основного.
    Ответ написан
    Комментировать
  • Как сформировать компактный код загрузки аватарки?

    Как проще всего это реализовать:
    1. поставь лимит на файл в 100-200Кб
    2. проверь что загружаемый файл является картинкой например пережми с помощью GD2 или Imagick
    3. содержимое файла перекодируй в base64
    4. сохрани base64 в базу

    Для аватарок это более чем достаточно.
    Ответ написан
    Комментировать
  • Проблема в с php, что делать?

    Вероятно в скрипте есть утечка памяти и чтобы скрипт заработал корректно, надо убрать эту ошибку.
    Ответ написан
    Комментировать
  • Как выполнить execute VK API PHP?

    Например так:
    class DevClass {
    	public $group_id = 30666517;
    	public $membersGroups = array();
    	public $access_token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    	public function devMethod(){
    		$opts = ["group_id"=>$this->group_id, "access_token"=>$this->access_token, "fields"=>"photo_50,members_count", "v"=>"5.80"];
    		$answer = $this->vk->getMethod("groups.getById", $opts, true);
    		//$members_count = $answer->response[0]->members_count;
    		$members_count = 45000;
    		$members_groups = 0;	//изначально в массиве 0 объектов
    		//выполняем цикл пока полученное кол-во участников меньше общего кол-ва участников в группе
    		while($members_count > $members_groups){
    			usleep(300000);	//задержка на 0.3 сек.
    			$answer = $this->getMembers25k($this->group_id, $members_count);
    			if($answer->response){
    				$new = explode(",",$answer->response);
    				$this->membersGroups = array_merge($this->membersGroups, $new);
    				//второй раз определяем переменную, уже с новым массивом данных
    				$members_groups = count($this->membersGroups);
    			}
    			else{
    				echo "NO RESPONSE";
                    print_r($answer);
    				die();
    			}
    		}
    		print_r($this->membersGroups);
    		die();
    	}
    
    	public function getMembers25k($group_id, $members_count) {
    		$members_groups = count($this->membersGroups);
    		$offset = 1000;
    		$code =  'var members = API.groups.getMembers({"group_id": '.$this->group_id.', "v": "5.80", "sort": "id_asc", "count": '.$offset.', "offset": '.$members_groups.'}).items;'
    			.'var offset = '.$offset.';'
    			.'while (offset < 25000 && (offset + '.$members_groups.') < '.$members_count.')'
    			.'{members = members + "," + API.groups.getMembers({"group_id": '.$this->group_id.', "v": "5.80", "sort": "id_asc", "count": '.$offset.', "offset": ('.$members_groups.' + offset)}).items;offset = offset + '.$offset.';};'
    			.'return members;';
    
    		$answer = $this->vk->getMethod("execute", ["code" => urlencode($code), "v"=>"5.80", "access_token" => $this->access_token], true);
            return $answer;
    	}
    }
    
    $dev = new DevClass();
    $dev->devMethod();

    но надо понимать что тут у меня уже сформирован access_token другим классом как и запросы к методам ($this->vk->getMethod), я лишь хотел показать логику.
    Ответ написан
    2 комментария
  • Как лучше вытащить access_token в VK?

    > Как выдернуть access_token и закрыть окно что бы человек не заморачивался с ручным копированием access_token ?
    > Может быть есть другие способы его получения?
    Я сделал возможность автоматического копирования токена.
    Суть в том что вы собираете заголовки всех 3 запросов:
    1. запрос где указан cliend_id, scope и redirect_uri, возвращает Location на второй запрос
    2. второй запрос вернет Location на redirect_uri, вот в нем и будет наш access_token.
    3. Заголовок к вашему redirect_uri.
    Дальше обычной регуляркой вытаскиваете Location из третьего запроса. Примерно это выглядит вот так:

    <?
    class VKClass {
    	protected $email = "TELEPHONE";
    	protected $pass = "PASSWORD";
    	protected $auth_url = "https://m.vk.com";
    	protected $cookie = "cookie.txt";
    	protected $client_id = "XXXXXXX";
    	protected $redir_url = "http://goto.ru/token";
    
    	public function __construct() {
    		//вызываем метод для загрузки необходимых объектов
    		if(empty($_SESSION["loggedIn"]))
    			$this->logIn();
    
    		if(empty($_SESSION["access_token"]))
    			$this->getAccessToken();
    	}
    
    	public function prependCurl($options){
    		$ch = curl_init();
    		curl_setopt($ch, CURLOPT_URL, $options["url"]);
    		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $options["flocation"]);
    		curl_setopt($ch, CURLOPT_POST, $options["post"]);
    		curl_setopt($ch, CURLOPT_HEADER, $options["header"]);
    		if($options["post"])
    			curl_setopt($ch, CURLOPT_POSTFIELDS, $options["postdata"]);
    		if($options["cookie_w"])
    			curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER["DOCUMENT_ROOT"].$this->cookie);
    		if($options["cookie_r"])
    			curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER["DOCUMENT_ROOT"].$this->cookie);
    		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    		$data = curl_exec($ch);
    		curl_close($ch);
            return $data;
    	}
    
    	public function logIn(){
    		$options = ["url" => $this->auth_url, "flocation" => 0, "post" => 0, "header" => 0, "cookie_w" => 1, "cookie_r" => 0];
    		$login_page = $this->prependCurl($options);
    		unset($options);
                    //функция str_get_html используется из бибилиотеки Simple HTML DOM Parser
    		$html = str_get_html($login_page);
    		$login_url = @$html->find("form",0)->action;
    
    		$options = ["url" => $login_url, "flocation" => 1, "post" => 1, "header" => 0, "postdata" => ["email" => $this->email, "pass" => $this->pass], "cookie_w" => 1, "cookie_r" => 1];
    		$this->prependCurl($options);
    
    		$_SESSION["loggedIn"] = $this->loggedIn= true;
    	}
    
    	public function getLocations($url){
    		$options = ["url" => $url, "flocation" => 1, "post" => 0, "header" => 1, "cookie_w" => 1, "cookie_r" => 1];
    		$data = $this->prependCurl($options);
    		return $data;
    	}
    
    	public function getAccessToken(){
    		//по ссылке возвращается access_token. собираем все заголовки запросов
    		$url = "https://oauth.vk.com/authorize?client_id=".$this->client_id."&redirect_uri=".$this->redir_url."?display=page&response_type=token";
    		$headers = $this->getLocations($url);
    		//разбиваем на кол-во запросов
    		$hdrs = explode("\r\n\r\n", $headers);
    		//т.к. у нас 2 редиректа (с oauth.vk.com на login.vk.com и с login.vk.com на домен), то нам нужен второй запрос ($hdrs[1]), где соджержится access_token
    		preg_match("/Location: (.*)/m", $hdrs[1], $matches);
    		//вырезаем наш access_token из ссылки что нам прислал вк сервер
    		@preg_match("/#access_token=(.*?)&/", $matches[1], $token);
    		//объявляем access_token в сессии и в классе
    		@$_SESSION["access_token"] = $this->access_token = $token[1];
    	}
    }

    Да, забыл что это на PHP версии.
    В JS я получал его обычным windlow.location.hash, проблема была получить его именно в PHP т.к. хэш (#) в пхп не передается.
    p.s. через некоторое время ВК стал отдавать ошибку Security Error, пришлось создать новое приложение и с ним всё работает без проблем.
    Ответ написан
    Комментировать