Задача
Необходимо проанализировать параметры программы, которые могут быть представлены как в сокращенном, так и в расширенном синтаксисе, или могут быть сгруппированы.
Решение
Это делается с помощью PEAR-класса Console_Getopt. Его метод getopt() может анализировать короткие параметры, такие как -a или -b, и длинные – --alice или --bob:
$o = new Console_Getopt;
// принимает -a, -b и -c
$opts = $o->getopt($_SERVER['argv'],'abc');
// принимает --alice и --bob
$opts = $o->getopt($_SERVER['argv'],'',array('alice','bob'));
Обсуждение
Для того чтобы проанализировать короткие параметры, передайте функции Console_Getopt::getopt() массив аргументов командной строки и строку с указанием допустимых параметров. Этот пример допускает -a, -b или -c в качестве аргументов, поодиночке или в группах:
$o = new Console_Getopt;
$opts = $o->getopt($_SERVER['argv'],'abc');
Для предыдущей строки параметров abc допустимыми для передачи множествами параметров являются:
% program.php -a -b -c
% program.php -abc
% program.php -ab -c
Метод getopt() возвращает массив. Первый элемент массива представляет собой список всех проанализированных параметров, указанныхв командной строке, вместе со своими значениями. Второй элемент – это любой указанный параметр командной строки, отсутствовавший в определении аргументов, переданных методу getopt(). Например, если предыдущая программа запускается как:
% program.php -a -b sneeze
то $opts имеет вид:
Array
(
[0] => Array
(
[0] => Array
(
[0] => a
=>
)
=> Array
(
[0] => b
=>
)
)
=> Array
(
[0] => program.php
=> sneeze
)
)
Поставьте двоеточие после параметра в строке определения, указывая тем самым, что параметр должен иметь значение. Два двоеточия означают, что значение может отсутствовать. Поэтому строка ab:c:: означает, что a не может иметь значения, b должна иметь значение, а c может принимать значение, если оно указано. При такой строке определения программа, запущенная как:
% program.php -a -b sneeze
выдает $opts:
Array
(
[0] => Array
(
[0] => Array
(
[0] => a
=>
)
=> Array
([0] => b
=> sneeze
)
)
=> Array
(
[0] => program.php
)
)
Поскольку sneeze теперь считается значением параметра b, ее больше нет в массиве непроанализированных параметров. Обратите внимание, что массив непроанализированных параметров всегда содержит имя программы.
Для того чтобы проанализировать длинные аргументы, надо передать методу getopt() массив, описывающий требуемые аргументы. Поместите каждый аргумент в элемент массива (не включайте начальные символы --) и завершите его символом = для обозначения обязательного аргумента или символом == для обозначения необязательного аргумента. Этот массив представляет третий аргумент метода getopt(). Второй аргумент (строка для коротких аргументов) может быть оставлен пустым или нет, в зависимости от необходимости анализа коротких аргументов. Следующий пример позволяет использовать debug в качестве аргумента без значения, name с обязательным значением, а size с необязательным значением:
require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($_SERVER['argv'],'',array('debug','name=','size=='));
Вот допустимые способы запуска этой программы:
% program.php --debug
% program.php --name=Susannah
% program.php --name Susannah
% program.php --debug --size
% program.php --size=56 --name=Susannah
% program.php --name --debug
Последний вариант вызова допустим (хотя и не производителен), поскольку он рассматривает --debug как значение аргумента name и не считает, что аргумент debug должен быть установлен. Значения могут быть отделены от своих аргументов символом = или пробелом.
Для длинных аргументов метод getopt() включает начальные символы -- в массив проанализированных аргументов; например, при таком способе запуска:
% program.php --debug --name=Susannah
$opts устанавливается в:Array
(
[0] => Array
(
[0] => Array
(
[0] => --debug
=>
)
=> Array
(
[0] => --name
=> Susannah
)
)
=> Array
(
[0] => program.php
)
)
Мы использовали в качестве массива аргументов командной строки $_SERVER['argv'], который хорош по умолчанию. Класс Console_Getopt предоставляет и другой метод, readPHPArgv(), для поиска аргументов командной строки в $argv и $HTTP_SERVER_VARS['argv']. Его результаты надо передать методу getopt():
require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($o->readPHPArgv(),'',array('debug','name=','size=='));
И метод getopt() и метод readPHPArgv(), столкнувшись с ошибкой, возвращают объект Getopt_Error, например, когда нет значения для аргумента, которому оно необходимо. Класс Getopt_Error расширяет базовый класс PEAR_Error, поэтому для обработки ошибок можно применять хорошо знакомые методы:
require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($o->readPHPArgv(),'',array('debug','name=','size=='));
if (PEAR::isError($opts)) {
print $opts->getMessage();
} else {
// обрабатываем опции
}