alchemyAPI for php not working - php

I am trying to use AlchemyAPI's php sdk. I am running the same example given on their Github page.
But when I try to run the example, I get this error message-
Warning: fclose() expects parameter 1 to be resource, boolean given in C:\wamp\www\twitter-analysis\alchemyapi.php on line 261
What could be the reason? In alchemyapi.php, this is where the warning is occuring-
private function analyze($url, $params) {
//Insert the base URL
$url = $this->_BASE_URL . $url;
//Add the API Key and set the output mode to JSON
$url = $url . '?apikey=' . $this->_api_key . '&outputMode=json';
//Add the remaining parameters
foreach($params as $key => $value) {
$url = $url . '&' . $key . '=' . $value;
}
//Create the HTTP header
$header = array('http' => array('method' => 'POST', 'Content-type'=> 'application/x-www-form-urlencoded'));
//Fire off the HTTP Request
try {
$fp = #fopen($url, 'rb',false, stream_context_create($header));
$response = #stream_get_contents($fp);
fclose($fp);
return json_decode($response, true);
} catch (Exception $e) {
return array('status'=>'ERROR', 'statusInfo'=>'Network error');
}
}
}

fopen() returns the resource if it succeeds, and false if it didn't work. The most likely case for the fopen to not work is if the path is invalid or if you don't have access to the resource.
A similar question was asked here: https://stackoverflow.com/questions/18636680/php-warning-fclose-expects-parameter-1-to-be-resource-boolean-given

Try to test on live server.
My experience it gives error in local server where works in live server.

Related

telegram api send message return nothing

I want to send message via telegram api but it's not working, and not send any message. this is what i tried so far:
function sendTelegram($chatID, $msg) {
echo "sending message to " . $chatID . "\n";
$token = "botxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$getUpdate = "http://api.telegram.org/" . $token . "/getUpdates";
$url = "https://api.telegram.org/" . $token . "/sendMessage?chat_id=" . $chatID;
$url = $url . "&text=" . urlencode($msg);
$ch = curl_init();
$optArray = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true
);
curl_setopt_array($ch, $optArray);
$result = curl_exec($ch);
curl_close($ch);
}
$msg = "Hi";
$chatID = "88132232";
sendTelegram($chatID, $msg);
My progress:
I made a new bot via #botfather and got a token.
Then sent a message to this bot with my telegram.
I got chat id in getUpdates.
https://api.telegram.org/botxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/getUpdates
and also send message via:
https://api.telegram.org/botxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/sendMessage?chat_id=88132232&text=hi
It works find when i go to this url but when i want to do this dynamically it give me nothing just echo sending message to 88132232 with no error. I searched and read many topics but no success, any idea what i missed? Before using curl i used get_file_contents but it also not worked.
You set CURLOPT_RETURNTRANSFER
CURLOPT_RETURNTRANSFER: TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
Please return $result in sendTelegram() function, and echo it.
function sendTelegram($chatID, $msg) {
// ...
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$result = sendTelegram($chatID, $msg);
echo $result; // JSON String
Probably you have error but in curl you should get curl error like this:
if(curl_error($ch)){
echo 'error:' . curl_error($ch);
}
And most problem is SSL. get your error and back. but i tested your code, as #Sean said, your code working fine, try it on php fiddle website. if you get SSL error, read this.

PHP and JSON for Reddit

want to grab from a specific Reddit user some data.
There's a dynamic JSON file on the Reddit servers which can be accessed remotely.
The JSON file path is: http://www.reddit.com/user/tiagoperes/about.json
(where you can replace “tiagoperes” in the URL with whatever user you were trying to look up) - thank you Tom Chapin
Problem: I get the error message
http error 500: reddiant.com/reddit.php
Error Log:
PHP Warning:
file_get_contents(https://www.reddit.com/user/tiagoperes/about.json):
failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden on
line 5
PHP Fatal error: Uncaught exception 'InvalidArgumentException'
with message 'Passed variable is not an array or object, using empty
array instead' on line 8
Code:
<?php
$url = "https://www.reddit.com/user/tiagoperes/about.json";
$json = file_get_contents($url);
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(json_decode($json, TRUE)),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
echo "$key:\n";
} else {
echo "$key => $val\n";
}
}
(inspired in this: http://codepad.org/Gtk8DqJE)
Solution: Ask for debug.
What's the problem right here?
Can not find a way to make it work and should be quite straightforward.
Thank you!
Was getting some troubles in the first procedure, so decided to change the approach.
Got it to work like that:
<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"User-Agent: reddiant api script\r\n"
));
$context = stream_context_create($opts);
$url = "http://www.reddit.com/user/tiagoperes/about.json";
$json = file_get_contents($url, false, $context);
$result = json_decode($json, true);
// Result:
var_dump($result);
//echo data
echo $result['data']['name'];

