Can't track down bug - php

The following is part of a script which is used to authenticate paypal payments.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://' . $server . '/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_error($ch);
curl_close($ch);
On some rare occasions there is a problem with curl_exec which causes the the script to stop executing at that line.
No errors are recorded in the cpanel error log and after trying a number of different things I am no clearer as to what may be causing this error with curl.
I am not very familiar with curl, so if anyone knows of a good way to obtain error information from this, or what could possibly cause this problem, I'd really appreciate it.
Thanks

It could just take a long time.
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
Set the time out to 30 seconds. Are you sure you waited that long?
Use CURLOPT_TIMEOUT_MS to set the timeout in milliseconds.

curl_error() returns a string, it doesn't do any output/logging of its own. The proper way to detect curl errors is as follows:
$result = curl_exec($curl);
if ($result === FALSE) {
error_log("CURL failed at " . date('c'));
error_log("CURL message: " . curl_error($curl));
}

Related

Running a function in the background in Codeigniter 3

I am trying to send a message to all my telegram bot subscribers. However, due to their large number curl_exec inside a loop of thousands users take lots of time to finish the function.
This is a problem, because if users send some request from my bot during the loop, they have to wait untill telegram api answers to my previous loop requests and then only to their requests. There will be confusion to TELEGRAM API also, and it may repeat same message to the users 2-3 times at this stage.
So I want to do it in the background, so that users keep working with the bot and not wait, and also I will not care how long it will take to send message to all subscribers.
I would be very grateful if you could help.
check this out
function broadcast($message) {
$url = 'https://api.telegram.org/bot' . getenv('TELEGRAM_BOT_TOKEN') . '/sendMessage';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'chat_id=' . getenv('TELEGRAM_CHAT_ID') . '&text=' . $message);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

Any ideas why this cURL script isn't working

I literally have similar cURL scripts running on other areas of this PHP page, and they work just fine. But for some reason, this one is different enough to be causing me problems. No error message, it just doesn't seem to be hitting the endpoint for some reason. Can you see any reason why this wouldn't work?
ob_start();
$destination = "https://www.example.com/record_serial_number.php?serial_number=" . $serial_number . "&employee_name=" . $employee_name . "&scan_purpose=Barcode printed&value=";
$destination = urlencode($destination);
$url = $destination;
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "hidden_username:hidden_password");
$response = curl_exec($ch);
curl_close($ch);
$response .= ob_get_contents();
ob_end_clean();
You need to use curl_errno() and curl_error() to find out if curl_exec() encountered an error.

Toggl Reporting API with PHP cURL

I am trying to access the Toggl Reporting API.
I tried following in PHP with cURL, which connects to the API but gives the following error message: 'This method may not be used.' Any light on why this is the case would be useful as I'm very new to webservices. I may be missing something obvious or totally going the wrong way about it, so apologies if this is the case.
<?php
$userAgent = 'xxx';//username
$token = 'xxx';//token
$returned_content = get_data('https://toggl.com/reports/api/v2/summary?&workspace_id=[workspaceid]&since=2013-05-19&until=2013-05-20&user_agent=[username here]');
print_r($returned_content);
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_USERPWD, $token.':api_token');
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
?>
Edit: I tried a different approach. If I run the following code, I no longer receive any error messages, so the code seems to be executing but I can't print the response to the screen. Is there something specific I need to do to view the output other than print_r?(Toggl API returns JSON). Thanks.
$json = curl%20-v%20-u%[myapitoken]:api_token%20https://toggl.com/reports/api/v2/weekly?workspace_id=[id]&wsid=282507&since=2012-08-19&until=2013-09-20&user_agent=[user].json;
print_r($json);
Edit: Finally resolved! Code is as follows:
$workspace_id = '[id here]';
$user_agent = '[user agent here]'; // no spaces
$api_token = '[token here]';
$report_url = 'https://toggl.com/reports/api/v2/weekly?user_agent='.$user_agent.'&since=2013-08-01&until=2013-09-01';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_USERPWD, $api_token . ':api_token');
curl_setopt($ch, CURLOPT_URL, $report_url . '&workspace_id=' . $workspace_id);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$result = curl_exec($ch);
$result = json_encode($result);
Hope this helps someone in the future!
As I understand, you are receiving this message because of CURLOPT_SSL_VERIFYPEER == FALSE.
Try to remove this string from the code:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
Maybe I wrong, but I think with this option you are receiving "HTTP 501 Not Implemented" error from the Toggl server, which contains exactly the same message, "This method may not be used."

