Output message after function timeout - php

I have a function that I need to timeout and output an error message.
I have found the set_time_limit() function, but I dont think I am using it right.
I have tried...
... some code ...
set_time_limit(12);
$client->sendHttp(URL, TIMEOUT_CONNECT, TIMEOUT_READ);
if (set_time_limit(12) != true){
$_SESSION['Message'] = "Transaction Timed Out!";
}
... some code ...
That's the best I could come up with but it doesn't work. Can you suggest anything?

set_time_limit limits the scripts time, the script all together will end after that amount of time no code will be executed after that
$client->sendHttp should return false, null if a timeout has been reached, read the documentation on that function to see what it will actually return.

Normally if the script timeout, the web server stops it and return an error while You have only a little chance of handling it by Yourself - by defining shutdown function.
But You could use a simple function of Your own, like this one:
function check_timeout($start) {
if(microtime() <= $start + MAX_EXECUTION_TIME)
return true;
return false;
}
while the MAX_EXECUTION_TIME constant would be defined somewhere like
define('MAX_EXECUTION_TIME', 10000); // 10 seconds
Now somewhere in Your code You could do:
// some code...
$start = microtime();
foreach($array as $key => $value) {
if(check_timeout($start)) {
// do something
} else {
// set HTTP header, throw exception, etc.
// return false; // die; // exit;
}
}

Related

doing_action() function stops my code from running

My action is called by WP Cron so I'm trying to prevent it from running twice at the same time. So, I have the following function that uses doing_action function to check if the action is running. Apparently, the code below can't run even when the action is not running. But when I removed the doing_action check, the code runs.
function upload_to_ipfs() {
if ( !doing_action( 'upload_file' ) ) {
//Code to run here
}
}
add_action( 'upload_file', 'upload_to_ipfs' );
You should probably have a look at site transients.
<?php
function so_73821350_get_transient_name() {
return 'so_73821350_transient_name'; // replace this with whatever you want
}
function so_73821350_upload_to_ipfs() {
// get the existing transient
//
// If the transient does not exist, does not have a value, or has expired,
// then the return value will be false.
$process_running = get_site_transient( so_73821350_get_transient_name() );
if ( $process_running ) {
// bail out in case the transient exists and has not expired
// this means the process is still running
return;
}
// set the transient to flag the process as started
// 60 is the time until expiration, in seconds
set_site_transient( so_73821350_get_transient_name(), 1, 60);
// Run the upload process here
upload_function();
// ...
// delete the transient to remove the flag and allow the process to run again
delete_site_transient( so_73821350_get_transient_name() );
}
add_action( 'upload_file', 'so_73821350_upload_to_ipfs' );
docs:
get_site_transient()
set_site_transient()
delete_site_transient()
You're running into a scenario where the code won't run because it's calling !doing_action on itself because the action IS running.
Also,
Wordpress doing_action works by looking at a global PHP variable is all.
This will not work since you're probably not on the same thread process (since a new one is started with every PHP request on most servers).
In which case you'll have to resort to an alternative method for checking.
One such alternative is checking the servers running processes for the action. Take a look at something like this https://write.corbpie.com/check-if-a-process-is-running-on-linux-with-php/ to help guide you in the right direction.
function is_server_doing_action(string $process): bool
{
if (empty(trim(shell_exec("pgrep $process")))) {
return false;
} else {
return true;
}
}
function upload_to_ipfs() {
if ( !is_server_doing_action( 'upload_file' ) ) {
//Code to run here
}
}
add_action( 'upload_file', 'upload_to_ipfs' );

How to write PHP codes usable both for http and ajax request?

