Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

PHP5_nachinayushim

.pdf
Скачиваний:
29
Добавлен:
20.03.2015
Размер:
26.79 Mб
Скачать

ODBC 803

Рис. Г.10.

Можно выбрать адреса, добавленные в базу, и изменить или удалить их (рис. Г.11).

Рис. Г.11.

Ä

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. Оболочки обычно имеют несколько простых встроенных кон+

CLI*интерфейс PHP 805

струкций наподобие управляющих и условных операторов. Кроме того, они часто за+ имствуют у системы средства для реализации большинства остальных возможностей. Однако для решения сложных и трудоемких задач необходимо использовать более гибкие инструменты; в качестве таких инструментов оказываются полезными различ+ ные интерпретаторы. Интерпретаторы по сравнению с оболочками обычно пред+ ставляют более гибкую типизацию, более широкий диапазон стандартных конструк+ ций для программирования и более развитые функции обеспечения безопасности.

Отвлечемся на короткое время от оболочек и вспомним, как возникла Web+среда. Первые World Wide Web+страницы представляли собой, главным образом, статиче+ ские документы, которые http+демон доставлял пользователям в ответ на соответст+ вующие запросы. Любые изменения приходилось вносить непосредственно в доку+ менты и копировать эти документы туда, где пользователи ожидали получить к ним доступ. Web+страницы были неспособны проделывать обычные в наши дни трюки, например, они не могли запоминать и идентифицировать пользователей и выдавать различное содержимое на основании данных о пользовательских предпочтениях. Чи+ тателям, для которых эта книга является первым экскурсом в серверные языки сцена+ риев, может показаться, что PHP представляет собой решение этой проблемы. Одна+ ко на самом деле PHP и его функциональные аналоги, такие как Active Server Pages и Java Server Pages, работает на поверхности другой более ранней технологии, кото+ рая называется Common Gateway Interface (интерфейс общего шлюза), или CGI.

С помощью CGI Web+сервер открывает интерфейс для внешних программ, обычно написанных на одном из упомянутых выше интерпретируемых языков. Сервер пере+ дает такой программе инструкции для генерирования страницы, которая затем воз+ вращается Web+серверу, а впоследствии в браузер пользователя. Здесь обе нити исто+ рии пересекаются.

Еще до возникновения идеи серверных модулей технология CGI в течение многих лет неплохо служила своей цели. PHP ++++++ один из таких модулей; Perl тоже может ра+ ботать как модуль Web+сервера Apache. Подобное развитие технологий было продик+ товано некоторыми проблемами CGI, например, трудностями, связанными с недоста+ точной производительностью и особенно с безопасностью.

CGI и сейчас довольно широко используется, даже во многих PHP+инсталляциях, несмотря на то, что это не самое оптимальное решение. Пользователи до сих пор иногда применяют инсталляции в CGI+стиле ++++++ они просто не передают конфигура+ ционному сценарию специфических для Web+сервера флагов. Идея использования PHP для системного администрирования не нова. Некоторые системные администра+ торы в своей работе часто используют PHP+интерпретатор.

Но это применение даже в очень простых сценариях теряется из виду на фоне Web+ориентированного CGI+модуля PHP. В PHP версии 4.2.x в качестве эксперимен+ тальной функции был представлен CLI+интерфейс PHP; к версии 4.3.x, а затем и в се+ рии 5.0 установка CLI стала использоваться по умолчанию. Если вы абсолютно увере+ ны, что CLI не должен присутствовать в используемой системе, можете передать конфигурационному сценарию флаг --disable-cli.

Некоторые важные моменты

Для опытных пользователей shell и системных администраторов, которые рабо+ тают с Perl или Python, будет полезно ознакомиться с некоторыми ключевыми отли+ чиями в работе PHP CLI.

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.

Зная, как читать аргументы из командной строки, и понимая, как это происходит, можно создать более сложное и полезное приложение.

808 Приложение Д

Запуск shell-команды

Команда users в Linux или в любой другой Unix+системе предоставляет систем+ ному администратору удобный способ узнать, кто в текущий момент зарегистрирован

всистеме. Однако недостаток этой команды заключается в том, что она возвращает неупорядоченный список разделенных пробелами имен, который трудно читать

вбесцветной консоли. Для быстрого поиска определенного пользователя необходимо более гибкое приложение. Приведенный ниже короткий сценарий принимает в каче+ стве аргумента имя пользователя, ищет его в списке активных в текущий момент пользователей, а затем возвращает сообщение о состоянии пользователя в системе. Создайте файл check_user и поместите в него следующий код:

#!/usr/local/bin/php

