The below PHP code returns 12345678910...... at a stretch.
for ($i=0; $i<1000; $i++) {
sleep(1);
echo $i;
}
How can I get it to print only the current loop number instead of printing all numbers together?
This can be easily done in php cli using the backspace character "\x08"
<?php
$length = 0;
for ($i=0; $i<1000; $i++)
{
// delete as much character as the length of the previous number
echo str_repeat("\x08", $length);
sleep(1);
echo $i;
// get the length of the number, so you know how much you have to delete
$length = strlen((string)$i);
}
This is my suggested answer (applicable to browser)
a) I believe the OP wants to have the output generated to the browser interface
b) To generate the output of the count during the 1-second sleep, we need to flush the output before each sleep
c) In a browser interface, it is not possible to generate a backspace, so let's do a javascript trick to update the div
<div id=output1></div>
<?php
$index=0;
while($index < 1000) {
ob_start();
echo "<script>document.getElementById('output1').innerHTML=" . $index . "</script>";
ob_end_flush();
#ob_flush();
flush();
sleep(1);
$index++;
}
?>
Related
echo "counter: ";
$i=1;
while ($i <= 5) {
print($i);
sleep(1);
$i++;
}
The above will output: counter: 12345 I need to output eg.: loop 3 - counter: 3 (one digit per loop)
How to do it:
1) When running in a browser?
2) When running from command line (php index.php)?
I think you want to make an auto-updated string. It's impossible to make it with only PHP. You should use Javascript (or a library like jQuery) and send the data from PHP via Ajax call.
You can even do this only with Javascript.
var counter = 1;
setInterval(function () {
counter++;
}, 5);
For command line you can use your code with "\r" at the end of the string.
$i=0;
while ($i <= 5) {
sleep(1);
$i++;
echo "counter: $i\r";
}
I think this is what you need. The counter string was brought inside the loop and a break was added for a new line simulation. Also the < was changed to <= as the loop was running for 4 times instead of 1.
$i=1;
while ($i <= 5) {
print("counter: $i <br>");
sleep(1);
$i++;
}
for($i = 0; $i < 5; $i++) {
echo $i . "\n";
sleep(1);
}
This is the code I run. Instead of showing a number each second, the php CLI decides to wait and after everything is executed shows
0
1
2
3
4
Why is this happening, how can I make it "real-time" ?
EDIT: Found the problem: because I included WP-Core (Wordpress) the output somehow buffered, if I remove the wp-core it is all fine. For more info, when including the wp_core there are some wp notices that are being logged in separate file.
You need to disable output buffering, or flush the buffer. You really only need the ob for requests that come over HTTP, as it lets you do all your server-side processing without having to worry about the connection to the client.
for($i = 0; $i < 5; $i++) {
echo $i . "\n";
sleep(1);
flush();
ob_flush();
}
Alternatively, if you can't change the code, you can disable output buffering completely in your CLI php.ini
output_buffering=Off
Servers usually buffer the output of a server side script until there's enough in it to output try something like this. Combination of setting output buffering off and manually flushing the buffer. Note the implcit flush line and the flush and ob_flush lines.
for ($i = 0; $i < 5; $i++) {
echo $i . "</br>";
sleep(1);
flush();
ob_flush();
}
for more info about ob-flush please read http://php.net/manual/en/function.ob-flush.php
i have this code
$number = 1;
echo $number;
for ($i=0; $i < 10; $i++) {
$number++;
}
the output of echo $number is 1 not 11.
How can get the last $number value when I called it before it changed?
Once you output something to the browser, it's done. You cannot change it again later. The only way to handle this is to not output the variable until you have found its final value; ie in the example you move the echo statement to the bottom.
It's generally considered a good idea to first run all of your PHP code and determine all your variables and only then start outputting things to the browser in order to prevent the kind of problem you have now.
$number = 1;
echo 'before increment :'.$number;
for ($i=0; $i < 10; $i++) {
$number++;
}
echo 'after increment :'.$number;
Try this way, now you will get expected result:
$number = 1;
for ($i=0; $i < 10; $i++) {
$number++;
}
echo $number;
Reason, you have put echo $number before the increment, which was logically wrong:
Say I have the following:
for ($i = 0; $i < 10; $i++) {
echo $i;
sleep(1);
}
Now, this will display:
0123456789
However, it will take 9 seconds to load, and will not display real-time.
How would I display it so it would be:
0(1 second)2(1 second)3(...)
My second question involves overwriting the current data on the page.
For example, say I have the same code as above. However, I want to display each number as itself. So the page would be:
0
Then after 1 second
1
And so on.
for ($i = 0; $i < 10; $i++) {
echo $i."\n";
$timeFirst = strtotime(date());
sleep(1);
$timeSecond = strtotime(date());
echo ($timeSecond - $timeFirst)." second(s) \n";
}
You can only do it with Client side script such as javascript. DOM loads only after the complete execution of your server side script.
There is no way you can execute each command and render the output to the web browser, unless you are doing it at CLI or doing it via Client Side.
Try this
for ($i = 0; $i < 10; $i++) {
echo $i;
flush();
ob_end_flush();
sleep(1);
}
Alright, I'm working on a (supposed-to-be) simple counting script using ncurses. Everytime it increments the number, I need it to delete the previous number before adding another number, so that it updates rather than appends.
Here is my code:
<?php
ncurses_init();
$i = 0;
$nStr = "Number: ";
ncurses_addstr($nStr);
ncurses_refresh();
for ($i=0; $i < 100; $i++)
{
$iLen = strlen($i);
for ($j=0; $j < $iLen; $j++)
{
ncurses_delch();
}
ncurses_addstr($i);
ncurses_refresh();
sleep(2);
}
ncurses_end();
?>
Currently when I run it, it outputs like this: Number: 01234[...]
Anyone see where my problem is and how I can fix it?
ncurses_delch() forward-deletes. If you want to move the cusor back one column then output \b instead.