php echo the result while iterating through the loop - php

I am execution loop and inside loop there is data processing function inside loop.
for($i = 0 ; $i <=680 ; $i = $i + 40)
{
$url = 'http://www.yelp.com/biz/franchino-san-francisco?start=80';
$root = yelp($url);
var_dump($root);
}
This loop takes long time to execute, and results are echoed at the end when entire loop completes.
How can I echo the result during each iteration?
Actually what happens here? does to result are stored in buffer and at the end echoed or what?

PHP buffers the output.
If you want to output stuff to the browser immediately you can use the flush() and ob_flush() functions:
for ($i = 0; $i <= 680; $i += 40) {
$url = 'http://www.yelp.com/biz/franchino-san-francisco?start=80';
$root = yelp($url);
var_dump($root);
flush();
ob_flush();
}

If you are executing PHP through a web-page, this would be the behaviour.
PHP is a server side language and all code will be executed before displaying the output to the client. (using a browser)
If you want to display the result within the loop, better use console / cmd (command line)
Here is something that will help you use PHP with commandline.

Related

How to print current index or for loop in PHP?

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++;
}
?>

While loop output one digit per loop at the same position

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++;
}

PHP Cli Output after run

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

No output from the loop

I'm iterating over a huge array and it involves querying multiple APIs so to avoid data loss and timeout, I'm doing this:
for ($i = 0; $i < $count; $i++) {
if ($i % 100 == 0) {
echo 'processed: '.$i."\n";
// save to file
}
}
... it works if the loop is a few hundred iterations during test and outputs processed ..., but nothing at all in prod environment during the script is running, it echos everything only after its done. I just want to avoid any timeouts incase it takes (and usually does) long.
PHP output is buffered; see here. If you flush the buffer (or turn buffering off), you'll see it happen in real-time.
As "belt and braces", if you really care about the output, I'd echo the $count before you even enter the loop.
what is the aim of this code block?
well, until $i reaches 100, it is waste of resource anyway..
you can try:
if( $count > 100 ) {
ini_set('max_execution_time', 0); // no time limit
// $count contains at least $i times 100
for($i = 1; $i <= $count / 100; $i++) {
echo $i * 100;
}
}

Is PHP capable of caching count call inside loop?

I know the more efficient way to have a loop over array is a foreach, or to store count in a variable to avoid to call it multiple times.
But I am curious if PHP have some kind of "caching" stuff like:
for ($i=0; $i<count($myarray); $i++) { /* ... */ }
Does it have something similar and I am missing it, or it does not have anything and you should code:
$count=count($myarray);
for ($i=0; $i<$count; $i++) { /* ... */ }
PHP does exactly what you tell it to. The length of the array may change inside the loop, so it may be on purpose that you're calling count on each iteration. PHP doesn't try to infer what you mean here, and neither should it. Therefore the standard way to do this is:
for ($i = 0, $length = count($myarray); $i < $length; $i++)
PHP will execute the count each time the loop iterates. However, PHP does keep internal track of the array's size, so count is a relatively cheap operation. It's not as if PHP is literally counting each element in the array. But it's still not free.
Using a very simple 10 million item array doing a simple variable increment, I get 2.5 seconds for the in-loop count version, and 0.9 seconds for the count-before-loop. A fairly large difference, but not 'massive'.
edit: the code:
$x = range(1, 10000000);
$z = 0;
$start = microtime(true);
for ($i = 0; $i < count($x); $i++) {
$z++;
}
$end = microtime(true); // $end - $start = 2.5047581195831
Switching to do
$count = count($x);
for ($i = 0; $i < $count; $i++) {
and otherwise everything else the same, the time is 0.96466398239136
PHP is an imperative language, and that means it is not supposed to optimize away anything that can possibly have any effect. Given that it's also an interpreted language, it couldn't be done safely even if someone really wanted.
Plus, if you simply want to iterate over the array, you really want to use foreach. In that case, not only the count, but the whole array will be copied (and you can modify the original one as you wish). Or you can modify it in place using foreach ($arr as &$el) { $el = ... }; unset($el);. What I mean to say is that PHP (as any other language) often provides better solutions to your original problem (if you have any).

Categories