I am wanting cURL to retry when cURL fails, but I have a situation like this
My function inside while loop is not working.
But when I remove the while loop, it works normally again.
Here is my function snippet:
function Curl($url){
$total_curl = 1;
$isRunning = true;
$sleep = 1;
while ($isRunning){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_REFERER, $this->url ?? $url);
//for debug only!
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT,10);
$resp = curl_exec($curl);
if((!$resp || curl_errno($curl))){
if($total_curl > 3){
$isRunning = false;
}
sleep($sleep);
}
curl_close($curl);
$total_curl++;
}
return $resp;
}
The problem is in your while loop. If the curl is successful your while loop will run forever because the $total_curl variable is never checked in the nested if.
I would suggest using recursion for this, sicne i find it a bit cleaner and this is how i would approach it:
/**
* Solve using recursion cause it's fun
*/
function Curl($url, $times_run = 0)
{
// Condition that will break recursion, in this case if curl failed and run 3 times
if ($times_run > 3) {
return;
}
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_REFERER, $url); // replace this with $this->url ?? $url if you want but i removed it since i am not inside a class
//for debug only!
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$resp = curl_exec($curl);
// Start recursive function if curl is not successful
if ((!$resp || curl_errno($curl))) {
Curl($url, $times_run++);
}
curl_close($curl);
return $resp;
}
The alternative would be to keep your way and just add a return $resp at the end of your while loop like so:
function Curl($url)
{
$total_curl = 1;
$isRunning = true;
while ($isRunning) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_REFERER, $this->url ?? $url);
//for debug only!
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$resp = curl_exec($curl);
if ((!$resp || curl_errno($curl))) {
if ($total_curl > 3) {
$isRunning = false;
}
curl_close($curl);
$total_curl++;
} else {
curl_close($curl);
return $resp;
}
}
}
I hope this helps with your problem, cheers.
Related
How I can use multi threads using CURL in my case, because the function curl_multi_init() work for different urls. In my case I have only one url that I need to sent a large requests. The code below works to me very fine but, need more than 5 minutes for 1000 requests and my data can be more than 50K.
<?php
class API {
private $url="http://xxxxxxxxxxxxxxxx";
public function __construct(){
}
public function __destruct() {
}
public function callAPI($list, $country){
$lists=explode(",",$list);
$data=array();
foreach ($lists as $element) {
$data[]=$this->callSingle($element, $country);
}
return json_encode($data);
}
private function callSingle($id, $country){
$url=$this->url.'/'.$country.'/'.$id;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_ENCODING, '');
curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 0);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
?>
Please, how to convert the following code to async GuzzleHttp?
In this way, php is waiting for the return of each query.
while ($p = pg_fetch_array($var)) {
$url = "https://url";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array("Content-Type: application/json");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$data = '{"s1":"s1","number":"'.$p['number'].'"}';
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
var_dump($resp);
}
Here's a working example using native curl_multi_*() functions. Specifically:
curl_multi_init()
curl_multi_add_handle()
curl_multi_exec()
curl_multi_getcontent()
curl_multi_remove_handle()
curl_multi_close()
<?php
$urls = ['https://example.com/', 'https://google.com'];
$handles = [];
foreach ($urls as $url) {
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$handles[] = $handle;
}
$multiHandle = curl_multi_init();
foreach ($handles as $handle) {
curl_multi_add_handle($multiHandle, $handle);
}
for(;;){
curl_multi_exec($multiHandle, $stillRunning);
if($stillRunning > 0){
// some handles are still downloading, sleep-wait for data to arrive
curl_multi_select($multiHandle);
}else{
// all downloads completed
break;
}
}
foreach ($handles as $handle) {
$result = curl_multi_getcontent($handle);
var_dump($result);
curl_multi_remove_handle($multiHandle, $handle);
}
curl_multi_close($multiHandle);
Now, how convert the code cUrl to GuzzleHttp?
I am working in Opencart platform. now I am really stuck in integrating a sms api link. last few days I have done many things but I can't reach there.
I don't know what is the issue in my code. I am using CURL method:
function curl_get_contents($url)
{
$curl = curl_init();
if (substr(HTTPS_CATALOG, 0, 5) == 'https') {
curl_setopt($curl, CURLOPT_PORT, 443);
}
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FORBID_REUSE, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
$json = curl_exec($curl);
if (!$json) {
$this->error['warning'] = sprintf($this->language->get('error_curl'), curl_error($curl), curl_errno($curl));
} else {
curl_close($curl);
}
}
this is my curl function, and I called the function like this.
$link= "http://**.**.**.**:****/sendsms/bulksms?username=****-****&password=********&type=0&dlr=1&destination=********&source=****&message=******"
$this->curl_get_contents($link);
I hope somebody will help me to survive from these problem
i am using codeigniter and my code is as follows :
Controller :
$json_string = 'http://maps.googleapis.com/maps/api/directions/json?origin=' . $user_addr . '&destination=' . $vendor_city .'&mode=Montreal';
$json = $this->curl_get_contents($json_string);
$obj = json_decode($json, true);
$this->load->view('get_direction_pg',$obj);
public function curl_get_contents($url)
{
$ch = curl_init($url);
if ($ch == FALSE) {
return array('error' =>"failed");
}else{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
$result = curl_exec($ch);
return $result;
}
}
and it if i access var_dump($routes);
it says,
undefined variable routes.
try using this: i.e. encoding the vars - before putting into url
$json_string = 'http://maps.googleapis.com/maps/api/directions/json?origin=' . urlencode($user_addr) . '&destination=' . urlencode($vendor_city) .'&mode=Montreal';
the parameters should be encoded for url, otherwise it is being invalid, and hence you are getting that error
Try this:
public function curl_get_contents($url)
{
$ch = curl_init($url);
if ($ch == FALSE) {
return array('error' =>"failed");
}
else
{
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
$result = curl_exec($ch);
return $result;
}
}
When I put my site into maintenance mode and try to use the order history from admin I get:
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of
the JSON data
How can I pass the authentication data in the curl request so the maintenance mode is disabled if logged in as admin?
public function api() {
$json = array();
// Store
if (isset($this->request->get['store_id'])) {
$store_id = $this->request->get['store_id'];
} else {
$store_id = 0;
}
$this->load->model('setting/store');
$store_info = $this->model_setting_store->getStore($store_id);
if ($store_info) {
$url = $store_info['ssl'];
} else {
$url = HTTPS_CATALOG;
}
if (isset($this->session->data['cookie']) && isset($this->request->get['api'])) {
// Include any URL perameters
$url_data = array();
foreach ($this->request->get as $key => $value) {
if ($key != 'route' && $key != 'token' && $key != 'store_id') {
$url_data[$key] = $value;
}
}
$curl = curl_init();
// Set SSL if required
if (substr($url, 0, 5) == 'https') {
curl_setopt($curl, CURLOPT_PORT, 443);
}
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FORBID_REUSE, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url . 'index.php?route=' . $this->request->get['api'] . ($url_data ? '&' . http_build_query($url_data) : ''));
if ($this->request->post) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($this->request->post));
}
curl_setopt($curl, CURLOPT_COOKIE, session_name() . '=' . $this->session->data['cookie'] . ';');
$json = curl_exec($curl);
curl_close($curl);
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput($json);
}
I noticed in the other methods they are this extra request for api/login. Is there a way I can merge the 2 together
$api_info = $this->model_user_api->getApi($this->config->get('config_api_id'));
if ($api_info) {
$curl = curl_init();
// Set SSL if required
if (substr(HTTPS_CATALOG, 0, 5) == 'https') {
curl_setopt($curl, CURLOPT_PORT, 443);
}
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_USERAGENT, $this->request->server['HTTP_USER_AGENT']);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FORBID_REUSE, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, HTTPS_CATALOG . 'index.php?route=api/login');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($api_info));
$json = curl_exec($curl);
if (!$json) {
$this->error['warning'] = sprintf($this->language->get('error_curl'), curl_error($curl), curl_errno($curl));
} else {
$response = json_decode($json, true);
if (isset($response['cookie'])) {
$this->session->data['cookie'] = $response['cookie'];
}
curl_close($curl);
}
}
This is something that's been noted a few times in the github issue list for OpenCart. This hasn't been fixed yet, but this commit shows what you need to do to get this working