Php cli in linux

Linux.yaroslavl.ru

С помощью этой опции можно либо специфицировать директорию для поиска php.ini , либо специальную директорию INI -файла (который не обязательно называется php.ini ), например:

Запускает PHP интерактивно.

Эта опция позволяет устанавливать специальное значение для каждой директивы конфигурации, которые допускаются в php.ini . Синтаксис таков:

Примеры:

Генерирует расширенную информацию для debugger/profiler.

Загружает Zend-расширение. Если задано только имя файла, PHP пытается загрузить данное расширение из текущего пути по умолчанию к библиотеке в вашей системе (обычно специфицируется как /etc/ld.so.conf в Linux-системах). Передача filename с абсолютным путём не будет использовать системный путь поиска библиотеки. Относительное filename с информацией директории скажет PHP — попытаться загрузить расширение относительно текущей директории.

Эта опция предоставляет удобный способ выполнения проверки синтаксиса данного PHP -кода. В случае успеха — текст No syntax errors detected in записывается в стандартный вывод, а return-код оболочки будет 0 . При неудаче — текст Errors parsing вместе с внутренним сообщением разборщика об ошибке записывается в стандартный вывод, а return-код оболочки будет 255 .

Эта опция не будет находить фатальные ошибки (вроде не определённых функций). Используйте -f , если хотите проверить также и наличие фатальных ошибок.

Примечание: эта опция не работает вместе с -r .

Используя эту опцию, PHP печатает на выводе встроенные (и загруженные) модули PHP и Zend:

Эта опция позволяет выполнять PHP прямо в командной строке. Начальный и конечный тэги PHP ( и ?> ) не нужны и вызывают ошибки разборщика.

Примечание: нужно проявлять внимание при использовании этой формы PHP , чтобы не было противоречий с заменой переменных командной строки, выполняемой оболочкой.

Пример, выводящий ошибку разборщика:

Проблема здесь в том, что sh/bash выполняет замену переменной даже при использовании двойных кавычек » . Поскольку переменная $foo вряд ли определена, она ни во что не разворачивается, что в результате даёт код, передаваемый в PHP для выполнения, фактически прочитанный:

Корректным будет использовать одинарные кавычки ‘ . Переменные в строках, заключённые в одинарные кавычки, не разворачиваются при работе sh/bash.

Если вы используете оболочку/shell иначе, чем sh/bash, у вас могут появиться новые вопросы. Отправляйте bug report или mail по адресу phpdoc@lists.php.net. Можно легко столкнуться с проблемами при попытке получить переменные оболочки в коде или использовании обратных слэшей (/) для замен/escaping.
Вы предупреждены.

Учебник РНР
Назад Вперёд

Начиная с версии 4.3, РНР поддерживает новый SAPI -тип (Server Application Programming Interface) под названием CLI , что означает Command Line Interface . Как следует из названия, главной задачей этого SAPI -типа является разработка приложений оболочки/shell (или рабочего стола) с помощью РНР. Имеются весьма небольшие отличия CLI SAPI от других SAPI , которые будут далее рассмотрены в этой главе.

CLI SAPI был выпущен в первый раз с PHP 4.2.0 , но тогда это был эксперимент, и нужно было явно включать его командой —enable-cli при запуске ./configure . Начиная с PHP 4.3.0 , CLI SAPI больше не является экспериментальным и всегда встроен и устанавливается как двоичный исполняемый файл php (называется php.exe в Windows).

Существенные отличия CLI SAPI от других SAPI :


В отличие от CGI SAPI , никакие шапки/headers не записываются в вывод.

Хотя в CGI SAPI имеется способ подавления HTTP-шапок, эквивалентного переключателя для их включения в CLI SAPI нет.

Имеются определённые директивы php.ini , которые переопределены в CLI SAPI , поскольку они не имеют смысла в среде окружения оболочки:

Таблица 24-1. Переопределение php.ini -директив

