getopts - Argumente richtig verarbeiten

Wer PHP-Scripts im CLI mit Argumenten aufruft möchte diese sauber verarbeiten.
PHP hat dafür getopt() eingebaut.

Grundlegende Verwendung

$options = getopt('u:p:vh', ['user:', 'port:', 'verbose', 'help']);

Kurze Optionen: u: erwartet ein Argument, v ist ein Flag.
Lange Optionen: user: erwartet ein Argument, verbose ist ein Flag.

Vollständiges Beispiel

<?php
if (php_sapi_name() !== 'cli') { exit; }

$opts = getopt('u:p:vh', ['user:', 'port:', 'verbose', 'help']);

if (isset($opts['h']) || isset($opts['help'])) {
    echo "Verwendung: php script.php -u benutzer -p 3306 [-v]\n";
    exit(0);
}

$user    = $opts['u'] ?? $opts['user'] ?? 'root';
$port    = (int)($opts['p'] ?? $opts['port'] ?? 3306);
$verbose = isset($opts['v']) || isset($opts['verbose']);

if ($verbose) {
    echo "Benutzer: $user, Port: $port\n";
}

Aufruf

php script.php -u deploy -p 5432 --verbose
php script.php --user=deploy --port=5432 -v
php script.php -h

Pflicht-Argumente prüfen

getopt gibt keine Fehler wenn Pflichtargumente fehlen — das muss man selbst prüfen.

if (!isset($opts['u']) && !isset($opts['user'])) {
    fwrite(STDERR, "Fehler: -u/--user ist erforderlich.\n");
    exit(1);
}

fwrite(STDERR, ...) schreibt in stderr statt stdout — gut für Fehlermeldungen die nicht in Pipes landen sollen.

Restliche Argumente nach den Optionen

// getopt verarbeitet $argv nicht vollständig
// Verbleibende Argumente ab dem ersten Nicht-Option-Argument
$nonOpts = array_slice($argv, getopt('u:v', [], $restIndex) !== false ? $restIndex : 1);

Für komplexere Argument-Parser ist es an diesem Punkt einfacher eine kleine Klasse zu schreiben.