php curl memory usage

I have this function that gets the html from a list of pages and once I run it for
two hours or so the script interrupts and shows that memory limit has been exceeded,
Now i've tried to unset/set to null some variables hopefully to free up some memory
but it's the same problem. Can you guys please take a look at the following piece of
code? :
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($proxystatus == 'on'){
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
ob_start();
return curl_exec($ch); // the line the script interrupts because of memory
ob_end_clean();
curl_close($ch);
ob_flush();
$site = null;
$ch = null;
}
Any suggestion is highly appreciated. I've set the memory limit to 128M, but before
increasing it (doesnt seem like the best option to me) I would like to know if there's
anything I can do to use less memory/free up memory while running the script.
Thank you.
You are indeed leaking memory. Remember that return immediately ends execution of the current function, so all your cleanup (most importantly ob_end_clean() and curl_close()) is never called.
return should be the very last thing the function does.
I know it's been a while, but others might run into a similar issue, so in case it helps anyone else...
To me the problem here is that curl is set to save the output to a string. [That's what happens with curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);] If the output gets too long, the script will run out of allowed memory for that string. [That returns an error like FATAL ERROR: Allowed memory size of 134217728 bytes exhausted (tried to allocate 130027520 bytes)] The way around this is to use one of the other output methods offered by curl: output to standard output, or output to file. In either case, ob-start shouldn't be needed at all.
Hence you could replace the content of the braces with either option below:
OPTION 1: Output to standard output:
$ch = curl_init();
if ($proxystatus == 'on'){
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
curl_exec($ch);
curl_close($ch);
OPTION 2: Output to file:
$file = fopen("path_to_file", "w"); //place this outside the braces if you want to output the content of all iterations to the same file
$ch = curl_init();
if ($proxystatus == 'on'){
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($curl, CURLOPT_FILE, $file);
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
curl_exec($ch);
curl_close($ch);
fclose($file); //place this outside of the braces if you want to output the content of all iterations to the same file
For sure this is not a cURL issue. Use tools like xdebug to detect which part of your script is consuming memory.
Btw I would also change it not to run for two hours, I will move it to a cronjob that runs everyminute, check what it needs and then stops.

See what CURL sends from a PHP script

I'm having dificulties to query a webform using CURL with a PHP script. I suspect, that I'm sending something that the webserver does not like. In order to see what CURL realy sends I'd like to see the whole message that goes to the webserver.
How can I set-up CURL to give me the full output?
I did
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
but that onyl gives me a part of the header. The message content is not shown.
Thanks for all the answers! After all, they tell that It's not possible. I went down the road and got familiar with Wireshark. Not an easy task but definitely worth the effort.
Have you tried CURLINFO_HEADER_OUT?
Quoting the PHP manual for curl_getinfo:
CURLINFO_HEADER_OUT - The request string sent. For this to work, add
the CURLINFO_HEADER_OUT option to the handle by calling curl_setopt()
If you are wanting the content can't you just log it? I am doing something similar for my API calls
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::$apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, count($dataArray));
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
$logger->info("Sending " . $dataString);
self::$results = curl_exec($ch);
curl_close($ch);
$decoded = json_decode(self::$results);
$logger->debug("Received " . serialize($decoded));
Or try
curl_setopt($ch, CURLOPT_STDERR, $fp);
I would recommend using curl_getinfo.
<?php
curl_exec($ch);
$info = curl_getinfo($ch);
if ( !empty($info) && is_array($info) {
print_r( $info );
} else {
throw new Exception('Curl Info is empty or not an array');
};
?>

Categories