Директива CLI SAPI- значение по умолчанию Комментарий
html_errors FALSE Бывает довольно сложно прочитать в оболочке сообщение об ошибке, наполненное всеми этими бессмысленными HTML -тэгами, поэтому по умолчанию значение этой директивы FALSE .
implicit_flush TRUE Желательно, чтобы любой вывод из print() , echo() и компании немедленно записывался в вывод, а не отправлялся в какой-нибудь буфер. Вы всё ещё можете пользоваться буферизацией вывода, если хотите поработать со стандартным выводом.
max_execution_time 0 (unlimited) Из-за бесконечно больших возможностей использования PHP в среде окружения оболочки, максимальное время выполнения не ограничено. В то время как приложения, написанные для web, выполняются в течение долей секунды, приложения оболочки пытаются занять для своего выполнения максимальное время.
register_argc_argv TRUE Глобальные переменные PHP $argc (количество аргументов, передаваемых приложению) и $argv (массив текущих аргументов) всегда регистрируются и заполняются соответствующими значениями при использовании CLI SAPI .

Примечание: эти директивы не могут быть инициализированы другим значением из файла конфигурации php.ini или специального файла (если специфицирован). Это является некоторым ограничением, поскольку эти значения по умолчанию применяются после разбора всех файлов конфигурации. Однако их значение может быть изменено на этапе прогона программы (что не имеет смысла для всех других директив, например, для register_argc_argv).

Легче работать в среде оболочки, когда определены следующие константы:

Таблица 24-2. Специфические CLI-константы

Константа Описание
STDIN Уже открытый поток в stdin . Она хранит открывшего её
STDOUT Уже открытый поток в stdout . Она хранит открывшего её
STDERR Уже открытый поток в stdout . Она хранит открывшего её

Имея всё это, вы не должны, например, самостоятельно открывать поток для stderr , а просто используете константу вместо ресурса потока:

Вам не нужно явно закрывать эти потоки, это делается РНР автоматически.

CLI SAPI не изменяет текущую директорию на директорию исполняемого скрипта!

Пример, показывающий отличие CGI SAPI :

Когда используется CGI -версия, на выходе будет:

Это ясно показывает, что PHP изменяет свою текущую директорию на директорию исполняемого скрипта.

Использование CLI SAPI даёт:

Это даёт большую гибкость при написании утилит командной строки на PHP .

Примечание: CGI SAPI поддерживает поведение CLI SAPI с помощью ключа -C при запуске из командной строки.

Список опций командной строки исполняемого файла PHP может быть получен в любое время путём запуска PHP с ключом -h :

CLI SAPI имеет три разных способа получения PHP -кода, который нужно выполнить:


Сказать PHP выполнить определённый файл.

Оба способа (с/без использования переключателя -f ) выполняют данный файл my_script.php . Вы можете выбрать для выполнения любой файл; названия ваших файлов скриптов PHP не обязаны заканчиваться расширением .php , а могут иметь любое имя или расширение.

Передать PHP код для выполнения непосредственно из командной строки.

Особого внимания требует замена переменных оболочки и использование кавычек.

Примечание: просмотрите пример внимательно, нет начальных и конечных тэгов! Переключателю -r они просто не нужны. Использование их в данном случае приведёт к ошибке разборщика.

Предоставить PHP -код для выполнения через стандартный ввод ( stdin ).

Это позволяет динамически создавать PHP -код и передавать его экзешнику, как показано в данном (надуманном) примере:

Вы не можете комбинировать эти три способа при выполнении кода.

Как и в любом приложении оболочки, не только сам PHP , но и ваши скрипты PHP также принимают аргументы. Количество передаваемых в скрипт аргументов в РНР не ограничивается (оболочка имеет ограничение на количество передаваемых символов).
Аргументы, передаваемые в ваш скрипт, доступны через глобальный массив $argv . Нулевой индекс всегда содержит имя скрипта (которое является символом — в случае, когда PHP -код приходит со стандартного ввода или с использованием ключа командной строки -r ).
Вторая регистрируемая глобальная переменная это $argc , которая содержит количество элементов в массиве $argv (а не количество аргументов, передаваемых в скрипт).