<?php

$command = "users";

$logged_in = explode(' ', shell_exec($command)); for ($i = 0; $i < count($logged_in); $i++) {

if ($argv[1] == trim($logged_in[$i])) { $found_user = 1;

}

}

if($found_user) {

print "Пользователь $argv[1] в настоящий момент находится в системе\n";

} else {

print "Пользователь $argv[1] в настоящий момент в системе НЕ зарегистрирован\n";

}

?>

Запустите сценарий с помощью следующей команды:

> ./check_user someuser

в результате должен появиться подобный вывод:

Пользователь someuser в настоящий момент находится в системе

В этом примере следует отметить использование PHP+функции trim(). Общеизве+ стно, что утилиты Unix для форматирования своего вывода используют пробелы, особен+ но в консоли. Хотя разделяющие пробелы были удалены путем передачи пробела функции explode() в качестве разделителя, команда users в конце своего вывода вставляет жест+ кий перевод строки, который нужно убрать, если он встречается в последнем имени в списке. Функция trim() удаляет только пробельные символы (пробелы, символы та+ буляции и перевода строки), оставляя полезную часть вывода нетронутой.

Windows+пользователи также могут использовать DOS+команды. Создайте новый файл directory со следующим кодом:

<?php

$dir = shell_exec("dir"); echo "$dir";

?>

Запустите сценарий из командной строки с помощью следующей команды:

> php directory

На экран будет выведено содержимое текущего каталога.

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

810 Приложение Д

Это более или менее то, что и ожидалось от сценария. Можно воспользоваться утилитой Cron для автоматического запуска этого сценария через каждые полчаса; но прежде следует изучить работу самой утилиты Cron. Программа Cron состоит из двух основных частей. Реальную работу выполняет программа crond, которую чаще назы+ вают Cron+демон. В Unix+подобных системах демон представляет собой программу, которая работает постоянно в фоновом режиме, как правило, ожидая некоторых ин+ струкций. Web+сервер, FTP+сервер и почтовый сервер ++++++ все это примеры демонов.

Cron+демон обычно запускается после всех остальных серверов в системе. Инст+ рукции он получает от второй части утилиты, файла crontab, который считывается во время запуска программы. crontab представляет собой простой текстовый файл, в котором содержится перечень заданий и указывается время, когда их нужно выпол+ нить. Файл crontab есть у каждого пользователя в системе, хотя он может быть пус+ тым. Чтобы просмотреть все задания в crontab, можно ввести команду crontab –l, которая выводит на консоль список Cron+заданий. Этот список может выглядеть так:

# Run hourly cron jobs at 47 minutes after the hour:

47 * * * * /usr/bin/run-parts /etc/cron.hourly 1> /dev/null

#

# Run daily cron jobs at 4:40 every day:

40 4 * * * /usr/bin/run-parts /etc/cron.daily 1> /dev/null

#

#Run weekly cron jobs at 4:30 on the first day of the week: 30 4 * * 0 /usr/bin/run-parts /etc/cron.weekly 1> /dev/null

#Run monthly cron jobs at 4:20 on the first day of the month: 20 4 1 * * /usr/bin/run-parts /etc/cron.monthly 1> /dev/null

Первые пять полей crontab+записи описывают время запуска команды, которая задается в шестом поле, продолжающемся до конца строки. Символ # предшествует комментариям. Порядок полей времени следующий: минута, час, день, месяц и день недели. Следующий пример дает некоторое представление о том, как эти поля ис+ пользуются, хотя, возможно, сразу не понятно, что назначение команды заключается в запуске сценария каждые полчаса. Фактически строка для описания этого Cron+ задания выглядит так:

*/30 * * * * user_report 1> /dev/null

По умолчанию демон Cron отправляет по e*mail отчет после успешного выполнения задания, что может оказаться излишним. Команда 1>/dev/null служит для того, чтобы просто перенаправлять стандартный вывод Cron в Unix*корзину.

Администратору может понадобиться в течение дня отслеживать все изменения файлов в определенном каталоге. Например, Windows+пользователи с помощью сле+ дующего кода могут отправлять на определенный e+mail+адрес листинг текущего каталога:

<?php

$dir = shell_exec("dir");

$subject = "Ежедневный отчет об изменениях файлов.";

$body = "В текущем каталоге находятся следующие файлы: \n\n"; $body .= $dir;

mail("root@localhost", $subject, $body, "From:root@localhost\r\n"); ?>

Для автоматического выполнения этого сценария в Windows зайдите в панель управления и выберите пункт Назначенные задания Добавить задание. Мастер

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 могли только мечтать.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]