oAuth signature creation issue with PHP (posting photoset to Tumblr)

I've made a simple script that posts images on tumblr.
everything is fine, but I've noticed some performance issues right after I've changed the host provider (my new host is limited and cheaper).
now, after debugging the script and after contacting the tumblr api helpdesk, I'm stuck on a problem:
there are 3 functions:
function oauth_gen($method, $url, $iparams, &$headers) {
$iparams['oauth_consumer_key'] = CONSUMER_KEY;
$iparams['oauth_nonce'] = strval(time());
$iparams['oauth_signature_method'] = 'HMAC-SHA1';
$iparams['oauth_timestamp'] = strval(time());
$iparams['oauth_token'] = OAUTH_TOKEN;
$iparams['oauth_version'] = '1.0';
$iparams['oauth_signature'] = oauth_sig($method, $url, $iparams);
$oauth_header = array();
foreach($iparams as $key => $value) {
if (strpos($key, "oauth") !== false) {
$oauth_header []= $key ."=".$value;
}
}
$str = print_r($iparams, true);
file_put_contents('data1-1.txt', $str);
$oauth_header = "OAuth ". implode(",", $oauth_header);
$headers["Authorization"] = $oauth_header;
}
function oauth_sig($method, $uri, $params) {
$parts []= $method;
$parts []= rawurlencode($uri);
$iparams = array();
ksort($params);
foreach($params as $key => $data) {
if(is_array($data)) {
$count = 0;
foreach($data as $val) {
$n = $key . "[". $count . "]";
$iparams []= $n . "=" . rawurlencode($val);
//$iparams []= $n . "=" . $val;
$count++;
}
} else {
$iparams[]= rawurlencode($key) . "=" .rawurlencode($data);
}
}
//debug($iparams,"iparams");
$str = print_r($iparams, true);
file_put_contents('data-1.txt', $str);
//$size = filesize('data.txt');
$parts []= rawurlencode(implode("&", $iparams));
//debug($parts,"parts");
//die();
$sig = implode("&", $parts);
return base64_encode(hash_hmac('sha1', $sig, CONSUMER_SECRET."&". OAUTH_SECRET, true));
}
these 2 functions above comes from an online functional example, they have always worked fine.
this is the function I use to call the APIs and the oAuth:
function posta_array($files,$queue,$tags,$caption,$link,$blog){
$datArr = array();
$photoset_layout = "";
foreach ($files as $sing_file){
$dataArr [] = file_get_contents($sing_file);
$photoset_layout .= "1";
}
$headers = array("Host" => "http://api.tumblr.com/", "Content-type" => "application/x-www-form-urlencoded", "Expect" => "");
$params = array(
"data" => $dataArr,
"type" => "photo",
"state" => $queue,
"tags"=>$tags,
"caption"=>$caption,
"photoset_layout" => $photoset_layout,
"link"=>str_replace("_","",$link)
);
debug($headers,"head");
oauth_gen("POST", "http://api.tumblr.com/v2/blog/$blog/post", $params, $headers);
debug($headers,"head 2");
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, "Tumblr v1.0");
curl_setopt($ch, CURLOPT_URL, "http://api.tumblr.com/v2/blog/$blog/post");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: " . $headers['Authorization'],
"Content-type: " . $headers["Content-type"],
"Expect: ")
);
$params = http_build_query($params);
$str = print_r($params, true);
file_put_contents('data_curl1.txt', $str);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
debug($response,"response");
return $response;
}
this is the function with some problems, I try to explain:
I called the oauth_gen passing the parameters array to it, the oauth_gen creates the oauth header that I later used here: "Authorization: " . $headers['Authorization'],.
As I stated, everything is working smoothly, until I have tried to post a gif photoset of 6 files for a total of 6Mb (tumblr permit 2Mb each file and 10Mb total).
PHP runs out of memory and return an error, here it starts my debugging, after a while I contacted the tumblr api helpdesk, and they answer in this way:
You shouldn't need to include the files in the parameters used for
generating the oauth signature. For an example of how this is done,
checkout one of our official API clients.
This changes everything. Untill now, I passed the entire parameters array to the oauth_gen, which, calling the oauth_sig, will rawencode everything into the array (binary strings of gif files inlcuded), with a result of a binary file of about 1Mb becomes at least 3Mb of rawurlencoded string.
and that's why I had memory issues. Nice, so, as the helpdesk say, I've changed the call to the oauth_gen in this way:
$new_array = array();
oauth_gen("POST", "http://api.tumblr.com/v2/blog/$blog/post", $new_array, $headers);
seams legit to me, I passed a new array to the function, the function then generate the oAuth, the headers are passed back and I can use them into the posting call, the result was:
{"meta":{"status":401,"msg":"Unauthorized"},"response":[]}
asking more to tumblr api helpdesk leads only to more links to their documentation and their "tumblr php client" which I can't use, so it isn't a option.
Does anyone has experience with oAuth and can explain me what I'm doing wrong? as far as I understand, the trick is into the encrypted data the oauth_sig create, but I can't figure out how to proceed.
I really want to understand the oauth, but more I read about it and more the tumblr helpdsek seams right to me, but... the solution doesn't work, and works only if I let the oauth function to encrypt the entire data array (with the images and everything) but I can understand that this is wrong... help me.
UPDATE 1
I've tried a new thing today, first I created the empty array, then passed by reference to the oauth_genand only after generating the signature, I've added to the same array all the other fields about the post itself, but the result is the same.
UPDATE 2
reading here: http://oauth.net/core/1.0a/#signing_process
seems that the parameters of the request must all be used for the signature, but this is not totally clear (if someone could explain it better, I really appreciate).
this is weird, because if it's true, it go against the words of the Tumblr help desk, while if it's not true, there is a little confusion in the whole process.
by the way, at this time, I'm stile struck in the same point.
After digging couple of hours into the issue, debugging, reviewing tumblr api and api client, registering a test account and trying to post some images. The good news is finally I come up with a solution. It is not using a native CURL only, you need guzzle and an OAuth library to sign the requests.
Tumblr guys are correct about signing the request. You don't need to pass image data to sign the request. If you check their official library you can see; https://github.com/tumblr/tumblr.php/blob/master/lib/Tumblr/API/RequestHandler.php#L85
I tried to fix the issue with native CURL library but unfortunately I was not successful, either I was signing the request in a wrong way or missing something in the request header, data etc. I don't know actually, Tumblr api is really bad at informing you what you are doing wrong.
So I cheated a little bit and start to read Tumblr api client code, and I come up with a solution.
Here we go, first you need two packages.
$ composer require "eher/oauth:1.0.*"
$ composer require "guzzle/guzzle:>=3.1.0,<4"
And then the PHP code, just define your keys, tokens, secrets etc. Then it should be good to go.
Since the signing request does not include picture data, it is not exceeding memory limit. After signing the request actually we are not getting the contents of the files into our post data array. We are using addPostFiles method of guzzle, which takes care of file addition to POST request, does the dirty work for you. And here is the result for me;
string(70) "{"meta":{"status":201,"msg":"Created"},"response":{"id":143679527674}}"
And here is the url;
http://blog-transparentcoffeebouquet.tumblr.com/
<?php
ini_set('memory_limit', '64M');
define("CONSUMER_KEY", "");
define("CONSUMER_SECRET", "");
define("OAUTH_TOKEN", "");
define("OAUTH_SECRET", "");
function request($options,$blog) {
// Take off the data param, we'll add it back after signing
$files = isset($options['data']) ? $options['data'] : false;
unset($options['data']);
$url = "https://api.tumblr.com/v2/blog/$blog/post";
$client = new \Guzzle\Http\Client(null, array(
'redirect.disable' => true
));
$consumer = new \Eher\OAuth\Consumer(CONSUMER_KEY, CONSUMER_SECRET);
$token = new \Eher\OAuth\Token(OAUTH_TOKEN, OAUTH_SECRET);
$oauth = \Eher\OAuth\Request::from_consumer_and_token(
$consumer,
$token,
"POST",
$url,
$options
);
$oauth->sign_request(new \Eher\OAuth\HmacSha1(), $consumer, $token);
$authHeader = $oauth->to_header();
$pieces = explode(' ', $authHeader, 2);
$authString = $pieces[1];
// POST requests get the params in the body, with the files added
// and as multipart if appropriate
/** #var \Guzzle\Http\Message\RequestInterface $request */
$request = $client->post($url, null, $options);
$request->addHeader('Authorization', $authString);
if ($files) {
if (is_array($files)) {
$collection = array();
foreach ($files as $idx => $f) {
$collection["data[$idx]"] = $f;
}
$request->addPostFiles($collection);
} else {
$request->addPostFiles(array('data' => $files));
}
}
$request->setHeader('User-Agent', 'tumblr.php/0.1.2');
// Guzzle throws errors, but we collapse them and just grab the
// response, since we deal with this at the \Tumblr\Client level
try {
$response = $request->send();
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
$response = $request->getResponse();
}
// Construct the object that the Client expects to see, and return it
$obj = new \stdClass;
$obj->status = $response->getStatusCode();
$obj->body = $response->getBody();
$obj->headers = $response->getHeaders()->toArray();
return $obj;
}
$files = [
"/photo/1.jpg",
"/photo/2.jpg",
"/photo/3.png",
"/photo/4.jpg",
"/photo/1.jpg",
"/photo/2.jpg",
"/photo/3.png",
"/photo/4.jpg",
"/photo/1.jpg",
"/photo/2.jpg",
];
$params = array(
"type" => "photo",
"state" => "published",
"tags"=> [],
"caption"=>"caption",
"link"=>str_replace("_","","http://stackoverflow.com/questions/36747697/oauth-signature-creation-issue-with-php-posting-photoset-to-tumblr"),
"data" => $files,
);
$response = request($params, "blog-transparentcoffeebouquet.tumblr.com");
var_dump($response->body->__toString());

