The following is for unix machines.
The goal is to retrieve the current terminal total columns. (using tput)
This is a base, ready to be expanded.
 #!/usr/bin/php
 <?php
 @ob_start();
 
 $shell = system("tput cols");
 
 @ob_end_clean();
  
 for( $i= 0 ; $i < $shell ; $i++ ){ echo "█"; usleep(100000); } 

The ob actions are here to hide the stdout of tput.
Let's say you would like to make a progress bar matching your task progress.
Just divide the remaining time in seconds by the numbers of columns.
You may end up with microseconds, so it's best to use usleep.
This way the progress bar will always match the user shell width, including when resized.
To do the same thing in pure bash:
for ((i=0; i<$(tput cols); i++)); do echo -e "█\c"; sleep 0.1; done
This shows the main singularity of the php echo: it does not append a new line, while the bash echo does.
When using loops, say to check for a condition in intervals,
one other nice way to warn for running activity is text effects.
The following using strtoupper and the ansi code reverse video.
#!/usr/bin/php
<?php
$iloop = "0"; /* Outside the loop */
while (true){  
  $warn = "Program running hold on!!\r";
  if (strlen($warn) === $iloop+1){
    $iloop = "0";
  }
  $warn = str_split($warn);
  $iloop++;
  $warn[$iloop] = "\033[35;2m\e[0m".strtoupper($warn[$iloop]);
  echo " \033[7m".implode($warn);
  usleep(90000);
}
Output:

Some may likes the party version, obtained by iteration of ansi codes.
#!/usr/bin/php
<?php
$iloop = "0"; /* Outside the loop */
while (true){    
for ($i=0;$i<=109;$i++){
  $warn = "Program running hold on!!\r";
  if (strlen($warn) === $iloop+1){
    $iloop = "0";
  }
  $warn = str_split($warn);
  $iloop++;
  $warn[$iloop] = "\033[$i;7m".strtoupper($warn[$iloop]);
  echo " \033[7m".implode($warn);
  usleep(90000);
}}

See more about ANSI codes: https://stackoverflow.com/a/48365998/2494754