valores - ¿Cómo envío una solicitud POST con PHP?
redireccionar con post php (11)
En realidad, quiero leer los contenidos que vienen después de la consulta de búsqueda, cuando se realiza. El problema es que la URL solo acepta métodos POST
, y no realiza ninguna acción con el método GET
...
Tengo que leer todos los contenidos con la ayuda de domdocument
o file_get_contents()
. ¿Hay algún método que me permita enviar parámetros con el método POST
y luego leer los contenidos a través de PHP
?
Estaba buscando un problema similar y encontré un mejor enfoque para hacer esto. Así que aquí va.
Simplemente puede colocar la siguiente línea en la página de redireccionamiento (por ejemplo, page1.php).
header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php
Necesito esto para redirigir las solicitudes POST para las llamadas de la API REST . Esta solución es capaz de redirigir con datos de publicación, así como valores de encabezado personalizados.
Aquí está el enlace de referencia .
Hay otro método CURL si vas por ese camino.
Esto es bastante sencillo una vez que entiendes cómo funciona la extensión de enrollamiento de PHP, combinando varias banderas con llamadas a setopt (). En este ejemplo, tengo una variable $ xml que contiene el XML que he preparado para enviar. Voy a publicar el contenido de este en el método de prueba de ejemplo.
$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
Primero inicializamos la conexión, luego configuramos algunas opciones usando setopt (). Éstos le dicen a PHP que estamos realizando una solicitud posterior, y que estamos enviando algunos datos con ellos, suministrando los datos. La bandera CURLOPT_RETURNTRANSFER le dice a curl que nos dé la salida como el valor de retorno de curl_exec en lugar de enviarla. Luego hacemos la llamada y cerramos la conexión, el resultado está en $ response.
Hay uno más que puedes usar
<?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);
?>
Le recomiendo que use la guzzle paquete de código abierto que está totalmente probada por la unidad y utiliza las últimas prácticas de codificación.
Instalación de Guzzle
Vaya a la línea de comandos en la carpeta de su proyecto y escriba el siguiente comando (asumiendo que ya tiene el gestor de paquetes instalado). Si necesita ayuda sobre cómo instalar Composer, debería echar un vistazo aquí .
php composer.phar require guzzlehttp/guzzle
Usando Guzzle para enviar una solicitud POST
El uso de Guzzle es muy sencillo, ya que utiliza una API ligera orientada a objetos:
// 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);
Método sin CURL con 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);
Consulte el manual de PHP para obtener más información sobre el método y cómo agregar encabezados, por ejemplo:
- stream_context_create : http://php.net/manual/en/function.stream-context-create.php
Me gustaría agregar algunas reflexiones sobre la respuesta basada en rizos de Fred Tanrikut. Sé que la mayoría de ellos ya están escritos en las respuestas anteriores, pero creo que es una buena idea mostrar una respuesta que los incluya a todos juntos.
Aquí está la clase que escribí para hacer solicitudes HTTP-GET / POST / PUT / DELETE basadas en curl, concernientes a casi el cuerpo de la respuesta:
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;
}
}
Mejoras
- Uso de http_build_query para obtener la cadena de consulta de una matriz de solicitudes (también puede usar la propia matriz, por lo tanto, consulte: php.net/manual/en/function.curl-setopt.php )
- Devolviendo la respuesta en lugar de repetirla. Por cierto, puede evitar la devolución eliminando la línea curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true); . Después de eso, el valor de retorno es booleano (verdadero = la solicitud fue exitosa, de lo contrario se produjo un error) y la respuesta se repite. Consulte: http://php.net/en/manual/function.curl-exec.php
- Limpie el cierre de la sesión y la eliminación del controlador de curl utilizando curl_close . Consulte: http://php.net/manual/en/function.curl-close.php
- Usar valores booleanos para la función curl_setopt en lugar de usar cualquier número (sé que cualquier número que no sea igual a cero también se considera verdadero, pero el uso de verdadero genera un código más legible, pero eso es solo mi opinión)
- Capacidad para realizar llamadas HTTP-PUT / DELETE (útil para pruebas de servicio RESTful)
Ejemplo de uso
OBTENER
$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));
ENVIAR
$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));
PONER
$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));
BORRAR
$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));
Pruebas
También puedes hacer algunas pruebas de servicio geniales usando esta clase simple.
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}]'');
}
}
Otra alternativa del método sin curvatura anterior es usar las funciones de flujo nativo:
- http://php.net/manual/en/function.stream-context-create.php :
Crea y devuelve un contexto de flujo con cualquier opción provista en las opciones preestablecidas.
-
stream_get_contents()
:Idéntico a
file_get_contents()
, excepto questream_get_contents()
opera en un recurso de flujo ya abierto y devuelve el contenido restante en una cadena, hasta bytes de longitud máxima y comenzando en el desplazamiento especificado.
Una función POST con estos puede ser simplemente así:
<?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;
}
Podrías usar 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;
?>
Pruebe el paquete HTTP_Request2 de PEAR para enviar fácilmente solicitudes POST. Alternativamente, puedes usar las funciones de enrollamiento de PHP o usar un contexto de flujo de PHP
HTTP_Request2 también permite simular el servidor, por lo que puede probar su código fácilmente
Si por casualidad está usando Wordpress para desarrollar su aplicación (en realidad es una forma conveniente de obtener autorización, páginas de información, etc. incluso para cosas muy simples), puede usar el siguiente fragmento de código:
$response = wp_remote_post( $url, array(''body'' => $parameters));
if ( is_wp_error( $response ) ) {
// $response->get_error_message()
} else {
// $response[''body'']
}
Utiliza diferentes formas de realizar la solicitud HTTP real, dependiendo de lo que esté disponible en el servidor web. Para más detalles, consulte la documentación de la API HTTP .
Si no desea desarrollar un tema o complemento personalizado para iniciar el motor de Wordpress, puede hacer lo siguiente en un archivo PHP aislado en la raíz de WordPress:
require_once( dirname(__FILE__) . ''/wp-load.php'' );
// ... your code
No mostrará ningún tema ni generará ningún HTML, ¡simplemente elimine las API de Wordpress!
Utilizo la siguiente función para publicar datos usando curl. $ data es una matriz de campos para publicar (se codificará correctamente usando http_build_query). Los datos se codifican utilizando 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 menciona que http_build_query puede omitirse ya que curl codificará correctamente la matriz pasada al parámetro CURLOPT_POSTFIELDS, pero tenga en cuenta que en este caso los datos se codificarán utilizando multipart / form-data.
Utilizo esta función con API que esperan que los datos se codifiquen utilizando application / x-www-form-urlencoded. Es por eso que uso http_build_query ().