Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Урок №20
Форумы портала PHP.SU » PHP » Уроки php » Урок №20

Страниц (1): [1]
 

1. Haron - 26 Апреля, 2011 - 18:17:35 - перейти к сообщению
Начиная с версии 4.3.0, PHP поддерживает новый интерфейс разработки серверных приложений под названием CLI, что означает интерфейс командной строки.
Как видно из названия, этот вид интерфейса предназначен для разработки консольных (или даже десктопных, да!, вы не ослышались!) приложений на PHP.
Однако, мало кто знает, и ещё меньше тех, кто может и умеет использовать эту возможность. Я постараюсь восполнить этот пробел в данном уроке.

Часть первая - будет посвящена:
- Собственно настройке и подготовке PHP к такому режиму работы.

Часть вторая - будет посвящена:
- Особенностям такого режима работы php
- Специальных предопределённых переменных доступных только в данном режиме.
- Некоторым важным принципам, которых необходимо придерживаться при разработке консольных приложений.

Часть третья - будет посвящена:
- Практическому применению php CLI
- Работа с Windows API, подключение, и экспортирование функций из сторонних DLL-библиотек.

Часть четвёртая - будет посвящена:
- Программирование Windows приложений с кнопками, окошками и и прочим, на примере написания простейшего калькулятора.
- Обзор Qt API

Сразу оговорюсь, здесь и далее предполагается что php у вас уже установлен, неважно как, в составе денвера и им подобных, установлен из инсталятора в режиме работы с вебсервером, либо скачан и распакован в отдельную папку.

Также скажу, что при установке php из инсталятора - в оном есть опция установки в режиме "CLI", однако, ставится php при этом - весьма криво (У меня CLI так и не заработало при выборе этой опции, пришлось руками исправлять), а попытка заставить работать сразу в нескольких режимах (Например последующее подключение к Apache) - приводит к вышеозначеному прописыванию параметров руками. Также не рассматриваются системы Windows Vista и Windows 7... Хотя, там почти всё также.


Часть 1:
Настройка PHP для работы в режиме CLI.

Первое, что нам нужно, это сделать так, чтобы командный интерпретатор (php.exe) запускался в командной строке - причём сразу, и без указания пути к оному:

Что для этого делаем:
1). Правым щелчком мыши - кликаем значок "Мой компьютер".
2). В меню выбираем "Свойства".
3). Переходим на вкладку "Дополнительно".
4). Нажимаем кнопку "Переменные среды".
5). В нижнем окне - ищем переменную "path", выделяем, и нажимаем "Изменить".
6). Ставим после всей строки точку с запятой и прописываем полный путь до папки с php.exe, и (снова через точку с запятой) до папки с расширениями php
Я себе дописал следующее:
;C:\server\PHP;C:\server\PHP\Ext
7). Жмём Ok, затем снова Ok и снова Ok.

Второе что нам нужно сделать - это чтобы php-скрипт запускался по двойному клику, как приложение, либо также запускался, но отдельным пунктом в контекстном меню.

Что для этого делаем:
1). Открываем Regedit (Пуск -> выполнить -> вводим regedit и жмёи Enter)
2). Переходим в раздел HKEY_CLASSES_ROOT
3). Пробуем создать в разделе - подраздел .php
4). Если создался успешно - переходим в него.
5). Изменяем значение ключа "по умолчанию" например на php_file
6). Сохраняем.
7). Переходим обратно в HKEY_CLASSES_ROOT и создаём ещё один раздел со значением заданного нами ранее ключа (У нас это был php_file).
8). Переходим в него и создаём там подраздел shell
9). В подразделе shell создаём подраздел open
10). В подразделе open создаём подраздел command
11). В подразделе command - меняем значение ключа "по умолчанию" на "C:\server\php\php.exe" "%1" %*
обратите внимание, путь до php.exe - у вас может быть совсем другим!
Теперь php-файл можно будет запустить по двойному клику.

