Как отправить запрос POST с помощью PHP?
На самом деле я хочу прочитать содержимое, которое идет после поискового запроса, когда это будет сделано. Проблема в том, что URL принимает только POST
методы, и он не предпринимает никаких действий с GET
метод...
Я должен прочитать все содержимое с помощью domdocument
или же file_get_contents()
, Есть ли способ, который позволит мне отправить параметры с POST
метод, а затем прочитать содержимое с помощью PHP
?
19 ответов
CURL-менее метод с PHP5:
$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }
var_dump($result);
См. Руководство по PHP для получения дополнительной информации о методе и о том, как добавить заголовки, например:
- stream_context_create: http://php.net/manual/en/function.stream-context-create.php
Вы можете использовать cURL:
<?php
//The url you wish to send the POST request to
$url = $file_name;
//The data you want to send via POST
$fields = [
'__VIEWSTATE ' => $state,
'__EVENTVALIDATION' => $valid,
'btnSubmit' => 'Submit'
];
//url-ify the data for the POST
$fields_string = http_build_query($fields);
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
echo $result;
?>
Я использую следующую функцию для публикации данных с помощью curl. $data - это массив полей для публикации (будет правильно закодирован с использованием http_build_query). Данные кодируются с использованием application/x-www-form-urlencoded.
function httpPost($url, $data)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
@Edward упоминает, что http_build_query может быть опущен, так как curl будет правильно кодировать массив, переданный параметру CURLOPT_POSTFIELDS, но имейте в виду, что в этом случае данные будут кодироваться с использованием multipart/form-data.
Я использую эту функцию с API, которые ожидают, что данные будут закодированы с помощью application/x-www-form-urlencoded. Вот почему я использую http_build_query().
Я рекомендую вам использовать пакетную утилиту с открытым исходным кодом, которая полностью протестирована модульно и использует новейшие методы кодирования.
Установка жрет
Перейдите в командную строку в папке вашего проекта и введите следующую команду (при условии, что у вас уже установлен компоновщик менеджера пакетов). Если вам нужна помощь в установке Composer, вы должны посмотреть здесь.
php composer.phar require guzzlehttp/guzzle
Использование Guzzle для отправки запроса POST
Использование Guzzle очень прямолинейно, поскольку он использует легкий объектно-ориентированный API:
// Initialize Guzzle client
$client = new GuzzleHttp\Client();
// Create a POST request
$response = $client->request(
'POST',
'http://example.org/',
[
'form_params' => [
'key1' => 'value1',
'key2' => 'value2'
]
]
);
// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();
// Output headers and body for debugging purposes
var_dump($headers, $body);
Я хотел бы добавить некоторые мысли об основанном на завитках ответе Фреда Танрикута. Я знаю, что большинство из них уже написаны в ответах выше, но я думаю, что это хорошая идея, чтобы показать ответ, который включает в себя все из них вместе.
Вот класс, который я написал для выполнения запросов HTTP-GET/POST/PUT/DELETE на основе curl, касающихся только тела ответа:
class HTTPRequester {
/**
* @description Make HTTP-GET call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPGet($url, array $params) {
$query = http_build_query($params);
$ch = curl_init($url.'?'.$query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
/**
* @description Make HTTP-POST call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPPost($url, array $params) {
$query = http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
/**
* @description Make HTTP-PUT call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPPut($url, array $params) {
$query = \http_build_query($params);
$ch = \curl_init();
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_HEADER, false);
\curl_setopt($ch, \CURLOPT_URL, $url);
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
$response = \curl_exec($ch);
\curl_close($ch);
return $response;
}
/**
* @category Make HTTP-DELETE call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPDelete($url, array $params) {
$query = \http_build_query($params);
$ch = \curl_init();
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_HEADER, false);
\curl_setopt($ch, \CURLOPT_URL, $url);
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
$response = \curl_exec($ch);
\curl_close($ch);
return $response;
}
}
улучшения
- Использование http_build_query для получения строки запроса из массива запроса (вы также можете использовать сам массив, поэтому смотрите: http://php.net/manual/en/function.curl-setopt.php)
- Возвращать ответ, а не повторять его. Кстати, вы можете избежать возврата, удалив строку curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);, После этого возвращаемое значение является логическим (истина = запрос был успешным, в противном случае произошла ошибка), и ответ отображается. Смотрите: http://php.net/en/manual/function.curl-exec.php
- Очистите закрытие сессии и удаление обработчика curl с помощью curl_close. Смотрите: http://php.net/manual/en/function.curl-close.php
- Использование логических значений для функции curl_setopt вместо использования любого числа (я знаю, что любое число, отличное от нуля, также считается истинным, но использование true создает более читаемый код, но это только мое мнение)
- Возможность совершать вызовы HTTP-PUT/DELETE (полезно для тестирования сервиса RESTful)
Пример использования
ПОЛУЧИТЬ
$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));
СООБЩЕНИЕ
$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));
ПОЛОЖИЛ
$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));
УДАЛЯТЬ
$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));
тестирование
Вы также можете сделать несколько крутых тестов сервиса с помощью этого простого класса.
class HTTPRequesterCase extends TestCase {
/**
* @description test static method HTTPGet
*/
public function testHTTPGet() {
$requestArr = array("getLicenses" => 1);
$url = "http://localhost/project/req/licenseService.php";
$this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
}
/**
* @description test static method HTTPPost
*/
public function testHTTPPost() {
$requestArr = array("addPerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
}
/**
* @description test static method HTTPPut
*/
public function testHTTPPut() {
$requestArr = array("updatePerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
}
/**
* @description test static method HTTPDelete
*/
public function testHTTPDelete() {
$requestArr = array("deletePerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
}
}
Если вы случайно используете Wordpress для разработки своего приложения (на самом деле это удобный способ получить авторизацию, информационные страницы и т. Д. Даже для очень простых вещей), вы можете использовать следующий фрагмент:
$response = wp_remote_post( $url, array('body' => $parameters));
if ( is_wp_error( $response ) ) {
// $response->get_error_message()
} else {
// $response['body']
}
Он использует различные способы создания фактического HTTP-запроса, в зависимости от того, что доступно на веб-сервере. Для получения дополнительной информации см. Документацию HTTP API.
Если вы не хотите разрабатывать собственную тему или плагин для запуска движка Wordpress, вы можете просто сделать следующее в изолированном файле PHP в корне Wordpress:
require_once( dirname(__FILE__) . '/wp-load.php' );
// ... your code
Он не отображает темы и не выводит HTML, просто взломайте API Wordpress!
Есть другой метод CURL, если вы идете по этому пути.
Это довольно просто, когда вы поймете, как работает расширение PHP curl, сочетая различные флаги с вызовами setopt(). В этом примере у меня есть переменная $ xml, которая содержит XML, который я подготовила для отправки - я собираюсь опубликовать содержимое этого метода тестирования в примере.
$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
//process $response
Сначала мы инициализировали соединение, затем мы установили некоторые параметры с помощью setopt(). Они говорят PHP, что мы делаем пост-запрос, и что мы отправляем с ним некоторые данные, предоставляя данные. Флаг CURLOPT_RETURNTRANSFER сообщает curl, чтобы он выдавал нам выходные данные в качестве возвращаемого значения curl_exec, а не выводил его. Затем мы делаем вызов и закрываем соединение - результат в $response.
Другая альтернатива описанного выше метода curlless - использовать встроенные функции потока:
stream_context_create()
:Создает и возвращает контекст потока с любыми параметрами, предоставленными в предустановке параметров.
stream_get_contents()
:Идентичны
file_get_contents()
, Кроме этогоstream_get_contents()
работает с уже открытым потоковым ресурсом и возвращает оставшееся содержимое в строке размером до макс. длины и начиная с указанного смещения.
Функция POST с этим может быть просто так:
<?php
function post_request($url, array $params) {
$query_content = http_build_query($params);
$fp = fopen($url, 'r', FALSE, // do not use_include_path
stream_context_create([
'http' => [
'header' => [ // header array does not need '\r\n'
'Content-type: application/x-www-form-urlencoded',
'Content-Length: ' . strlen($query_content)
],
'method' => 'POST',
'content' => $query_content
]
]));
if ($fp === FALSE) {
fclose($fp);
return json_encode(['error' => 'Failed to get contents...']);
}
$result = stream_get_contents($fp); // no maxlength/offset
fclose($fp);
return $result;
}
Здесь используется только одна команда без cURL. Очень просто.
echo file_get_contents('https://www.server.com', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded",
'content' => http_build_query([
'key1' => 'Hello world!', 'key2' => 'second value'
])
]
]));
Лучший способ отправки GET
или же POST
запросы с PHP
как показано ниже:
<?php
$r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
$r->setOptions(array('cookies' => array('lang' => 'de')));
$r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
try {
echo $r->send()->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
Код взят из официальной документации здесь http://php.net/manual/it/httprequest.send.php
Исходя из основного ответа, вот что я использую:
function do_post($url, $params) {
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $params
)
);
$result = file_get_contents($url, false, stream_context_create($options));
}
Пример использования:
do_post('https://www.google-analytics.com/collect', 'v=1&t=pageview&tid=UA-xxxxxxx-xx&cid=abcdef...');
Я искал похожую проблему и нашел лучший подход для этого. Так что вот так.
Вы можете просто поместить следующую строку на странице перенаправления (скажем, page1.php).
header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php
Это нужно для перенаправления запросов POST на вызовы API REST. Это решение может перенаправлять с данными поста, а также с пользовательскими значениями заголовка.
Вот ссылка ссылка.
Есть еще один, который вы можете использовать
<?php
$fields = array(
'name' => 'mike',
'pass' => 'se_ret'
);
$files = array(
array(
'name' => 'uimg',
'type' => 'image/jpeg',
'file' => './profile.jpg',
)
);
$response = http_post_fields("http://www.example.com/", $fields, $files);
?>
Здесь все в порядке с этим кодом:
<?php
$postdata = http_build_query(
array(
'name' => 'Robert',
'id' => '1'
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://localhost:8000/api/test', false, $context);
echo $result;?>
Попробуйте пакет PEAR HTTP_Request2, чтобы легко отправлять POST-запросы. В качестве альтернативы, вы можете использовать функции curl в PHP или использовать потоковый контекст PHP.
HTTP_Request2 также позволяет макетировать сервер, так что вы можете легко тестировать свой код
Я делаю функцию для запроса публикации с использованием JSON:
const FORMAT_CONTENT_LENGTH = 'Content-Length: %d';
const FORMAT_CONTENT_TYPE = 'Content-Type: %s';
const CONTENT_TYPE_JSON = 'application/json';
/**
* @description Make a HTTP-POST JSON call
* @param string $url
* @param array $params
* @return bool|string HTTP-Response body or an empty string if the request fails or is empty
*/
function HTTPJSONPost(string $url, array $params)
{
$content = json_encode($params);
$response = file_get_contents($url, false, // do not use_include_path
stream_context_create([
'http' => [
'method' => 'POST',
'header' => [ // header array does not need '\r\n'
sprintf(FORMAT_CONTENT_TYPE, CONTENT_TYPE_JSON),
sprintf(FORMAT_CONTENT_LENGTH, strlen($content)),
],
'content' => $content
]
])); // no maxlength/offset
if ($response === false) {
return json_encode(['error' => 'Failed to get contents...']);
}
return $response;
}
Я предпочитаю этот:
function curlPost($url, $data = NULL, $headers = []) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout in seconds
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_ENCODING, 'identity');
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ch);
if (curl_error($ch)) {
trigger_error('Curl Error:' . curl_error($ch));
}
curl_close($ch);
return $response;
}
Пример использования:
$response=curlPost("http://my.url.com", ["myField1"=>"myValue1"], ["myFitstHeaderName"=>"myFirstHeaderValue"]);
Лучшие ответы не сработали для меня. Это было первое решение, которое работало отлично:
$sPD = "name=Jacob&bench=150"; // The POST Data
$aHTTP = array(
'http' => // The wrapper to be used
array(
'method' => 'POST', // Request Method
// Request Headers Below
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $sPD
)
);
$context = stream_context_create($aHTTP);
$contents = file_get_contents($sURL, false, $context);
echo $contents;
Если вы пришли из предыдущего POST / GET / ..., вы можете
include('fileName.php')
или
require('fileName.php')
Сценарий PHP в реальном листе php. Таким образом, он продолжит петицию POST / GET / ... будет действителен в рамках