Skip to Content
Course content

241: Interactive CLI Prompts in PHP

Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I actually capture a string from the terminal?

When you're moving from web requests to CLI scripts, the first thing you'll realize is that $_POST and $_GET are gone. To get a response from a user, you have two main options: fgets(STDIN)` and readline().

In my experience, readline() is the way to go for most interactive prompts. It's cleaner and handles the newline character for you, whereas fgets()` leaves that annoying \n at the end of the string, forcing you to call trim() every single time. Here is how a basic prompt looks:

<?php
$env = readline("Which environment are you deploying to? (staging/production): ");
echo "Preparing deployment for $env...\n";
?>

Just a heads-up: readline() requires the readline extension to be enabled in your php.ini. If you're on a locked-down server where you can't change the config, fall back to trim(fgets(STDIN))`β€”it does the exact same thing, just with a bit more typing.

How do I keep asking until the user gives me a valid answer?

Users are unpredictable. They'll hit Enter by accident or type "maybe" when you specifically asked for "yes" or "no". I never trust the first response. The best pattern here is a while(true) loop that only breaks once the input meets your criteria.

Let's say we're building a script to configure a database port. We can't just take any string; it has to be a number. I usually handle it like this:

<?php
while (true) {
    $port = readline("Enter the database port [default 3306]: ");
    
    // Handle the default value if they just hit enter
    if (empty($port)) {
        $port = 3306;
        break;
    }

    if (is_numeric($port) && $port > 0 && $port < 65536) {
        break; // Input is valid, exit the loop
    }

    echo "Invalid port. Please enter a number between 1 and 65535.\n";
}

echo "Port set to: $port\n";
?>

Can I hide the input for sensitive data like API keys?

This is where PHP gets a little gritty. PHP doesn't have a built-in readPassword() function. If you use readline() for an API key, the key will stay visible on the screen in plain text, which is a security nightmare if someone is looking over the user's shoulder.

To get around this on Unix-based systems (Linux/macOS), you have to talk to the terminal directly to turn off "echoing." I use shell_exec to toggle the stty setting. It's a bit of a hack, but it's the industry standard for simple PHP CLI tools.

<?php
echo "Enter your Secret API Key: ";

// Turn off echoing of characters
shell_exec('stty -echo');

$apiKey = trim(fgets(STDIN));

// Turn echoing back on immediately!
shell_exec('stty echo');

echo "\nKey captured successfully.\n";
// Now you can use $apiKey safely
?>

Be very careful here: if your script crashes between stty -echo and stty echo, the user's terminal will remain "silent," and they'll think their keyboard is broken. Always make sure your echoing is restored.




πŸ“‹ Practical Task

Build a CLI Project Initialization Tool

Create a PHP script that acts as a "Project Starter." The script must interactively collect the following information from the user to create a simulated config file:

  • Project Name: Must not be empty. If the user hits enter, prompt them again until a name is provided.
  • Project Type: Must be either 'web' or 'api'. If they enter anything else, tell them the options and ask again.
  • Database Password: Must be captured using the stty -echo method so the password doesn't appear on the screen.

Once all three are collected, the script should print a summary of the "Config File" it created (e.g., Project: MyCoolApp | Type: api | Password: [HIDDEN]).

Rating
0 0

There are no comments for now.

to be the first to leave a comment.