Вот как обычно бывает: Нам нужно написать малюсенький консольный скрипт бекапа, который, может запускаться из крона, и при этом скрипт должен принимать параметры для соединения с базой данных.
Функции argv и argc
Самое простейшее что мы начнём писать будет выглядеть примерно так:
cli-argv-argc.php
// Ожидаем что скрипт будет вызываться с такими параметрами:
// php backup.php dbuser dbpassword database host
if ($argc != 5) {
die(PHP_EOL . 'Use: php backup.php dbuser dbpassword database host' . PHP_EOL);
}
$dbuser = $argv[1];
$dbpassword = $argv[2];
$database = $argv[3];
$host = $argv[4];
$mysql = mysql_connect($host, $dbuser, $dbpassword);
mysql_select_db($database, $mysql);
// ...
Тут мы использовали системную переменную argс для получения количества всех параметров. Запомните, что нулевой параметр (имя скрипта) тут тоже учитывается.
И системную переменную argv с массивом всех параметров.
Для простейшего скрипта этого хватит, но что если мы захотим поддерживать и отдать этот скрипт другим разработчикам?
Скорее всего будет куча ругани в нашу сторону, потому что очень легко можно ошибиться и перепутать местами пароль и базу данных и заметить ошибку будет крайне сложно. Посмотрите:
php backup.php dbuser database dbpassword host
Разбираем параметры с функцией getopt
Вот тут нам на помощь приходит крайне удобная функция разбора параметров: getopt
Основная мощь getopt в том, что она позволяет нам использовать флаги, обязательные и необязательные параметры в произвольном порядке.
Давайте напишем простой, но очень выразительный пример использования getopt, а потом, посмотрите как люди раньше мучались с регулярками, что бы разобрать командную строку :)
backup.php
// Тут показаны две формы записи аргументов: короткая и полная
// При этом, если после параметра стоит два двоеточия, значит параметр необязательный,
// а если одно двоеточие - значит обязательный.
// все параметры которые не указаны в конфигурации будут проигнорированы
$params = array(
'' => 'help',
'h::' => 'host::',
'u:' => 'user:',
'p::' => 'password::',
'd:' => 'database:',
);
// Default values
$host = 'localhost';
$user = 'root';
$password = null;
$database = '';
$errors = array();
$options = getopt( implode('', array_keys($params)), $params );
if (isset($options['host']) || isset($options['h']))
{
$host = isset( $options['host'] ) ? $options['host'] : $options['h'];
}
if (isset($options['user']) || isset($options['u']))
{
$port = isset( $options['user'] ) ? $options['user'] : $options['u'];
}
else
{
$errors[] = 'user required';
}
if (isset($options['password']) || isset($options['p']))
{
$socket = isset( $options['password'] ) ? $options['password'] : $options['p'];
}
if (isset($options['database']) || isset($options['d']))
{
$database = isset( $options['database'] ) ? $options['database'] : $options['d'];
}
else
{
$errors[] = 'database required';
}
if ( isset($options['help']) || count($errors) )
{
$help = "
usage: php backup.php [--help] [-h|--host=127.0.0.1] [-u|--user=root] [-p|--password=secret] [-d|--database]
Options:
--help Show this message
-h --host Server hostname (default: localhost)
-u --user User
-p --password Password (default: no password)
-d --database Database
Example:
php backup.php --user=root --password=secret --database=blog
";
if ( $errors )
{
$help .= 'Errors:' . PHP_EOL . implode("\n", $errors) . PHP_EOL;
}
die($help);
}
$mysql = mysql_connect($host, $user, $password);
mysql_select_db($database, $mysql);
// ....
Теперь запустим наш скрипт с параметром –help и порадуемся что хорошо поддерживаемую и понятную программу так легко написать
php backup.php --help
Если вкратце, то getopt принимает все аргументы из командной строки и складывает валидные параметры в массив $options. А из уже получившегося массива мы можем получить все аргументы и в зависимости от них выдать результат.
Давайте ещё добавим последний штрих, который должен быть во всех наших скриптах:
- Можно убрать расширение php
- В начало каждого скрипта добавим опцию для интерпритатора #!/usr/bin/env php
- Сделаем наши скрипты исполняемыми chmod +x backup.php
После этого можно пользоваться получившимся скриптом как настоящей юникс-программой:
./backup --help
или
./backup --user=ukko --password=password --database=db1