Если аргументы, которые вы хотите передать в скрипт, не начинаются с символа дефиса (-) , ничего специально наблюдать не надо. Передача в скрипт аргумента, начинающегося с — , создаст проблемы, поскольку PHP думает, что должен сам их обработать. Чтобы предотвратить это, используйте в качестве сепаратора аргументов списка — . После того как аргумент будет разобран PHP , каждый последующий аргумент передаётся в ваш скрипт без изменений/не разобранным.

Однако, вот другой способ использования PHP для скриптинга оболочки. Вы можете написать скрипт, первая строка которого начинается с #!/usr/bin/php , а затем идёт нормальный PHP -код, содержащийся между начальным и конечным тэгами PHP , и соответствующим образом устанавливаются атрибуты выполнения файла. Таким способом он может быть исполнен как нормальный скрипт оболочки или perl:

Приняв, что файл называется test и находится в текущей директории, мы можем выполнить:

Как вы видите, ничего особо не нужно делать при передаче параметров в скрипт, который начинается с — .

Таблица 24-3. Опции командной строки

Отображать синтаксис в цвете.

Эта опция использует внутренний механизм разбора файла, производит его расцвеченную HTML -версию и записывает её в стандартный вывод. Заметьте, что генерируется лишь блок [. ] HTML -тэгов без HTML -header.

Примечание: эта опция не работает вместе с опцией -r .

Отобразить исходный текст без комментариев и пробелов.

Примечание: эта опция не работает вместе с опцией -r .

Разбирает и выполняет данный файл. Этот переключатель является необязательным и может быть опущен. Достаточно предоставить имя файла для выполнения.

Записывает PHP, PHP SAPI и Zend-версии в стандартный вывод, например:

-c
-a
-e
-i Эта опция командной строки вызывает phpinfo() и печатает на выводе результаты. Если PHP не работает правильно, советуем выполнить php -i и посмотреть, выводятся ли сообщения об ошибке до или вместо таблиц информации. Имейте в виду, что вывод будет на HTML и, следовательно, довольно сумбурным.
-r
-h С помощью данной опции вы можете получить информацию о действующем списке опций командной строки и небольшое описание их работы.

Исполняемый файл PHP может быть использован для запуска PHP-скриптов абсолютно независимо от web-сервера.
Если вы работаете под Unix, вы должны добавлять специальную первую строчку в ваши PHP-скрипты и делать их исполняемыми, чтобы система знала, какая программа должна выполнять эти скрипты.
Под Windows вы можете ассоциировать php.exe с опцией двойного щелчка по файлам .php либо сделать batch-файл (.bat) для запуска скрипта через PHP. Строка, добавленная в начало скрипта для работы под Unix, не помешает под Windows, поэтому вы можете писать таким образом межплатформенные программы. Ниже дан пример простой РНР-программы для выполнения из командной строки.

Пример 24-1. Скрипт, предназначенный для запуска из командной строки (script.php)

Здесь мы используем специальную первую строку для указания на то, что этот файл должен быть запущен в PHP. Мы работаем с CLI-версией, поэтому не выполняется вывод HTTP-шапок/header. Имеются две переменные, которые вы можете использовать при написании РНР-приложений для командной строки: $argc и $argv . Первая — это количество аргументов плюс 1 (имя запущенного скрипта). Вторая — это массив аргументов, начиная с имени скрипта с индексом ноль ( $argv[0] ).

Мы проверяем, имеется ли менее или более одного аргумента. Также, если аргумент был —help , -help , -h или -? , мы печатаем help-сообщение, выводя имя скрипта динамически. Если мы получили какой-либо другой аргумент, мы выводим его (echo).

Если вы хотите выполнить вышеприведённый скрипт под Unix, вам необходимо сделать его executable и просто вызвать как script.php echothis или script.php -h . Под Windows вы можете создать batch-файл для выполнения этой задачи:

