PHP - Unbuffered While() Loop - php

I am using php, I see while() loop in php. I want to ask something can we use
while() loop as mysql_unbuffered_query().
This code make good understanding.
<?php
echo 'While Loop is going to start';
$i = 0;
while($i <= 1000){
echo 'Now number is '.$i;
$i++;
}
echo 'Continue to running script';
?>
What happens when we run this code first of all this code read while loop is going to start
then read the while loop and create the statement to run Now number is 0.....1000
then read Continue to running script And when the code is finished it print out whole data.But I did not want this.
What I want.
First script read the while Loop is going to start and print out then read while loop and
print out Now number is 0 then go Continue to running script and print out But the
back end of script while loop still working, My mean both while loop and continue script working at once.
This give you more understanding.
OUTPUT(First time when script running is start)
1 - While Loop is going to start
2 - Now number is 0
3 - Continue to running script
OUTPUT(Script running is continue)
1 - While Loop is going to start
2 - Now number is 0
3 - Now number is 1
. - ...............
1000 - Now number is 1000
1001 - Continue to running script
Might be this is impossible.If yes how I can do that.
But maybe this is possible like mysql_unbuffered_query().
Like when while loop complete one cycle it print out the number and then other one and so on to complete.
OUTPUT(First time when while loop complete one cycle)
1 - While Loop is going to start
2 - Now number is 0
OUTPUT(while loop complete second cycle)
1 - While Loop is going to start
2 - Now number is 0
3 - Now number is 1
If this is possible, Please guide me how can I do that.
Thanks..............

