Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

garrettmassey's avatar

creating a progress bar for long functions in tinker

I have a function that I am writing in development that only needs to run one time in production. the function takes a long time to complete and we want to have a progress bar show up on the output of Tinker. What I'm having a hard time with is getting the progress bar to show up on one line, and then clear that line for the next iteration of the progress bar. Right now we can get it to show up with each successful iteration of the bar as a new line.... Any tips?

PS. we are using Tinker because we have limited access to the console otherwise, and limited access to run commands outside of artisan commands, so tinker is the easiest way for us to execute one-time scripts in the terminal.

public static function financialAssistance()
{
	//data is a large array of values needed to be processed
	$data[...];
    $count = count($data);
    $done = 1;

    ob_start();
    foreach ($data as $ID => $dat) {
        $provider = Provider::whereHas('metadata', function (Builder $query) use ($ID) {
            $query->where('id', '=', $ID);
        })->first();
        $done++;
        ob_clean();
        print_r(OneTimeDataProcessor::progress($done, $count));
    }
}

public static function progress($done, $total, $info = "", $width = 50)
{
    $perc = round(($done * 100) / $total);
    $bar = round(($width * $perc) / 100);
    return sprintf("%s%%[%s>%s]%s", $perc, str_repeat("=", $bar), str_repeat(" ", $width - $bar), $info);
}

As written, the progress bar just outputs the final 100%, and if we 'dump' the results of progress, we get each stage of the progress bar on a new line.

0 likes
3 replies
garrettmassey's avatar

@click We can run artisan commands, yes, for one-time functions we've just been writing the function and then doing:

php artisan tinker

>>> App\Processors\OneTimeFunctions::functionName();

and then it runs the function in that class.

garrettmassey's avatar

@click if I wanted to display a status like:

	$this->line($item->name() . ' processing');

underneath the progress bar, how would I go about deleting that line and replacing it with the next item in the loop so that the whole screen doesn't get overloaded by the lines, and the progress bar is still visible?

Please or to participate in this conversation.