Пример 24-2. Пакетный/Batch-файл для запуска PHP-скрипта в командной строке (script.bat)

Приняв, что вы назвали программу script.php и что ваш php.exe находится в c:\php\php.exe , этот batch-файл запустит её с добавленными вами опциями: script.bat echothis или script.bat -h .

См. также в документации по расширению Readline о функциях, которые можно использовать для усовершенствования вашего РНР-приложения для командной строки.

Источник

Написание системных утилит на PHP CLI

Для большинства специалистов PHP не является языком, который бы всерьёз использовался для написания консольных утилит, и для этого есть много причин. PHP изначально разрабатывался как язык для создания веб-сайтов, но, начиная с PHP 4.3, в 2002-ом году появилась официальная поддержка режима CLI, поэтому он уже давно перестал быть таковым. Разработчики Badoo на протяжении нескольких лет вполне успешно используют множество интерактивных CLI-утилит на PHP.

В данной статье нам хотелось бы поделиться своим опытом работы с CLI-режимом в PHP и дать несколько рекомендаций тем, кто собирается писать скрипты на PHP, при условии, что они будут запускаться в *nix-системе (впрочем, почти всё верно и для Windows).

Рекомендации

Скорость работы
Вывод на экран

В CLI- и в веб-режиме вывод на экран значительно отличается. В веб-режиме вывод, как правило, буферизуется, у пользователя нельзя ничего спросить во время исполнения скрипта; отсутствует как класс понятие вывода в поток ошибок. В CLI-режиме, естественно, неприемлем вывод HTML, а также крайне нежелателен вывод длинных строк. В CLI echo по умолчанию вызывает flush() (подробнее можно посмотреть здесь) — это удобно тем, что можно не заботиться о вызове flush() вручную, если, к примеру, вывод перенаправляется в файл.

Также для CLI-скриптов имеет смысл выводить ошибки не в STDOUT (используя echo), а в STDERR: таким образом, даже если вывод программы будет перенаправлен куда-либо еще (например, в /dev/null или grep), пользователь не пропустит текст ошибки в случае ее появления. Это стандартное поведение для большинства «родных» *nix’овых консольных утилит, и STDERR существует именно по причине, описанной выше. В PHP для записи в STDERR можно пользоваться, к примеру, fwrite(STDERR, $message) или error_log($message).

Использование кодов возврата

Код возврата — это число, которое равно 0 в случае успешного выполнения команды и не равно 0 в противном случае. Код возврата, равный 1, часто применяется в случае некритичных ошибок (например, если указаны неправильные аргументы командной строки), а 2 — в случае критичных системных ошибок (например, при ошибке сети или диска). Значения наподобие 127 или 255 обычно используются для каких-либо специальных случаев, которые отражаются отдельно в документации.

По умолчанию при простом завершении PHP-скрипта предполагается, что все команды отработали успешно и возвращается 0. Чтобы выйти с определенным кодом возврата, нужно явно вызвать exit(NUM), где NUM — это и есть код возврата (помним, что он равен 0 в случае успеха и имеет другое значение в случае ошибок).

Чтобы понять, что внешняя команда, исполняемая с помощью exec() или system(), завершилась неуспешно, нужно передавать переменную $return_var в качестве параметров соответствующих функций и проверять значение на равенство нулю.

Внимание! Если вы собираетесь написать exec(‘some_cmd … 2>&1’, $output), чтобы ошибки тоже попали в $output, рекомендуем ознакомиться с причинами разделения STDOUT и STDERR и убрать явное перенаправление потока ошибок в STDOUT (2>&1). Такое перенаправление требуется намного реже, чем может показаться. Единственный случай, когда его использование хоть немного оправдано (в PHP-скрипте) — необходимость распечатать на веб-странице (не в CLI!) результат выполнения команды, включая ошибки, которые произошли (иначе они попадут в лог веб-сервера или вообще уйдут в /dev/null).

«Маскировка» под встроенные команды системы