12). Если возникла ошибка (Раздел уже существует) - то делаем следующее:
13). ищем его (.php) и смотрим внутри, значение ключа по умолчанию.
14). Ищем в HKEY_CLASSES_ROOT раздел с именем как это значение.
15). Разворачиваем. Создаём внутри подраздел, ну например, run.
16). В подразделе run - создаём подраздел command
17). Выполняем шаг 11.
Теперь в контекстном меню файла php - появится опция 'run', запускающая скрипт.

Итак - наконец-то ВСЁ готово для запуска скриптов с консоли, и по двойному клику (либо по опции в меню).

- Давайте напишем наш тестовый скрипт!
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. echo "Ia Super Script!!!\n";
  4. $value = 2+2;
  5. echo "a 2+2=$value!!111";


Здесь есть важный момент с русскими буквами. При выполнении этого скрипта в консоли - вы увидите кракозябры вместо русских букв, зато латинские отобразятся нормально. Чтобы в консоли оторбажался русский текст - скрипт необходимо сохранять в кодировке OEM866. Поэтому предпочтительней юзать таки латиницу. (Перегонять в oem - умеет например notepad++).

Сохраним-ка мы его в файл test.php. Теперь мы можем запустить скрипт двойным щелчком мыши. Кликаем, видим открывшееся досовское окошко где мелькнул текст и окошко тут же закрылось. Это значит что скрипт запустился и отработал нормально.

Давайте таки убедимся что скрипт действительно отработал:

- Закидываем наш файл на диск C:\
Вообще, можно в любую папку закинуть, но придётся писать много слов в консоли.
- Открываем консоль (Пуск -> выполнить -> cmd -> enter)
- Там пишем:
cd c:\ (этой командой мы переходим сразу на диск c:\)
- Далее - пишем:
test2.php

Ура! Если всё сделано правильно - то мы увидим
Ia Super Script!!!
a 2+2=4!!

И действительно, наш скрипт удачно отработал!
На этом первая часть - заканчивается...

Часть 2:
Особенности работы PHP в режиме CLI

Выполнение скриптов в режиме CLI - имеет ряд важных особенностей и отличий от других режимов работы. В частности, есть 4 директивы файла конфигурации php.ini, которые переопределяются в данном режиме, и их изменение в самом php.ini - не приведёт ни к какому результату. Тем не менее три из них можно переопределять в самом скрипте.

Это следующие директивы:
html_errors - по умолчанию становится FALSE. Так сделано для того, чтобы не пришлось читать в консоли жуткую смесь слов ошибки и html-тегов.

implicit_flush - по умолчанию становится как TRUE. Это значит, что ВЕСЬ вывод (из print(), echo() и пр.) будет немедленно отправлен в вывод, без записи в какие-либо буфера. Однако возможность работы со стандартным выводом - оставлена. С буферизацией работать - можно.

max_execution_time - по умолчанию ставится 0 (не ограничено). Это значит что Ваши скрипты смогут выполняться безо всяких ограничений по времени.

register_argc_argv - по умолчанию ставится TRUE. Регистрирует специальные глобальные переменные php $argc и $argv (Про них ниже). Обратите внимание, что данную директиву не удастся переопределить из скрипта. В CLI она всегда TRUE.

Специальные глобальные переменные $argc и $argv
В первой части мы рассмотрели запуск скриптов из командной строки Windows как обычных программ, и вполне закономерно - возникает вопрос: А можно ли запускать скрипты с параметрами, и как это сделать? Ответ: Да, можно, и делается с помощью вышеозначеных глобальных переменных. Имейте в виду, что данные переменные необходимо писать МАЛЕНЬКИМИ буквами, иначе будет ошибка.

Переменная $argc - будет содержать число переданных скрипту аргументов.
Переменная $argv - будет содержать массив из переданных скрипту параметров.

