i have a script which output the percentage of completeness : 10% 20%...100% done.
Can i bring that output to the web?
I call it using jquery ajax:
$.post('dojob.php?id=jobid');
thanks Arman
If I'm understanding what you want, you're looking to call dojob.php and have it return it's progress at certain intervals. This can't be done with one ajax call.
If you need to do this, you will have to call dojob.php but then every x seconds make a separate call to somehow monitor it's progress. For instance, lets say you have checkStatus.php which can give you the progress of dojob. So you call dojob.php, then every 5 seconds call checkStatus.php which will return your % complete of dojob.
Simiarly, you could call dojob and have it kick off a separate thread and then return. THen every x seconds call checkStatus.php, which will either return the % complete, or upon completion return the result of dojob.
to simply write it, try the following code
html:
<div id="progress"></div>
js code:
$('#progress').load('dojob.php?id=jobid');
Related
Is it possible to set a delay between 2 portion of code in PHP? I want something like this-
<?php
function firstFunc(){
echo "anything";
}
function secondFunc(){
echo "something";
}
// call first fumction
firstFunc();
// I want the script to wait for 2 seconds here, then call second function
secondFunc();
Is it possible?
If you want to delay the execution of something, you can use the sleep($seconds) function. Here's what the documentation says
Delays the program execution for the given number of seconds.
It returns zero on success and false on error.
So you can do something like:
<?php
function firstFunc(){
echo "anything";
}
function secondFunc(){
echo "something";
}
// call first function
firstFunc();
sleep(2); //Delays execution for 2 seconds.
secondFunc();
?>
Keep in mind though, PHP is a server side language. The only thing the client will receive from a PHP script(if the client has to receive anything at all) is HTML(or CSS, JS and so on). So when you run this code, the page will show nothing for 2 seconds and then output anything and something together because the delay is happening at a server level, and not on client machine. If you want a kind a delay where something is visible on the screen and then after 2 seconds anything appears, you want to use JavaScript.
Hope this helps :)
You should use function sleep(int seconds)
I have a function where I want to delay a certain call in the middle, but I don't want to stop the whole function. Even after the last line I want the part I delayed to run after a designated time. Here's an example of what I mean:
function delayInMiddle()
{
function call 1
if(some condition met in 30 seconds)
{function call 2}
function call 3
}
I want to have function 1 called, check for function 2, continue to function call 3, then go back and do function call 2 in 30 seconds.
Is this possible in php?
How about this as a possible solution.
Instead of calling function2 in that script, write the relevant data to a table that is operated as a queue + a time before which it should not process this queue item, that creates your x second delay.
Then make function 2 a cron job that runs every 30 seconds. It looks at the queue to see what if anything there is for it to do.
foreach ( row in queue ) {
send twitter;
delete row from table;
}
exit;
You can use sleep() for delay. http://php.net/manual/en/function.sleep.php
Context :
I'm making a PHP websocket server (here) running as a DAEMON in which there is obviously a main loop listening for sockets connections and incoming data so i can't just create an other loop with a sleep(x_number_of_seconds); in it because it'll freeze my whole server.
I can't execute an external script with a CRON job or fork a new process too (i guess) because I have to be in the scope of my server class to send data to connected client sockets.
Does anyone knows a magic trick to achieve this in PHP ? :/
Some crazy ideas :
Keeping track of the last loop execution time with microtime(true), and compare it with the current time on each loop, if it's about my desired X seconds interval, execute the method... which would result in a very drunk and inconsistent interval loop.
Run a JavaScript setInterval() in a browser that will communicate with my server trough a websocket and tell it to execute my method... i said they where crazy ideas !
Additional infos about what i'm trying to achieve :
I'm making a little online game (RPG like) in which I would like to add some NPCs that updates their behaviours every X seconds.
Is there an other ways of achieving this ? Am I missing something ? Should I rewrite my server in Node.js ??
Thanks a lot for the help !
A perfect alternative doesn't seams to exists so I'll use my crazy solution #1 :
$this->last_tick_time = microtime(true);
$this->tick_interval = 1;
$this->tick_counter = 0;
while(true)
{
//loop code here...
$t= microtime(true) - $this->last_tick_time;
if($t>= $this->tick_interval)
{
$this->on_server_tick(++$this->tick_counter);
$this->last_tick_time = microtime(true) - ($t- $this->tick_interval);
}
}
Basically, if the time elapsed since the last server tick is greater or equal to my desired tick interval, execute on_server_tick() method. And most importantly : we subtract the time overflow to make the next tick happen faster if this one happened too late. This way we fill the gaps and at the end, if the socket_select timeout is set to 1 second, we will never have a gap greater than 1.99999999+ second.
I also keep track of the tick counter, this way I can use modulo (%) to execute code on multiple intervals like this :
protected function on_server_tick($counter)
{
if($counter%5 == 0)
{
// 5 seconds interval
}
if($counter%10 == 0)
{
// 10 seconds interval
}
}
which covers all my needs ! :D
Don't worry PHP, I won't replace you with Node.js, you still my friend.
It looks to me like the websocket-framework you are using is too primitive to allow your server to do other useful things while waiting for connections from clients. The only call to PHP's socket_select() function is hard-coded to a one second timeout, and it does nothing when the time runs out. It really ought to allow a callback or an outside loop.
Look at the http://php.net/manual/en/function.socket-select.php manual page. The last parameter is a timeout time. socket_select() waits for incoming data on a socket or until the timeout time is up, which sounds like what you want to do, but the library has no provision for it. Then look at how the library uses it in core/classes/SocketServer.php.
I'm assuming you call run() and then it just never returns to your calling code until it gets a message on the socket, which prevents you from doing anything.
I try to make some kind of progress indicator for a simple php loop.
There are a lot of ajax / php questions here regarding progress and php loops, but after reading a lot of them, I still can not implement (nor understand exactly ) the logic..
Most of them are either talking about -upload- progress bar or are too localized to a specific case .( either that - or I do not know how to choose the right keywords to search.)
My final goal is to make a progress bar, but to start, I tried a little echo loop.
I tried the following :
HTML form :
<p class="submit">
<input type="submit" class="button-primary" id="o99_sudi_do_now" value="<?php _e('DO IT NOW !', 'o99_sudi_domain'); ?>" />
<img src="<?php echo admin_url('/images/wpspin_light.gif'); ?>" class="waiting" id="o99_sudi_loading" style="display:none;"/>
</p>
<div id="o99_sudi_results"></div>
jQuery
jQuery(document).ready(function($){
jQuery('#o99_sudi_do_now_form').click(function(e){
e.preventDefault();
jQuery.post(ajaxurl,{action:'o99_random_loop'}, function(data){
jQuery('#o99_sudi_results').empty().append( data );
});
});
});
PHP
function o99_random_loop_cb(){
for ($i = 0; $i < 10; $i++) {
//ob_end_clean(); // [TESING]
echo '-- step' .$i . ' of 10</br>';
//flush();// [TESING]
//usleep(100000000000*0.1); // total time 10 sec.// [TESING]
//ob_flush();// [TESING]
usleep(20000);
}
die();
and since it is all in a wordpress admin area -
add_action( 'wp_ajax_o99_random_loop', 'o99_random_loop_cb' );
the result (or output) is :
-- Step 0 of 10
-- Step 1 of 10
-- Step 2 of 10
-- Step 3 of 10
-- Step 4 of 10
-- Step 5 of 10
-- Step 6 of 10
-- Step 7 of 10
-- Step 8 of 10
-- Step 9 of 10
which is kind of ok , but the problem is that the output arrives and the div is updated only when the execution is finished - and I want it to be updated on-the-fly ,step by step... (my real planned loop is quite long and will take about 2-3 seconds for iteration. )
Like you can see with the code, i have tried flush(); , ob_flush(); and any other suggestion that I have seen , but I suspect that the LOGIC is wrong here (because it is wordpress?? or flushing in wrong place ?) and actually , no matter how much I flush(); - the result arrive only when the function is ENDING ..
My goal is to make a progress bar - but for now even help with a simple echoing progress will be great ..
You can't achieve what you want with a single POST to PHP. Even if you flush your PHP output, the jQuery side won't process the result handler until the entire PHP process is complete. Long ago you could get something like this behavior with only some browsers (Netscape, etc) that would start displaying content before the document was complete, however, with AJAX you won't see any of the resulting content from PHP until the PHP script is finished.
Hence the reason you are getting all your output at once.
There are a few possible ways to accomplish what you want to do. One method is to break your PHP loop into stages so that only a portion of the loop is executed each time. You could then execute a few iterations (or even one iteration) and return that result to the browser. The browser would then display the result and call to PHP again for the next iteration (or set of iterations). While this would give you your progress indicator it would dramatically slow down your overall operation and is not recommended.
EDITED to remove use of SESSION which won't work due to concurrency issues:
Another option is to have PHP save the progress of your loop to a database and have the browser side regularly poll another PHP script that checks the database to determine the progress. On a quick loop this won't be all that helpful, but on a longer running loop this could be workable. So along with your $.post call you'll start a series of timed $.get calls to check the progress.
EDIT:
Here are a few snippets to illustrate:
// variable to control polling logic
var pollInterval;
// Your current post logic here with the addition of a variable to stop execution of the polling process
jQuery.post(ajaxurl,{action:'o99_random_loop'}, function(data){
// post is complete so stop execution
window.clearInterval(pollInterval);
});
// Now start a get process to get the progress every 5 seconds
pollInterval = window.setInterval(function () {
// I'm assuming pollingurl is the URL to your PHP script that checks the progress
jQuery.get(pollingurl, function(data){
jQuery('#o99_sudi_results').empty().append( data );
});
}, 5000);
I'll assume for now that on the PHP side you are comfortable saving your progress to a database table and retrieving said progress from the table.
The question sort of says it all - is there a function which does the same as the JavaScript function setTimeout() for PHP? I've searched php.net, and I can't seem to find any...
There is no way to delay execution of part of the code of in the current script. It wouldn't make much sense, either, as the processing of a PHP script takes place entirely on server side and you would just delay the overall execution of the script. There is sleep() but that will simply halt the process for a certain time.
You can, of course, schedule a PHP script to run at a specific time using cron jobs and the like.
There's the sleep function, which pauses the script for a determined amount of time.
See also usleep, time_nanosleep and time_sleep_until.
PHP isn't event driven, so a setTimeout doesn't make much sense. You can certainly mimic it and in fact, someone has written a Timer class you could use. But I would be careful before you start programming in this way on the server side in PHP.
A few things I'd like to note about timers in PHP:
1) Timers in PHP make sense when used in long-running scripts (daemons and, maybe, in CLI scripts). So if you're not developing that kind of application, then you don't need timers.
2) Timers can be blocking and non-blocking. If you're using sleep(), then it's a blocking timer, because your script just freezes for a specified amount of time.
For many tasks blocking timers are fine. For example, sending statistics every 10 seconds. It's ok to block the script:
while (true) {
sendStat();
sleep(10);
}
3) Non-blocking timers make sense only in event driven apps, like websocket-server. In such applications an event can occur at any time (e.g incoming connection), so you must not block your app with sleep() (obviously).
For this purposes there are event-loop libraries, like reactphp/event-loop, which allows you to handle multiple streams in a non-blocking fashion and also has timer/ interval feature.
4) Non-blocking timeouts in PHP are possible.
It can be implemented by means of stream_select() function with timeout parameter (see how it's implemented in reactphp/event-loop StreamSelectLoop::run()).
5) There are PHP extensions like libevent, libev, event which allow timers implementation (if you want to go hardcore)
Not really, but you could try the tick count function.
http://php.net/manual/en/class.evtimer.php is probably what you are looking for, you can have a function called during set intervals, similar to setInterval in javascript. it is a pecl extension, if you have whm/cpanel you can easily install it through the pecl software/extension installer page.
i hadn't noticed this question is from 2010 and the evtimer class started to be coded in 2012-2013. so as an update to an old question, there is now a class that can do this similar to javascripts settimeout/setinterval.
Warning: You should note that while the sleep command can make a PHP process hang, or "sleep" for a given amount of time, you'd generally implement visual delays within the user interface.
Since PHP is a server side language, merely writing its execution output (generally in the form of HTML) to a web server response: using sleep in this fashion will generally just stall or delay the response.
With that being said, sleep does have practical purposes. Delaying execution can be used to implement back off schemes, such as when retrying a request after a failed connection. Generally speaking, if you need to use a setTimeout in PHP, you're probably doing something wrong.
Solution: If you still want to implement setTimeout in PHP, to answer your question explicitly: Consider that setTimeout possesses two parameters, one which represents the function to run, and the other which represents the amount of time (in milliseconds). The following code would actually meet the requirements in your question:
<?php
// Build the setTimeout function.
// This is the important part.
function setTimeout($fn, $timeout){
// sleep for $timeout milliseconds.
sleep(($timeout/1000));
$fn();
}
// Some example function we want to run.
$someFunctionToExecute = function() {
echo 'The function executed!';
}
// This will run the function after a 3 second sleep.
// We're using the functional property of first-class functions
// to pass the function that we wish to execute.
setTimeout($someFunctionToExecute, 3000);
?>
The output of the above code will be three seconds of delay, followed by the following output:
The function executed!
if you need to make an action after you execute some php code you can do it with an echo
echo "Success.... <script>setTimeout(function(){alert('Hello')}, 3000);</script>";
so after a time in the client(browser) you can do something else, like a redirect to another php script for example or echo an alert
There is a Generator class available in PHP version > 5.5 which provides a function called yield that helps you pause and continue to next function.
generator-example.php
<?php
function myGeneratorFunction()
{
echo "One","\n";
yield;
echo "Two","\n";
yield;
echo "Three","\n";
yield;
}
// get our Generator object (remember, all generator function return
// a generator object, and a generator function is any function that
// uses the yield keyword)
$iterator = myGeneratorFunction();
OUTPUT
One
If you want to execute the code after the first yield you add these line
// get the current value of the iterator
$value = $iterator->current();
// get the next value of the iterator
$value = $iterator->next();
// and the value after that the next value of the iterator
// $value = $iterator->next();
Now you will get output
One
Two
If you minutely see the setTimeout() creates an event loop.
In PHP there are many libraries out there E.g amphp is a popular one that provides event loop to execute code asynchronously.
Javascript snippet
setTimeout(function () {
console.log('After timeout');
}, 1000);
console.log('Before timeout');
Converting above Javascript snippet to PHP using Amphp
Loop::run(function () {
Loop::delay(1000, function () {
echo date('H:i:s') . ' After timeout' . PHP_EOL;
});
echo date('H:i:s') . ' Before timeout' . PHP_EOL;
});
Check this Out!
<?php
set_time_limit(20);
while ($i<=10)
{
echo "i=$i ";
sleep(100);
$i++;
}
?>
Output:
i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10