Хорошая консольная утилита должна себя вести стандартным образом и пользователи могут даже и не знать, что она на PHP. Для этого в *nix-системах предусмотрен механизм, который многим известен по запуску скриптов на Perl/Python/Ruby, но в равной степени применимый и к PHP.

Если добавить в начало PHP-файла, к примеру, #!/usr/bin/env php и перенос строки, дать ему права на исполнение (chmod 755 myscript.php) и убрать расширение .php (последнее не обязательно), то файл можно будет исполнить, как и любой другой исполняемый файл (./myscript). Можно добавить директорию со скриптом в PATH или переместить его в одну из стандартных директорий PATH, например, /usr/local/bin, и тогда скрипт можно будет вызывать простым набором «myscript», как и любые другие системные утилиты.

Обработка аргументов командной строки

Существует соглашение о формате аргументов командной строки, которому следуют большинство встроенных системных утилит, и мы рекомендуем следовать ему и ваших скриптах.

Пишите краткую справку для своего скрипта, если он получил неверное количество аргументов.

Чтобы узнать имя вызываемого скрипта, используйте $argv[0]:

Для облегчения обработки флагов можно использовать getopt(). Getopt() — одна из встроенных функций для обработки аргументов командной строки. С другой стороны, нет ничего сложного в том, чтобы обрабатывать часть аргументов вручную, т.к. на PHP это не представляет особого труда. Такой способ может понадобиться, если нужно обработать аргументы в стиле ssh или sudo (sudo -u nobody echo Hello world выполнит echo Hello world из-под пользователя nobody, который указан после флага -u перед командой).

Рекомендации для более сложного уровня

Вызов «правильного» system() для CLI

О реализации system() уже было написано здесь. Речь идет о том, что стандартный system() в PHP является не вызовом system() в С, а оберткой над popen(), соответственно, «портит» STDIN и STDOUT у вызываемого скрипта. Чтобы этого не происходило, нужно пользоваться следующей функцией:

Работа с файловой системой

К возможному удивлению, мы рекомендуем не писать свои реализации рекурсивного удаления (копирования, перемещения) файлов, а вместо этого использовать встроенные команды mv, rm, cp (под Windows — соответствующие аналоги). Такое не переносимо между Windows/*nix, но зато позволяет избежать некоторых проблем, описанных ниже.

Давайте рассмотрим простой пример реализации рекурсивного удаления директории на PHP:

На первый взгляд всё верно, так? Более того, даже в известных файловых менеджерах на PHP (например, в eXtplorer и в комментариях к документации) удаление папки реализовано именно таким способом. Теперь создадим символическую ссылку на несуществующий файл (ln -s some_test other_test) и попробуем её удалить. Или создадим в папке символическую ссылку на себя, или на корень ФС (рекомендуем не тестировать такой вариант)… Конкретно для recursiveDelete() фикс, конечно же, тривиален, но понятно, что лучше не изобретать велосипед и использовать встроенные команды, пусть и теряя немного в производительности.

Очистка в случае ошибок

Если ваш скрипт делает какие-то операции с файлами (базой данных, сокетами и пр.), то зачастую возникает необходимость корректно завершать работу программы в случае возникновения непредвиденных ошибок: это может быть запись в лог, очистка временных файлов, снятие файловых блокировок и т.д.

В веб-режиме PHP это реализуется с помощью register_shutdown_function(), которая срабатывает даже тогда, когда скрипт завершился с фатальной ошибкой (этот способ, кстати, годится для отлова почти любых ошибок, в том числе ошибок нехватки памяти). В CLI-режиме всё немного сложнее, поскольку пользователь, к примеру, может послать вашему скрипту Ctrl+C, и register_shutdown_function() при этом не сработает.

Но объясняется это просто: PHP по умолчанию вообще не обрабатывает UNIX-сигналы, поэтому получение любого сигнала немедленно вызывает завершение скрипта. Это можно исправить путем добавления declare(ticks=1), в начало файла после

Источник

Читайте также:  Ultra viewer mac os
Оцените статью