Давайте перепишем наш первый скрипт, и сделаем так, чтобы он запускался с параметрами и производил с ними некоторые операции:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. // Если не передано аргументов
  3. // Либо передан аргумент -?
  4. if (($argc !== 2) or ($argv[0] === '-?'))
  5. {      
  6.         echo "Super Script, version 1.0\nUsage: -? - print this help message\n -<arg> - print argument";
  7. }
  8. // Если аргумент передан - напечатаем его на экране.
  9. else
  10. {
  11.         echo $argv[1];
  12. }
  13. ?>


Обратите внимание, в $argv[0] - будет содержаться имя скрипта.
Таким образом можно передавать в скрипт неограниченное число аргументов, и управлять его работой.

Работа с потоками ввода-вывода STDIN и STDOUT
Давайте рассмотрим пример программки, которая будет просить, а затем суммировать два числа:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. echo 'Input first number: ';
  3. $number_1 = fread(STDIN, 1024);
  4.  
  5. echo 'Input second number: ';
  6. $number_2 = fread(STDIN, 1024);
  7.  
  8. echo $number_1+$number_2;
  9. ?>


STDIN - это константа, хранящая открытый в данный момент дескриптор пользовательского ввода.
Над ним применимы все операции и функции php, применимые для файлов (Здесь например fread()).
Тем не менее - STDIN открыт ТОЛЬКО для чтения, и записать туда что-либо не получится.
Фактически STDIN абсолютно аналогичен $stdin = fopen('php://stdin', 'r'). Кроме того - вам
не придётся закрывать открытые потоки функцией fclose($stdin), PHP это сделает автоматически.
Да и писать STDIN - несомненно проще, короче и удобней чем открывать и закрывать потоки вручную.

А теперь давайте рассммотрим использование дескриптора вывода данных - STDOUT.
- Перепишем немного нашу программу:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. fwrite(STDOUT ,'Input first number: ');
  3. $number_1 = fread(STDIN, 1024);
  4.  
  5. fwrite(STDOUT ,'Input second number: ');
  6. $number_2 = fread(STDIN, 1024);
  7.  
  8. $sum = $number_1 + $number_2;
  9. fwrite(STDOUT, $sum);
  10. ?>


Как видно, можно (и даже нужно!) не пользоваться echo, print и им подобными конструкциями, а использовать
стандартные дескрипторы. По умолчанию, STDOUT будет выводить сообщения на дисплей (то есть в консоль). Однако, можно перенаправить вывод либо в NUL либо в файл.

Например:

Цитата:
Microsoft Windows [Version 5.2.3790]
(С) Microsoft Corporation, 1985-2003.

C:\Documents and Settings\Haron>cd c:\

C:\>tst.php >NUL


Здесь я перенаправил вывод в "никуда", и если мы нажмём ентер - числа у нас даже не спросят, хотя их можно ввести.
Но не увидим мы и ответа. Вообще - в windows, NUL - есть аналог dev/null/ в *nix системах. Т.е. вывод фактически "в никуда". Правда, в *nix'ах - он на порядок быстрее работает.

Но если мы напишем вот так:

Цитата:
C:\>tst.php >out.txt


То у нас скрипт также ничего не будет просить (но вводить данные можно, и они также будут обработаны); Но после работы со скриптом мы обнаружим на диске c:\ файл out.txt с выводом сообщений скрипта, и суммой введённых чисел.

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

Аналогично STDIN - данные константы являются аналогами fwrite('php://stdout', 'w'), и fwrite('php://stderr', 'w').

Некоторые особенности работы с вводом и выводом.

- Для форматирования сообщений, например переноса строки - не используйте <br />, (Да и любой другой html-код) так как в CLI - его использование теряет
всякий смысл. Используйте \n или \r\n для переноса строк, а строки заключайте не в одинарные а двойные кавычки.
Вместо \r или \r\n - целесообразно использовать предопределённую константу PHP_EOL, так как в разных операционных системах -
символы переноса троки - различны (В частности \n - в *nix, \r\n - в windows, а \r - в MacOS).
- Ещё раз повторю, для вывода - лучше используйте стандартные потоки STDOUT и STDERR вместо echo и print.
- Также не имеет смысла (и не будет работать) функция отправки заголовков header(), их собственно, отправлять-то и некуда.
- Теряют смысл суперглобальные переменные $_POST, $_GET, $_COOKIE и $_REQUEST
- Изменяется содержание массива $_SERVER. К примеру, вышеописанная переменная $argv будет доступна как $_SERVER['argv']
(ИМХО жуткое наследие register_globals кхм...)
Посмотреть все из них можно таким скриптом:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. print_r($_SERVER);
  3. ?>


