I have successfully utilized PayPal-PHP-SKD to request a payment sending the user to the PayPal payment gateway sandbox with credentials and sandbox buyer account etc. Everything works and I get a request to the returnURL with $_GET variables success=true, paymentID, token and PayerID. My problem is in the next step which captures the paymentID and PayerID, creates objects for Payment PaymentExecution which seems to work OK but crashes when I execute the line "result = $payment->execute($exClaimPayment, $mPPcredentials);". If I comment out that line, the code works without error but when I include it the code crashes.
"result = $payment->execute($exClaimPayment, $mPPcredentials);"
if (isset($_GET['success'], $_GET['paymentId'], $_GET['PayerID'])) {
if ($_GET['success'] == 'true') {
$mSuccess = TRUE;
$mPaymentID = $_GET['paymentId'];
$mPayerID = $_GET['PayerID'];
$payment = Payment::get($mPaymentID, $mPPcredentials);
$exClaimPayment = New PaymentExecution();
$exClaimPayment->setPayerId($mPayerID);
$mProgress = 'in success after $exClaimPayment->setPayerId($mPayerID)';
try {
$mProgress = 'in try';
//result = $payment->execute($exClaimPayment, $mPPcredentials);
} catch(Exception $ex){
$errorMsg = json_decode($ex->getData());
}
}
} else {
$mSuccess = FALSE;
$mProgress = 'in NOT success';
}
In my envoronment, Win 10, Notepad++, FileZilla, Hostmonnster hosting and Chrome, I cannot see the error. It just crashes (with HTTP 500 ??)
I found my error! It was MY error.
The line:
result = $payment->execute($exClaimPayment, $mPPcredentials);
Should have been:
$result = $payment->execute($exClaimPayment, $mPPcredentials);
I have worked on this code for half a day and did not see my error until 5 minutes after I posted the question on StackOverflow.
My conspicuous errors in PHP often cost me a lot of time. I would benefit from an environment that would point out my syntax errors.
StackOverflow is a very good resource. Thanks!
Related
I'm using neverbounce api in my project to check the email is valid or not. Usually neverbounce returning 5 result codes as a response result codes.In this, we'll get response for status code 0 to 3 in almost 3-4 seconds. but the last status code for unknown emails took almost 30 seconds to get the result. They are providing a timeout option in the API itself but it is not working. I contacted the support team but no use still the issue exists.
So I need to exit the functionality and return a default value if the response didn't receive from API. I tried by using set_time_limit(5); but it didn't work.Any help is appreciable.
This is the code that we're using
$res = 0;
try {
// Make verification request, specify optional $max_execution_time
$result = \NeverBounce\Single::check($email, // Email to verify
true, // Address info
true, // Credits info
5// Timeout in seconds
);
if (!empty($result->result_integer)) {
$res = $result->result_integer;
} else {
$res = 0;
}
// Call wrapper method here
} catch (\NeverBounce\Errors\AuthException $e) {
// The API credentials used are bad, have you reset them recently?
$res = 0;
} catch (\NeverBounce\Errors\BadReferrerException $e) {
// The script is being used from an unauthorized source, you may need to
// adjust your app's settings to allow it to be used from here
$res = 0;
} catch (\NeverBounce\Errors\ThrottleException $e) {
// Too many requests in a short amount of time, try again shortly or adjust
// your rate limit settings for this application in the dashboard
$res = 0;
} catch (\NeverBounce\Errors\HttpClientException $e) {
// An error occurred processing the request, something may be wrong with
// the Curl PHP extension or your network
$res = 0;
} catch (\NeverBounce\Errors\GeneralException $e) {
// A non recoverable API error occurred check the message for details
$res = 0;
} catch (Exception $e) {
// An error occurred unrelated to the API
$res = 0;
}
return $res;
I am running a web app to get a list of users with Google API PHP Client Library 2.0.3. and save them to a CSV file and at the same time, I am tracking the process on screen. The code I am using is the following:
$pageToken = null;
$optParams = array(
"customer" => "my_customer",
"maxResults" => 500,
"orderBy" => "email",
"sortOrder" => "ASCENDING"
);
try {
$usernum = 0;
do {
if ($pageToken){
$optParams['pageToken'] = $pageToken;
}
$results = $service->users->listUsers($optParams);
$pageToken = $results->getNextPageToken();
$users = $results->getUsers();
foreach ($users as $user) {
$usernum++;
$csvfileusers = array($user->getPrimaryEmail());
fputcsv($savecsv, $csvfileusers);
$usersemails = $user->getPrimaryEmail();
print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
}
} while($pageToken);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
Everything works fine. The problem is that from time to time I am getting { error: { errors: [ { domain: global, reason: backendError, message: Service unavailable. Please try again } ], code: 503, message: Service unavailable. Please try again } }
I know this means that I am sending requests to Google Server too fast hence I need to implement an exponential backoff solution. My problem is that I don't know how to do that. Would someone be kind enough to provide me an example on how to do that using the PHP Client Library? I know that I might be able to figure this out at the long term but if I can get some help I will greatly appreciate it.
Unfortunately, the documentation is lacking for the actual backoff implementation. However, the Google_Task_Runner class outlines the backoff implementation process. You can see how it does it here.
However, based on what you're doign you don't actually want to implement a exponential backoff procedure in general networking terms. You're really wanting to just throttle the request so you don't slam the API. Depending on how many $pageToken you're iterating over, you could just do a sleep before doing the next while iteration.
Additionally, what does $pageToken = $results->getNextPageToken(); become after one request? Becuase you're setting that from the response rather than decrementing it programatically, which may be causing an infinute loop or something of that nature.
So after 20 days of trying and investigating and thanks to the information provided by #kyle, I came up with this exponential backoff solution.
$attemptNum = 1; // retry attempt
$expBackoff = false; // exponential backoff rety indicator
do {
if($attemptNum <= 4) {
try {
$usernum = 1;
do {
if ($pageToken){
$optParams['pageToken'] = $pageToken;
}
$results = $service->users->listUsers($optParams);
$pageToken = $results->getNextPageToken();
$users = $results->getUsers();
foreach ($users as $user) {
$csvfileusers = array($user->getPrimaryEmail());
fputcsv($savecsv, $csvfileusers);
$usersemails = $user->getPrimaryEmail();
print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
$usernum++;
}
} while($pageToken);
} catch (Exception $e) {
$err503ReasonA = "Service unavailable"; // Service unavailable.
$err503ReasonB = "Backend Error"; //Backend Error
$exception = $e->getMessage();
if(strpos($exception, $err503Reason) !== false || strpos($exception, $err503ReasonB) !== false){
$expBackoff = true;
$sleeptime = $retrynum * 1; //retrynum * seconds
sleep($sleeptime);
$retrynum++;
} else {
$expBackoff = false;
print "There was an error -> $exception";
}
}
} else {
$expBackoff = false;
}
} while ($expBackoff);
I have been trying this solution for two days now and it has worked like a charm. Hopefully this might be helpful for someone else. I´m happy now. :)
I have made a script that checks a server's availability.
The site was down and I was awaiting a fix(I was on call for a client and was awaiting a ticket from the provider), to limit calls I have used sleep():
$client = new \GuzzleHttp\Client();
$available = false;
date_default_timezone_set('doesntMatter');
//The server was more likely to respond after 5 AM, hence the decrese between intervals
$hours = array( //Minutes between calls based on current hour
0=>30,
1=>30,
2=>30,
3=>30,
4=>20,
5=>20,
6=>10,
7=>10,
8=>10
);
$lastResponse = null;
while(!$available) {
$time = time();
$hour = date('G', $time);
echo "\n Current hour ".$hour;
try {
$crawler = $client->request('GET', 'www.someSiteToCheck.com');
$available = true; //When the server returns a stus code of 200 available is set to TRUE
} catch (\GuzzleHttp\Exception\ServerException $e) {}
if(!$available) {
$secondsToSleep = $hours[$hour]*60;
echo "\n Sleeping for ".$secondsToSleep;
sleep($hours[$hour]*$secondsToSleep); //Sleep until the next request
} else {
exec('start ringtone.mp3'); //Blast my stereo to wake me up
}
}
Problem:
When I started the script it went in a 1800 second sleep and froze, it didn't re-execute anything
Given:
I tested my script with a sleep of 160 (for ex) and it made multiple calls
Checked my power settings so that the machine wouldn't go in stand-by
Checked error logs
(Even if obvious) I ran in CLI
Checked sleep() documentation for issues but nothing
Couldn't find anithing related
I think you have an error in your logic.
For example:
When it's 5AM
Then $secondsToSleep is 20*60 = 1200sec;
When you call the sleep function you multiply it again with 20
sleep($hours[$hour]*$secondsToSleep); => sleep(20*1200); => 24000sec => 6,66... hours
If you simply update your sleep parameter the result should be as expected.
if(!$available) {
$secondsToSleep = $hours[$hour]*60;
echo "\n Sleeping for ".$secondsToSleep;
sleep($secondsToSleep); //Sleep until the next request
}
I am using the amazon.com products API. The call is GetMatchingProductForId. When I type as single value into the call, it works. When I input a large file to my program it works, but I occasionally get a fatal error:
Fatal Error:Can Only Throw Objects in J:/filepath/client.php on line 1003.
I have no idea what the possible error is. When i contacted amazon developer support they said they would investigate the issue.
The problem could possibly be the user input because I ran my program yesterday and was able to get 2797 files in response, but eventually received the same error. When i ran my program for the first time during testing, there was no problem at all. If anyone has knowledge of this error and could explain just the error, I would greatly appreciate it.
Client.php lines 992 - 1004:
for (;;) {
$response = $this->_httpPost($parameters);
$status = $response['Status'];
if ($status == 200) {
return array('ResponseBody' => $response['ResponseBody'],
'ResponseHeaderMetadata' => $response['ResponseHeaderMetadata']);
}
if ($status == 500 && $this->_pauseOnRetry(++$retries)) {
continue;
}
throw $this->_reportAnyErrors($response['ResponseBody'],
$status, $response['ResponseHeaderMetadata']);
}
I did not edit any of this code. This came from developer.amazonservices.com
_reportAnyErrors Function :
private function _reportAnyErrors($responseBody, $status, $responseHeaderMetadata, Exception $e = null)
{
$exProps = array();
$exProps["StatusCode"] = $status;
$exProps["ResponseHeaderMetadata"] = $responseHeaderMetadata;
libxml_use_internal_errors(true); // Silence XML parsing errors
$xmlBody = simplexml_load_string($responseBody);
if ($xmlBody !== false) { // Check XML loaded without errors
$exProps["XML"] = $responseBody;
$exProps["ErrorCode"] = $xmlBody->Error->Code;
$exProps["Message"] = $xmlBody->Error->Message;
$exProps["ErrorType"] = !empty($xmlBody->Error->Type) ? $xmlBody->Error->Type : "Unknown";
$exProps["RequestId"] = !empty($xmlBody->RequestID) ? $xmlBody->RequestID : $xmlBody->RequestId; // 'd' in RequestId is sometimes capitalized
} else { // We got bad XML in response, just throw a generic exception
$exProps["Message"] = "Internal Error";
continue;
}
}
Values :
20373001862
20373002678
20373002685
20373002937
20373003002
20373003583
20373003644
20373003651
20373003675
20373003682
20373003781
20373003811
20373003828
20373003835
20373003842
20373003859
20373003866
20373003873
20373003880
20373003897
20373003903
20373005006
With these values it crashed on the third file which would be the 20th value.
I have this code:
<?php
foreach($items as $item) {
$site = $item['link'];
$id = $item['id'];
$newdata = $item['data_a'];
$newdata2 = $item['data_b'];
$ch = curl_init($site.'updateme.php?id='.$id.'&data1='.$newdata.'&data2='.$newdata2);
curl_exec ($ch);
// do some checking here
curl_close ($ch);
}
?>
Sample input:
$site = 'http://www.mysite.com/folder1/folder2/';
$id = 512522;
$newdata = 'Short string here';
$newdata = 'Another short string here with numbers';
Here the main process of updateme.php
if (!$id = intval(Tools::getValue('id')))
$this->_errors[] = Tools::displayError('Invalid ID!');
else
{
$history = new History();
$history->id = $id;
$history->changeState($newdata1, intval($id));
$history->id_employee = intval($employee->id_employee);
$carrier = new Carrier(intval($info->id_carrier), intval($info->id_lang));
$templateVars = array('{delivery}' => ($history->id_data_state == _READY_TO_SEND AND $info->shipping_number) ? str_replace('#', $info->shipping_number, $carrier->url) : '');
if (!$history->addWithemail(true, $templateVars))
$this->_errors[] = Tools::displayError('an error occurred while changing status or was unable to send e-mail to the employee');
}
The site will always be changing and each $items will have atleast 20 data inside it so the foreach loop will run atleast 20 times or more depending on the number of data.
The target site will update it's database with the passed variables, it will probably pass thru atleast 5 functions before it is saved to the DB so it could probably take some time too.
My question is will there be a problem with this approach? Will the script encounter a timeout error while going thru the curl process? How about if the $items data is around 50 or in the hundreds now?
Or is there a better way to do this?
UPDATES:
* Added updateme.php main process code. Additional info: updateme.php will also send an email depending on the variables passed.
Right now all of the other site are hosted in the same server.
You can have a php execution time problem.
For your curl timeout problem, you can "fix" it using the option CURLOPT_TIMEOUT.
Since the cURL script that calls updateme.php doesn't expect a response, you should make updateme.php return early.
http://gr.php.net/register_shutdown_function
function shutdown() {
if (!$id = intval(Tools::getValue('id')))
$this->_errors[] = Tools::displayError('Invalid ID!');
else
{
$history = new History();
$history->id = $id;
$history->changeState($newdata1, intval($id));
$history->id_employee = intval($employee->id_employee);
$carrier = new Carrier(intval($info->id_carrier), intval($info->id_lang));
$templateVars = array('{delivery}' => ($history->id_data_state == _READY_TO_SEND AND $info->shipping_number) ? str_replace('#', $info->shipping_number, $carrier->url) : '');
if (!$history->addWithemail(true, $templateVars))
$this->_errors[] = Tools::displayError('an error occurred while changing status or was unable to send e-mail to the employee');
}
}
register_shutdown_function('shutdown');
exit();
You can use set_time_limit(0) (0 means no time limit) to change the timeout of the PHP script execution. CURLOPT_TIMEOUT is the cURL option for setting the timeout, but I think it's unlimited by default, so you don't need to set this option on your handle.