PHP cURL GET request and request's body
CURLOPT_POSTFIELDS
as the name suggests, is for the body (payload) of a POST
request. For GET
requests, the payload is part of the URL in the form of a query string.
In your case, you need to construct the URL with the arguments you need to send (if any), and remove the other options to cURL.
curl_setopt($ch, CURLOPT_URL, $this->service_url.'user/'.$id_user);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
//$body = '{}';
//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
//curl_setopt($ch, CURLOPT_POSTFIELDS,$body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
php curl -X GET with request body
Alright, here we go with the proper answer.
on terminal,
curl -X GET http://ip:777/api \
-d "r=request"
works perfectly. However, the problem with converting that to php curl is quite troublesome while very easy at the same time.
I've read through every stack problem regarding this and no-one has provided a clear answer to the problem. I'm not sure the reason behind it but as a generous person I'll give out the code so that anyone in the future facing this rare problem will solve it out easily.
Long story short,
curl -X GET -d
is the same as curl -X POST -H "X-HTTP-Method-Override: GET"
.
The actual request is POST but THE SERVER will consider it as a GET. This way you won't face the LONG URI problem.
$long_query = "r=" . $request;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"ip:777/api");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $long_query); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'X-HTTP-Method-Override: GET',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
curl_setopt($ch, CURLOPT_TIMEOUT, 140);
curl_close ($ch);
var_dump($server_output);
I've set the timeout to 140 as the query is long and it takes a bit of time for the server to go through it and respond (in my case its a json). Nevertheless, I've added var_dump so that anyone who uses it in the future might see if its a serialized array or whatever.
Good luck!
How to view PHP cURL request body (like CURLINFO_HEADER_OUT for headers)
I was unable to find any such option after extensively searching the PHP cURL documentation.
My solution was to use the web proxy tool Charles
Charles is an HTTP proxy / HTTP monitor / Reverse Proxy that enables a developer to view all of the HTTP and SSL / HTTPS traffic between their machine and the Internet. This includes requests, responses and the HTTP headers (which contain the cookies and caching information).
How to send raw data with curl GET in PHP?
GET requests do not have a body, that's the whole idea: you're just getting something from the server, as opposed to posting something to it. From RFC 7231:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
In other words, a GET request can have data, but it should not. From earlier in the spec, where GET is defined as a safe method:
Request methods are considered "safe" if their defined semantics are
essentially read-only; i.e., the client does not request, and does
not expect, any state change on the origin server as a result of
applying a safe method to a target resource.
...
Of the request methods defined by this specification, the GET, HEAD,
OPTIONS, and TRACE methods are defined to be safe.
If you really want to have JSON in your GET request (and send it to a reasonably implemented server resource) the only place it can go is in the URI as part of the query string. For GET requests I find using file_get_contents
to be much easier than dealing with cURL.
<?php
$payload = json_encode(["user" => $data]);
$url_data = http_build_query([
"json" => $payload
]);
$url = "https://some.example/endpoint.php?" . $url_data;
$result = file_get_contents($url);
If you want to send it to an unreasonably implemented server resource, and violate the spirit of the HTTP RFCs, you could do this:
<?php
$url = "https://some.example/endpoint.php";
$payload = json_encode(["user" => $data]);
$ctx = stream_context_create(["http" => [
"header"=>"Content-Type: application/json",
"content"=>$payload
]]);
$result = file_get_contents($url, false, $ctx);
If you're determined to do this specifically with cURL, you might have luck with the CURLOPT_CUSTOMREQUEST
option set to "GET" and CURLOPT_POSTDATA
with your data.
Getting content body from http post using php CURL
CURLOPT_VERBOSE
should actually show the details. If you're looking for the response body content, you can also use CURLOPT_RETURNTRANSFER
, curl_exec()
will then return the response body.
If you need to inspect the request body, CURLOPT_VERBOSE
should give that to you but I'm not totally sure.
In any case, a good network sniffer should give you all the details transparently.
Example:
$curlOptions = array(
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_VERBOSE => TRUE,
CURLOPT_STDERR => $verbose = fopen('php://temp', 'rw+'),
CURLOPT_FILETIME => TRUE,
);
$url = "http://stackoverflow.com/questions/tagged/java";
$handle = curl_init($url);
curl_setopt_array($handle, $curlOptions);
$content = curl_exec($handle);
echo "Verbose information:\n", !rewind($verbose), stream_get_contents($verbose), "\n";
curl_close($handle);
echo $content;
Output:
Verbose information:
* About to connect() to stackoverflow.com port 80 (#0)
* Trying 64.34.119.12...
* connected
* Connected to stackoverflow.com (64.34.119.12) port 80 (#0)
> GET /questions/tagged/java HTTP/1.1
Host: stackoverflow.com
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Date: Wed, 14 Mar 2012 19:27:53 GMT
< Content-Length: 59110
<
* Connection #0 to host stackoverflow.com left intact
<!DOCTYPE html>
<html>
<head>
<title>Newest 'java' Questions - Stack Overflow</title>
<link rel="shortcut icon" href="http://cdn.sstatic.net/stackoverflow/img/favicon.ico">
<link rel="apple-touch-icon" href="http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon.png">
<link rel="search" type="application/opensearchdescription+xml" title="Stack Overflow" href="/opensearch.xml">
...
cURL request in Laravel
Give the query-option from Guzzle a try:
$endpoint = "http://my.domain.com/test.php";
$client = new \GuzzleHttp\Client();
$id = 5;
$value = "ABC";
$response = $client->request('GET', $endpoint, ['query' => [
'key1' => $id,
'key2' => $value,
]]);
// url will be: http://my.domain.com/test.php?key1=5&key2=ABC;
$statusCode = $response->getStatusCode();
$content = $response->getBody();
// or when your server returns json
// $content = json_decode($response->getBody(), true);
I use this option to build my get-requests with guzzle. In combination with json_decode($json_values, true) you can transform json to a php-array.
How to get info on sent PHP curl request
If you set CURLINFO_HEADER_OUT
to true
, outgoing headers are available in the array returned by curl_getinfo()
, under request_header
key:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://foo.com/bar");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "someusername:secretpassword");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
$info = curl_getinfo($ch);
print_r($info['request_header']);
This will print:
GET /bar HTTP/1.1
Authorization: Basic c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk
Host: foo.com
Accept: */*
Note the auth details are base64-encoded:
echo base64_decode('c29tZXVzZXJuYW1lOnNlY3JldHBhc3N3b3Jk');
// prints: someusername:secretpassword
Also note that username and password need to be percent-encoded to escape any URL reserved characters (/
, ?
, &
, :
and so on) they might contain:
curl_setopt($ch, CURLOPT_USERPWD, urlencode($username).':'.urlencode($password));
PHP Curl, Request data return in application/json
You should modify the code where you set the HTTP headers in your request. You weren't specifying the Accept
header
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
This should sent the HTTP request to the API's URL with the information that you would like to get the response in the particular format.
Edit (in case this could be useful to someone):
- The
Accept
header is a request header and it specifies the acceptable type of the response's body - The
Content-Type
header is both a request and a response header and it specifies the format of the body of the request/response
Example of the HTTP requests could look something like this (often, the request contains only the header part):
GET /index.html HTTP/1.1
Host: www.example.com
Accept: application/json
And the response could look something like that:
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 24
{
"hello": "world"
}
Related Topics
Differencebetween Null and Empty
Required_If Laravel 5 Validation
How to Implement a Decorator in PHP
Remotely Connecting to a MySQL Database
Best Way to Periodically Execute a PHP Script
How to Convert All Images to Jpg
Selecting All Fields Except Only One Field in MySQL
How to Select Rows in MySQL Starting at a Given Row Number
How to Take a Photo and Send to Http Post Request with Android
Adding Multiple Items to Woocommerce Cart at Once
Connection Reset by Peer: Mod_Fcgid: Error Reading Data from Fastcgi Server
Making a Http Get Request with Http-Basic Authentication
Regex/Domdocument - Match and Replace Text Not in a Link