I have some php codes, and there is a condition which declare type of ajax. Now I want to know, should I write all php codes for each request separately? In other word, should I write all php codes twice (almost repeatedly) for both methods?
if(!empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest")
{
// I'm ajax
$arr = array('key1'=>'value1', 'key2'=>'value2');
echo json_encode($arr);
} else {
// I'm not ajax
$arr = array('key1'=>'value1', 'key2'=>'value2');
$_SESSION["arr"] = arr;
header('Location: '.$_SERVER['HTTP_REFERER']); // redirect to previous page
}
So, as you see, I have to write all PHP code twice. One time for regular request and one time for ajax request. In reality there is a lot of codes, Maybe 1000 lines of code that I have two write them again for ajax requests (while they are almost identical). Is this a normal way?
Also I want to know, is there any succinct approach? Actually I like to use a approach which needs to php code just one time for both requests ...!
I would create a class to handle those request and put common code right into a method used by both contexts:
// file: class.handler.php
class contextHandler() {
public function handleHttp() {
$this->handleGeneral();
// What ever has to be done in this context
$_SESSION["arr"] = arr;
header('Location: '.$_SERVER['HTTP_REFERER']);
}
public function handleAjax() {
$this->handleGeneral();
// What ever has to be done in this context
echo json_encode($arr);
}
private function handleGeneral() {
// put common code here
$arr = array('key1'=>'value1', 'key2'=>'value2');
}
}
In your code you could then use that class:
include 'class.handler.php';
$handler = new contextHandler();
if(
!empty($_SERVER["HTTP_X_REQUESTED_WITH"]) &&
strtolower($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest"
)
{
$handler->handleAjax();
} else {
$handler->handleHttp();
}
This has of course to be adjusted to your concrete needs but offers a nice and clean way of reusing code and generating small and readable code.

Returning Boolean Value PHP MongoDB

I am trying to implement error proofing to a log in script. But, I cannot get it to work? I have no idea what is going on, or why it doesn't work like I expect it to. I have tried everything, please advise.
This is the method I am calling:
public function i_exist($this_username)
{
//$host_array = null;
//$host_array = $this->collection->findOne(array("Username" => $this_username));
//if ($host_array['Username'] = $this_username)
//{
return true;
//}
//return false;
}
This is how I am calling it:
if (!empty($_POST['Username']))
{
$host = new Host();
$event = new Event();
if ($host->i_exist($_POST['Username']))
{
header("Location: http://www.drink-social.com/error.php?login=duplicate");
}
It is supposed to check the database and see if that username is already in use. But it never directs to the error page? I have even tried commenting everything out and returning true, and returning 1. Nothing?
Any advice?
When you call header(); you will also need to call exit(); otherwise the script continues running.

PHP redirection issue

I have a program that prints reports for a user id list. The program is supposed to print reports one by one for users on the list uploaded. The problem is that when I was running the printing process and getting to print the report with indexInList=30, I got error:
This webpage has a redirect loop
The webpage at http://127.0.0.1/content/8520?print=1&bulkprinting=1&filename=/private/var/tmp/phpHRXEw8.moved&indexInList=30&nopeergroup=1&nolabpage=0&hideScreeningOnly=1&showOnlyScreening=0&hideHoldMailing=1 has resulted in too many redirects. Clearing your cookies for this site or allowing third-party cookies may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer.
I tried to clean the cookie but still keep getting the same error.
I attached some code here and hope anyone can help me:
$sessionData['first_name'] = $foundUser->first_name;
$sessionData['last_name'] = $foundUser->last_name;
// Overwrite $_REQUEST variable with parameters before including
// the hpa report
$_REQUEST = array(
'user_id' => $foundUser->id,
'bulkprinting' => true
);
if($nopeergroup) { $_REQUEST['nopeergroup'] = $nopeergroup; }
if($nolabpage) { $_REQUEST['nolabpage'] = $nolabpage; }
if($hideScreeningOnly) { $_REQUEST['hideScreeningOnly'] = $hideScreeningOnly; }
if($showOnlyScreening) { $_REQUEST['showOnlyScreening'] = $showOnlyScreening; }
if($hideHoldMailing) { $_REQUEST['hideHoldMailing'] = $hideHoldMailing; }
$includeValue = include __DIR__.'/../hpa/hpa.php';
$url = sprintf(
"/content/8520?print=1&bulkprinting=1&filename=%s&indexInList=%s" .
"&nopeergroup=%s&nolabpage=%s&hideScreeningOnly=%s" .
"&showOnlyScreening=%s&hideHoldMailing=%s",
$filename, $indexInList, (int)$nopeergroup, (int)$nolabpage,
(int)$hideScreeningOnly, (int)$showOnlyScreening, (int)$hideHoldMailing);
if($hradata[0] !== false) {
$sessionData['hra_id'] = $hradata[0]['id'];
}
if($screeningdata[0] !== false) {
$sessionData['screening_id'] = $screeningdata[0]['id'];
}
if($includeValue !== 1) {
// Redirect to URL
$sessionData['message'] = $messages_set[$includeValue];
$_SESSION['printing_set'][] = $sessionData;
redirect($url);
}
$sessionData['markAsMailed'] = true;
$_SESSION['printing_set'][] = $sessionData;
?>
<script type="text/javascript">
function waitPrint() {
window.print();
var t = setTimeout("timed()", 1000);
}
function timed() {
window.location.replace("<?php echo $url ?>");
}
if(window.attachEvent) {
window.attachEvent("onload", waitPrint);
} else if(window.addEventListener) {
window.addEventListener("load", waitPrint, false);
}
</script>
Sounds like you have a lot of files that need printing!
You may be able to alter your browser settings (I seem to remember you can in Firefox) to allow more than 30 loops.
Alternatively, you could always limit your code to 30 loops then wait for further user interaction to proceed to the next 30.
The 3rd option is to always create a Word document or PDF with one report on each page, then save the file and print it - a little more hassle (in a way) but at least you'll be able to print everything at once.
In order for $includeValue to be set to anything, the file __DIR__.'/../hpa/hpa.php' must have a return statement inside of it, as demonstrated in the PHP documentation for include, example 5. include will only return a value when called if the included file returns a value.
If your script still produces an infinite loop, your logic within the included file is incorrect and it is consistently producing a value that is not 1.
Essentially, here is the code that your question boils down to:
$includeValue = include __DIR__.'/../hpa/hpa.php';
if($includeValue !== 1) {
// Redirect
}
Browsers have checks built-in to help you when sites are misconfigured into a redirection loop, and 30 must be the limit for the browser you're using. You've built a redirection loop on purpose, but the browser doesn't know that. Instead of using the window.location.replace() method, how about a form that automatically submits? That should look different to the browser, and allow your loop to progress as designed.
<script type="text/javascript">
function waitPrint() {
window.print();
var t = setTimeout("timed()", 1000);
}
function timed() {
window.reloadForm.submit();
}
if(window.attachEvent) {
window.attachEvent("onload", waitPrint);
} else if(window.addEventListener) {
window.addEventListener("load", waitPrint, false);
}
</script>
<form name="reloadForm" action="<?php echo $url ?>">
</form>

Checking if a session is active

I am building a captcha class. I need to store the generated code in a PHP session. This is my code so far:
<?php
class captcha
{
private $rndStr;
private $length;
function generateCode($length = 5)
{
$this->length = $length;
$this->rndStr = md5(time() . rand(1, 1000));
$this->rndStr = substr($rndStr, 0, $this->length);
if(session_id() != '')
{
return "session active";
} else {
return "no session active";
}
}
}
?>
And using this code to check:
<?php
include('captcha.class.php');
session_start();
$obj = new captcha();
echo $obj->generateCode();
?>
But it doesn't output anything to the page, not even a PHP error. Does someone know why this is? And is there a better way I can check if I've started a session using session_start()?
Thanks.
$this->rndStr = substr($rndStr, 0, $this->length);
return $rndStr; //You return before the if statement is processed
if(session_id() != '')
{
return "session active";
} else {
return "no session active";
}
Answer in commented code above
Edit: And you changed your question and removed the return line, not nice for people bothering to answer :)
i was testing your class, seems ok here, got session active on page, maybe you want to try this line :
include(dirname(__FILE__).'/captcha.class.php');
You do have an error, so I suggest checking your error reporting level and display errors setting - lots of short tutorials on how to do that.
Notice: Undefined variable: rndStr in
/home/eric/localhost/test.php on line
12
Of course this is because you wrote $rndStr instead of $this->rndStr.
When I ran your code, aside from the error, I saw the expected output.
session active
Are you able to successfully output to the browser in other scripts?

Categories