HTTP Request Failed - Google Maps

I have a question with my Google Maps API. I am using a simple geocoding script to pull a txt/xml file from my server and geocoding the addresses. I have a problem with the addresses coming back as a null value and breaking the script and my database because the coord_lat and coord_long are floats and cannot accept null values.
The error I am receiving is: Warning: file_get_contents(http://maps.google.com/maps/geo?key=AIzaSyBmT9F_ixjLlW8oDiYVqgHqt14a008kXwc&output=xml&q=131+rochestor+ave+039482) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden in /includes/sfupdate/func.php on line 294 {"status":"Failed","data":"SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'coord_lat' cannot be null"}
ErrorSyntaxError: Unexpected token
Is this a problem with my connection with Google Maps API? I see HTTP Request failed which leads me to believe that I am being rejected and the addresses are turning back a null value because of it. Advice would be appreciated, thank you.
Sorry for posting a new answer, but here is my current geocoding script.
function get_lat_long($address, $zipcode) {
if(strlen($zipcode) == 4){
$zipcode = '0' . $zipcode;
//echo $zipcode . "\n";
}
$apikey = "IzaSyBmT9F_ixjLlW8oDiYVqgHqt14a008kXwc";
$geourl = "http://maps.google.com/maps/geo?key=" . $apikey . "&output=xml&q=" . urlencode($address) . "+" . urlencode($zipcode);
//echo $geourl;
//echo "<br>";
// Grab XML content using $geourl
$context = stream_context_create(array('http' => array('header' => 'Accept: application/xml')));
$xml = file_get_contents($geourl, false, $context);
$xml = simplexml_load_string($xml);
//Parse the lat and long from the XML
$Lat = $xml->results->result->locations->location->displayLatLng->latLng->lat;
//echo $Lat;
$Lng = $xml->results->result->locations->location->displayLatLng->latLng->lng;
//echo $Lng;
//Return
if($Lng && $Lat) {
return array('lat'=>$Lat,
'lng'=>$Lng
);
} else {
return false;
}
}

Can't read XML with simplexml_load_file PHP

So i am trying to parse data from an XML url and insert it into a table using php, which can be seen here, (please keep in mind there are more products than displayed on this page, i am not trying to get it for just this Product,the code below shows how i am parsing all products) but i keep getting the following errors:
[EDITED]
class DataGrabber {
//The URL where data will be extracted from, which is an XML file
protected $URL = "http://json.zandparts.com/api/category/GetCategories/44/EUR/";
public function call_api($data) {
if(count($data) == 0) return array();
$jsondata = array();
foreach($data as $entry){
$url = $this->URL . $entry['model'] . "/" . urlencode($entry['family']) . "/" . urlencode($entry['cat']) . "/" . $entry['man'] . "/null";
$json = file_get_contents($url);
$data = json_decode($json, true);
if(!empty($data['Products'])){
foreach ($data['Products'] as $id => $product) {
$jsonentry = array(
'productnumber' => $id,
'partnumber' => $product['strPartNumber'],
'description' => $product['strDescription'],
'manu' => $product['Brand']
);
$jsondata[] = $jsonentry;
}
}
}
return $jsondata;
}
}
[NEW ERRORS]
So i have fixed the error:
PHP Warning: file_get_contents(http://json.zandparts.com/api/category/GetCategories/44/EUR/ET10B/E Series/AC Adapter/Asus/null): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
in /home/svn/dev.comp/Asus.php on line 82
by using urlencode as shown in my code above
This warning below isnt finding the values for the url:
PHP Warning: file_get_contents(http://json.zandparts.com/api/category/GetCategories/44/EUR///04G265003580/Asus/null): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
as you can see after, 44/EUR there are three forward slashes with no data?? How would i resolve this??
The remote server appears to use the Accept HTTP header to choose the output format. With PHP default options it sends back JSON instead of XML:
<?php
echo file_get_contents('http://json.zandparts.com/api/category/GetCategories/44/EUR/ET10B/E%20Series/AC%20Adapter/Asus/null');
... prints:
{"Categories":[{"Brand":null,"Fami...
To specify an Accept header you need to retrieve the data with some other function, e.g.:
<?php
$context = stream_context_create(
array(
'http' => array(
'header' => "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n",
)
)
);
echo file_get_contents('http://json.zandparts.com/api/category/GetCategories/44/EUR/ET10B/E%20Series/AC%20Adapter/Asus/null', false, $context);
... prints:
<?xml version="1.0" encoding="utf-8"?><ProductCategory ...
Tweak it to your exact needs, I just copied the header from my browser.
Here's a code snippet that shows you how to get the values for strPartNumber, strDescription and Brand for all the products in that JSON data:
<?php
$url = 'http://json.zandparts.com/api/category/GetCategories/44/EUR/ET10B/E%20Series/AC%20Adapter/Asus/null';
$json = file_get_contents($url);
// Decode the JSON data as a PHP array
$data = json_decode($json, true);
if (!empty($data['Products'])) {
foreach ($data['Products'] as $id => $product) {
echo "Product #{$id}\n";
echo "Part number: {$product['strPartNumber']}\n";
echo "Description: {$product['strDescription']}\n";
echo "Brand: {$product['Brand']}\n\n";
}
}
Output:
Product #0
Part number: 04G265003580
Description: POWER ADAPTER 65W19V 3PIN
Brand: Asus
Product #1
Part number: 14G110008340
Description: POWER CORD 3P L:80CM,TW(B)
Brand: Asus

Categories