Related
The following code runs without any errors, however it doesn't return anything.
If I paste it into my browser it returns the information I'm looking for, I can also replace it with another URL and it works perfectly.
$ch = curl_init();
$url = 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaName=Somerset&structure={"date":"date","areaName":"areaName","areaCode":"areaCode","newCasesByPublishDate":"newCasesByPublishDate","cumCasesByPublishDate":"cumCasesByPublishDate","newDeathsByDeathDate":"newDeathsByDeathDate","cumDeathsByDeathDate":"cumDeathsByDeathDate"}';
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$decode =json_decode($resp);
print_r($decode);
curl_close($ch);
You can use following generated code by the postman
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.coronavirus.data.gov.uk/v1/',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POSTFIELDS =>'{"date":"date","areaName":"areaName","areaCode":"areaCode","newCasesByPublishDate":"newCasesByPublishDate","cumCasesByPublishDate":"cumCasesByPublishDate","newDeathsByDeathDate":"newDeathsByDeathDate","cumDeathsByDeathDate":"cumDeathsByDeathDate"}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
This code is worked. Reason is encoding of received content.
try {
$ch = curl_init();
// Check if initialization had gone wrong*
if ( $ch === false ) {
throw new RuntimeException( 'failed to initialize' );
}
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL,
'https://api.coronavirus.data.gov.uk/v1/data?filters=areaName=Somerset&structure={"date":"date","areaName":"areaName","areaCode":"areaCode","newCasesByPublishDate":"newCasesByPublishDate","cumCasesByPublishDate":"cumCasesByPublishDate","newDeathsByDeathDate":"newDeathsByDeathDate","cumDeathsByDeathDate":"cumDeathsByDeathDate"}' );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Solution is here. Response is the compressed content which your curl failed to detect. Empty encoding means to handle any type of encoding. It should solve your issue.
curl_setopt($ch, CURLOPT_ENCODING, '');
$content = curl_exec( $ch );
curl_close( $ch );
if ( $content === false ) {
throw new RuntimeException( curl_error( $ch ), curl_errno( $ch ) );
}
/* Process $content here */
$decode = json_decode( $content );
var_dump( $decode );
// Close curl handle
curl_close( $ch );
} catch ( RuntimeException $e ) {
trigger_error(
sprintf(
'Curl failed with error #%d: %s',
$e->getCode(),
$e->getMessage()
),
E_USER_ERROR
);
}
When we make a query to [Translate API][1]:
function curl($url, $post_array=false){
$handle = curl_init();
if (FALSE === $handle)
throw new Exception('failed to CURL initialize; '. __FILE__);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
if($post_array) {
curl_setopt($handle, CURLOPT_POST, 1 );
curl_setopt($handle, CURLOPT_POSTFIELDS, $post_array );
}
curl_setopt($handle,CURLOPT_HTTPHEADER,array('X-HTTP-Method-Override: GET'));
$response = curl_exec($handle);
return $response;
}
var_dump ( curl("https://www.googleapis.com/language/translate/v2", ['key'=>$key, 'q[]'=>"hello", 'q[]'=>"world", 'source'=>"en", 'target'=>'ru'] ) );
ends in error:
{
"error": {
"code": 400,
"message": "Required Text",
"errors": [
{
"message": "Required Text",
"domain": "global",
"reason": "required"
}
]
}
}
How to send multiple q input texts? As I see, the API doesn't allow q[] type arrays, instead it uses multiple q parameters. But in php we can't have same key multiple times in array...
i believe this API supports JSON, and JSON supports arrays, so just do
function curl($url, array $post_array){
$handle = curl_init();
curl_setopt_array($ch,array(
CURLOPT_POST=>1,
CURLOPT_POSTFIELDS=>json_encode($post_data),
CURLOPT_HTTPHEADER=>array('Content-Type: application/json')
));
(...)
}
and call it like
var_dump ( curl("https://www.googleapis.com/language/translate/v2",
['key'=>$key, 'q'=>array("hello","world"),
'source'=>"en", 'target'=>'ru'] ) );
You should encode the post fields. PHP offers http_build_query.
function curl($url, $post_array=false){
$handle = curl_init();
if (FALSE === $handle)
throw new Exception('failed to CURL initialize; '. __FILE__);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
if($post_array) {
curl_setopt($handle, CURLOPT_POST, 1 );
curl_setopt($handle, CURLOPT_POSTFIELDS, http_build_query($post_array) );
}
curl_setopt($handle,CURLOPT_HTTPHEADER,array('X-HTTP-Method-Override: GET'));
$response = curl_exec($handle);
return $response;
}
var_dump ( curl("https://www.googleapis.com/language/translate/v2", ['key'=>$key, 'q'=> array("hello", "world"), 'source'=>"en", 'target'=>'ru'] ) );
Relevant are this post and this post.
As suggested in a comment, rather than using an array where there can not be repeated keys in the POSTFIELDS data array ( or any array in PHP ) you can supply a string for the POST data
My curl function
function curl( $url=NULL, $options=NULL ){
$cacert='c:/wwwroot/cacert.pem'; #<---- edit to suit
$vbh = fopen('php://temp', 'w+');
$res=array(
'response' => NULL,
'info' => array( 'http_code' => 100 ),
'headers' => NULL,
'errors' => NULL
);
if( is_null( $url ) ) return (object)$res;
session_write_close();
/* Initialise curl request object */
$curl=curl_init();
if( parse_url( $url,PHP_URL_SCHEME )=='https' ){
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
}
/* Define standard options */
curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_FAILONERROR, true );
curl_setopt( $curl, CURLOPT_HEADER, false );
curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 );
curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' );
curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
curl_setopt( $curl, CURLOPT_ENCODING, '' );
curl_setopt( $curl, CURLOPT_VERBOSE, true );
curl_setopt( $curl, CURLOPT_NOPROGRESS, true );
curl_setopt( $curl, CURLOPT_STDERR, $vbh );
/* Assign runtime parameters as options */
if( isset( $options ) && is_array( $options ) ){
foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value );
}
/* Execute the request and store responses */
$res=(object)array(
'response' => curl_exec( $curl ),
'info' => (object)curl_getinfo( $curl ),
'errors' => curl_error( $curl )
);
rewind( $vbh );
$res->verbose=stream_get_contents( $vbh );
fclose( $vbh );
curl_close( $curl );
return $res;
}
The configuration for the request:
$key='AIzaSyxxxxxxxxxxxxxxxxxxx9oIhY8Q8xxxxx';
$url='https://www.googleapis.com/language/translate/v2';
$arr=array( 'another', 'elephant', 'banana', 'woman' );
/* some translate parameters */
$params=array(
'target' => 'fr',
'format' => 'text',
'source' => 'en',
'model' => 'nmt'
);
/* the POST data */
$query=implode( '&', array(
sprintf( 'key=%s&q=%s',$key, implode( '&q=', $arr ) ), #query
urldecode( http_build_query( $params ) ) #google params
));
$config=array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $query
);
$res=curl( $url, $config );
if( $res->info->http_code==200 ){
printf('<pre>%s</pre>',print_r( $res->response,true ) );
}
Appears to work OK and returns:
{
"data": {
"translations": [
{
"translatedText": "un autre",
"model": "nmt"
},
{
"translatedText": "l'éléphant",
"model": "nmt"
},
{
"translatedText": "banane",
"model": "nmt"
},
{
"translatedText": "femme",
"model": "nmt"
}
]
}
}
For others finding their way here and looking for how to translate multiple texts in a simple GET-request to the Google Cloud Translation v2 REST API, you just need to add multiple q= parameters to your URL.
No need to mess around with cURL, just use file_get_contents and get on with your life. Something like this would do the job:
$texts = ['foo', 'bar', 'hello world'];
// Translate from english to swedish
$queryParams = [
'target' => 'sv',
'source' => 'en',
'format' => 'text',
'key' => 'INSERT_YOUR_API_KEY_HERE',
];
// Now let's add q=<text> for each text
$queryString = http_build_query($queryParams);
foreach($texts as $t){
$queryString .= '&q='.rawurlencode($t);
}
$url = "https://translation.googleapis.com/language/translate/v2?$queryString";
$responseBody = file_get_contents($url);
$responseArr = json_decode($responseBody, true);
this is my well-worked code snippet.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://translation.googleapis.com/language/translate/v2?API-KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$text1="The Great Pyramid of Giza (also known as the Pyramid of Khufu or the Pyramid of Cheops) is the oldest and largest of the three pyramids in the Giza pyramid complex.";
$text2="this is second text example";
$params = array(
'source'=>"en",
'target'=> "sr-Latn",//serbian sr
'format'=>"text",
);
$post=implode('&',array(sprint_f('&q=%s',implode('&q=',array($text1,$text2)),urldecode(http_build_query($params)))));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$result=json_decode($response,true);
print_r($result['data']['translations']);
I used following code in PHP to send GCM message to Android:
<?php
$apiKey = "xxxxx"; //my api key
$registrationIDs = array("APA91bGGN7o7AwVNnv35lwP5Jw8OTJQL331XcxPfEIu4xt-ZKLe6R0aSSbAve99uKSDXhzE9L2PVLihpqFt0DEawhymUs9h5ICbTMweMAEJypg6ZLFqmf6SOGlyULQzudw9MM1DjbPaaKbo--wxWoHGkjyec2H_63e7mesYjaRf4_rgxBe655M0");
// Message to be sent
$message = "Message Text";
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registrationIDs,
'data' => array( "message" => $message ),
);
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
It's working fine. Here I added my device tokens manually(hardcoded).
But when i tried getting device tokens from the database, I am getting below mentioned error.
Code:
<?php
include 'config.php';
if($_REQUEST['msg']!='')
{
echo $message = $_REQUEST['msg'];
// Replace with real BROWSER API key from Google APIs
$apiKey ="xxxxxx"; //my api key
// Replace with real client registration IDs
$sql = mysql_query("SELECT `device_token` FROM `users`");
$result = mysql_fetch_array($sql);
$registrationIDs = $result;
// Message to be sent
$message = $_REQUEST['msg'];
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registrationIDs,
'data' => array( "message" => $message ),
);
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
}
I also tried using json_encode($registration_ids) with no use.
"registration_ids" field is not a JSON array
I finally got a solution. I used a for loop to get all the results into an array and converted array into JSON array using json_encode();
I was getting the same error because my array indexes are not properly sorted I fix it by using PHP's sort() function.
Before Sort
$registration_ids = Array
(
[1] => "xxx"
[6] => "xxx"
[8] => "xxx"
)
Sort
sort($registration_ids);
After Sort
$registration_ids = Array
(
[0] => "xxx"
[1] => "xxx"
[2] => "xxx"
)
Pass to PHP's cURL
$fields = array(
'registration_ids' => $ids,
'data' => array('message' => $data)
);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
I have the following JSON code:
{"username":"user1","password":"123456"}
That I need to pass to a url, lets say: http://api.mywebsite.com
I'm an extreme php newb, so I've been following a curl tutorial, but here is my current PHP code:
<?php
function get_web_page( $url )
{
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle compressed
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
?>
You might want to look into the CURLOPT_POSTFIELDS AND CURLOPT_POST options. These allow you to do a POST request and pass the data set into the CURLOPT_POSTFIELDS in the request.
Something in the lines of this:
$body = 'bar=1&foo=2&baz=3';
$c = curl_init ($url);
curl_setopt ($c, CURLOPT_POST, true);
curl_setopt ($c, CURLOPT_POSTFIELDS, $body);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
When you want to use normal GET Params:
$jsonString ='{"username":"user1","password":"123456"}';
$params = json_decode($jsonString);
$getParams = '';
$first = true;
foreach ($params as $key => $param){
if ($first){
$getParams .= '?';
$first = false;
} else{
$getParams .= '&';
}
$getParams .= $key .'=' .$param;
}
echo $getParams;
get_web_page($url . $getParams);
I'm using file_get_contents() to grab content from a site, and amazingly it works even if the URL I pass as argument redirects to another URL.
The problem is I need to know the new URL, is there a way to do that?
If you need to use file_get_contents() instead of curl, don't follow redirects automatically:
$context = stream_context_create(
array(
'http' => array(
'follow_location' => false
)
)
);
$html = file_get_contents('http://www.example.com/', false, $context);
var_dump($http_response_header);
Answer inspired by: How do I ignore a moved-header with file_get_contents in PHP?
You might make a request with cURL instead of file_get_contents().
Something like this should work...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$a = curl_exec($ch);
if(preg_match('#Location: (.*)#', $a, $r))
$l = trim($r[1]);
Source
Everything in one function:
function get_web_page( $url ) {
$res = array();
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // do not return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$res['content'] = $content;
$res['url'] = $header['url'];
return $res;
}
print_r(get_web_page("http://www.example.com/redirectfrom"));
A complete solution using the bare file_get_contents (note the in-out $url parameter):
function get_url_contents_and_final_url(&$url)
{
do
{
$context = stream_context_create(
array(
"http" => array(
"follow_location" => false,
),
)
);
$result = file_get_contents($url, false, $context);
$pattern = "/^Location:\s*(.*)$/i";
$location_headers = preg_grep($pattern, $http_response_header);
if (!empty($location_headers) &&
preg_match($pattern, array_values($location_headers)[0], $matches))
{
$url = $matches[1];
$repeat = true;
}
else
{
$repeat = false;
}
}
while ($repeat);
return $result;
}
Note that this works only with an absolute URL in the Location header. If you need to support relative URLs, see
PHP: How to resolve a relative url.
For example, if you use the solution from the answer by #Joyce Babu, replace:
$url = $matches[1];
with:
$url = getAbsoluteURL($matches[1], $url);
I use get_headers($url, 1);
In my case redirect url in get_headers($url, 1)['Location'][1];