PHP5_nachinayushim
.pdfÄ
CLI-интерфейс PHP
Одним из самых приятных усовершенствований, внесенных в PHP за последние годы, является введение CLI+интерфейса (Command Line Interpreter ++++++ интерпрета+ тор командной строки). CLI позволяет использовать PHP+сценарии в не+Web+среде, например, для решения задач системного администрирования или даже в качестве встраиваемого компонента для другого приложения. Это дает PHP возможность ре+ шать широкий круг задач, для которых обычно использовались такие средства, как Perl, Bash или DOS. Приложение Д знакомит читателя с CLI+интерфейсом и демонст+ рирует возможные варианты его использования.
Поскольку CLI+интерфейс в PHP представляет собой новый виток развития языка и заимствует некоторые более ранние технологии, стоит рассмотреть некоторые ис+ торические вехи этого развития.
Начало
В течение очень долгого времени пользователям Unix и DOS приходилось исполь+ зовать понятие сценариев оболочки ++++++ как правило, очень простых программ для вы+ полнения рутинных задач системного администрирования, написанных на одном из нескольких доступных языков сценариев. Трудно представить себе работу на Linux+ машине без некоторых shell+сценариев; многие стандартные задачи администрирова+ ния, например, ротация системных журналов и резервное копирование, часто реша+ ются с помощью этих на первый взгляд простых программ. Вместе с тем эти сценарии сами по себе без интерпретатора, который выполняет содержащиеся в них инструк+ ции, не представляют особого интереса.
Интерпретатор, как правило, представлен в одной из двух форм: интерактивная оболочка или интерпретируемый язык. Примерами первой формы является печально известный command.com в MS+DOS и множество оболочек, доступных большинству Linux/Unix+пользователей ++++++ Bash, Csh, Zsh и масса других. Примеры второй фор+ мы ++++++ такие широко известные языки программирования, как Perl, Python, Tcl, а с не+ давнего времени PHP. Оболочки обычно имеют несколько простых встроенных кон+
806Приложение Д
PHP CLI не изменяет рабочий каталог на каталог, в котором находится испол+ няемый сценарий. Чтобы добиться этого, необходимо явно указать полные ра+ бочие пути либо использовать константы или переменные.
Вызов PHP CLI без параметров не приводит к запуску интерактивной оболоч+ ки, как это происходит в Python или Tcl.
В отличие от Perl, код внутри CLI+сценария в PHP все равно должен находиться между тегами <?php и ?>, даже если интерпретатор определен с помощью обычного синтаксиса #!/usr/local/bin/php. Строки, не заключенные в теги сценария, возвращаются в стандартный вывод (stdout) неизмененными.
PHP CLI принимает несколько ключей командной строки, которые описаны в приведенной ниже таблице.
Ключ |
Описание |
|
|
-s |
Включает цветную подсветку исходного кода сценария. Пример использования: |
|
php -s myscript. Эта команда возвращает подсвеченную цветную версию |
|
сценария, используя HTML-тег font. В консоли это не особенно полезно, но если |
|
передать этот вывод в браузер, то он красиво отобразит код |
-w |
Отображает исходный код сценария без комментариев и пробельных символов |
-f |
Используется для указания файла, передаваемого интерпретатору, например, php |
|
-f myscript. Этот флаг не обязательный и команда php myscript приводит к |
|
идентичному результату. Данный флаг может оказаться полезным для повышения |
|
четкости в crontab или сценариях, вызывающих другие сценарии |
-v |
Распечатывает номер версии и завершает работу |
-c |
Указывает.ini-файл, отличный от используемого по умолчанию |
-a |
Запускает интерпретатор в интерактивном режиме |
-d |
Определяет значение переменной в php.ini, например, php -d safe_mode=off. |
|
Это значение сохраняется только в текущем экземпляре интерпретатора |
-e |
Генерирует расширенную информацию для отладчика и профайлера кода |
-z |
Загружает указанное Zend-расширение. Это расширение будет работать только |
|
в текущем экземпляре интерпретатора |
-l |
Выполняется только проверка синтаксиса. Это может оказаться очень полезным |
|
для не деструктивного тестирования сценариев, данный ключ иногда используется |
|
в Web-сценариях |
-m |
Возвращает перечень модулей, скомпилированных в PHP. При этом имена |
|
динамически загружаемых модулей не возвращаются |
-i |
Возвращает общую конфигурационную информацию PHP. Использование этого |
|
флага эквивалентно использованию функции phpinfo() без HTML- |
|
форматирования. Можно передать вывод программе постраничного просмотра, |
|
например, more или less |
-r |
Выполняет код, введенный в командную строку без тегов сценария. Код |
|
необходимо заключить в одинарные кавычки |
-h |
Возвращает список ключей командной строки и параметров форматирования |
CLI*интерфейс PHP 807
Обработка параметров командной строки
PHP+сценарии в Web могут легко получить и обработать аргументы из различных источников, таких как cookie+файлы, Web+формы и значения полей баз данных. Зна+ чения полей баз данных также легко получить и в сценариях, использующих CLI, од+ нако в этом случае отсутствует браузер, из которого можно было бы получить осталь+ ные аргументы. Тем не менее, во время выполнения сценария можно передавать ему значения или аргументы. В PHP CLI для передачи данных, введенных в командной строке, используются переменные $argc и $argv. Эти переменные известны про+ граммистам на C/C++. В PHP $argc ++++++ скалярная переменная, содержащая количест+ во аргументов, а $argv ++++++ глобальный массив (с отсчетом элементов с нуля), содер+ жащий сами аргументы в том порядке, в котором они были считаны.
Аргументыв PHP CLI
Следующий сценарий принимает несколько аргументов и выводит их на экран. Создайте файл с именем myscript и введите в него код, как показано ниже (Windows+ пользователи могут пропустить первую строку):
#!/usr/local/bin/php
<?php
print "Получено $argc аргументов\n";
for ($i = 0; $i <= $argc -1 ; $i++) {
print "Это аргумент $i и его значение равно $argv[$i]\n";
}
?>
Сохраните файл, а затем запустите его из командной строки. Явно указывать интер+ претатор нет необходимости, он уже задан в первой строке сценария. Этот метод исполь+ зуется во всех остальных примерах данного приложения. Передайте сценарию несколько аргументов и обратите внимание на вывод. Для этого в Linux введите такую команду:
> ./myscript Dan David Alan Steven Clark Wankyu
в Windows команда должна выглядеть так:
> php myscript Dan David Alan Steven Clark Wankyu
Результат будет выглядеть примерно так:
Получено 7 аргументов
Это аргумент 0 и его значение равно ./myscript Это аргумент 1 и его значение равно Dan
Это аргумент 2 и его значение равно David Это аргумент 3 и его значение равно Alan Это аргумент 4 и его значение равно Steven Это аргумент 5 и его значение равно Clark Это аргумент 6 и его значение равно Wankyu
Первый аргумент ++++++ имя самого сценария, несмотря на то, что оно не было пере+ дано в командной строке в списке аргументов. Это удобно, когда нужно, чтобы сцена+ рий обращался к самому себе, поскольку в CLI переменная $_SERVER[SCRIPT_NAME] недоступна. В результате первый индекс из всех реальных аргументов равен 1, хотя отсчет элементов начинается с 0.
Зная, как читать аргументы из командной строки, и понимая, как это происходит, можно создать более сложное и полезное приложение.
CLI*интерфейс PHP 809
Автоматизация PHP CLI
Выше было показано, как можно при необходимости запускать CLI+сценарии из командной строки, однако запуск таких сценариев можно автоматизировать. Напри+ мер, можно отправлять e+mail+напоминания пользователям системы (такая функцио+ нальность является частью проекта PHP WebCalendar). Можно также в течение дня отслеживать пользователей в системе. В этом разделе описанный ранее сценарий бу+ дет расширен для отслеживания пользователей в гипотетической системе. Каждые полчаса сценарий будет просматривать список пользователей и отправлять систем+ ному администратору отчет по e+mail. Стандартным средством автоматизации задач в Windows является встроенный планировщик, весьма понятный и простой в исполь+ зовании инструмент. В Linux таким средством является Cron, более сложная про+ грамма. В этом разделе рассматривается использование именно этой утилиты.
Windows+пример будет представлен далее. Пока начнем с первой версии сценария check_user. Чтобы включить в сценарий описанную выше функциональность, необ+ ходимо внести несколько изменений:
#!/usr/local/bin/php
<?php
$first_command = "users"; $second_command = "date"; $third_command = "hostname";
$logged_in = explode(' ', shell_exec($first_command)); for ($i = 0; $i <= count($logged_in); $i++) {
$users .= trim($logged_in[$i]) . "\n";
}
$dt = shell_exec($second_command);
$subject = "Получасовой отчет о зарегистрированных пользователях.";
$body .= $subject . "\n\n";
$body .= trim($dt) . "; В системе " . shell_exec($third_command) . "зарегистрированы следующие пользователи:\r\n";
$body .= $users;
mail("root@localhost", $subject, $body, "From:root@localhost\r\n"); ?>
В этом сценарии, по сути, нет ничего нового. Все задействованные здесь функции уже рассматривались ранее в этой книге. Системные команды специфичны для Unix/Linux, но их имена ясно свидетельствуют об их назначении. Сначала данные, возвращаемые командой users, для более удобного чтения форматируются в виде списка в один столбец с одним именем в каждой строке. Команда date используется фактически для датирования сообщения. Затем вызывается команда hostname, кото+ рая может оказаться полезной, если запускать этот сценарий на разных машинах.
Сначала можно (и нужно) протестировать этот сценарий из командной строки. Сценарий должен отправлять e+mail+сообщение примерно следующего содержания:
Получасовой отчет о зарегистрированных пользователях.
Mon Jan 26 12:42:16 EST 2004; В системе ds3 зарегистрированы следующие пользователи:
akent cmorgan dmercer dsquier snowicki wchoi
CLI*интерфейс PHP 811
поможет сделать необходимые настройки. В поле Выполнить необходимо ввести сле+ дующую команду:
C:\PHP5\php.exe directory
Можно также нажать кнопку Обзор, найти исполняемый файл PHP на второй странице мастера и добавить имя сценария, который необходимо запустить.
Взависимости от настроек по расписанию будут приходить письма с отчетами
осодержимом каталога.
Интерактивность средствами PHP CLI
Интерактивность командной строки PHP развита не хуже, чем интерактивность Web+ сценариев. Можно легко создавать CLI+сценарии, которые для выполнения больших задач с использованием потоков принимают последовательные биты пользовательского вво+ да. PHP предоставляет доступ к трем потокам, которые имитируют соответствующую функциональность Unix. Эти потоки описываются в приведенной ниже таблице.
Поток |
Чему соответствует |
Доступ в PHP |
|
|
|
Стандартный ввод |
Клавиатуре |
php://stdin |
Стандартный вывод |
Консоли (экрану монитора) |
php://stdout |
Стандартный поток ошибок |
Консоли или системному журналу |
php://stderr |
|
|
|
Рассмотрим простой сценарий, который собирает пользовательскую информацию
исоздает файл подписи для использования в e+mail+клиенте. Создайте файл sigfile
ивведите в него следующий код:
#!/usr/local/bin/php
<?php
$stdin = fopen('php://stdin', 'r');
echo "PHP-генератор файла подписей.\n"; echo "Введите свое полное имя: ";
$name = trim(fgets($stdin,100));
echo "Введите свой адрес (улицу): ";
$address = trim(fgets($stdin,100)); echo "Введите название города: ";
$city = trim(fgets($stdin,100));
echo "Введите название штата: ";
$state = trim(fgets($stdin,100));
echo "Введите свой почтовый индекс: ";
$zip = trim(fgets($stdin,100));
echo "Введите номер телефона: ";
$phone = trim(fgets($stdin,100)); echo "Введите e-mail-адрес: ";
$email = trim(fgets($stdin,100));
echo "Как Вы хотите обозначить эту подпись: "; $sig = trim(fgets($stdin,100));
fclose($stdin);
$data = "$name\n$address\n$city, $state $zip\n$phone\n$email"; shell_exec("touch $sig");
if (!$sigfile = fopen($sig, 'w')) {
print "Невозможно открыть файл для записи\n"; } else {
if (!fwrite($sigfile,$data)) {
print "\n\nНе удалось записать данные\n";
812 Приложение Д
} else {
print "\n\nПодпись готова\n";
}
fclose($sigfile);
}
?>
Сначала открывается поток стандартного ввода, который остается открытым вплоть до получения последнего ответа пользователя. Затем из каждого последующе+ го пользовательского ввода извлекается первых 100 символов. Эти символы переда+ ются функции trim(), так как, к сожалению, нажатие пользователем клавиши <Enter> передает сценарию жесткий перевод строки. После получения от пользова+ теля всех данных поток ввода закрывается и открывается файл с именем, которое вы+ брал пользователь. Составленная из ответов пользователя подпись записывается в этот файл, после чего он закрывается.
Windows+пользователи могут применить тот же сценарий, заменив строку
shell_exec("touch $sig");
на
'copy con $sig ^Z \n';
Сохраните файл. Сценарий генерирует примерно следующий вывод:
> php sigfile
PHP-генератор файла подписей. Введите свое полное имя: David Mercer
Введите свой адрес (улицу): 148 Mystreet Введите название города: Cape Town Введите название штата: WP
Введите свой почтовый индекс: 8001 Введите номер телефона: 021 555-1234
Введите e-mail-адрес: davidm@doggiesrugby.co.za
Как Вы хотите обозначить эту подпись: MySig
Подпись готова
Заключение
Очевидно, что PHP CLI обладает той же гибкостью и эффективностью, что и PHP в Web+среде. Можно с уверенностью утверждать, что потенциальные варианты приме+ нения ограничены только мощностью самого PHP, что, вообще говоря, нельзя назвать серьезным ограничением. Интерактивность, обеспечиваемая потоками, является осо+ бенно полезной. Системные администраторы могут использовать PHP CLI для решения своих повседневных задач, например, для резервного копирования, рассылки систем+ ных уведомлений и любых других административных функций. Выполняемые по распи+ санию CLI+сценарии совместно с Web+приложениями могут реализовывать такие воз+ можности, о которых раньше разработчики программ на PHP могли только мечтать.