В чем может быть проблема при подключении к API через PHP?
Коллеги, подскажите, пожалуйста, в чем может быть проблема при подключении к API через PHP?
Пытаюсь пройти авторизацию, но ничего не получается.
Проект использует B2B Motion. У них есть краткая инструкция на сайте:
https://future.hogart.ru/gotovye-reshenija/API.php
Полная документация здесь:
https://b2bmotion.docs.apiary.io/
Прочитал - все просто, вроде, но не удается ничего вразумительного получить:
$data = array( 'phone' => '*******', 'password' => '********', ); $options = array( 'http' => array( 'method' => 'GET', 'content' => json_encode( $data ), 'header'=> "Content-Type: application/jsonrn" . "Accept: application/jsonrn" ) ); $context = stream_context_create( $options ); $result = file_get_contents( $url, false, $context ); echo "<pre>"; print_r($result); echo "</pre>"; |
$data = array( 'phone' => '*******', 'password' => '********', ); $options = array( 'http' => array( 'method' => 'GET', 'content' => json_encode( $data ), 'header'=> "Content-Type: application/jsonrn" . "Accept: application/jsonrn" ) ); $context = stream_context_create( $options ); $result = file_get_contents( $url, false, $context ); echo "<pre>"; print_r($result); echo "</pre>";
Дополнительно:
Ответы:
Во-первых, надо забыть про функцию print_r.
Если вы хотите увидеть хоть какой-то вразумительный результат, то надо использовать var_dump.
Во-вторых, надо включить режим отображения ошибок (либо смотреть их в логе).
Судя по всему, file_get_contents возвращает false, а это происходит в случае ошибки.
file_get_contents по умолчанию выплевывает обычный Warning. И если вы его не видите, это значит, что вы не видите вообще никакие ошибки РНР. И как можно вообще заниматься разработкой в таком случае - загадка.
Для отладки полезно вывести содержимое специальной переменной, которая содержит заголовки ответа, var_dump($http_response_header);
Ну и на всякий случай, надо конкретнее описывать свои проблемы. Что означают ваши "ничего не работает" и "не удается получить" никто не знает. Надо четко писать, что вы видите.
- print_r просто удобен, когда смотришь содержание массивов, использовал его по привычке) var_dump тоже смотрел, выдавал false булевого типа. По сути, ничего же?
Да, еще пробовал через POST отправлять запрос (как и надо, судя по документации) - тот же результат.
Еще пробовал от безысходности curl, он почему-то выкидывает 301 Moved Permanently nginx/1.14.2. Но ведь при переходе на страницу через браузер ответ выдается... Значит, проблема в коде, так?
Вывод ошибок включен, так как если какие-либо ошибки в коде php есть, то он тут же выдает об этом.
- false - это НЕ НИЧЕГО. Это конкретный ответ. Результат работы вашего кода. Чтобы не скулить потом, что "ничего конкретного".
Что делать, если "curl почему-то выкидывает 301 Moved Permanently", можно найти за две секунды в интернетеПлюс я добавил в ответ еще одну рекомендацию по отладке НТТР запросов через file_get_contents
- Но в целом, если посмотреть код повнимательнее, то очень смущает вот эта строчка,
'content' => json_encode( $data ),ОБЫЧНО у гет запросов не бывает тела.
- po4emu4ka2020, некоторые функции могут вернуть false и null и это не просто "ничего", а два РАЗНЫХ ответа. А еще с сервера может вернуться пустая строка, и это совершенно нормально, если вы читаете пустой файл, например.
И через print_r это все будет выглядеть одинаково. - Ипатьев, сейчас выводит NULL. var_dump($http_response_header); тоже пишет NULL.
С curl удалось достигнуть такого же результата. Ошибки Moved Permanently nginx/1.14.2. теперь нет (УРА!).
А почему в ответе NULL? Можно ли как-то узнать, что запрос дошел?
- Ипатьев, да, там должен быть POST.
- Stalker_RED, да, вы правы, теперь выводит NULL. Но только куда теперь копать?
Почему не выводятся ошибки, которые я вижу, когда перехожу по адресу через браузер?Или то, что по адресу страницы выводит в браузере, это и есть тот NULL, который я получаю в ответе?
{"name":"Not Found","message":"Страница не найдена.","code":0,"status":404} - file_get_contents не может вернуть null.
Вы можете скопировать сюда вывод var_dump($result);? - po4emu4ka2020, ещё раз: Moved permanently это НЕ ОШИБКА.
Разработчики сайта куда-то переместили страницу, и сообщают вам, что новый адрес такой-то.
Браузер автоматически переходит на новый адрес. Для curl можно указать опцию, чтобы тоже автоматически переходил.
Ну или поправьте адрес который запрашивает, чтобы сразу делать запрос по правильному адресу. - po4emu4ka2020, статус 404 - значит по этому адресу нет страницы.
- Ипатьев, получилось, использовал просто другой код для curl
function geturl($url,$data){ (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini'); $cookie = tempnam ("/tmp", "CURLCOOKIE"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; CrawlBot/1.0.0)'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , 5); curl_setopt($ch, CURLOPT_TIMEOUT, 5); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_ENCODING, ""); curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); # required for https urls curl_setopt($ch, CURLOPT_MAXREDIRS, 15); $html = curl_exec($ch); $status = curl_getinfo($ch); curl_close($ch); if($status['http_code']!=200){ if($status['http_code'] == 301 || $status['http_code'] == 302) { list($header) = explode("rnrn", $html, 2); $matches = array(); preg_match("/(Location:|URI:)[^(n)]*/", $header, $matches); $url = trim(str_replace($matches[1],"",$matches[0])); $url_parsed = parse_url($url); return (isset($url_parsed))? geturl($url,$data):''; } } return $html; }
function geturl($url,$data){ (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini'); $cookie = tempnam ("/tmp", "CURLCOOKIE"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; CrawlBot/1.0.0)'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , 5); curl_setopt($ch, CURLOPT_TIMEOUT, 5); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_ENCODING, ""); curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); # required for https urls curl_setopt($ch, CURLOPT_MAXREDIRS, 15); $html = curl_exec($ch); $status = curl_getinfo($ch); curl_close($ch); if($status['http_code']!=200){ if($status['http_code'] == 301 || $status['http_code'] == 302) { list($header) = explode("rnrn", $html, 2); $matches = array(); preg_match("/(Location:|URI:)[^(n)]*/", $header, $matches); $url = trim(str_replace($matches[1],"",$matches[0])); $url_parsed = parse_url($url); return (isset($url_parsed))? geturl($url,$data):''; } } return $html; }
- А лучше покажите, что у вас выводит вот этот код
$r = file_get_contents("https://b2b.hogart.ru/api/v1/product-scroll");
var_dump($r, $http_response_header); - ну то есть вместо одного говнокода, который вы не понимаете, взяли другой говнокод, в котором тоже не поняли ни строчки
ну тоже вариант
такие нынче программисты
пишут программу с помощью двух инструментов: поискать код в интернете или написать на форум чтобы его исправили - Ипатьев, я не знаю трех параметров curl, которые используются в функции, однако с get_contents все понятно было. Спасибо на добром слове и за помощь в решении проблемы. Но кусок с парсингом ответа и параметром вывода ответа в строку очень пригодился, так как стало понятно, что надо просто поставить https вместо http в адрес) Если бы не "говнокод", то проблема так бы и осталась проблемой.
получилось, использовал просто другой код для curl
function geturl($url,$data){ (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); $html = curl_exec($ch); $status = curl_getinfo($ch); curl_close($ch); if($status['http_code']!=200){ if($status['http_code'] == 301 || $status['http_code'] == 302) { list($header) = explode("rnrn", $html, 2); $matches = array(); preg_match("/(Location:|URI:)[^(n)]*/", $header, $matches); $url = trim(str_replace($matches[1],"",$matches[0])); $url_parsed = parse_url($url); return (isset($url_parsed))? geturl($url,$data):''; } } return $html; } |
function geturl($url,$data){ (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); $html = curl_exec($ch); $status = curl_getinfo($ch); curl_close($ch); if($status['http_code']!=200){ if($status['http_code'] == 301 || $status['http_code'] == 302) { list($header) = explode("rnrn", $html, 2); $matches = array(); preg_match("/(Location:|URI:)[^(n)]*/", $header, $matches); $url = trim(str_replace($matches[1],"",$matches[0])); $url_parsed = parse_url($url); return (isset($url_parsed))? geturl($url,$data):''; } } return $html; }
Подключите себе в проект guzzle и начните жить, а не пилить очередной велосипед
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
При подключении к API через PHP могут возникать различные проблемы, которые могут быть связаны как с самим API, так и с настройками сервера, на котором запускается скрипт.
Одной из распространенных проблем может быть неправильно указанный URL API. Неверный адрес API может привести к тому, что запросы не будут отправляться на нужный ресурс, а, следовательно, не будет получен ожидаемый результат.
Еще одной частой проблемой является неправильно сформированный запрос к API. Некорректные параметры запроса, отсутствие необходимых заголовков или неправильный формат данных могут привести к ошибкам при обращении к API.
Также следует обратить внимание на наличие необходимых библиотек и расширений PHP для работы с API. Некоторые API могут требовать определенные расширения, которые нужно установить на сервере.
Еще одной причиной проблемы может быть ограничение доступа к API. Некоторые API требуют авторизацию или выдачу ключа доступа для обращения к ним. Если ключ доступа не был получен или использован неправильно, запросы к API могут завершаться ошибкой.
Также стоит учитывать возможные проблемы сети или сервера, на котором запущен скрипт. Нестабильное интернет-соединение или проблемы с конфигурацией сервера могут привести к тому, что запросы к API не будут выполняться корректно.
В целом, для успешного подключения к API через PHP необходимо внимательно проверить все аспекты запроса, убедиться в правильности указания URL, корректности параметров запроса, наличии необходимых библиотек и расширений, а также в правильной настройке авторизации и ключей доступа. При возникновении проблем стоит также обратить внимание на возможные ошибки в логах сервера или ответы от API, чтобы понять причину ошибки и найти ее решение.