I'm trying to make a HTTP POST request to my PHP script. However, it doesn't seem to be retrieving the request data.
To simulate a POST request, I used Request Maker and sent over a url of http://php-agkh1995.rhcloud.com/lta.php and a request data of var1=65059.
Using the default url in the else statement works perfectly fine but not the other
I'm suspecting the request headers to be the fault unless there's a major flaw in my code
lta.php
$stopid=$_POST['var1'];
$defurl = ""; // Default url
if(!empty($stopid)){
$defurl = 'http://datamall2.mytransport.sg/ltaodataservice/BusArrival?BusStopID=$stopid';
} else {
$defurl = 'http://datamall2.mytransport.sg/ltaodataservice/BusArrival?BusStopID=83139';
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $defurl,
CURLOPT_USERAGENT => 'Ashton',
CURLOPT_HTTPHEADER => array('AccountKey: ********', 'UniqueUserId: ******', 'accept: application/json')
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp); // To test if data is displayed or not
return $resp;
Request headers sent
POST /lta.php HTTP/1.1
Host: php-agkh1995.rhcloud.com
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
You could use array_key_exists to test the existence of the POST variable
if(array_key_exists($_POST,'var1')){
$stopid=$_POST['var1'];
$defurl = "http://datamall2.mytransport.sg/ltaodataservice/BusArrival?BusStopID=$stopid";
} else {
..
}
PS : if your $defurl is set to the else case value by default you don't even need the else clause
Related
I am executing a POST request to a server, which responds "properly", but when trying to call the mergeFromString() function I receive the following error:
Google\Protobuf\Internal\GPBDecodeException: Error occurred during parsing: Unexpected wire type. in Google\Protobuf\Internal\Message.php on line 353
I am using CURL with PHP:
$handle = curl_init($url);
$curl_options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HEADER => true,
CURLOPT_VERBOSE => true
];
curl_setopt_array($handle, $curl_options);
$curlResponse = curl_exec($handle);
$responseMessage = new MyMessage();
$responseMessage->mergeFromString($curlResponse);
curl_close($handle);
The result of var_dump($curlResponse) is as follows:
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
In plain text it should look something like this:
1: 1
2: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrig
3: 1619765852
My .proto file for the response is as follows:
message MyMessage{
// I'm only interested in property 2
string prop = 2;
}
Environment:
"protobuf-php / protobuf": "^ 0.1.3",
"google / protobuf": "^ 3.16"
However, tests using Protoman (A Postman-like API client for protobuf-based messages) are successful. I did the tests with the same proto files that I use in PHP.
In this case the error is because the string is invalid.
And it is invalid because the value (string) returned by CURL includes all the data from the HTTP request, for example:
HTTP/2 200
content-type: application/x-protobuf
date: Wed, 02 Jun 2021 23:12:37 GMT
content-length: 172
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
I didn't notice this because I thought those details were due to the CURLOPT_VERBOSE => true option.
Now, how to extract the body from the value returned by CURL is a bit complex, in this question you will see why.
My solution is as follows (I repeat, read the question I mentioned, maybe a simpler solution will work for you):
// I can't trust the Content-Length header (it may or may not be present).
// However, I can reliably calculate the length of the headers and use it instead.
$responseHeadersLength = 0;
$handle = curl_init($url);
$curl_options = [
// ...
CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$responseHeadersLength) {
$len = strlen($header);
$responseHeadersLength += $len;
return $len;
}
];
curl_setopt_array($handle, $curl_options);
$response = curl_exec($handle);
$body = trim(substr($response, $responseHeadersLength));
I'm trying to create a relatively simple PHP endpoint for users to send requests to. I know that the endpoint is working because when I accessed it using cURL the parameters I sent to my database we're added. The problem however is that when I use
var_dump($response);
The page returns "NULL".
So the code is working fine, I just want to know how to print an error/success message
This is what I've tried so far on the endpoint
header("HTTP/1.1 200 OK");
header('Content-Type: text/plain');
echo 'Success message';
the full cURL code:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_POSTFIELDS => 'example=this'
);
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
$response = json_decode($resp, true);
var_dump($response);
So how can I get the success message to properly show instead of "NULL"?
Test if your curl code returns something by testing: var_dump($resp). It looks like NULL comes from json_decode. You are not returning valid JSON from the endpoint.
php > var_dump(json_decode("Success message", true));
NULL
Try returning a json string such as:
php > echo json_encode("Success", true);
"Success"
Note the " around it. This encodes a json string. See the JSON spec for a reference on how to encode json. Best practice, if your return json, then run your content through json_encode().
Your curl code seems correct.
I'm building an application that makes frequent get calls to an external api and caches the data that is sent back. The api also sends "requestnext" url, last modified date, and ETag that can be used to make conditional get calls for updates. When making a requestnext call, I should be receiving a status 304 when there is no new data, but I'm only getting status 200 (even if there is no new data).
My code:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $nextrequest . '&apiKey='.$apikey,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => array($lastmod, $etag),
CURLOPT_HEADER => 1,
));
$response = curl_exec($curl);
$curlinfo = curl_getinfo($curl);
// Get http response code
$httpresponse = $curlinfo['http_code'];
The $lastmod and $etag variables contain
$lastmod = If-Modified-Since: Wed, 24 Feb 2016 22:38:22 GMT
$etag = If-None-Match: "ffffffffec3c286a-json"
Any ideas for what I might be doing wrong?
Turns out I was sending the conditional get request to the wrong url. I should've been sending it to the original url I used to make the request (I was sending it to the "nextrequest" url instead).
This was for the AP Elections api in case anyone was wondering!
I am working on a project, to help me learn how to use curl through PHP. I am attempting to get data from the Twitch-API using my own account for testing.
I have successfully authenticated my account with my domain by using:
https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=...&redirect_uri=...&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription&state=...
I have removed client_id, redirect_uri and state to show the link I used.
Once successfully authenticated it returns back to a domain that I specify (redirect_uri), once it gets back to that domain the website only knows the authentication key that is generated once accepted by the user, from twitch.
Example auth: 3ofbaoidzkym72ntjua1gmrr66o0nd
Now I would like to be able to get the username of the user, there is documentation on it:
curl -H 'Accept: application/vnd.twitchtv.v3+json' -H 'Authorization: OAuth <access_token>' \
-X GET https://api.twitch.tv/kraken/user
I am attempting to do this in PHP, but I don't understand the curl functions... Here's what I've got so far:
<?php if(isset($_GET['code']) && isset($_GET['scope'])) { ?>
<pre>
<?php
$auth = $_GET['code'];
$twitch = curl_init();
$headers = array();
$headers[] = 'Accept: application/vnd.twitchtv.v3+json';
$headers[] = 'Authorization: OAuth ' .$auth;
curl_setopt($twitch, CURLOPT_HEADER, $headers);
curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/user");
curl_exec($twitch);
?>
</pre>
<?php }; ?>
When I attempt to run this section of code, I get some errors:
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Sat, 08 Aug 2015 13:43:51 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 89
Connection: keep-alive
Status: 401 Unauthorized
X-API-Version: 3
WWW-Authenticate: OAuth realm='TwitchTV'
Cache-Control: max-age=0, private, must-revalidate
Vary: Accept-Encoding
X-UA-Compatible: IE=Edge,chrome=1
X-Request-Id: 4bc2e0bfadf6817366b4eb19ab5751bf
X-Runtime: 0.007862
Accept-Ranges: bytes
X-Varnish: 1641121794
Age: 0
Via: 1.1 varnish
X-MH-Cache: rails-varnish-5cb970; M
{"error":"Unauthorized","status":401,"message":"Token invalid or missing required scope"}
But I am unsure on how to fix this problem as, to me, it seems I am/have done everything that the documentation says to do...
How should I go about fixing this issue?
Edit:
It seems to work if I request using my twitch username:
curl -H 'Accept: application/vnd.twitchtv.v3+json' \
-X GET https://api.twitch.tv/kraken/users/test_user1
My Code for using the username:
<?php
$auth = urlencode($_GET['code']);
$twitch = curl_init();
$headers = array();
$headers[] = 'Accept: application/vnd.twitchtv.v3+json';
#$headers[] = 'Authorization: OAuth ' .$auth;
curl_setopt($twitch, CURLOPT_HTTPHEADER , $headers);
curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/users/...");
curl_exec($twitch);
?>
But I wouldn't know the user's username unless I get it from the statement which is producing an error and store it in a database.
Edit:
Reading into the documentation abit more, it requires the scope as well as the access token. I have been able to get this:
Example:
Array
(
[0] => Accept: application/vnd.twitchtv.v3+json
[1] => Authorization: OAuth code=scn89zerug002sr6r95z9ngbxmd0d2&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription
)
But I still get the error...
Edit:
So I read through the documentation EVEN MORE and now I have gotten to this:
class twitch {
var $base_url = "https://api.twitch.tv/kraken/";
var $client_id = "...";
var $client_secret = "...";
var $return_url = "...";
var $scope_array = array('user_read','channel_read','channel_subscriptions','user_subscriptions','channel_check_subscription');
public function get_access_token($code,$state) {
$ch = curl_init($this->base_url . "oauth2/token");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$fields = array(
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->redirect_url,
'code' => $code
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$data = curl_exec($ch);
$response = json_decode($data, true);
curl_close($ch);
echo "<pre>".print_r($this->redirect_url,true)."</pre>";
echo "<pre>".print_r($response,true)."</pre>";
return $response["access_token"];
}
};
$auth = new twitch();
print_r($auth->get_access_token($_GET['code'],$_GET['state']));
But this time there is another error, saying that my 'redirect_uri' => $this->redirect_url is different to the one which is held by twitch.
Array
(
[error] => Bad Request
[status] => 400
[message] => Parameter redirect_uri does not match registered URI
)
I have even copied and pasted from the twitch website to my variable and the other way around, I still get the same error... Now I'm even more stuck, but at least a step closer.
Right I'm going to do this with you as I do it :d So far I've been able to get one user, the reason you're getting errors is because you're not setting any curl options. I taught myself using this https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php which I found MASSIVELY helpful when learning curl. The code itself is basic but it's so easy to read. I managed to understand it and make it 100% more complicated :D
First things first, I'll show you how I got the test user.
What you want to do is set the options, I'll keep to the simple method first.
The 2 methods are CURLOPT_HEADER and CURL_RETURNTRANSFER. Your url you can set with the init function.
$twitch=curl_init('https://api.twitch.tv/kraken/users/test_user1');
curl_setopt($twitch,CURLOPT_HTTPHEADER,array('Accept: application/vnd.twitchtv.v3+json'));//must be an array.
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
$info=curl_getinfo($twitch);
print_r($result);
This will get you your test user and hopefully show you a little bit about what you're doing wrong. If you wanted to use the array method, then you must use your curl options as the array key so that the set function know what to set what as. (don't ask me how it all technically works :S)
I'll update to show you how to get an authorisation and data once I've worked it out. But the basic principles are you need to send post data and set CURLOPT_POST to true and include the postdata CURLOPT_POSTFIELDS which must be a json array as your application requires json I believe?
Anyway the array:
curl_set_opts($twitch,array(CURLOPT_HEADER=>array('Accept: application/vnd.twitchtv.v3+json',CURLOPT_RETURNTRANSFER=true));
Seeing as you already know how to authorise a user I'll skip that bit, although I'd recommend using something a little more secure than a $_GET. Maybe a session variable would be a bit better.
To get a specific user using the Auth that is returned. You want to do something like this: (Sorry I can't test it myself, I don't have a twitch dev account)
$twitch=curl_init('https://api.twitch.tv/kraken/user');
curl_setopt($twitch,CURLOPT_HEADER,array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$_SESSION['token']));
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
print_r($result);
//don't forget to close!
curl_close($twitch);
$user=json_decode($result);
echo$user->display_name;
That should work although I have no idea how you're getting a oAuth token lol
if you wanted to be a really cool programmer 8| I'd recommend doing some classes for this. Like this
class twitch{
private$token,$twitch,$url="http://api.twitch.tv/kraken/";
protected$code,$state,$report;
private static$details;
public function __construct($code,$state){
$this->code=$code;
$this->state=$state;
self::$details=(object)array('client_id'=>'id','client_secret'=>'secret','return_url'=>'redirect');
$result=$this->makeCall('oauth2/token',true);
print_r($result);
}
protected function makeCall($extention,$auth=false,$object=true){
$this->twitch=curl_init($this->url.$extention);
//$opts=array(CURLOPT_)
if($auth!==false){
$opts=array(CURLOPT_FOLLOWLOCATION=>true,CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode(array('client_id'=>self::$details->client_id,'client_secret'=>self::$details->client_secret,'grant_type'=>'authorization_code','code'=>$this->code,'redirect_uri'=>self::$details->return_url)));
}else{
$opts=array(CURLOPT_HEADER=>array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$this->token),CURLOPT_RETURNTRANSFER=>true);
}
curl_setopt_array($this->twitch,$opts);
$result=curl_exec($this->twitch);
$this->report=array('info'=>curl_getinfo($this->twitch),'error'=>curl_error($this->twitch));
curl_close($this->twitch);
return($object===true)?json_decode($result):$result;
}
protected function userDetails(){
return$this->makeCall('user');
}
public function user(){
return$this->userDetails();
}
}
I'm currently working on some automatization script in PHP (No HTML!).
I have two PHP files. One is executing the script, and another one receive $_POST data and returns information.
The question is how from one PHP script to send POST to another PHP script, get return variables and continue working on that first script without HTML form and no redirects.
I need to make requests a couple of times from first PHP file to another under different conditions and return different type of data, depending on request.
I have something like this:
<?php // action.php (first PHP script)
/*
doing some stuff
*/
$data = sendPost('get_info');// send POST to getinfo.php with attribute ['get_info'] and return data from another file
$mysqli->query("INSERT INTO domains (id, name, address, email)
VALUES('".$data['id']."', '".$data['name']."', '".$data['address']."', '".$data['email']."')") or die(mysqli_error($mysqli));
/*
continue doing some stuff
*/
$data2 = sendPost('what_is_the_time');// send POST to getinfo.php with attribute ['what_is_the_time'] and return time data from another file
sendPost('get_info' or 'what_is_the_time'){
//do post with desired attribute
return $data; }
?>
I think i need some function that will be called with an attribute, sending post request and returning data based on request.
And the second PHP file:
<?php // getinfo.php (another PHP script)
if($_POST['get_info']){
//do some actions
$data = anotherFunction();
return $data;
}
if($_POST['what_is_the_time']){
$time = time();
return $time;
}
function anotherFunction(){
//do some stuff
return $result;
}
?>
Thanks in advance guys.
Update: OK. the curl method is fetching the output of php file. How to just return a $data variable instead of whole output?
You should use curl. your function will be like this:
function sendPost($data) {
$ch = curl_init();
// you should put here url of your getinfo.php script
curl_setopt($ch, CURLOPT_URL, "getinfo.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec ($ch);
curl_close ($ch);
return $result;
}
Then you should call it this way:
$data = sendPost( array('get_info'=>1) );
I will give you some example class , In the below example you can use this as a get and also post call as well. I hope this will help you.!
/*
for your reference . Please provide argument like this,
$requestBody = array(
'action' => $_POST['action'],
'method'=> $_POST['method'],
'amount'=> $_POST['amount'],
'description'=> $_POST['description']
);
$http = "http://localhost/test-folder/source/signup.php";
$resp = Curl::postAuth($http,$requestBody);
*/
class Curl {
// without header
public static function post($http,$requestBody){
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $http ,
CURLOPT_USERAGENT => 'From Front End',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $requestBody
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
return $resp;
}
// with authorization header
public static function postAuth($http,$requestBody,$token){
if(!isset($token)){
$resposne = new stdClass();
$resposne->code = 400;
$resposne-> message = "auth not found";
return json_encode($resposne);
}
$curl = curl_init();
$headers = array(
'auth-token: '.$token,
);
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_HTTPHEADER => $headers ,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $http ,
CURLOPT_USERAGENT => 'From Front End',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $requestBody
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
return $resp;
}
}