Intermittently echo out data with long-running PHP script

2.1k views Asked by At

I have a PHP script that makes a bunch of cURL requests. After each cURL request, I want to echo out some data, but presently, data only gets echoed out after every 5-10 cURL requests.

I've tried using ob_flush and flush, but it doesn't seem to make a difference. The following is the basic flow of my script:

<?php

  header('Content-Type: text/html; charset=UTF-8');

  set_time_limit(0);

  ob_start();

  $arr = array(); // Lots of strings in this array

  foreach ($arr as $elem) {

    // Use $elem to make cURL request and return HTML.
    // Run regexes on returned HTML.

    echo '<pre>';

    print_r($matches[1]);

    print_r($matches[2]);

    echo '</pre>';

    ob_flush();

    flush();

  }

Is there anything I can do to force the script to output the echoed/print_r'ed data after each iteration of the foreach loop?

Thank you very much.

2

There are 2 answers

7
Drew On

You need to move the ob_start() inside the loop, as:

<?php

  header('Content-Type: text/html; charset=UTF-8');

  set_time_limit(0);

  $arr = array(); // Lots of strings in this array

  foreach ($arr as $elem) {

    ob_start();

    // Use $elem to make cURL request and return HTML.
    // Run regexes on returned HTML.

    echo '<pre>';

    print_r($matches[1]);

    print_r($matches[2]);

    echo '</pre>';

    ob_end_flush();

    flush();

  }

Think of the Output Buffer (ob_*) functions as push and pop on a stack. You specify where you want to start recording by pushing a buffer onto the stack (ob_start()) and then when you want to output, you pop the buffer off the stack and do something with the result (ob_flush(), ob_get_*(), etc). Each ob_start() must have a matching buffer end function.

You'll also want to use ob_end_flush() instead of ob_flush() as I don't think you want keep the buffer after each run.

1
nl-x On

Try using this at start:

apache_setenv('no-gzip', 1);
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);
ini_set('implicit_flush', 1);

And then do the stuff you already did.