SOLVED: Issue was in Content-type. Should have been
Content-Type: application/x-www-form-urlencoded
Helping link: http://www.bradino.com/php/empty-post-array/
I cannot seem to get POST data to send. I've combed over this method for a while now and each time I run a test, the $_POST array is empty.
$output = new SimpleXMLElement($xml);
$params = "method=updateOrder&xml=".$output;
$response = Rest::Post("example.com", 80, "/resource/path.php", $params);
Above is another method I call statically which creates the HttpRequest with the desired method. Below is the method that gets sub-called and passed the same data but including the method name. IE: POST.
private static function httpRequest($host, $port, $method, $path, $params)
{
//Check method
if(empty($method))
$method = "GET";
$method = strtoupper($method);
//Port
if(empty($port))
$port = 80;
//Build Querystring
$data = "";
if(!empty($params) && $method == "GET")
foreach($params as $name => $value)
{
$data .= $name . "=" . urlencode($value) . "&";
}
if($method == "GET" && !empty($data))
$path .= "?" . $data;
//connection
$socket = fsockopen($host, $port);
if(!$socket)
die("Socket failed, no connection.");
//Write Data and headers to stream
fputs($socket, $method ." ". $path . " HTTP/1.1\r\n");
fputs($socket, "Host: " . $host . "\r\n");
if($method === "POST")
{
fputs($socket, "Content-type: text/xml\r\n");
fputs($socket, "Content-length: " . strlen($params) . "\r\n");
}
fputs($socket, "Connection: close\r\n\r\n");
//Write body
if($method === "POST")
fputs($socket, $params);
//Gets headers
$responseHeader = "";
do
{
$responseHeader .= fgets($socket, 1024);
}
while(strpos($responseHeader, "\r\n\r\n") === false);
//Gets body
$responseBody = "";
while(!feof($socket))
$responseBody .= fgets($socket, 1024);
//Done & return
fclose($socket);
return array(0=>$responseHeader, 1=>$responseBody);
}
You should consider using the built-in cURL library.
function httpRequest($host, $port = 80, $method = 'GET', $path = '/', $params = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ( ! empty($port) )
curl_setopt($ch, CURLOPT_PORT, $port);
if ( ! empty($method) && $method == 'POST' )
{
curl_setopt($ch, CURLOPT_URL, $host . ( ! empty($path) ? $path : '/' ));
curl_setopt($ch, CURLOPT_POST, TRUE);
if ( ! empty($params) )
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
else
curl_setopt($ch, CURLOPT_URL, $host . ( ! empty($path) ? $path : '/' ) . ( ! empty($params) ? '?' . $params : null ));
$result = curl_exec($ch);
curl_close($ch);
return explode("\r\n\r\n", $result, 2);
}
The function above will return an array containing the headers and the body.
Does this help?
Change
fputs($socket, "Content-type: text/xml\r\n");
to
fputs($socket, "Content-type: application/x-www-form-urlencoded\r\n");
Related
I'm using coinbase pro API to fetch some data and to make some trades but API is returning
{"message":"IP does not match IP whitelist"}
I'm using Rest API with correct API keys. I'm sure API keys are authenticated correctly and while creating API keys, I've entered correct IP address of my server. I rechecked IP 5 times but it's correct. Below is my sample code
<?php
function signature($request_path='', $body='', $timestamp=false, $secret = '', $method='GET') {
$body = is_array($body) ? json_encode($body) : $body;
$timestamp = $timestamp ? $timestamp : time();
$what = $timestamp.$method.$request_path.$body;
return base64_encode(hash_hmac("sha256", $what, base64_decode($secret), true));
}
function make_request($url, $method, $headers, $body = ''){
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// Set the url
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, true);
if ($method == "POST") {
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
// "accept" => "application/json"
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute
$result_json = curl_exec($ch);
curl_close($ch);
return $result_json;
}
try {
$apiurl = "https://api.pro.coinbase.com";
$secret = "SUPER_SECRET";
$api_key = "API_KEY";
$passphrase = "PASSPHRASE";
$method = "GET";
$requestPath = "/accounts";
$body = "";
$url = $apiurl . $requestPath;
$data["name"] = "";
$body = json_encode($data);
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$list = explode(" ", $user_agent);
$user_agent = $list[0];
$timestamp = (string) time();
$string = $timestamp . $method . $requestPath;
$sig = signature($requestPath, '', $timestamp, $secret);
$headers = [
"CB-ACCESS-KEY: ".$api_key,
"CB-ACCESS-SIGN: ".$sig,
"CB-ACCESS-TIMESTAMP: ".$timestamp,
"CB-ACCESS-PASSPHRASE: ".$passphrase,
"User-Agent:". $user_agent,
"Content-Type: application/json",
];
$result_json = make_request($url, $method, $headers);
var_dump($result_json);
die;
}
catch(Exception $e){
var_dump($e->getMessage());
die;
}
I've searched a lot for this problem and been struggling with it since 2 days. If anyone can help or point me in right direction? That would be highly appreciated.
Thanks & Regards.
I am learning how to make Shopify apps right but I am in trouble because even after following every single line of code correctly I can't seem to figure out what I have done wrong.
Error - It says theshopifystore.myshopify.com refused to connect
everything else is fine i can even store all the info about a store on MySQL but i think the redirect url should be something else can anyone figure out what it is?
Here is the code of all the files that I have made in that process
first - index.php
<?php
include_once("inc/mysql_connect.php");
include_once("header.php");?>
Second - install.php
<?php
// Set variables for our request
$shop = $_GET['shop'];
$api_key = "22xxxxxx151d751c89";
$scopes = "read_orders,write_orders,read_products,write_products";
$redirect_uri = "https://videomap.host/token.php";
// Build install/approval URL to redirect to
$install_url = "https://" . $shop . "/admin/oauth/authorize?client_id=" . $api_key . "&scope=" . $scopes . "&redirect_uri=" . urlencode($redirect_uri);
// Redirect
header("Location: " . $install_url);
die();?>
Third - token.php
<?php
// Get our helper functions
require_once("inc/functions.php");
require_once("inc/mysql_connect.php");
// Set variables for our request
$api_key = "x7151d751c89xxxxxxxxxxx";
$shared_secret = "shxxxxxxxxa72837xxxxxx4f";
$params = $_GET; // Retrieve all request parameters
$hmac = $_GET['hmac']; // Retrieve HMAC request parameter
$params = array_diff_key($params, array('hmac' => '')); // Remove hmac from params
ksort($params); // Sort params lexographically
$computed_hmac = hash_hmac('sha256', http_build_query($params), $shared_secret);
// Use hmac data to check that the response is from Shopify or not
if (hash_equals($hmac, $computed_hmac)) {
// Set variables for our request
$query = array(
"client_id" => $api_key, // Your API key
"client_secret" => $shared_secret, // Your app credentials (secret key)
"code" => $params['code'] // Grab the access key from the URL
);
// Generate access token URL
$access_token_url = "https://" . $params['shop'] . "/admin/oauth/access_token";
// Configure curl client and execute request
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $access_token_url);
curl_setopt($ch, CURLOPT_POST, count($query));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
$result = curl_exec($ch);
curl_close($ch);
// Store the access token
$result = json_decode($result, true);
$access_token = $result['access_token'];
// Show the access token (don't do this in production!)
$sql = "INSERT INTO shop (shop_url, access_token, install_date)
VALUES ('".$params['shop']."', '".$access_token."', NOW())";
if (mysqli_query($conn, $sql)) {
header('Location: https://'.$params['shop'].'/admin/apps');
die();
} else {
echo "Error inserting new record: " . mysqli_error($conn);
}
} else {
// Someone is trying to be shady!
die('This request is NOT from Shopify!');
}?>
Fourth - header.php
<?php $shopify = $_GET;
$sql = "SELECT * FROM shops WHERE shop_url='" . $shopify['shop'] . "' LIMIT 1";
$check = mysqli_query($conn, $sql);
if(mysqli_num_rows($check) < 1){
header("Location: install.php?shop=" . $shopify['shop']);
exit();
}else{
$shop_row = mysqli_fetch_assoc($check);
$shop_url = $shopify['shop'];
$token = $shop_row['access_token'];
}
?>
Fifth - inc/functions.php
<?php
function shopify_call($token, $shop, $api_endpoint, $query = array(), $method = 'GET', $request_headers = array()) {
// Build URL
$url = "https://" . $shop . $api_endpoint;
if (!is_null($query) && in_array($method, array('GET', 'DELETE'))) $url = $url . "?" . http_build_query($query);
// Configure cURL
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_MAXREDIRS, 3);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 3);
// curl_setopt($curl, CURLOPT_SSLVERSION, 3);
curl_setopt($curl, CURLOPT_USERAGENT, 'My New Shopify App v.1');
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
// Setup headers
$request_headers[] = "";
if (!is_null($token)) $request_headers[] = "X-Shopify-Access-Token: " . $token;
curl_setopt($curl, CURLOPT_HTTPHEADER, $request_headers);
if ($method != 'GET' && in_array($method, array('POST', 'PUT'))) {
if (is_array($query)) $query = http_build_query($query);
curl_setopt ($curl, CURLOPT_POSTFIELDS, $query);
}
// Send request to Shopify and capture any errors
$response = curl_exec($curl);
$error_number = curl_errno($curl);
$error_message = curl_error($curl);
// Close cURL to be nice
curl_close($curl);
// Return an error is cURL has a problem
if ($error_number) {
return $error_message;
} else {
// No error, return Shopify's response by parsing out the body and the headers
$response = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
// Convert headers into an array
$headers = array();
$header_data = explode("\n",$response[0]);
$headers['status'] = $header_data[0]; // Does not contain a key, have to explicitly set
array_shift($header_data); // Remove status, we've already set it above
foreach($header_data as $part) {
$h = explode(":", $part);
$headers[trim($h[0])] = trim($h[1]);
}
// Return headers and Shopify's response
return array('headers' => $headers, 'response' => $response[1]);
}
}
Sixth - inc/mysql_connect.php
<?php
$host = "localhost";
$username = "xxxxxxx_shopify";
$password ="xxxxxxx1#";
$database = "xxxxxxxopify";
$conn = mysqli_connect($host, $username, $password, $database);
if(!$conn){
die("Connection Error" . mysqli_connect_error());
}
?>
The following PHP code working perfect in development environment but on production environment returns error :
{"uuid":"xxxxx", "serverErrorCode":"AUTHENTICATION_FAILED", "reason":"Authentication failed"}
any idea ?
function cloudKitRequest($requestType, $jsonbody)
{
$KEY_ID = '97659598759875987508750875087087608785987585985';
$CONTAINER = 'xyz.zz.zzyyxx.xyz';
$PRIVATE_PEM_LOCATION = 'eckey.pem';
//$Environment = 'development';
$Environment = 'production';
$dbtype = 'public';
$result = NULL;
$url = 'https://api.apple-cloudkit.com/database/1/' . $CONTAINER . '/'. $Environment . '/' . $dbtype . '/records/'.$requestType;
// Set cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
// Create signature
date_default_timezone_set('UTC');
$explode_date = explode('+', date("c", time()));
$time = $explode_date[0] . 'Z';
$signature = $time . ":" . base64_encode(hash("sha256", $jsonbody, true)) . ":" . explode('cloudkit.com', $url)[1];
// Get private key
$pkeyid = openssl_pkey_get_private("file://" . $PRIVATE_PEM_LOCATION);
// Sign signature with private key
if(openssl_sign($signature, $signed_signature, $pkeyid, "sha256WithRSAEncryption")) {
openssl_free_key($pkeyid);
// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER,
[
"Content-Type: text/plain",
"X-Apple-CloudKit-Request-KeyID: " . $KEY_ID,
"X-Apple-CloudKit-Request-ISO8601Date: " . $time,
"X-Apple-CloudKit-Request-SignatureV1: " . base64_encode($signed_signature),
]
);
// Set body
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonbody);
// Send the request & save response to $resp
$resp = curl_exec($ch);
if($resp === false) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
} else {
//echo $resp;
// $result = json_decode($resp, true);
$result = $resp;
}
curl_close($ch);
} else {
while ($msg = openssl_error_string()) {
echo $msg . "<br />\n";
}
}
return $result;
}
any idea
I am using this PHP Class for Instagram's API: https://github.com/cosenary/Instagram-PHP-API.
It works perfectly but I can't seem to access the rate limit information for each call I make.
Inside the class, this is the method that makes the call:
protected function _makeCall($function, $auth = false, $params = null, $method = 'GET') {
if (false === $auth) {
$authMethod = '?client_id=' . $this->getApiKey();
} else {
if (true === isset($this->_accesstoken)) {
$authMethod = '?access_token=' . $this->getAccessToken();
} else {
throw new \Exception("Error: _makeCall() | $function - This method requires an authenticated users access token.");
}
}
if (isset($params) && is_array($params)) {
$paramString = '&' . http_build_query($params);
} else {
$paramString = null;
}
$apiCall = self::API_URL . $function . $authMethod . (('GET' === $method) ? $paramString : null);
$headerData = array('Accept: application/json');
if (true === $this->_signedheader && 'GET' !== $method) {
$headerData[] = 'X-Insta-Forwarded-For: ' . $this->_signHeader();
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiCall);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerData);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if ('POST' === $method) {
curl_setopt($ch, CURLOPT_POST, count($params));
curl_setopt($ch, CURLOPT_POSTFIELDS, ltrim($paramString, '&'));
} else if ('DELETE' === $method) {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
}
$jsonData = curl_exec($ch);
if (false === $jsonData) {
throw new \Exception("Error: _makeCall() - cURL error: " . curl_error($ch));
}
curl_close($ch);
return json_decode($jsonData);
}
The information I need to access from Instagram's API is:
X-Ratelimit-Limit
X-Ratelimit-Remaining
(http://instagram.com/developer/limits/ for more information about Instagram's limits).
For obvious reasons I need the app I'm creating to "shut itself down" before the rate limit kicks in. By accessing the rate limit information I can achieve this.
I have found a Gist that should work with this class but I can't seem to get it to work: https://gist.github.com/cosenary/6af4cf4b509518169b88
Also this topic here on Stackoverflow seems to be fruitless:
Instagram API count limits using HTTP header
If anyone could help me out here that would be amazing!
Best regards,
Peter de Leeuw
I have modified the function _makeCall and it is as follows by adding first curl_setopt($ch, CURLOPT_HEADER, true); and calling the function processHeader() as cosenary suggested on this gist cosenary/ratelimit.php:
protected function _makeCall($function, $auth = false, $params = null, $method = 'GET') {
if (false === $auth) {
// if the call doesn't requires authentication
$authMethod = '?client_id=' . $this->getApiKey();
} else {
// if the call needs an authenticated user
if (true === isset($this->_accesstoken)) {
$authMethod = '?access_token=' . $this->getAccessToken();
} else {
throw new \Exception("Error: _makeCall() | $function - This method requires an authenticated users access token.");
}
}
if (isset($params) && is_array($params)) {
$paramString = '&' . http_build_query($params);
} else {
$paramString = null;
}
$apiCall = self::API_URL . $function . $authMethod . (('GET' === $method) ? $paramString : null);
// signed header of POST/DELETE requests
$headerData = array('Accept: application/json');
if (true === $this->_signedheader && 'GET' !== $method) {
$headerData[] = 'X-Insta-Forwarded-For: ' . $this->_signHeader();
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiCall);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerData);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if ('POST' === $method) {
curl_setopt($ch, CURLOPT_POST, count($params));
curl_setopt($ch, CURLOPT_POSTFIELDS, ltrim($paramString, '&'));
} else if ('DELETE' === $method) {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
}
$jsonData = curl_exec($ch);
// split header from JSON data
// and assign each to a variable
list($headerContent, $jsonData) = explode("\r\n\r\n", $jsonData, 2);
// convert header content into an array
$headers = $this->processHeaders($headerContent);
// get the 'X-Ratelimit-Remaining' header value
$ratelimitRemaining = $headers['X-Ratelimit-Remaining'];
$this->setHeaderLimit($ratelimitRemaining);
if (false === $jsonData) {
throw new \Exception("Error: _makeCall() - cURL error: " . curl_error($ch));
}
curl_close($ch);
return json_decode($jsonData);
}
the processHeader() method which processes the header and the set and get methods for the $rateLimitRemaining are as follows :
private function processHeaders($headerContent){
$headers = array();
foreach (explode("\r\n", $headerContent) as $i => $line) {
if($i===0){
$headers['http_code'] = $line;
}else{
list($key,$value) = explode(':', $line);
$headers[$key] = $value;
}
}
return $headers;
}
private function setHeaderLimit($HeaderLimit){
$this->HeaderLimit = $HeaderLimit;
}
public function getHeaderLimit(){
return $this->HeaderLimit;
}
You can access the X-Ratelimit-Remaining now from another class just by calling the getHeaderLimit()
*Don't forget to declare the public field HeaderLimit within the class where _makeCall() resides, which in this case is Instagram.php.
**I have tested this solution and it works perfectly.
Hope this helps you guys :)
I am totally new to php. I had 2 pages let A.php and B.php want to run Page B while I am at Page A.For that I had created a Socket Connection and able to run The Page B but problem is that when I send an array of objects to page B.page A send only the First object listed in the array and other values of the array were nothing
here is my some code
in A.php
$arr = array("message" => $pushData,
"messageType" => $messageType,
"displayGroupID" => $displayGroupID,
"db"=>$db);
$fp1 = $this->JobStartAsync('localhost', 'B.php', $arr);
$r1 = $this->JobPollAsync($fp1);
function JobStartAsync($server, $url, $data, $port=80,$conn_timeout=10, $rw_timeout=86400)
{
$errno = '';
$errstr = '';
$data = http_build_query($data);
set_time_limit(0);
$fp = fsockopen($server, $port, $errno, $errstr, $conn_timeout);
if (!$fp)
{
echo "$errstr ($errno)<br />\n";
return false;
}
$out = "POST $url HTTP/1.1\r\n";
$out .= "Host: $server\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Content-length: ". strlen($data) ."\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "$data";
stream_set_blocking($fp, false);
stream_set_timeout($fp, $rw_timeout);
fwrite($fp, $out);
//fwrite($fp, $data);
return $fp;
}
function JobPollAsync(&$fp)
{
if ($fp === false)
return false;
if (feof($fp))
{
fclose($fp);
$fp = false;
return false;
}
return fread($fp, 10000);
}
IN B.php
fileWrite ($_POST['displayGroupID'],$_POST['message'],$_POST['messageType']);
it get only "message" as it is listed as 1st element in array
Take a look at CURL. This is what you need and everyone else uses.
ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
curl_close ($ch);
For async variation take a look at a similar question answered before - How do I make an asynchronous GET request in PHP?