If you are running this script from the command line, output buffering is always off, and implicit flush is always on (according to http://us3.php.net/manual/en/outcontrol.configuration.php ). Because of this, I suspect you are running this PHP within a web server.
There are several PHP INI values which affect buffering, so you may wish to turn off these features:
<?php
ini_set('zlib.output_compression', 'off');
ini_set('implicit_flush', 'on');
ini_set('output_buffering', 'off');
echo "While Loop is going to start.\n";
$i = 0;
while($i <= 10){
echo "Now number is ".$i."\n<br>\n";
$i++;
sleep(1);
}
echo "\n<br>Finished running script\n\n";
?>
Even after all that, it's possible that PHP is behaving exactly as you want, but your web server is buffering the output. This thread may be of interest: php flush not working
If you are using apache, you can add a line to an .htaccess file to turn off gzip compression (which automatically buffers until there's enough data to compress and send)
I found this page (http://www.bluehostforum.com/showthread.php?18996-Turning-off-Gzip) which describes the process, but it basically says to add
SetEnv no-gzip dont-vary
to your .htaccess file.
Can you confirm that the script I posted above works as you'd expect in your command line environment or not?
Also, if you are working within a web server, please post which web server you're using (IIS/apache/etc)

You need threads or processes. This is a good thread: Does PHP have threading?
My favorite answer there is https://stackoverflow.com/a/14201579/650405

Forcing output to the browser works with the following calls in this order
ob_flush();
flush();
It, however, will not background any processing going on.

Related

Real time output of an external program in PHP

I've written and compiled a command line program (abc.exe) that runs for about 10 mins, makes some calculations and outputs 1 line of results per 10 secs, like this:
C:\>abc.exe
Result 1
Result 2
Result 3
.
.
.
The following php script should theoretically show these results in real time, as they are produced by the program.
<?php
$a = popen('abc.exe', 'r');
while($b = fgets($a)) {
echo $b."<br>\n";
ob_flush();flush();
}
pclose($a);
?>
However, I just get all the results at the end of the execution of the program. Why could this be happening? Please note that if I replace abc.exe with ping 8.8.8.8 or tracert 8.8.8.8, the script works like a charm. Please, help me, I've tried everything that is suggested in similar questions here, but nothing seems to work!

Pause-Continue reading large text file with php

I have the below PHP code. I want to be able to continue reading the text file from the point it stopped, and the text file is over 90mb.
Is it possible to continue reading from the point the script stopped running?
$in = fopen('email.txt','r');
while($kw = trim(fgets($in))) {
//my code
}
No, that's not easily possible without saving the current state from time to time.
However, instead of doing that you should better try to fix whatever causes your script to stop. set_time_limit(0); and ignore_user_abort(true); will most likely prevent your script from being stopped while it's running.
If you do want to be able to continue from some position, use ftell($in) to get the position and store it in a file/database from time to time. When starting the script you check if you have a stored position and then simply fseek($in, $offset); after opening the file.
If the script is executed from a browser and it takes enough time to make aborts likely, you could also consider splitting it in chunks and cleanly terminating the script with a redirect containing an argument where to continue. So your script would process e.g. 1000 lines and then be restarted with an offset of 1000 to process the next 1000 lines and so on.

Timed loop in php

I just want to print a counting from 1 to 10 at an interval of 10 sec between each integer.
eg.
$i=10; //Time delay
for($j=1;$j<11;$j++)
{
echo $j;
//do something to delay the execution by $i seconds
}
I have tried everything including flush(), ob_flush(), ob_implicit_flush() but all i get is a frozen screen untill the whole time is executed.
http://php.net/manual/en/function.sleep.php
The sleep function will interrupt execution of your script.
But have you considered using Javascript for something like this? Your script may reach maximum execution time, and will be hogging resources on the server. Use the client's resources instead!
What you want is much more javascript-related than PHP. Because PHP is serverside it is not designed to do these kind of operations. You COULD get it to work, but it would not be very pretty.
In my logic; counting from 1 to 10 should not involve the server at all. You can do this directly in the browser, hence use javascript.
you want to print the countdown while your php script is running?
if yes, then try that non-recommended fragment:
ob_start();
for($i=0;$i<10;$i++) {
echo str_repeat(" ",10000);
echo 'printing...<br />';
ob_flush();
flush();
sleep(1);
}
you see, the strange line:
echo str_repeat(" ",10000);
it seems that browsers needs some "data" before deciding to really flush your data.
Use javascript for real time counters.
Use jQuery. On $(document).ready add a delay of 10 seconds to show a specific div which would contain the info to appear after 10 seconds.
For ready - http://api.jquery.com/ready/
For delay - http://api.jquery.com/delay/
Yes, use Javascript as it's not possible to accomplish this task with PHP using HTTP because of output buffering.

PHP: Printing out status messages during runtime

I'm developing a long running php script that compiles scraped information from multiple sources, organizes them, and caches them in a database.
As this script has a very high runtime, I'd like to print out runtime status reports in order to track the progress.
for ($i = 1; $i<= 10; $i++) {
echo "Starting iteration #$i\n";
set_time_limit(40);
echo "Time Limit set, starting 10 second sleep.\n";
sleep(10);
echo "Finishing iteration #$i\n\n";
}
echo "Iterations Finished.";
would output:
Starting iteration #1
Time Limit set, starting 10 second sleep
then wait 10 seconds and output:
Finishing iteration #1
Starting iteration #2
Time Limit set, starting 10 second sleep
then right before the php finishes parsing, it will output:
Iterations Finished.
What is the best way to achieve this?
If you are running PHP from the CLI you can output directly to stdout, without having to wait for the script
to end, using :
$handle = fopen('php://stdout', 'r');
fwrite($handle, $output);
If run from CGI, which would be really bad for a script like this, you would have to change how the buffer acts with flush();
Try writing the runtime status reports to a file, then viewing live updates of the file using ajax, per this question: Live feed of an updating file

PHP exec on another PHP file - How to get my script to wait?

I'm running a continuous PHP loop that executes another PHP file by using exec("php ...");. The plan is for the executed script to run, then sleep for 2 seconds, then start again. However, it seems like my loop is starting a new instance every 2 seconds instead. So long question short, how do I get my first php script to wait until the execution of script nr 2 is complete?
All this is run using the command line. I would also like the echo functions in script nr 2 to show up on the command line.
Any thoughts would help.
Thanks
Exec does not maintain any state information between instances. You could:
Loop in your subscript
OR
You could set some sort of environment variables or that are read at the beginning of the subscript and written at the end.
OR
You could have the subscript read/write to a file in a similar fashion
OR
You could pass in parameters to the subscript who's output is captured
For outputting to the screen, you might play around with the other exec/system calls:
exec
shell_exec
passthru
system
I believe passthru() will work. Another possibility if it doesn't is to call exec(), using the output parameters to capture the output strings from the subscript. Then just echoing that output on return of the subscript.
I also believe that using the output parameters (or capturing the result of the function in a variable) will cause the exec to wait until the command is complete before continuing on.
The problem is, once you excute the script, it will run. Another exec will start another instance like you found out.
What you can do is
Put the sleep inside the executed script. Once it starts running, it will do its own sleep. You can look at setting an execution time limit and maybe ignoring user abort.
You can create a function and let your script call that function. It will then sleep after execution and call the function again.
// maybe set time limit here
Function loop ()
{
Sleep(120);
//you can make a check whether to loop or not.
Loop();
}
Loop();

Categories