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