Getting a password hidden from STDIN with PHP-CLI

Friday, August 22, 2008

Today a friend asked me if it is possible to get a password with PHP-CLI, without the usual output of STDIN. I was kinda sure that there must be some way, and so I tried a bit around. I quickly found out, that there was no native PHP way, just a halfy working one with non-blocking STDIN, but not really what I expected. So I searched a bit on the internet, and found a way, how to catch single characters on the shell. With this knowledge I was able to create a tiny function, which can both output nothing while entering the password as well as character replacing stars. For those of you who are interested in this piece of code, here it is:

Note: This works on *nix systems only!
<?php
/**
 * Get a password from the shell.
 *
 * This function works on *nix systems only and requires shell_exec and stty.
 *
 * @param  boolean $stars Wether or not to output stars for given characters
 * @return string
 */
function getPassword($stars = false)
{
    // Get current style
    $oldStyle = shell_exec('stty -g');

    if ($stars === false) {
        shell_exec('stty -echo');
        $password = rtrim(fgets(STDIN), "\n");
    } else {
        shell_exec('stty -icanon -echo min 1 time 0');

        $password = '';
        while (true) {
            $char = fgetc(STDIN);

            if ($char === "\n") {
                break;
            } else if (ord($char) === 127) {
                if (strlen($password) > 0) {
                    fwrite(STDOUT, "\x08 \x08");
                    $password = substr($password, 0, -1);
                }
            } else {
                fwrite(STDOUT, "*");
                $password .= $char;
            }
        }
    }

    // Reset old style
    shell_exec('stty ' . $oldStyle);

    // Return the password
    return $password;
}

// Get the password
fwrite(STDOUT, "Password: ");
$password = getPassword(true);

// Output the password
echo "Your password: " . $password . "\n";

Comments to this article

  • Avatar of beberlei Reply beberlei Friday, August 22, 2008 11:48 PM

    this is great, thank you very much for the work :-)

    i have tons of applications that need this :)

  • Avatar of Brian Reply Brian Monday, April 6, 2009 8:08 AM

    Hey thanks for posting this. Exactly what I was looking for and works great!

  • Avatar of Alex Reply Alex Thursday, May 28, 2009 12:30 AM

    thanks a lot !
    (I'd like your horde style captcha too :)

  • Avatar of raphael Reply raphael Tuesday, June 30, 2009 10:24 PM

    Great ! this is very useful. Thanks for sharing your work.

  • Avatar of carlitos Reply carlitos Thursday, September 24, 2009 11:20 AM

    very ugly ..... NOOOO i'm joking
    very helpful thanks! :)

  • Avatar of Janos Reply Janos Wednesday, September 30, 2009 1:10 PM

    Thanx for this! Very nice solution!

  • Avatar of killerbees19 Reply killerbees19 Tuesday, October 27, 2009 7:58 PM

    THANK YOU! I've searched ~2h a solution for a y/n confirm question in a php-cli application. With your code I can handle every input char without waiting for a newline. Great! :-)

    Greets from Vienna, Christian

  • Avatar of and77 Reply and77 Thursday, February 9, 2012 6:06 PM

    what does it mean from line 27 to 31.can you please explain me?

    • Avatar of Ben Scholzen 'DASPRiD' Reply Ben Scholzen 'DASPRiD' Wednesday, March 7, 2012 12:45 AM

      That code handles the backspace character.

  • Avatar of AndyReutimann Reply AndyReutimann Saturday, September 15, 2012 10:10 AM

    If it's enough to just not show the password, it's way easier to implement it like this:
    <code>
    system('stty -echo');
    $password = trim(fgets(STDIN));
    system('stty echo');
    </code>

  • Avatar of Rodrigo Nascimento Reply Rodrigo Nascimento Tuesday, July 29, 2014 9:34 PM

    Awesome method! ((:

Leave a comment

Please note that your email address will not be shown, it is only used to fetch your avatar image from gravatar.com and for notifications.

                                  _ 
__      ____ _ _ __ ___ _ __ ___ (_)
\ \ /\ / / _` | '__/ _ \ '_ ` _ \| |
 \ V  V / (_| | | |  __/ | | | | | |
  \_/\_/ \__,_|_|  \___|_| |_| |_|_|