Php Timer with a Pause Function - php

I'm trying to figure out a way to create a function to have the user be able to start a project by clicking a button and the timer would start. At the same time, I would like the user to be able to pause as well as stop the timer. When finished with a task, they can then hit 'Finished' to record the total amount of recorded time, minus any paused time, for the task to a variable in which I can record.
I have been researching and found that a Javascript timer wouldn't be very reliable which is why I wanted to go with Php. I figured I could take a Timestamp on 'Start' and 'Stop', but since I'm needing a 'Pause' as well, it's throwing a whole new kink into my plans.
Anyone know of a good way to accomplish this? I know that one Timestamp to another will get the total time, but how can you calculate one to another if the process had been paused?

I don't think "Javascript timer wouldn't be very accurate" is an accurate statement.
However, if you decide to use PHP, you will not be having the script running for the whole duration of the project. What you need is simply a number of markers in an object. You can store the object in a database table or as JSON string in a file. Here's an example using JSON:
[
[1440264185, "start"],
[1440280217, "pause"],
[1440288349, "resume"],
[1440292161, "pause"],
[1440317465, "resume"],
[1440325597, "stop"]
]
The object is built progressively with each event adding the timestamp of the signal received with the signal type (start, pause, resume, stop).
Then, when you want to calculate the amount of time spent working on the project/task you can use code like this:
$markers = json_decode($json_markers, true);
$num_markers = count($markers);
$markers[] = $markers[$num_markers-1];
$time_worked = 0;
for($i = 0; $i < $num_markers; $i++) {
if(in_array($markers[$i][1], array("start","resume"))) {
$time_worked += $markers[$i+1][0] - $markers[$i][0];
}
}
var_dump($time_worked); // int(27976)
Here's the code above.

Related

php continue execution after leaving the page

I have a simple script that counts from 1 to 5000 with a for loop. It flushes output in real time to browser and shows a progress bar with %.
What I have: If I leave the page, the process interrupts. If I come back, it starts from 0.
What I want to achieve: If I leave the page, the process continues and, If I come back , it shows the right percentage.
Example: I run the process, it counts till 54, I leave the page for 10 seconds, when I come back it shows me 140 and continues to flush.
Is it possible?
I would suggest you to use server workers - scripts which are intended to run independently from webserver context.
The most common way of doing it - usage of message queues (RabbitMQ, Qless, etc). Event should be initiated by the script in web context, but the actual task should be executed by queue listener in a different context.
What you have asked seems quite simple to do with a session. (Purely assuming on the use case given). This is not running any process in the background, it just simply keep track of the time and show the progress. That's why I said "based on what you asked". If you want to keep track of any real background tasks, then I believe the case would be totally different, and you will have to change the wordings of your question as well ;)
Something like this would do.
<?php
session_start();
$s = &$_SESSION;
$sleep = 1; //seconds
//check if we have a value set in session before, if not set default = 0.
if(!isset($s['last'])){
$s['last'] = 0;
}
//check if we have a last time set in session before. if not set a default = curret time.
if(!isset($s['time'])){
$s['time'] = time();
}
//get the idle time of the user.
$idle = time() - $s['time'];
//start the loop..and set starting point.
$start = $s['last'] + ($idle / $sleep);
for( $i = $start; $i < 100; $i++){
echo $i . '<br />';
$s['last']++;
$s['time'] = time();
flush();
sleep($sleep);
}
Hope it helps!!

Selenium Scroll Wait

