3

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?

10
  • 6
    Wouldn't it be better to prompt for confirmation, rather than wait? What if the person runs it then looks away for a few seconds? Commented Apr 12, 2011 at 16:39
  • Is this a system level function it is going to perform that could be destructive? Commented Apr 12, 2011 at 16:40
  • 2
    This 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. youtube.com/watch?v=9jK-NcRmVcw Commented Apr 12, 2011 at 16:40
  • 1
    As an alternative to @jnpcl, I would stop and print a message if a certain option wasn't given, e.g. --force. Commented Apr 12, 2011 at 16:43
  • @DarkDust: I would use that as an additional safeguard, certainly not on its own. Commented Apr 12, 2011 at 16:44

5 Answers 5

13

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;
Sign up to request clarification or add additional context in comments.

2 Comments

that's a good idea (and funny). would you mind elaborating on how to actually implement this in the PHP script?
+1 For a detailed, easy to understand, and deeply funny answer. Would +3 if I could.
4

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";

2 Comments

The web server won't necessarily flush this to the browser while the script is still in progress.
@ceejayoz True, though in this case the asker said it's running CLI.
4

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!";

Comments

3

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.

Comments

2

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.

1 Comment

In the if condition, did you mean to put strtolower() around $response instead of 'y'?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.