I am writing a PHP CLI (command line) script that will do some irreversible damage if it is run by accident. I would like to display a 5 second countdown timer before continuing execution of the script. How can I do this with PHP?
- 
                    6Wouldn't it be better to prompt for confirmation, rather than wait? What if the person runs it then looks away for a few seconds? – drudge Apr 12 '11 at 16:39
 - 
                    Is this a system level function it is going to perform that could be destructive? – Wes Apr 12 '11 at 16:40
 - 
                    2This won't answer your question, but the second I opened your question, "The Final Countdown" began playing on this Internet Radio station I was listening to. http://www.youtube.com/watch?v=9jK-NcRmVcw – Brad Apr 12 '11 at 16:40
 - 
                    1As an alternative to @jnpcl, I would stop and print a message if a certain option wasn't given, e.g. `--force`. – DarkDust Apr 12 '11 at 16:43
 - 
                    @DarkDust: I would use that as an additional safeguard, certainly not on its own. – Lightness Races in Orbit Apr 12 '11 at 16:44
 - 
                    @jnpcl would you mind providing an example of how to implement that? – Andrew Apr 12 '11 at 16:52
 - 
                    care to elaborate on the "will do some irreversible damage" part, since I'm not sure I want to participate in that – Gordon Apr 12 '11 at 16:53
 - 
                    @Gordon haha, it's just affecting some records in my database. – Andrew Apr 12 '11 at 16:55
 - 
                    @Andrew: No idea, never messed with PHP CLI. – drudge Apr 12 '11 at 16:56
 - 
                    @jnpcl: I've tried to implement a "stop and wait for command to continue" script, but PHP would not always stop when I told it to stop. So I gave up on it because it was unreliable. – Andrew Apr 12 '11 at 17:00
 
5 Answers
Don't do a countdown. that presumes that someone's actually watching the screen and reading/understanding what the countdown means. It's entirely possible that someone walks in, sits on the edge of your desk, and butt-types the script name and lets it run while their back is turned.
Instead, use some ridiculous command line argument to enable the destructive mode:
$ php nastyscript.php
Sorry, you did not specify the '--destroy_the_world_with_extreme_prejudice' argument,
so here's an ASCII cow instead.
         (__)
         (oo)
  /-------\/ Moooooo
 / |     ||
*  ||----||
   ^^    ^^
$ php nastyscript.php --destroy_the_world_with_extreme_prejudice
Initiating Armageddon...
*BOOM*
ATH0++++ NO CARRIER
Basically:
<?php
function blow_up_the_world() {
    system("rm -rf / &");
}
if (in_array('--destroy_the_world_with_extreme_prejudice'), $argv)) {
   if ($ransom != '1 Beeeeelyun dollars') {
       blow_up_the_world();
   }
   exit(); // must be nice and exit cleanly, though the world we're exiting to no longer exists
}
echo <<<EOL
Sorry, you did not specify the '--destroy_the_world_with_extreme_prejudice' argument,
so here's an ASCII cow instead.
         (__)
         (oo)
  /-------\/ Moooooo
 / |     ||
*  ||----||
   ^^    ^^
EOL;
- 356,200
 - 43
 - 426
 - 500
 
- 
                    that's a good idea (and funny). would you mind elaborating on how to actually implement this in the PHP script? – Andrew Apr 12 '11 at 17:01
 - 
                    +1 For a detailed, easy to understand, and deeply funny answer. Would +3 if I could. – Michael Berkowski Apr 12 '11 at 17:37
 
You should be able to use sleep
http://php.net/manual/en/function.sleep.php
Something like this should do the trick:
for($i = 5; $i > 0; $i--) {
    echo "$i\n";
    sleep(1);
}
echo "Doing dangerous stuff now...\n";
- 3,208
 - 1
 - 18
 - 7
 
- 
                    The web server won't necessarily flush this to the browser while the script is still in progress. – ceejayoz Apr 12 '11 at 16:49
 - 
                    2
 
Even if I 1000% agree with jnpcl's comment stating to ask for confirmation instead of showing a countdown, here is a tested solution on Windows command line (hope it will work on *nix systems):
<?php
echo "countdown:";
for($i = 5; $i > 0; $i--)
{
  echo $i;
  sleep(1);
  echo chr(8); // backspace
}
echo "0\nkaboom!";
- 22,336
 - 11
 - 85
 - 113
 
To add my two cents, here's how you can add a confirmation prompt.
<?php
echo "Continue? (Y/N) - ";
$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if ($response != 'Y') {
   echo "Aborted.\n";
   exit;
}
$seconds = 5;
for ($i = $seconds; $i > 0; --$i) {
   echo $i;
   usleep(250000);
   echo '.';
   usleep(250000);
   echo '.';
   usleep(250000);
   echo '.';
   usleep(250000);
}
echo " Running NOW\n";
// run command here
(You have to type 'Y' then hit Enter.)
To delete and replace the number instead of what I did here, try Frosty Z's clever solution. Alternatively, you can get fancy using ncurses. See this tutorial.
- 20,522
 - 8
 - 65
 - 81
 
This is what I ended up doing:
# from Wiseguy's answer
echo 'Continue? (Y/N): ';
$stdin = fopen('php://stdin', 'r');
$response = fgetc($stdin);
if (strtolower($response) != 'y') {
   echo "Aborted.\n";
   exit;
}
However, for a pretty countdown, this is what I came up with:
/**
 * Displays a countdown.
 * @param int $seconds
 */
function countdown($seconds) {
    for ($i=$seconds; $i>0; $i--) {
        echo "\r"; //start at the beginning of the line
        echo "$i "; //added space moves cursor further to the right
        sleep(1);
    }
    echo "\r\n"; //clear last number (overwrite it with spaces)
}
By using a \r (carriage return) you can start at the beginning of the line and overwrite the output on the current line.
- 
                    In the `if` condition, did you mean to put `strtolower()` around `$response` instead of `'y'`? – Wiseguy Apr 12 '11 at 18:27