I can not understand why only part of the links are returned without sleep(1); function. Although the script works synchronously and after $web_driver->executeScript the object is already loaded, all links have already been loaded.
<?php
require_once('vendor/autoload.php');
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$caps = array("platform"=>"SIERRA", "browserName" => "chrome", "version" => "69");
$web_driver = RemoteWebDriver::create(
"http://localhost:4444/wd/hub",
$caps
);
$web_driver->get("https://winestyle.ru/wine/gerard-bertrand/");
$web_driver->executeScript('window.scrollTo(0,document.body.scrollHeight);');
sleep(1);
$element = $web_driver->findElements(WebDriverBy::cssSelector(".bg-text[title='Артикул']"));
foreach ($element as $e){
echo $e->getText().'<br>';
}
$web_driver->quit();
?>
return without sleep:
Артикул:в101222
Артикул:в99863
Артикул:в99981
Артикул:в101225
Артикул:в101212
Артикул:в101224
Артикул:в101211
Артикул:в92722
Артикул:в92723
Артикул:в101208
Артикул:в101210
Артикул:в99979
Артикул:в101223
Артикул:в101220
Артикул:в101213
Артикул:в101221
Артикул:в101227
Артикул:в101218
Артикул:в101217
Артикул:в101215
return with sleep:
Артикул:в101222
Артикул:в99863
Артикул:в99981
Артикул:в101225
Артикул:в101212
Артикул:в101224
Артикул:в101211
Артикул:в92722
Артикул:в92723
Артикул:в101208
Артикул:в101210
Артикул:в99979
Артикул:в101223
Артикул:в101220
Артикул:в101213
Артикул:в101221
Артикул:в101227
Артикул:в101218
Артикул:в101217
Артикул:в101215
Артикул:в101226
Артикул:в99980
Артикул:в85254
Артикул:в66382
Артикул:в66386
Артикул:в66387
Артикул:в85253
Артикул:в101214
Артикул:в101219
Most probably the page has implemented lazy loading - any extra information - new elements, are request through ajax only when the user scrolls to the end of the page.
And this is what's happening in your script - you've executed the js to scroll to the end. If you at that moment execute findElements without the sleep, the page would not have time to send the ajax request, wait for an parse the respone, and update the DOM. Thus you will get only the currently present elements.
With the sleep you give it that possibility.
Have in mind the hardcoded value 1s may sometimes work, and sometimes - not; if the backend takes more time to generate the response, or the network is slow - new data may not be received in time.
An alternative solution would be to poll the DOM for the number of target elements every X milliseconds, and continue once that number increases. This though must accommodate for the case where there are no more results (no more артикулы Russian? артикули Bulgarian? :), and to break out of the polling loop (could be done if there's a total results counter on the page, or similar).

PHP / Laravel - Execute command every minute for ten minutes

Apologies if the answer to this is a simple one, but my brain just can't seem to solve this today, I'm hoping someone has had to solve something similar.
So in my database I have various records with timestamps.
In the 10 minutes prior to the timestamp, I'd like to perform an action and store a result in a field.
I'm well aware that this would be easily solved if I just stored these records vertically, as it is I'd like to have the extra fields tenminutes nineminutes etc in the db - I know this is probably bad DB design but ssshhh, just go with it!
Ok, so my (pseudo)code at the minute read a bit like this:
// In a command that is executed every minute using the scheduler....
$current = Carbon::now();
foreach ($things as $thing) {
if ($thing->thingStartTime->diffInMinutes($current) <= -10) {
//Get data
//Update table field `tenminutes`
}
if ($thing->thingStartTime->diffInMinutes($current) <= -9) {
//Get data
//Update table field `nineminutes`
}
}
Can you see how horrible this will become?
I was thinking along the lines of an associative array, loop through it and have a kind of 'tenminutes' => 10 thing going on?
Or is there a funkier way of using carbon I dont know about? Any ideas?
Other info, this is inside a cron job executed every minute! So if thres a way I can use Laravels scheduler to be smart about this, that would be good to know!
You could iterate through the items and dispatch jobs with different delays?
$current = Carbon::now();
foreach ($things as $thing) {
$delayTime = $current - $thing->thingStartTime;
$job = (new SendReminderEmail($user))->delay($delayTime);
$this->dispatch($job);
}
There is more documentation here.

PHP countdown timer without causing a spinlock

The problem:
I'm a programming student and currently studying PHP. Apparently Java can designate threads for things like countdown timers; however, I have been told that PHP can have issues with a standard countdown function using delay, or even time() logic, as it will result in a spinlock. How do I go about avoiding a spinlock and having a simple, efficient countdown timer?
Summary of what I am trying to solve:
I need to create a 30 second timer on the backend PHP. Once the timer is completed, PHP will use my Slack API to communicate with a particular Slack channel - letting everyone know that the coffee is done, etc. With this said, I need to be able to start multiple clocks (as there is both coffee and tea) and must avoid a spin lock as it will kill the multi-countdown ability that is required.
Code so far that results in spinlock:
$startTime = time();
$actualTime = (int)$startTime;
$finishTime = ((int)$startTime) + 30;
var_dump($startTime);
var_dump($actualTime);
var_dump($finishTime);
while(($finishTime - $actualTime) > 0) {
usleep(250000);
$actualTime = ((int)time());
if ($actualTime === $finishTime) {
echo "Tea is ready!";
}
}

PHP: Check mysql database every 10 seconds for any new rows

I am making a php chat and am starting the php checking database part. So when a user types something into the chat, it gets recorded in the MySQL database, how would I check the database every 10 seconds so that one user's chat would update with new messages from other users. I know that you can use an ajax request to a page with an interval, but I want the php to be on the same page, instead of having to use numerous pages. This is the code for checking the database
<?php
$con = mysqli_connect('host','user','pass','database');
$query = mysqli_query($con,"SELECT * FROM `messages`");
while ($row=mysqli_fetch_assoc($query)) {
$user = $row['user'];
$message = $row['message'];
echo 'User: ',$user,' Message: ',$message;
}
?>
Thanks in advance anyone!
Use MySQL Event Scheduler.
Below link will guide you through .
http://www.9lessons.info/2012/10/mysql-event-scheduler.html.
I think best option in your case .
AJAX is probably the simplest solution. You can perform an AJAX request on the same page your PHP code is executing on if you really want to.
(function check() {
$.get('mypage.php', function(data) {
doSomethingWith(data);
setTimeout(check, 5000); // every 5 seconds
});
})();
PHP doesn't have a setInterval function. While I'm sure you can use a crontask to automate it on the server, you can also achieve this with some simple Javascript.
The concept you are trying to achieve is known as Short Polling. What you want to do is to have a setInterval function in Javascript that constantly makes AJAX requests to your PHP file which performs the check to the database for new messages. Your PHP should return that information to your script where you can then simply populate the user's screen.
There is also Long Polling where you simply maintain the connection and have a setTimeout to wait for messages to come in. You can find more information yourself and if you have questions, you can come back here.
A good video about this:
https://www.youtube.com/watch?v=wHmSqFor1HU
Hope this helps.
This is what you need. We need set time for ajax auto reload. Don't put everything in one page. Because you must reload page to refresh data. That is bad solution.
Call jQuery Ajax Request Each X Minutes
Make a while for 30 seconds, and check the db every second, once you find a record the while is being broken, also it is being broken when 30 secs are expired.
$sec = 1;
while($sec <= 30) {
if(has record)
Send to the user;
$sec++;
sleep(one sec here);
}
Use sleep for 10 secs in order to check every 10 secs...

Categories