На этом вторая часть - заканчивается...
2. Ch_chov - 26 Апреля, 2011 - 19:04:03 - перейти к сообщению
1. Почему унылое? Вистой не пользовался, а вот семерка вполне приличная ось.
2. Минимальная конфигурация, для использования PHP в консольном режиме это всего два файла: php.exe и php5st.dll. При необходимости, можно ещё скачать dll-ки для используемых расширений. Установщик не нужен.
3. Запуск скриптов по двойному щелчку, можно организовать стандартными средствами windows. Контекстное меню -> открыть с помощью -> указать путь к php.exe (по умолчанию).
4. Очень удобно, для консольных php скриптов использовать другое расширение. Например, phpc. Для того чтобы отличать их от обычных.
5. Желательно для этих скриптов настроить error_log.
3. EuGen - 26 Апреля, 2011 - 19:49:17 - перейти к сообщению
0. Краткое описание в названии урока обязательно.
1.
Haron пишет:
И последнее: Здесь НЕ РАССМАТРИВАЕТСЯ УНЫЛОЕ Г**НО

В уроках не приемлима подобная "терминология"
2. Урок должен по возможности не иметь хотя бы орфографических ошибок
4. Haron - 26 Апреля, 2011 - 20:43:49 - перейти к сообщению
Цитата:
Краткое описание в названии урока обязательно.

А чем текущее плохо? Кроме того - это лишь третья часть из задуманного, поэтому - логично предположить что дальше будет лучше, не так-ли?

Цитата:
В уроках не приемлима подобная "терминология"

Извиняюсь, исправил.

Цитата:
Урок должен по возможности не иметь хотя бы орфографических ошибок

Допускаю ошибки пунктуации, также немало слов-паразитов типа "клик", "юзать", а вот ошибок орфографии нет - это Вы зря. Нахмурился
5. morosit - 28 Апреля, 2011 - 08:59:23 - перейти к сообщению
Хорошо что тему такую подняли, мне то же интересно
насчет ошибок:
Текст ошибок отправлен в личку
6. EuGen - 28 Апреля, 2011 - 09:16:08 - перейти к сообщению
Гм, я бы рекомендовал это делать через Личные сообщения - так думаю, более корректно и автору не будет неудобно. Без ошибок не бывает, опечататься все могут.
А мы заинтересованы в том, чтобы здесь были качественные уроки - а этот урок хороший, у нас по MS Windows вообще немного материалов.
7. morosit - 28 Апреля, 2011 - 09:48:59 - перейти к сообщению
EuGen
Про ЛС как-то не подумал Однако
Согласен и с тем что урок хороший, и с тем что материал нужный
8. Haron - 29 Апреля, 2011 - 10:27:38 - перейти к сообщению
Сделано
9. EuGen - 29 Апреля, 2011 - 11:21:06 - перейти к сообщению
Пожалуй, стоит весь урок размещать в 1-м сообщении (используйте редактирование).
10. Haron - 29 Апреля, 2011 - 15:09:24 - перейти к сообщению
Вот с последующими частями - могут возникнуть проблемы. Для их организации нужен модуль w32api, который начиная с версии php 5.1.0 - "был перемещён в PECL". Зашёл я в PECL, и выяснилось - проект заброшен уже больше полутора лет, печально...

Можно рассмотреть возможность использования "обёртки" winbinder, но это увы, не универсальное решение.

Щас вот думаю, как быть. Видимо придётся самому w32api собрать из исходников.

 

Powered by ExBB FM 1.0 RC1