I was trying to make a request post
in php by using file_get_contents
but when I passed the headers to it, it seemed that it was not taking them as it always specified another one Content-type
than the one I had set by default. Given this problem, I decided to use curl
it to make the request, like this:
function send_post(string $url, array $headers, array $body){
$headers["Host"] = $this->host;
$headers = $this->arrHeader_from_array($headers);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $body);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
return "--->".$result;
}
What the function arrHeader_from_array
does is convert an associative array with this structure (result of a var_dump
):
array(7) {
["Accept"]=>
string(3) "*/*"
["Content-Type"]=>
string(16) "application/json"
["Content-Length"]=>
string(2) "67"
["Accept-Encoding"]=>
string(17) "gzip, deflate, br"
["Host"]=>
string(14) "127.0.0.1:8080"
["Connection"]=>
string(5) "close"
}
To something like this:
array(7) {
[0]=>
string(11) "Accept: */*"
[1]=>
string(30) "Content-Type: application/json"
[2]=>
string(18) "Content-Length: 67"
[3]=>
string(34) "Accept-Encoding: gzip, deflate, br"
[4]=>
string(22) "Host: http://127.0.0.1"
[5]=>
string(17) "Connection: close"
}
And how body
do you get the following:
array(2) {
["username"]=>
string(17) "[email protected]"
["password"]=>
string(8) "password"
}
In the end the result I get is this:
---><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)</p>
Out of pure curiosity, it occurred to me to change the content body
of the requestcurl
...
curl_setopt($ch,CURLOPT_POSTFIELDS, 'postvars=val1&postvars2=val2');
...
And it turns out that my server does not return any response, I am waiting for a long time and I have to restart the server.
The complete code is as follows:
<?php
class Redir {
function __construct(string $url, int $port){
$this->host = $url;
$this->port = $port;
}
function arrHeader_from_array(array $headers){
$arr_header=[];
foreach($headers as $header=>$value){
array_push($arr_header,"$header: $value");
}
return $arr_header;
}
function send_post(string $url, array $headers, array $body){
$headers["Host"] = $this->host;
$headers = $this->arrHeader_from_array($headers);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $body);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
return "--->".$result;
}
static function getallheaders(){
foreach($_SERVER as $K=>$V){
$a=explode('_' ,$K);
if(array_shift($a)=='HTTP'){
array_walk($a,function(&$v){
$v=ucfirst(strtolower($v));
});
$retval[join('-',$a)]=$V;
}
}
return $retval;
}
function start(){
$req = $_SERVER["REQUEST_METHOD"];
if ($req == "POST"){
$route = $_SERVER['REQUEST_URI'];
$body = json_decode(file_get_contents('php://input'), true);
//print_r($body);
$url = "$this->host:$this->port".$route;
$headers = $this->getallheaders();
//print_r($headers);
echo $this->send_post($url, $headers, $body);
return;
}
}
}
?>
And the server that will receive the request is a python server made with flask
:
@app.post("/data")
def data():
print(request.json, request.headers)
return "yep"
When sending the information using json_encode($body)
the problem is the same, the request does not send a response and seems to be eternal. So how do I make the curl request?
Hello, in my case when I implement CURL I use the following form:
A. CURL script to send data:
Explanation:
First of all I like to nest information, so you will see that the variable
$fields
is an array which in turn contains another array injson
.when sending something in json format I rule out the use of
http_build_query
in the header above I write the method with
POST
and indicate the header:"Content-Type: application/json"
I put together an Array where I place all the
CURLOPT_*
as you will see in the last instance is that I dojson_encode
the variable$fields
and thatCURLOPT_POST
I am passing a true instead of the field count.Example:
B. Reception of Data:
Explanation:
I use the php method
getallheaders()
to capture the Request header.I do the reading of the data from "php://input" using
file_get_contents
Example:
Output:
Other POST that may interest you:
Convert array key value to php object
Get key value from an array
How to correctly send an array by Postman
How to extract a value from a JSON URL to PHP giving it a format?