I am trying to get response from multiple url using API call and change color based on response. Problem is I want to get response from multiple url at the same time. But the program only can take the last url from the array.
I also tried using array for multiple url and looping but didn't work. Below is my code.
<?php
// An array of URLs to make requests to
$urls = array(
'https://example.com/v1/objects/services?service=1',
'https://example.com/v1/objects/services?service=2'
);
// Create a new cURL multi handle
$mh = curl_multi_init();
$username = "root";
$password = "apipass";
$headers = array(
'Accept: application/json',
'X-HTTP-Method-Override: GET'
// Add each URL to the cURL multi handle
foreach ($urls as $i => $url) {
$ch[$i] = curl_init();
curl_setopt_array($ch[$i], array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_USERPWD => $username . ":" . $password,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0
));
curl_multi_add_handle($mh, $ch[$i]);
}
// Execute the cURL multi handle
do {
$status = curl_multi_exec($mh, $active);
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
// Get the responses from each handle
foreach ($urls as $i => $url) {
$response[$i] = curl_multi_getcontent($ch[$i]);
}
// Close the cURL multi handle and each individual handle
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh, $ch[$i]);
}
curl_multi_close($mh);
foreach ($response as $i => $response) {
// check response and change color based on it
if(strpos($response, "Unreachable") !== false) {
$color[$i] = 'red';
// success response
} else {
$color[$i] = 'green';
}
}
print $status;
print $color[$i];
?>
Related
I am trying to get response from an array of webpages parallelly, with the help of curl_multi. Following is what I have tried:
$urls = ["wrongUrl1", "http://Wrongurl2.com"]
$mh = curl_multi_init();
foreach ($urls as $key => $url) {
$chs[$key] = curl_init($url);
curl_setopt($chs[$key], CURLOPT_RETURNTRANSFER, true);
curl_setopt($chs[$key], CURLOPT_FAILONERROR, true);
curl_multi_add_handle($mh, $chs[$key]);
}
//running the requests
$running = null;
do {
curl_multi_exec($mh, $running);
if ($running) {
// Wait a short time for more activity
curl_multi_select($mh);
}
} while ($running);
//getting the responses
foreach(array_keys($chs) as $key){
$error = curl_error($chs[$key]);
$header = curl_getinfo($chs[$key], CURLINFO_HTTP_CODE);
$time = curl_getinfo($chs[$key], CURLINFO_TOTAL_TIME);
$response = curl_multi_getcontent($chs[$key]); // get results
if (!empty($error)) {
echo "The request $key return a error: $error" . "\n";
}
else {
echo "The request to $urls[$key] : $error returned in $time seconds as $header" . "<br>";
}
curl_multi_remove_handle($mh, $chs[$key]);
}
// close current handler
curl_multi_close($mh);
$error always remains an empty string, why?.
Secondly I am able to get individual times for all urls. I wonder if the total time taken by curl_multi_exec to fetch all urls is same as the largest value $time?
I am working on API that return single currency record in one request. One request take 0.5-1 sec to response, and 15 requests take 7-15 seconds.
As i know server can manage 100s of request per seconds.
I want to hit 15 request on server at once so server will give response in 1-2 seconds not in 15 Seconds. Return all data in one single array to save my loading time.
Check my Code
I am using Loop, loop wait until previous curl request not complete. How can i say to loop, keep continue and dont wait for response.
$time_Start = microtime(true);
$ids = array(1,2,11,15,20,21); // 6 ids in demo, 15+ ids in real
$response = array();
foreach ($ids as $key => $id) {
$response[$id] = get_data($id);
}
echo "Time: ". (microtime(true)-$time_Start)."sec";
// output 5 seconds on 6 request
function get_data($id){
$fcs_api_key = "API_KEY";
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,"https://fcsapi.com/api/forex/indicators?id=".$id."&period=1d&access_key=".$fcs_api_key);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$buffer = curl_exec($ch);
curl_close($ch);
return $buffer;
}
You can use PHP multi curl https://www.php.net/manual/en/function.curl-multi-init.php
Below I write a code that open Parallel request.
$time_Start = microtime(true);
$ids = array(1,2,3,4,5,6); // You forex currency ids.
$response = php_curl_multi($ids);
echo "Time: ". (microtime(true)-$time_Start)."sec";
// Time: 0.7 sec
Function
function php_curl_multi($ids){
$parameters = "/api/forex/indicators?period=1d&access_key=API_KEY&id="; // ID will set dynamic
$url = "https://fcsapi.com".$parameters;
$ch_index = array(); // store all curl init
$response = array();
// create both cURL resources
foreach ($ids as $key => $id) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.$id);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ch_index[] = $ch;
}
//create the multiple cURL handle
$mh = curl_multi_init();
//add the handles
foreach ($ch_index as $key => $ch) {
curl_multi_add_handle($mh,$ch);
}
//execute the multi handle
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
//close the handles
foreach ($ch_index as $key => $ch) {
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
// get all response
foreach ($ch_index as $key => $ch) {
$response[] = curl_multi_getcontent($ch);
}
return $response;
}
I need to do a recursive loop on every result suggested by google up to a user-defined depth and save results in a multidimensional array, explored later on.
I want to get this result.
google
google app
google app store
google app store games
google app store games free
google maps
google maps directions
google maps directions driving
google maps directions driving canada
...
Currently, my recursive function returns replicated results from the second nesting.
google
google app
google app
google app store
google app store
google app
google app store
google app store
google app store
...
I think the problem comes from the array (parent results) that I pass as an argument to my function recursive_function() to each nested loops.
$child = recursive_function($parent[0][1], $depth, $inc+1);
Recursive function
// keywords at line or spaced
$keywords = explode("\n", trim("facebook"));
$result = recursive_function($keywords, 2);
function recursive_function($query, $depth, $inc = 1)
{
$urls = preg_filter('/^/', 'http://suggestqueries.google.com/complete/search?client=firefox&q=', array_map('urlencode', $query));
$parent = curl_multi_function($urls);
array_multisort($parent[0][1]);
if (count($parent[0][1]) === 0 || $inc >= $depth)
{
$out[] = $parent[0][1];
}
else
{
$child = recursive_function($parent[0][1], $depth, $inc+1);
$out[] = $child;
}
return $out;
}
Function curl
function curl_multi_function($data, $options = array())
{
// array of curl handles
$curly = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
// loop through $data and create curl handles
// then add them to the multi-handle
foreach ($data as $id => $d)
{
$curly[$id] = curl_init();
$url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
curl_setopt($curly[$id], CURLOPT_URL, $url);
curl_setopt($curly[$id], CURLOPT_HEADER, 0);
curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curly[$id], CURLOPT_SSL_VERIFYPEER, 0);
// post?
if (is_array($d))
{
if (!empty($d['post']))
{
curl_setopt($curly[$id], CURLOPT_POST, 1);
curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
}
}
// extra options?
if (!empty($options)) {
curl_setopt_array($curly[$id], $options);
}
curl_multi_add_handle($mh, $curly[$id]);
}
// execute the handles
$running = null;
do
{
curl_multi_exec($mh, $running);
}
while($running > 0);
// get content and remove handles
foreach($curly as $id => $c)
{
$result[$id] = curl_multi_getcontent($c);
// decode json result
$result[$id] = json_decode(utf8_encode($result[$id]));
curl_multi_remove_handle($mh, $c);
}
// all done
curl_multi_close($mh);
return $result;
}
Thank's
I've changed your recursive_function a little bit:
function recursive_function($query, $depth, $inc = 1)
{
$urls = preg_filter('/^/', 'http://suggestqueries.google.com/complete/search?client=firefox&q=', array_map('urlencode', $query));
$parent = curl_multi_function($urls);
foreach ($parent as $key => $value) {
array_multisort($value[1]);
$words = explode(' ', $value[0]);
$lastWord = end($words);
if (count($value[1]) === 0 || $inc >= $depth) {
$out[$lastWord] = [];
} else {
unset($value[1][0]);
$child = recursive_function($value[1], $depth, $inc+1);
$out[$lastWord] = $child;
}
}
return $out;
}
It generates an array like this:
[
google =>
[
app =>
[
store =>
[
games =>
[
free => []
]
]
]
...
]
]
Is that what you want?
I am writing my telegram bot codes in PHP. I would like to split my inline keyboard into 2 or 3 columns. Here is my code:
foreach ($categories as $cat) {
$key[] = array(
array('text'=>$cat['name'],'callback_data'=>'sub-'.$cat['id'])
);
if ($k % 2 == 0) {
$keyoptions[] = $key;
$key = array();
}
$k++;
}
$telegram->SendMessage($userid, $keyoptions);
but my code doesn't work. Where is the problem and how can I solve my issue?
EDIT :
i just used this code
$keyoptions = array_chunk($keyoptions,3);
but still can't find the problem;
Telegram API: inline_keyboard: Array of Array of InlineKeyboardButton
Example:
keyboard: [
["uno :+1:"],["uno \ud83d\udc4d", "due"],["uno", "due","tre"]
]
I don't know what library you are using and what are those fields in your code, but this a working with native telegram API:
function inlineKeyboard($text, $chatID, $btnNames, $callBackDatas)
{
$inlineRow = array(); // this is array for each row of buttons
$i = 0;
foreach ($btnNames as $name) {
array_push($inlineRow, array("text" => $name, "callback_data" => $callBackDatas[$i]));
$i++;
}
/* if you need multiple rows then just create other inlineRow arrays
and push to this array below */
$inlineKeyboard = array($inlineRow);
$keyboard = array(
"inline_keyboard" => $inlineKeyboard
);
$postfields = array
(
'chat_id' => "$chatID",
'text' => $text,
'reply_markup' => json_encode($keyboard)
);
send('sendMessage', $postfields);
}
define('BaseURL', 'https://api.telegram.org/bot<TOKEN>');
function send($method, $datas)
{
$url = BaseURL . "/" . $method;
if (!$curld = curl_init()) {
exit;
}
curl_setopt($curld, CURLOPT_POST, true);
curl_setopt($curld, CURLOPT_POSTFIELDS, $datas);
curl_setopt($curld, CURLOPT_URL, $url);
curl_setopt($curld, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($curld);
curl_close($curld);
return $output;
}
I'm writing a mass youtube link finder, which imports a list of titles from an array, generates an API url and the executes them with curl_multi.
However, curl returns blank data for each link. Links are fine as I can access to them correctly via Chrome.
file_get_contents() tried in another script with a url amongst those returns an ERR_EMPTY_RESPONSE in Chrome.
Any help would be much appreciated,
EDIT: Code:
function getYTUrl($urls){
$curls = array();
$result = array();
$arrjson = array();
$mh = curl_multi_init();
foreach ($urls as $key => $value) {
echo $value;
$curls[$key] = curl_init();
curl_setopt($curls[$key], CURLOPT_URL, $value);
curl_setopt($curls[$key], CURLOPT_HEADER, 0);
curl_setopt($curls[$key], CURLOPT_RETURNTRANSFER, true);
curl_setopt($curls[$key],CURLOPT_SSL_VERIFYPEER,false);
curl_multi_add_handle($mh, $curls[$key]);
}
$active = null;
do{
$mrc = curl_multi_exec($mh, $active);
}
while ($active);
foreach ($urls as $key => $value) {
$result[$key] = curl_multi_getcontent($curls[$value]);
curl_multi_remove_handle($mh, $value);
}
curl_multi_close($mh);
}