|
ДОКУМЕНТАЦИЯ ПО REFAL-PHP |
|
|
Леонид
Белоус |
|
|
Copyright © 2002 Леонид
Белоус |
|
|
14-12-2002 |
|
|
|
|
|
Содержание |
|
|
|
|
|
- 1. Введение в Refal-PHP
- 1.1. Что
такое Refal?
- 1.2. Что
такое PHP?
- 1.3. Что
такое Refal-PHP?
|
|
|
- 2. Интерфейс с PHP как расширение Refal
- 2.1. Использование
PHP в программах на языке Refal
2.2. Передача
данных между средами Рефал-машины и окружением PHP
- 2.3. О
парадигмах операторного и функционального
языков программирования
- 2.4. Интерфейс с
базой данных
- 2.5. Вычисление
математических функций
|
|
|
- 3. Refal-PHP
как встроенный скриптовый язык
- 3.1. Простейший
пример 'Hello World!'
- 3.2. Как
это работает ?
- 3.3. Общая структура
программы на языке Refal-PHP
- 3.4. Сфера
действия переменных и вызовов функций
|
|
|
- 4. Получение,
установка и запуск Refal-PHP
- 4.1. Варианты
рабочих конфигураций Refal - (PHP, PHP+MySQL, PHP+MySQL+Apache)
- 4.2. Платформа
Windows 9x/ME/NT/2000/XP
- 4.3. Платформа
UNIX
- 4.4. Работа с системой
Refal-PHP
- 4.5. Рекомендации
по отладке программ
- 4.6. Некоторые
"мелочи"
- 4.7. Информация
для системных программистов
|
|
|
- ПРИЛОЖЕНИЕ
А
- А.1. Демонстрационные
примеры
- А.2. Библиотеки
функций Refal-PHP
- А.3. Лицензия
-
|
|
|
|
|
|
1. Введение в Refal-PHP |
|
|
|
|
|
1.1. Что такое Refal? |
|
|
|
|
|
РЕФАЛ (РЕкурсивных
Функций АЛгоритмический язык)
- это функциональный язык программирования,
ориентированный на задачи символьной обработки
информации. Был создан в 60-х годах В.Ф.Турчиным (в
бывшем тогда СССР) в качестве "метаязыка"
для описания семантики других языков. Однако
язык оказался удобным рабочим инструментом и для
программистов, решающих прикладные задачи в
самых различных областях. История языка Рефал
неразрывно связана с драматическими событиями в
жизни его автора, известного физика, В.Ф.Турчина.
Подробно о языке Рефал и его авторе можно узнать
на сайте "Содружество
Рефал/Суперкомпиляция" www.refal.net
(зеркало www.refal.org).
После некоторого
затишья Рефал снова стал привлекать внимание как
удобный и элегантный язык программирования,
свободный от мелких деталей, с простой и
естественной конструкцией сопоставления с
образцом. Здесь и далее, если не оговорено
противное, в качестве канонической реализации
языка Рефал будет пониматься система Рефал-5. Мы
позволим себе некоторую вольность в
одновременном использовании названий Refal и Рефал
(как синонимов): с одной стороны, это позволяет
избежать двусмысленности в записи Рефал-PHP,
поскольку PHP - в латинском регистре, а с другой
стороны, русское название Рефал обычно более
распространено в русской документации.
Приведём два примера на языке Рефал.
Пример 1.1-1 "Hello world!"
$ENTRY Go { = <Print "Hello world!\n">;
} |
Программа печатает в результате своей работы
традиционную фразу "Hello world!" с последующим
переводом строки.
Нижеследующий пример более содержателен и
показывает специфику языка Refal.
Рассмотрим следующую простую задачу. Мы хотим
задать функцию, которая определяет для любой
заданной строки символов, является ли она
палиндромом. Палиндром - это строка, одинаково
читаемая как слева направо, так и справа налево.
Пример 1.1-2 Палиндром
$ENTRY Go { = <Print <Pal 'revolver'>>; } Pal {
= True;
s.1 = True;
s.1 e.2 s.1 = <Pal e.2>;
e.1 = False;
} |
Программа печатает, в качестве результата
анализа обрабатываемой строки 'revolver', значение
False.
Язык Рефал хорош прежде всего тем, что
позволяет писать программы, которые очень близки
к математической постановке задачи, вместо того,
чтобы придумывать (с точностью до мелочей!)
детальный алгоритм её решения. Данный пример
является иллюстрацией этого случая. Программа,
как можно заметить, отражает следующее
математическое уточнение понятия палиндрома:
1) Пустая строка является палиндромом.
2) Строка из одного символа является
палиндромом.
3) Если строка начинается и оканчивается одним и
тем же символом, то она является палиндромом
тогда и только тогда, когда строка, полученная из
неё путем удаления начального и конечного
символов, является палиндромом.
4) Если не выполнено ни одно из вышеприведенных
условий, строка палиндромом не является.
Здесь s.1, e.2 - обозначения для образцов
одиночного символа и произвольного выражения
соответственно. Специальный интерпретатор
(Рефал-машина) действительно выполняет
вышеуказанные проверки-замены пошагово, выбирая
первое применимое правило именно в том порядке,
как написано в программе, притом третье правило
приводит к рекурсивному обращению (функция
"Pal" обращается сама к себе).
Еще одно качество
языка Рефал хотелось бы отметить. Он очень удобен
для обработки данных, структурированных в виде
деревьев. Например - алгебраические выражения,
структуры в формате XML, SGML, ...и т.д.
Более подробно с системой Рефал-5 можно
ознакомиться здесь. |
|
|
|
|
|
|
|
|
1.2. Что
такое PHP? |
|
|
|
|
|
Сравнительно недавно (1994 г.)
появившийся язык PHP имеет необычный
“рекурсивный” акроним (Php: Hypertext Preprocessor), что
можно перевести как гипертекстовый
препроцессор. PHP представляет собой встроенный
в HTML скриптовый язык, и в этом качестве стал
своего рода стандартом де-факто при создании
динамически меняющихся web-страниц. Является
свободно распространяемым по технологии open source.
Синтаксис языка вобрал в себя черты С, Java и Perl,
но имеет и свои особые конструкции.
Привлекательными чертами являются простота и
лёгкость изучения языка, кроссплатформенная
реализация, стыковка практически со всеми
популярными СУБД.
Менее известным фактом является то, что язык PHP
допускает самостоятельное применение,
безотносительно к web технологиям, как обычный
универсальный язык программирования с
богатейшей библиотекой интерфейсных функций.
Два примера на языке PHP
Пример 1.2-1
"Hello world!"
<?php echo "Hello world!\n";
?> |
Этот текст, оформленный в виде файла, скажем, с
именем world.php,
интерпретируется web сервером, как задание на
генерацию web страницы.
Эта генерация действительно происходит, когда
посетитель сайта, содержащего эту страницу,
задает её URL (или попадает на неё по ссылке). Тогда
в окне web-броузера появляется текст “Hello world!”,
как если бы просматривалась обычная HTML страница.
Если посмотреть броузером её исходный код, то,
действительно, мы не увидим вышеуказанного PHP
текста, а только результат с HTML тэгами,
полученный после генерации.
Печать 'Hello world!' как результат работы
вышеуказанной PHP программы можно увидеть и при
работе в режиме командной строки без всякого
сервера и броузера, если выполнить команду
> php -q world.php
при условии, что PHP
установлен для работы в таком режиме. Это
замечательное качество сильно упрощает отладку.
Никакой компиляции, сборки, ….
PHP работает в интерпретирующем режиме, и в этом
качестве начинает с успехом использоваться как
интерпретатор скриптов на платформах UNIX наряду с
sh, bash, perl. Ключ –q подавляет выдачу лишней HTML
информации, не требующейся в данном случае.
Пример 1.2-2 Интеграция с HTML
<html>
<head> <title> Example </title> </head>
<body>
<?php
echo "Hello world!\n";
?>
</body>
</html>
|
Пример демонстрирует, каким образом текст на
языке PHP встраивается в HTML страницы. Для этого
служит пара тэгов <?php и ?>,
обрамляющих текст на этом языке.
Кроме того, сервер должен ещё иметь указания на
предмет возможного наличия в странице кода PHP.
Обычно применяется соглашение при котором
страницы, не содержащие кода PHP, имеют в имени
файла расширение htm или html, в
отличие от страниц с php, у которых в расширении
ставят php.
Эти меры позволяют для больших сайтов снизить
затраты на интерпретацию PHP, убирая лишний анализ
для страниц, где этого кода заведомо нет.
В данном примере серверная сторона выдаст в
чистом виде (без каких либо изменений) весь код
HTML, который добавляет на страницу в поле title
её заголовок “Example”, но вставит и то,
что получается от интерпретации кода PHP
(совпадает с предыдущим примером). Т.е.
интерпретатор PHP ведет себя как прозрачный
фильтр по отношению к HTML коду.
Подробно с PHP можно познакомиться на
официальном сайте www.php.net
Пусть Вас не пугает кажущийся
бесконечным список функций в этом языке J . Большинство
из них вряд-ли когда могут понадобиться. Однако
велика вероятность, что и для вашей области
деятельности найдутся полезные функции.
Основная часть, посвященная собственно языку,
достаточно компактна.
Не менее важен тот факт, что очень быстро
пополняются коллективные, свободно доступные
хранилища самых разнообразных приложений,
написанных на PHP. Есть и попытки стандартизации
этого процесса. Например, можно порекомендовать
библиотеку классов на PHP( http://www.phpclasses.org/
). Похоже, что в этом качестве PHP вскоре не будет
уступать языку Perl со своим богатым репозиторием
CPAN. |
|
|
|
|
|
|
|
|
1.3. Что
такое Refal-PHP? |
|
|
|
|
|
Refal-PHP представляет собой
интерфейс системы Refal c PHP , позволяющий
создавать кросс-платформенные приложения как на
стороне сервера, так и на стороне клиента,
сочетая преимущества функционального языка
программирования Рефал с возможностями
универсального языка PHP. Создаваемые
приложения легко можно модифицировать для
работы либо в автономном (standalone) режиме, не
требующем web сервера и броузера, либо, наоборот,
предназначать их для работы в качестве
серверного приложения.
Предлагается два варианта интерфейса, подробно
рассматриваемые ниже.
Первый из них представляет расширение языка
Рефал специальной функцией
<Php e.php> ,
где аргументом e.php является программа на языке
PHP. На базе этой функции написаны дополнительные
библиотечные функции для работы с базой данных и
функция вычисления арифметических выражений с
действительными числами. Эти функции могут
служить примерами встраивания дополнительных
возможностей в язык Рефал, при этом пользователь
может и не подозревать о существовании другого
языка, если не требуется явный выход в PHP.
Второй, более универсальный вариант,
превращает Рефал в равноправный с PHP (по
отношению к HTML) встроенный скриптовый язык со
своей парой тэгов <?ref и ?> . |
|
|
|
|
|
|
|
|
|
|
|
2. Интерфейс с
PHP как расширение Refal |
|
|
|
|
|
Этот способ фактически не
требует от пользователей языка Рефал
дополнительных усилий для изучения новой
операционной обстановки. Можно считать, что
используется обычная система Refal-5 с
добавлением новых функций. В принципе, если не
требуется выход непосредственно в PHP, то и
знакомство с этим новым языком тоже не
обязательно. Например, для пользования функциями
работы с СУБД и вычислением арифметических
выражений диапазона действительных чисел
изучения PHP не требуется. Достаточно
познакомиться только со спецификациями новых
функций. Тот факт, что при этом работает
интерфейс с PHP, скрыт от пользователя.
Собственно говоря, это утверждение в равной
степени можно отнести к языкам C , и к самому языку
Рефал, при написании на них специальных функций и
библиотечных модулей. Но в данном случае речь
идёт о языке с богатейшей интерфейсной
библиотекой, на котором такие модули можно
создавать быстро и эффективно, используя
преимущества открытой технологии.
Мы продемонстрируем этот подход ниже, на
примерах, а сейчас представим функцию, которая,
собственно, и открывает для Рефала мир PHP. |
|
|
|
|
|
|
|
|
2.1. Использование
PHP в программах на языке Refal |
|
|
|
|
|
Специальная функция
<Php e.php>
вызывает из Рефала интерпретатор PHP, передавая
ему в качестве аргумента выражение языка Рефал
e.php, которое должно представлять собой текст на
языке PHP. Результат выполнения PHP-программы
остается как строка в поле зрения Рефал-машины.
Пример 2.1-1 "Hello world!"
$ENTRY Go { = <Print <Php 'echo "Hello
world!\n";' >>;
} |
В данном примере сначала выполняется
внутренняя функция “Php”, которая вызывает
интерпретатор PHP, передавая ему текст <?php echo
"Hello world!\n";> .
Тэги <?php и ?>
добавляются автоматически.
После выполнения этой PHP-программы, выдаваемая
строка символов “Hello world!”, перехватывается
функцией “Php” и оставляется уже как её результат
в поле зрения Рефал-машины.
Следующий по очереди вызов Рефал-функции <Print...>
приводит к выводу копии этой строки на
стандартное устройство вывода, но оставляет её в
поле зрения. В Рефал-языке есть и другая функция
<Prout...>, которая вместе с выводом
уничтожает саму строку. Несмотря на то, что здесь
и в других местах этого руководства было бы более
естественным использовать именно её, мы для
наглядности будем писать более понятное <Print...>
. |
|
|
|
|
|
|
|
|
2.2. Передача данных между
средами Рефал-машины и окружением PHP |
|
|
|
|
|
При использовании функции
<Php e.php> следует учитывать локальную
сферу действия переменных программы e.php,
ограниченную только данным вызовом
Рефал-функции <Php...>. Любой новый
вызов этой функции не предполагает сохранности
переменных PHP при любых других вызовах, включая
повторные. Для решения этой проблемы в случае
использования такого стиля программирования
предусмотрены специальные функции как в языке
Рефал, так и в PHP. Идея состоит в организации
специального общего буфера обмена, через который
можно передавать необходимые данные. В принципе
это совершенно аналогично механизму ящиков в
языке Рефал. Только доступ к этим ящикам возможен
не только из среды Рефала, но и из среды PHP.
Вот эти четыре функции (имена переменных в PHP
начинаются со знака $):
Для языка Refal:
- <Write_var '$var=value'>
Записать в буфер обмена
значение value для переменной $var
языка PHP.
<Read_var '$var'>
Прочитать из
буфера обмена значение переменной $var
языка PHP.
Для языка PHP:
- write_var($var, $value)
-
- Записать в буфер обмена под
именем $var значение $value.
-
- read_var($var)
-
- Прочитать из буфера обмена значение переменной $var
Пример 2.2-1 Два
вызова PHP
$ENTRY Go { = <Php '$var = 1;'>
<Print 'Second call for PHP' >
<Print '$var= ' <Php '$var = $var + 1; echo $var;' >>;
} |
В результате, вместо ожидаемого значения 2,
будет напечатано
- Second call for PHP $var = 1
-
- , поскольку факт присвоения единицы при первом
вызове функции <Php...> будет забыт при
втором вызове этой же функции. Единица будет
добавлена к неприсвоенному (пустому) начальному
значению переменной $var.
Ситуацию можно исправить,
воспользовавшись предложенными функциями
обмена.
Пример 2.2-2 Буферный обмен
$ENTRY Go { = <Php '$var = 1; write_var("\\$var",
$var );' >
<Print 'Second call for PHP' >
<Print '$var= '
<Php '$var=read_var("\\$var"); $var = $var + 1;
echo $var;' >
>
- }
|
Теперь будет напечатано
Second call for PHP $var = 2
Удвоение обратного слэша в этой программе
(сохраняющий символ) обеспечивает его передачу
как символа строки в PHP. Это необходимо, чтобы
в качестве параметра передать имя переменной
вместо её значения.
В данной реализации вызов PHP является
достаточно дорогой операцией. Поэтому следует
стремиться минимизировать количество переходов
между системами Рефал и PHP. В данном примере, если
бы между двумя вызовами <Php...> не
стояло ничего, то можно было бы объединить два
вызова в один, и проблема бы исчезла. |
|
|
|
|
|
|
|
|
2.3. О парадигмах
операторного и функционального языков
программирования |
|
|
|
|
|
Нетрудно заметить, что
предложенный способ обмена данными между
фрагментами Рефал-программ и PHP-программ
достаточно неудобен. Но, к счастью, вряд ли в нём
возникнет большая потребность.
- Дело в том, что процесс выполнения операторов
программы в операторном языке, каковым является
PHP, строго детерминирован управляющими
конструкциями языка. В функциональном же языке
Рефал порядок выполнения вычислений
определяется во время интерпретации
обрабатываемых выражений и может быть
достаточно запутанным, особенно при наличии
рекурсивных функций.
-
- Если для операторного языка рекурсия скорее
исключение, чем правило, то для Рефала, наоборот,
рекурсивные определения позволяют писать очень
наглядные и компактные определения функций.
-
- По этой причине фрагменты программ на этих
языках трудно состыковать по данным через
глобальные переменные. Момент, когда мы захотим
воспользоваться значением переменной языка PHP в
языке Рефал, равно как и наоборот, может
оказаться совсем неподходящим, и, следовательно,
мы можем получить неправильное значение
переменной, то ли неприсвоенное, то ли не с того
уровня рекурсивного вызова.
-
- Поэтому общей рекомендацией может являться
совет избегать связи между системами Рефал и PHP
по данным через функции буферного обмена со
всеми недостатками, присущими аппарату
глобальных переменных. В принципе, это даже и
неплохо, что значения переменных во фрагментах PHP
программ локализованы внутри Рефал-вызовов
функции
<Php...>.
|
|
|
|
|
|
|
|
|
2.4. Интерфейс с базой данных |
|
|
|
|
|
- В PHP предложен удобный, хорошо продуманный
интерфейс с базами данных, что является одним из
наиболее выигрышных качеств этого языка.
-
- Наиболее популярной и простой является СУБД MySQL.
К счастью, простота MySQL вовсе не означает
ограниченность её возможностей. Эта система
очень хорошо масштабируется и не теряет своей
эффективности при работе с базами данных
масштаба крупных предприятий.
-
- Интерфейс достаточно прост для тех, кто знаком c
PHP и MySQL. Хотя описанных в предыдущем разделе
функций достаточно, чтобы обращаться из Рефала к
базам данных, однако предлагаемый ниже набор
функций предназначен для пользователей, не
имеющих большого желания вникать в подробности
интерфейса PHP+MySQL, которые дают полную
универсальность, но требуют времени для
изучения.
-
- Под базой данных понимается хранилище данных,
организованное таким образом, чтобы были
удобными быстрый поиск, пополнение и модификация
(в случае необходимости) этих данных. Типичным
примером может служить электронная библиотека
книжных фондов.
-
- Стандартом де-факто являются т.н. реляционные
базы данных и стандартизованный язык запросов
(SQL). Этому стандарту удовлетворяет и система MySQL.
-
- Уточнением понятия "база данных" в
реляционной модели может служить такое
определение: база данных - это совокупность
взаимосвязанных таблиц, каждая из которых
состоит из своего набора полей (колонок). Таблица
состоит из строк (записей), собственно и
являющихся самими данными. В простых случаях
можно считать, что база данных состоит только из
одной таблицы.
-
- Например, такая таблица может служить образцом
базы данных:
-
-
- Data
|
- Wether
|
- 14.05.2002
|
- Хорошая
|
- 15.05.2002
|
- Плохая
|
-
- Проектирование реляционной базы данных
предполагает в качестве основного этапа
конструирование таблиц (выбор полей),
определение взаимосвязи между таблицами,
определение ключевых полей с учётом запросов на
поиск. Всё это, конечно, не является простым
занятием, и мы не будем углубляться в детали.
-
- Предлагаемый ниже набор специальных функций,
пополняющих библиотеку Рефала, позволяет
создавать таблицу с задаваемой структурой,
помещать данные для хранения в таблицу и
выбирать эти данные. Естественно, можно
расширять набор этих операций, скрывая детали
интерфейса Рефала с PHP и MySQL, однако с какого-то
момента пользователь уже должен определиться,
уровень какого языка ему ближе, и применять свои
знания с учётом имеющихся возможностей.
-
- Может показаться необычным тот факт, что Refal-PHP
позволяет работать с базой данных в отрыве от web
технологий, т.е. не требуя web-сервера и броузера.
Для этого достаточно конфигурации Refal+PHP+MySQL (см.
4.1. Варианты рабочих
конфигураций Refal - (PHP, PHP+MySQL, PHP+MySQL+Apache).
-
- Рассмотрим теперь функции языка Рефал для
работы с СУБД MySQL и примеры их
использования. Мы будем считать, что у нас уже
имеется определённое имя базы данных (пусть это
будет “refal”), и при установке системы
Refal-PHP база была проинициализирована. Если речь
идет об узле Интернет провайдера, то обычно имя
базы выдаётся новому пользователю как ресурс.
Сам пользователь обычно не имеет полномочий
выполнять операцию создания базы данных. Однако
ему обычно доступны средства администрирования
на уровне популярной web-программы phpMyAdmin, которой по силам
любые манипуляции с базами данных. Использование
phpMyAdmin предполагает наличие web-сервера.
-
- Ниже приводятся интерфейсные функции для связи
с СУБД. Их можно рассматривать как примеры такого
встраивания возможностей PHP+MySQL в Рефал, при
котором требование знакомства пользователей
языка Рефал с PHP и MySQL не является обязательным.
-
<Db_create_table (e.table)
e.structure>
Создает таблицу с именем e.table и со структурой
полей, определяемых e.structure. Если таблица уже
имеется, то результат операции эквивалентен
пустому оператору. Структура полей (колонок)
таблицы e.structure представляет собой строку
символов (заключенную в одиночные кавычки!),
состоящую из пар, разделённых запятыми (без
пробела после запятой), вида
'<field> <пробел> <type>, ….' .
Например, следующая рефал-функция
<Db_create_table ('table1') 'm integer,a text'
>
создаст в базе данных ("refal")
таблицу с именем "table1", состоящую
из двух текстовых полей (колонок) c именами "m"
и "a".
Имеется порядка 30 типов полей, и в нашу задачу
не входит детальное знакомство с ними. Для наших
примеров достаточно будет двух традиционных: text
– для строковых полей, и integer – для
задания целых чисел. В случае необходимости
смотрите руководство по MySQL, где всё подробно
описано.
- <Db_select_table e.table>
-
- Выбирает для работы таблицу e.table. Все
последующие операции будут относится к этой
выбранной (текущей) таблице. Операция нужна
только при работе более чем с одной таблицей.
Предыдущая функция <Db_create_table...>
автоматически завершает своё выполнение данной
функцией выбора таблицы, делая текущей только
что созданную таблицу.
-
- <Db_write e.record>
-
- Добавляет строку e.record в таблицу.
<Db_read_field
e.field>
Читает в поле зрения все строки
таблицы, выбирая только заданное поле e.field.
<Db_read_all>
Читает в поле зрения все строки
таблицы (полностью, со всеми полями).
<Db_print_field
e.field>
Выдает на печать все строки
таблицы, выбирая только заданное поле e.field.
<Db_print_all>
Выдает на печать все строки
таблицы (полностью, со всеми полями).
- В качестве примера напишем
сначала простейшую программу на языке Рефал,
которая создаёт базу данных в виде таблицы из
одного поля data и добавляет туда строку,
которую генерирует Рефал-функция <Time>
в момент обращения к ней. Затем печатаются все
записи, которые накапливаются в базе данных.
Пример 2.4-1 Работа
с базой данных - простейший пример
$ENTRY Go { = <Db_create_table ("table1") 'data
text'>
<Db_write ‘"’
<Time> ‘"’>
<Db_print_all>
} |
Первая функция создаёт таблицу с именем “table1”
и c одним текстовым полем – data, затем эта
таблица фиксируется как текущая.
Следующая функция <Db_write...> сначала
ждёт исполнения внутреннего вызова функции <Time>,
оставляющей в поле зрения строку символов -
текущий момент времени, а затем добавляет эту
запись в базу данных. Иными словами, добавляется
новая строка в таблицу “table1”.
Наконец,
последняя строка программы извлекает из базы
данных и выдает на печать все записи.
Последующие обращения к
этой программе будут добавлять очередные строки
с новыми фиксируемыми моментами времени, при
этом первая функция (создания таблицы) не
является необходимой. Она будет срабатывать, как
пустая.
При написании
модифицированных программ (учитывающих тот факт,
что таблица уже создана, и не нужно повторно
пытаться её создавать) вместо функции <Db_create_table
...> следует писать обращение к функции выбора
таблицы <Select_table 'table1'>.
- Теперь немного усложним
предыдущий пример. Напишем программу, которая
запрашивает в диалоге текст строки, записывает в
базу данных эту строку вместе с датой её ввода, и
печатает всё, что мы вводили с терминала. Под
базой данных здесь будет пониматься таблица из
двух полей: data, record.
Пример
2.4-2 Работа с базой данных - таблица с двумя
полями
$ENTRY Go { = <Db_create_table ("table2") 'data
text,record text'>
<Print "Enter record">
<Db_write '"' <Time>
'","' <Card> '"'>
<Db_print_field 'record'>
} |
- Первая функция создаёт таблицу с именем “table2”
и c двумя колонками (полями) – data и record,
затем эта таблица фиксируется как текущая.
Обратите внимание, что это уже другая таблица.
-
- Вторая функция печатает приглашение для ввода
записи.
-
- Следующая функция <Db_write...> сначала
ждёт исполнения двух внутренних вызовов -
функция <Time> возвращает в поле зрения
строку символов, которая представляет собой
текущий момент времени, а функция <Card>
ожидает ввода строки, о чём пользователю было
только что сообщено.
-
- После нажатия “enter” запись, сформированная из
двух полей, разделённых запятой, добавляется в
базу данных. Иными словами добавляется очередная
строка в таблицу “table2”.
Наконец, последняя строка программы выдаёт на печать все
записи из поля "record". Программа в том виде, как она
написана, рассчитана на работу в режиме
командной строки с терминала. Для работы через WWW
необходимо запрограммировать ввод информации.
Возможностей Рефал-функции <Card> для
этого явно недостаточно. При попытке же
запустить этот пример по общей схеме, как для
предыдущего примера, с использованием сервера
Apache (см. 4.4. Работа с
системой Refal-PHP ) процесс refgo зависнет
по причине ожидания вводимых данных.
|
|
|
|
|
|
2.5. Вычисление
математических функций |
|
|
|
|
|
Как известно, в последней
версии Рефала-5 работа с действительными числами
отсутствует. Предлагаемая ниже рефал-функция
<Evalf e.expression>
исключает этот недостаток, позволяя
использовать в Рефал-программах традиционные
арифметические выражения с математическими
функциями. В состав системы PHP входит набор из
более чем 40 функций, вместе с часто используемыми
константами, позволяющий оперировать с
машинными числами диапазона действительных
чисел. В PHP реализована платформенно-зависимая
арифметика с плавающей точкой, где integer
и float соответствуют типам данных long
и double языка “C”. Типичным
является максимальное значение чисел около 1.8e308
с точностью приблизительно 14 знаков (формат 64 бит
IEEE).
- В качестве e.expression допускается
любое арифметическое выражение в синтаксисе
языка PHP. Результат остаётся в поле зрения
Рефал-машины в виде строки символов,
представляющей результирующее число. Подробное
описание функций см. в разделе руководства по PHP (LII. Mathematical Functions).
|
|
|
|
|
|
Пример
2.5-1 Машинная арифметика
$ENTRY Go { = <Print <Evalf
'sin(0.235)+cos(1/3)'>>
} |
|
|
|
|
|
|
В результате напечатается:
1.1777999318272
|
|
|
|
|
|
|
|
|
3. Refal-PHP как встроенный
скриптовый язык |
|
|
|
|
|
Этот, более универсальный
вариант использования языка Рефал в связке с PHP,
предполагает знакомство с HTML и PHP. Идея состоит в
том, что фрагменты кода на языке Рефал,
выделяемые своей специальной парой тегов <?ref
... ?>, могут использоваться при
конструировании HTML страниц совместно с кодом PHP. |
|
|
|
|
|
|
|
|
3.1. Простейший пример
"Hello World!" Рассмотрим
традиционный простейший пример.
Пример 3.1-1 "Hello
world!" - файл hello.rphp
<?ref <Print "Hello world!\n">;
?> |
Если в режиме командной строки выполнить
команду
> refalphp hello.rphp
то будет напечатано то, что ожидается от этого
примера - "Hello World!" с переводом
строки. |
|
|
|
|
|
|
|
|
3.2.
Как это работает ? Cтраницы,
содержащие код Refal-PHP, отмечаются
расширением rphp в имени файла.
Специальный транслятор (refalphp)
обрабатывает такие страницы и строит
эквивалентную программу, порождая одноимённую
страницу на чистом PHP (hello.php), в
которой уже не содержится фрагментов Рефал-кода.
Из фрагментов Рефал-кода, в свою очередь,
строится одноимённая Рефал-программа (hello.ref),
которая транслируется Рефал-компилятором и
превращается опять же в одноимённый
интерпретируемый модуль (hello.rsl), готовый
к выполнению Рефал-интерпретатором refgo.
Из страницы PHP в соответствующих местах стоит
динамическое обращение (через refgo) к
этому модулю с соответствующим списком
параметров. Инициатором выполнения является
страница hello.php.
Мы излишне подробно остановились здесь на
технической стороне вопроса, связанной с
реализацией, поскольку это сразу снимает много
вопросов, связанных с тем, что можно, а чего
нельзя (или неудобно) написать в Refal-PHP, как во
встроенном скриптовом языке. С другой стороны, мы
более подробно рассмотрим структуру порождаемых
динамически (на лету) программ в разделе,
содержащем рекомендации по отладке.
Если же речь идет о веб-сайте и его страницах, то
здесь, как правило, имеет смысл выполнить
предварительную обработку страниц с кодом Refal-PHP
компилятором refalphp, чтобы иметь дело
только с порождёнными PHP-страницами и
интерпретируемыми Рефал-модулями. Хотя, в
принципе, нет препятствий и для динамического
применения модуля refalphp. |
|
|
|
|
|
|
|
|
3.3. Общая структура
программы на языке Refal-PHP Будем называть Рефал-вкраплением всё,
что ограничено рефал-тегами.
В общем случае Рефал-вкрапления могут
допускать:
Может быть одиночный вызов,
например,
<?ref <Time> ?>
либо последовательность
вызовов, например,
<?ref <Func1 e.1>
<Func2 e.2> ...<FuncN e.n> ?>
- Описания рефал-функций + Вызовы
функций
Например,
<?ref
Func1 { .... } Func2 { .... } ..... FuncN { ..... }
<Func1 e.1> ....<Card>... <Time>.... <XFunk
e.x>
?>
Точка с запятой в конце вызова
(или вызовов) не ставится.
Между парой тегов <?ref и
?> действует синтаксис Рефал-языка с
одним умолчанием-расширением, касающимся
начальной точки входа $ENTRY Go,
обязательной для обычной Рефал-программы. Эту
точку в Refal-PHP можно не указывать. Соответствующая
начальная точка будет добавлена автоматически.
Это сделано не только из
соображений удобства, но и по следующей причине.
Все Рефал-вкрапления в конечном итоге
превращаются в единую Рефал-программу. Описания
функций, независимо от того, в каком
Рефал-вкраплении они были заданы, собираются в
начале этой программы, а оставшиеся вызовы
функций оформляются тоже в виде описаний
функций, но со специальным именем F_rphp_N,
дописываемых за уже имеющимися. Добавляемая же
автоматически точка $ENTRY Go ведёт на
специальную функцию, которая по заданному номеру
N обеспечивает вызов функций F_rphp_N.
Именно эти функции и вызываются динамически из
головной PHP-страницы, когда работает PHP-программа.
Фактически Рефал-программа, получившаяся в
результате работы транслятора refalphp,
представляет собой модуль с N точками
входа.
Рассмотрим примеры.
Пример 3.3-1 Вызов рефал-функций.
<?php echo "This is PHP\n"; ?> This is HTML
<?ref <Print "This is Refal"> ?>
<?php echo "This is PHP again"; ?> |
В результате будет выдано
This is PHP
This is HTML
This is Refal
This is PHP again
В данном примере печать фразы "This is Refal"
обеспечивается Рефал-вкраплением одиночного
вызова функции <Print ...>.
Пример 3.3-2 Описание рефал-функции
вместе с вызовами.
<?ref
Func1 {
e.1 = <Print "Func1: " e.1>;
}
<Func1 "This is Refal">
?> <?php echo "This is PHP\n"; ?>
<?ref <Func1 "This is Refal again"> ?> |
В результате будет выдано
Func1: This is Refal
This is PHP
Func1: This is Refal again
|
|
|
|
|
|
|
|
|
3.4.
Сфера действия переменных и вызовов функций. Как уже упоминалось ранее, с
логической точки зрения все Рефал-вкрапления
являются частями одной Рефал-программы. По этой
причине сфера действия имён функций и глобальных
переменных (ящиков) распространяется на все
Рефал-вкрапления.
Что касается обмена данными между
Рефал-вкраплениями и PHP-фрагментами через
переменные PHP, то в данной реализации это пока
осуществимо только с помощью функций обмена
данными между окружениями Рефал-программ и
PHP-программ, которые были описаны в разделе
2.2. Предполагается, однако, реализовать обмен
данными через переменные PHP без необходимости
прибегать к услугам этих служебных функций.
Пример 3.4-1 Доступ к переменным PHP
<?php $var = 'string_value';
write_var ('\$var', $var);
?>
<?ref
<Print '$var = ' <Read_var '$var'>>
?> |
В результате будет выдано
$var = string_value
|
|
|
|
|
|
|
|
|
4.
Получение, установка и запуск Refal-PHP |
|
|
|
|
|
4.1.
Варианты рабочих конфигураций Refal - (PHP, PHP+MySQL,
PHP+MySQL+Apache) |
|
|
|
|
|
В зависимости от
преследуемых целей возможны различные по
составу конфигурации для работы Refal-PHP, от
минимальной (Refal + PHP) до полной (Refal + PHP + MySQL +
Apache). Варианты Refal + PHP
и Refal + PHP + MySQL не требуют установки сервера
Apache и не требуют использования броузера.
Минимальный вариант
требует примерно 3 Мбт, а полный около 10 Mbt на
ж`стком диске. Эти цифры приблизительные и
меняются с выходом новых версий упомянутых
систем.
Процедура установки системы Refal-PHP
предполагает, что необходимые для выбранной
конфигурации компоненты (PHP, MySQL, Apache) либо уже
установлены, либо их необходимо установить
самостоятельно. Все системы являются свободно
распространяемыми, но с соблюдением своих
собственных лицензий. Refal-5 включён в состав
дистрибутива, но может быть получен и установлен
отдельно. Ниже приведены адреса соответствующих
сайтов.
PHP - http://www.php.net , с
русифицированным руководством http://www.php.net/manual/ru/
MySQL - http://www.mysql.com
, а также русскоязычный сайт http://www.mysql.ru/
Apache - http://www.apache.org
, с русскоязычной поддержкой http://apache.lexa.ru/
Refal-5 - http://botik.ru/pub/local/scp/refal5/refal5.html
, а также http://www.refal.net/doctrain.html
|
|
|
|
|
|
4.2.
Платформа Windows 9x/ME/NT/2000/XP |
|
|
|
|
|
- После установки (как минимум PHP), скачайте
дистрибутив последней версии Refal-PHP здесь
и разархивируйте его в любом месте.
- Войдите в директорию с именем rphp-<date>-<version>-win32
(например, это может быть rphp-021128-0.1.0-win32) и
запустите инструкцию install, в результате
образуется директория <rphp_home> (по умолчанию c:\refalphp).
- Скопируйте директорию с установленной системой
PHP (сохраняя то же имя php) в <rphp_home>.
На этом установка минимального варианта (Refal+PHP)
завершается. Для установки расширенного
варианта следует дополнительно скопировать (в
зависимости от вашего выбора) в ту же директорию
<rphp_home> установленные системы Apache и/или
MySQL, затем выполнить инструкцию <rphp_home>\tuning.bat.
Если предполагается работа с базами данных и
сервером Apache, то настоятельно рекомендуется
установить также систему phpMyAdmin, установив её в
директорию <rphp_home>\www\ . Процедура установки
phpMyAdmin состоит в простой переписи содержимого
разархивированного дистрибутива (например,
содержимое директории phpMyAdmin-2.3.3-rc1) в
<rphp_home>\www\phpMyAdmin. Никаких дополнительных
настроек не требуется. Вызов производится
броузером по URL: http:\\localhost\phpMyAdmin
(сервер Apache должен быть запущен). Программа имеет
дружественный интерфейс (вплоть до
автоматического распознавания русскоязычности)
и среди баз данных, которые вам будут предложены
для выбора, вы увидите и базу "refal".
|
|
|
|
|
|
4.3.
Платформа UNIX |
|
|
|
|
|
В большинство популярных дистрибутивов Linux уже
включена поддержка PHP, MySQL, Apache. Поэтому процедура
установки Refal-PHP, в основном, сводится к умению
установить Рефал-5 под соответствующую версию UNIX.
Скачайте последний дистрибутив системы Рефал-5 с
исходными текстами здесь,
разархивируйте, и следуйте инструкции по
установке для UNIX систем. Специальный
дистрибутив для установки Refal-PHP под UNIX находится
в стадии подготовки, но, в принципе, в нём нет
особой необходимости. Исходные тексты, входящие
в дистрибутив для платформы Windows, практически те
же самые. Основное изменение, которое кое-где
нужно вносить, состоит в замене обратных слэшей
на прямые в указаниях полных путей (path) для
директорий.
В остальном можно следовать рекомендациям
раздела 4.7.Информация
для системных программистов по встраиванию
системы Refal-PHP в уже имеющуюся конфигурацию
Refal+PHP+MySQL+Apache с выбором <rphp_home> в наиболее
удобном для вас месте.
|
|
|
|
|
|
4.4. Работа с
системой Refal-PHP. |
|
|
|
|
|
Проще всего начать работать с системой Refal-PHP,
начав с запуска демонстрационных примеров,
приведенных в данном руководстве. Они
расположены в директории <rphp_home>\www\demo
. По умолчанию <rphp_home> = c:\refalphp - место
установки системы. Для проверки минимальной
версии можно запустить диалоговый Refal-PHP
калькулятор, войдя в директорию <home_rphp>\www\demo
и выполнив в режиме командной строки
инструкцию
> cr.bat
В результате запустится зацикленный вариант
программы (см. calculator.ref), прототипом
которой можно рассматривать пример 2.5-1 (Машинная
арифметика). Программа рассчитана на ввод
выражения с клавиатуры (приглашение для ввода
"Enter expression:"). После ввода
очередного выражения печатается результат, и
следует приглашение для следующего вычисления.
Выход из программы по CTRL-C.
Для проверки полной версии (Refal+PHP+MySQL+Apache)
следует запустить сервер Apache (автоматически
будет запущен и сервер баз данных MySQL).
Рекомендуется на рабочем столе Windows завести
иконки "StartR" для команды <rphp_home>\start.bat
и "StopR" - для <rphp_home>\stop.bat
.
Запустив Apache командой "StartR" (при
этом появится фоновый процесс для приложения
Apache), следует вызвать любым броузером страницу http://localhost . В результате вы должны
увидеть данное руководство, но все примеры в нем
будут "живыми", в том смысле, что их можно
будет выполнять в реальном времени, нажав на
кнопку "submit", расположенную возле
каждого примера.
Этот вариант руководства (с интерактивным
выполнением примеров) входит в состав
дистрибутива. По завершении работы с Refal-PHP
следует выполнить команду "StopR" для
остановки серверов Apache и MySQL.
При работе в режиме командной строки рабочей
директорией должна быть <rphp_home>\www\demo\,
в противном случае надо позаботиться обычным
образом о PATH переменной.
Структура примеров в случае Интерфейс с
PHP как расширение Refal
Все примеры организованы единообразным
способом. Рассмотрим подробно один из них,
Пример 2.5-1 Машинная арифметика.
Для его выполнения в режиме командной строки
достаточно минимальной конфигурации (Refal+PHP), а в
случае полной - не обязательно запускать сервер
Apache.
С этим примером связаны следующие три файла:
- example251.ref
- example251.rsl
- example251.php
Первый (основной) файл является исходным
текстом на языке Refal-5
$EXTRN Evalf;
$ENTRY Go { =
<Print <Evalf 'sin(0.235)+cos(1/3)'>>
}
Об использовании PHP здесь говорит только лишь
специальная Refal функция (Evalf), описанная
ранее в этом руководстве. В приводимых в тексте
примерах мы позволили себе некоторую вольность,
опустив описания $EXTRN для того, чтобы не
загромождать текст руководства, поскольку при
иной организации библиотек в Refale-5 и Refal-PHP этих
описаний можно избежать.
Второй файл получается в качестве работы
компилятора языка Refal-5. Для этого необходимо
выполнить команду
> refc example251
Все примеры, вошедшие в дистрибутив, прошли
фазу компиляции, и в результате появились файлы с
расширением rsl, на так называемом языке
сборки, которые готовы к эффективной
интерпретации с помощью команды refgo.
Все что нужно теперь сделать - выполнить
команду
> refgo example251+..\lib\rphplib
Дополнительный текст со знаком плюс есть
указание на библиотеку фазы run time при
выполнении Refal программ.
В результате напечатается результат:
1.1777999318272
Третий файл требуется только при использовании
клиент-серверной веб-технологии. Для этого
необходимо, чтобы был запущен сервер Apache. Эта
модель ничем принципиально не отличается от
того, что применяется в реальном Internet. Более
того, если ваша машина подключена к реальной сети
Internet и там видна, то следует предпринимать
меры по защите от хакерских атак. Эти вещи носят
специальный характер и не входят в круг наших
рассмотрений. Мы будем считать, что работаем
на локальной машине, возможно в локальной (Intranet)
сети, и будем предполагать, что нам такие
опасности не угрожают :).
Текст третьего файла example251.php:
<?php echo `refgo example251+..\\lib\\rphplib`; ?>
Как легко заметить, это есть та самая команда,
которую выполняют в режиме командной строки,
только обрамленная неким окружением, которое
позволяет броузеру рассматривать этот текст как
HTML страницу, обрабатываемую интерпретатором PHP. В
данном случае страница не содержит ничего, кроме
PHP текста. Одиночная левая кавычка имеет особый
смысл при создании строк на PHP, а именно, это
указание на немедленное выполнение кода,
заключённого в одиночные кавычки. Обратный слэш
в этой команде удваивается из-за того, что он
имеет специальный смысл (сохраняет следующий за
ним символ). Команда echo перенаправляет выдачу на
стандартный вывод. В конечном итоге броузер
покажет страничку, которая сгенерировалась
динамически.
Заметим, что если выполнить в режиме командной
строки
> php -q example251.php
, то мы увидим тот же самый результат, который
выдаётся по цепочке Apache -> броузер -> экран.
Естественно, это очень ценное качество PHP
интерпретатора следует использовать для
предварительной отладки страниц с кодом PHP при
создании сайтов, особенно когда ваш хостинг
является удалённым.
Структура примеров в случае Refal-PHP как встроенный скриптовый язык
Исходные файлы в этом случае имеют расширение rphp.
Рассмотрим пример 3.3-2 Описание
рефал-функции вместе с вызовами.
Файл example332.rphp:
<?ref
Func1 {
e.1 = <Print "Func1: " e.1>;
}
<Func1 "This is Refal">
?>
<?php echo "This is PHP\n"; ?>
<?ref <Func1 "This is Refal again"> ?>
После обработки этого файла специальной
командой, вызывающей транслятор refalphp, эта
страница превращается в тройку файлов со
структурой, описанной в предыдущем разделе. А
именно, порождаются:
файл example332.ref:
* Refal run time module for page example332.rphp
$ENTRY Go { = <Mu <Implode <Arg 1>> <Arg 2>> }
Func1 { e.1 = <Print "Func1: " e.1>; }
F_rphp_1 { =
<Func1 "This is Refal">;
}
F_rphp_2 { =
<Func1 "This is Refal again"> ;
}
файл example332.rsl
(скомпилированный вариант) и
файл example332.php:
// PHP run time module for page example332.rphp
<?php include("..\\lib\\rphplib.php"); ?>
<?php
$out = `refgo example332+..\\lib\\rphplib F_rphp_1`;
echo "$out";
?>
<?php echo "This is PHP\n"; ?>
<?php
$out = `refgo example332+..\\lib\\rphplib F_rphp_2`;
echo "$out";
?>
Имеется два варианта
использования транслятора refalphp - статический,
когда модуль с расширением rphp предварительно
обрабатывается командой rphp_c, и
динамический, когда компилятор вызывается
командой rphp_cgo. Во втором случае команда
может выдаваться из страниц PHP, она выполняет те
же действия, что и rphp_c, но затем вызывает
немедленное выполнение модуля с расширением php
(в данном примере example333.php). Описанные
команды можно выполнять и в режиме командной
строки.
Примеры с расширением rphp
в дистрибутиве системы прошли обработку
командой rphp_c. Исходные тексты
полученных при этом модулей на языке Рефал в
принципе не нужны, но оставлены для целей
обучения.
|
|
|
|
|
|
4.5. Рекомендации по отладке
программ |
|
|
|
|
|
Система Refal-5 имеет встроенный трассировщик.
Система PHP такового не имеет, но имеются
разработки, позволяющие в той или иной степени
облегчить отладку (см., например, http://apd.communityconnect.com/ ). В
нашу задачу не входит давать какие-либо
общепринятые рекомендации как следует (или не
следует) отлаживать программы на Refal-5 или PHP. Ниже
описывается специфика системы Refal-PHP, зная
которую, можно существенно упростить отладку, не
прибегая к специальным отладочным средствам.
- Непосредственно после выполнении
Рефал-функции <Php e.1> в директории
<rphp_home>\www\demo\ остаются два файла php.in
и php.out. В первом из них содержится текст
фрагмента на языке PHP, а второй - является
результатом его выполнения.
- При создании библиотеки rphplib.php предусмотрен
режим отладки. Во второй строке файла rphplib.php
стоит (по умолчанию) оператор define("debug", 0),
выключающий отладочные выдачи. Если заменить 0 на
1, то включается печать имен выполняемых функций
и значений аргументов.
Исследуемую программу достаточно временно
остановить в желаемом месте, например, для Refal-5
можно вставить функцию <Card>, что
приведёт к ожиданию ввода с терминала. После чего
можно посмотреть (не выполняя ввод) содержимое
указанных файлов, открыв для этого другую сессию.
В качестве примера давайте исследуем пример 2.4-2 - (Работа
с базой данных - таблица с двумя полями).
Программа написана в расчёте на работу в режиме
командной строки и настроена на ввод с терминала,
который как раз и обеспечивается рефал
функцией <Card>.
Запустив эту программу
приказом
> refgo example242+..\lib\rphplib
, мы можем получить на
экране предупреждающее сообщение, которое
предшествует приглашающей ко вводу строке
программы ("Enter record")
PHP Warning: mysql_connect()
[http://www.php.net/function.mysql-connect]: Can't
connect to MySQL server on 'localhost' (10061) in C:\refalphp\www\lib\rphplib.php on line
55
, которое означает, что мы не запустили сервер
MySQL. Программа, тем не менее, после этого печатает
приглашение ко вводу "Enter
record" , и переходит в режим ожидания ввода.
Пытаться что-то делать дальше в принципе уже
бессмысленно, поскольку мы можем догадаться о
дальнейших ошибочных сообщениях при попытке
занесения в базу данных того, что мы введём.
Останавливаем программу,
набрав CTRL-C, и исправляем нашу ошибку. Выполняем
запуск серверов Apache и MySQL иконкой "Start"
и повторяем команду refgo
example242+..\lib\rphplib.
Получив приглашение для
ввода "Enter record", оставим
временно окно с ожиданием ввода и откроем
другую сессию, в которой любым текстовым
просмотрщиком можно посмотреть содержимое
упоминавшихся файлов. При включённом режиме
отладки в библиотеке rphplib.php мы в этот
момент увидим следующее.
В рабочей директории ws_rphp_tmp
нет никаких новых файлов (возможно там
остались старые от предыдущей работы),
содержимое файла php.in:
<?php include ('..\lib\rphplib.php');
db_open(); db_create_table(table2,"data text,record text"); ?>
содержимое файла php.out:
Function: db_open
HostName=/localhost/
UserName=/test/
Password=//
-------------------
Function: db_create_table
table=/table2/
structure=/data text,record text/
-------------------
Эта выдача достаточно информативно подтверждает
правильность выполнения двух операций - подключения
к серверу MySQL и создания таблицы table2.
Вернемся в окно с ожиданием вводимых данных, и
введём, например, "qu-qu". Программа
проработает, занеся в базу данных строку из двух
полей, и выдаст на экран все записи базы данных,
отфильтровывая только второе поле record
из таблицы table2. В данном случае мы
получим на экране только одну строчку
qu-qu
, поскольку в базе данных образовалась только
одна строка. Программа выходит на останов, и мы
можем посмотреть снова на содержимое рабочей
директории ws_rphp_tmp и файлов php.in
и php.out.
Файл php.in:
<?php include ('..\lib\rphplib.php');
db_read_field (table2,record, "\$all_base"); ?>
Файл php.out:
Function: db_read_field
table=/table2/
field=/record/
all_base=/$all_base/
-------------------
На этот раз в директории ws_rphp_tmp появились
два файла $all_base и $record .
Файл $all_base: qu-qu
Файл $record: "Wed Dec 04
19:36:54 2002","22222"
Если повторять запуск программы командой refgo
example242+..\lib\rphplib, то в базу данных будут
добавлятся новые строки, и программа будет
печатать удлиняющийся столбик из поля record.
Мы надеемся, что столь (возможно излишне)
подробное описание поможет облегчить процесс
отладки программ в системе Refal-PHP. |
|
|
|
|
|
4.6. Некоторые
"мелочи" |
|
|
|
|
|
Мелочей в программировании, как известно, не
бывает. Однако, по ряду причин, в основном
тексте руководства не хотелось заострять
внимания на тонкостях технического характера,
которые, тем не менее, важно особо отметить, чтобы
они не потерялись. Мы выбрали пока два момента.
Возможно, в дальнейшем этот раздел будет
пополняться новыми замечаниями.
- О кавычках в языке Рефал-5. В последней
версии системы Рефал-5 (с новым синтаксисом)
одинарные кавычки и двойные - не равнозначны. А
именно, двойные кавычки обладают, если можно так
выразиться, "замораживающим" эффектом. Всё,
что в них заключено, после Рефал-компиляции
превращается в неделимый символ. По этой причине,
если вы обратили внимание, в разделе (2.4),
описывающем интерфейсные операции с базой
данных, подчёркивалось, что строка, задающая
структуру полей, должна быть заключена в
одинарные кавычки. В противном случае дальнейшая
посимвольная обработка этой строки при обменах
между системами Refal и PHP будет невозможна. В
двойные кавычки заключайте только то, что не
будет подвергаться дальнейшей обработке, и там,
где не удаётся обойтись только одной парой
кавычек.
- О печати в формате HTML и терминальной выдаче.
В приведенных в данном руководстве примерах
преследовалась цель совместить (для простоты)
два режима работы - режима командной строки (в ДОС
сессии) и режима работы через WWW (по цепочке Apache
-> броузер -> экран). По этой причине в части
вывода информации не везде получился одинаковый
формат выдачи. В тех местах, где в руководстве
приведена выдача информации, может быть разница.
А именно, вместо печати в столбик, когда примеры
выполняются в режиме командной строки, всё
выдаётся в виде одной сплошной строки при
просмотре по технологии WWW. И наоборот, некоторые
примеры при выполнении в режиме командной строки
будут выдавать, кроме самих данных, ещё и HTML
приказы. Прежде всего это относится к символу
новой строки. Символа "\n" достаточно для
перехода к новой строке только при терминальной
выдаче, для броузера же нужно наличие <br>.
В составляемых вами программах необходимо
специально учитывать специфику вывода в формате
HTML.
|
|
|
|
|
|
4.7. Информация для системных
программистов |
|
|
|
|
|
Данный раздел носит вспомогательный характер
и не нужен, если у вас не было проблем с
установкой и запуском Refal-PHP. В противном случае,
содержащаяся здесь информация может помочь в
решении возникших проблем, если вы обратитесь за
помощью к тем, кто имеет опыт установки систем PHP,
MySQL, Apache и работы с ними. К сожалению, сложно (и
вряд ли целесообразно) написать полностью
автоматическую процедуру установки
расширенного варианта системы Refal-PHP, по причине
большого разнообразия версий и конфигураций
для Apache и MySQL.
Процедура установки системы Refal-PHP достаточно
проста. Её идея состоит в копировании в
директорию <rphp_home> ранее установленных систем
PHP, MySQL, Apache и собственно самой системы Refal-PHP
(скрипт install.bat). Затем производится
коррекция конфигурационного файла httpd.conf
для Apache и открытие базы данных "refal"
для MySQL (скрипт tuning.bat).
Это сделано для того, чтобы не нарушать работы
систем PHP+MySQL+Apache, которые, возможно, уже
установлены ранее. Конечно, можно не заниматься
таким дублированием и встроить Refal-PHP в имеющуюся
конфигурацию в качестве дополнения, если вы
имеете соответствующий опыт. В этом случае
следует скорректировать htppd.conf, если
возникнет такая необходимость, и создать базу
"refal" в MySQL с помощью, например,
phpMyAdmin.
В заключение необходимо скорректировать файл
<rphp_home>\www\demo\php.bat, который зависит от
места расположения php.exe.
Предполагается, что Apache установлен с
возможностью вызова PHP в режиме CGI. В противном
случае (только модуль PHP) система Refal-PHP не сможет
работать.После этого можно запускать сервер Apache
и действовать в соответствии с пунктом 4.4.Работа с
системой Refal-PHP
В заключение несколько слов об эффективности
реализации Refal-PHP. Нынешняя версия, конечно, может
вызвать нарекания по поводу возможной
неэффективности работы системы, особенно
заметной на платформах Windows-95 из-за неэффективной
реализации вызова интерпретатора php.exe
(через Рефал-функцию System). Однако автор
не ставил перед собой задачу повышения
эффективности в число первоочередных. Главной
целью была отработка языкового интерфейса при
встраивании Рефала в HTML. Тем более, что резерв
повышения эффективности известен - это написание
модуля для Apache сервера, подобно тому, как сейчас
существует модульная реализация PHP, более
эффективная, чем PHP для CGI.
|
|
|
|
|
|
ПРИЛОЖЕНИЕ
А |
|
|
|
|
|
А.1. Демонстрационные примеры |
|
|
|
|
|
Пример 1.1-1 "Hello
world!"
$ENTRY Go { = <Print "Hello world!\n">;
} |
Печатает в результате своей работы
традиционную фразу "Hello world!" с последующим
переводом строки.
Пример 1.1-2 Палиндром
$ENTRY Go { = <Print <Pal 'revolver'>>; } Pal {
= True;
s.1 = True;
s.1 e.2 s.1 = <Pal e.2>;
e.1 = False;
} |
Программа печатает в качестве результата
анализа поданной строки 'revolver' значение False.
Пример
1.2-1 "Hello world!"
<?php echo “Hello world!\n";
?> |
Печать “Hello world!” как результат работы
вышеуказанной PHP программы можно увидеть и при
работе в режиме командной строки без сервера и
броузера, если выполнить команду
> php -q world.php
Обычно же этот код отрабатывается на
серверной стороне, а броузер (клиент) показывает
фразу "Hello world!" в своём окне.
Пример 1.2-2 Интеграция
с HTML
<html>
<head> <title> Example </title> </head>
<body>
<?php
echo "Hello world!\n";
?>
</body>
</html>
|
Пример демонстрирует, каким
образом текст на языке PHP встраивается в HTML
страницы. Для этого служит пара тэгов <?php
и ?> , обрамляющих текст на этом
языке.
Пример 2.1-1 "Hello
world!"
$ENTRY Go { = <Print <Php 'echo "Hello
world!\n";' >>;
} |
Простейший пример применения интерфейсной
рефал-функции <Php...> .
Рефал-программа напечатает результат работы
PHP-программы.
Пример 2.2-1 Два
вызова PHP
$ENTRY Go { = <Php '$var = 1;'>
<Prout "Second call for PHP ">
<Prout '$var= ' <Php '$var = $var + 1; echo $var;' >>;
} |
В результате, вместо ожидаемого значения 2,
будет напечатано
- Second call for PHP
- $var = 1
-
- поскольку факт присвоение единицы при первом
вызове функции “Php” будет забыт при втором
вызове “Php”. Единица будет добавлена к
неприсвоенному (пустому) начальному значению
переменной $var.
Ситуацию можно исправить,
воспользовавшись предложенными функциями
обмена.
Пример 2.2-2 Буферный обмен
$ENTRY Go { = <Php '$var = 1; write_var("\\$var",
$var );'>
<Print "Second call for PHP ">
<Print "$var= "
<Php '$var=read_var("\\$var"); $var = $var + 1;
echo $var;'>
>;
- }
|
Теперь будет напечатано
Second call for PHP
$var = 2
Пример 2.4-1 Работа с базой данных -
простейший пример
$ENTRY Go { = <Db_create_table ("table1") 'data
text'>
<Db_write '"' <Time>
'"'>
<Db_print_all>
} |
Первая функция создает таблицу с именем “table1”
c одним текстовым полем – data, затем эта таблица
фиксируется как текущая.
Следующая функция (Db_write) сначала ждет
исполнения внутреннего вызова - функции <Time>,
возвращающей в поле зрения строку символов -
текущий момент времени, а затем добавляет эту
запись в базу данных. Иными словами добавляется
новая строка в таблицу “table1”.
Наконец, последняя строка
программы извлекает из базы данных и выдает на
печать все записи.
Пример 2.5-1 Машинная арифметика
$ENTRY Go { = <Print <Evalf
'sin(0.235)+cos(1/3)'>>
} |
В результате напечатается:
1.1777999318272
Пример 3.1-1 "Hello
world!" - файл hello.rphp
<?ref <Print "Hello world!\n">;
?> |
Если в режиме командной строки выполнить
команду
> refalphp hello.rphp
, то будет напечатано то, что ожидается от этого
примера - "Hello World!" с переводом
строки.
Пример 3.3-1 Вызов
рефал-функций.
<?php echo "This is PHP\n"; ?> This is HTML
<?ref <Print "This is Refal"> ?>
<?php echo "This is PHP again"; ?> |
В результате будет выдано
This is PHP
This is HTML
This is Refal
This is PHP again
В данном примере печать фразы "This is Refal"
обеспечивается рефал-вкраплением одиночного
вызова функции <Print ...>.
Пример 3.3-2 Описание
рефал-функции вместе с вызовами.
<?ref
Func1 {
e.1 = <Print "Func1: " e.1>;
}
<Func1 "This is Refal">
?> <?php echo "This is PHP\n"; ?>
<?ref <Func1 "This is Refal again"> ?> |
В результате будет выдано
Func1: This is Refal
This is PHP
Func1: This is Refal again
Пример 3.4-1 Доступ
к переменным PHP
<?php $var = 'string_value';
write_var ('\$var', $var);
?>
<?ref
<Print '$var = ' <Read_var '$var'>>
?> |
В результате будет выдано
$var = string_value
|
|
|
|
|
|
А.2.
Библиотеки функций Refal-PHP |
|
|
|
|
|
Ниже приведен
список функций, которые подробно разбирались в
данном руководстве, в виде двух библиотек, для
систем Refal и PHP соответственно.
Библиотека RPHPLIB.REF
<Write_var
'$var=value'>
Записать в буфер обмена значение value
для переменной $var языка PHP.
<Read_var
'$var'>
Прочитать из буфера обмена
значение переменной $var языка PHP.
<Db_create_table (e.table) e.structure>
Создать таблицу с именем e.table со
структурой полей, определяемых e.structure.
- <Db_select_table e.table>
-
- Выбрать для работы таблицу e.table.
-
- <Db_write e.record>
-
- Добавить строку e.record в таблицу.
<Db_read_field
e.field>
Читать в поле зрения все строки
таблицы, выбирая только заданное поле e.field.
<Db_read_all>
Читать в поле зрения все строки
таблицы (полностью, со всеми полями).
<Db_print_field
e.field>
Выдать на печать все строки
таблицы, выбирая только заданное поле e.field.
<Db_print_all>
Выдать на печать все строки
таблицы (полностью, со всеми полями).
<Evalf
e.expression>
Вычислить числовое значение
выражения e.expression в синтаксисе PHP.
Библиотека RPHPLIB.PHP
В состав этой библиотеки входит больше функций,
чем разобрано в примерах руководства. Эти
"дополнительные" функции являются
служебными, они используются в Рефал-библиотеке rphplib.ref
через функцию <Php ...> для
построения тех "высокоуровневых"
Рефал-функций, которые были подробно описаны
ранее. В обычных случаях знакомство с ними
необязательно.
-
- write_var ($var, $value)
-
- Записать в буфер обмена под
именем $var значение $value.
-
- read_var ($var)
-
- Прочитать из буфера обмена значение переменной $var.
-
- db_open ()
-
- Открыть соединение с базой
данных.
-
- db_close ()
-
- Закрыть соединение с базой
данных.
-
- db_create_table ($table, $structure)
-
- Создать таблицу $table со
структурой полей $structure.
-
- db_write ($table, $fields, $values)
-
- Записать в таблицу $table
в поля $fields значение $values.
-
- db_read_field ($table, $field, $all_base)
-
- Прочесть в таблице $table
все строки, выдавая только заданное поле $field,
в переменную $all_base.
-
- db_read_all ($table, $all_base)
-
- Прочесть все строки таблицы $table
в переменную $all_base.
|
|
|
|
|
|
|
|
|
А.3. Лицензия
|
|
|
|
|
|
Копирайт © 2002 Леонид Белоус
Все права сохранены.Разрешаются дальнейшие
распространение и использование, как в исходном,
так и в двоичном видах, с модификацией или без
неё, при соблюдении следующих условий:
1. Дальнейшие распространения исходного кода
должны воспроизводить предупреждение из
предыдущего копирайта, указанный перечень
условий и приведенный ниже отказ от обязательств
и гарантий.
2. Дальнейшие распространения в двоичном виде
должны воспроизводить предупреждение из
предыдущего копирайта, указанный перечень
условий и последующий отказ в документации и/или
в других материалах, предусматриваемых при
дистрибутиве.
3. Имя автора не может быть использовано при
рекламировании либо при продвижении продуктов,
полученных с помощью указанного программного
обеспечения, без специального предварительного
письменного на то разрешения.
ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
ПОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ОНО ЕСТЬ'' БЕЗ ЛЮБЫХ
ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ВКЛЮЧАЯ, НО
НЕ ОГРАНИЧИВАЯ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ
ПРИБЫЛЬНОСТИ И ПРИМЕНИМОСТИ СО СПЕЦИАЛЬНОЙ
ЦЕЛЬЮ НЕ ГАРАНТИРОВАНЫ.
НИ В КОЕМ СЛУЧАЕ АВТОР НЕ БУДЕТ НЕСТИ
ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ,
СЛУЧАЙНЫЕ, НАМЕРЕННЫЕ, ОБРАЗЦОВЫЕ ЛИБО
ПРОИСТЕКШИЕ УБЫТКИ (ВКЛЮЧАЯ, НО НЕ ИСКЛЮЧАЯ,
ПОСТАВКИ СУРРОГАТНЫХ ТОВАРОВ ИЛИ УСЛУГ; ПОТЕРЮ
ПРИМЕНИМОСТИ,
ДАННЫХ, ИЛИ ПРИБЫЛЕЙ; ИЛИ НАРУШЕНИЕ БИЗНЕСА) И ВСЕ
ЖЕ ОСНОВАННЫЕ НА ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ,
БУДЬ ТО КОНТРАКТ, СТРОГАЯ ОТВЕТСТВЕННОСТЬ, ИЛИ
ГРАЖДАНСКО-ПРАВОВОЙ ДЕЛИКТ
(ВКЛЮЧАЯ ХАЛАТНОСТЬ ИЛИ ЧТО-ЛИБО ЕЩЕ) ВОЗНИКАЮЩЕЕ
ПРИ ЛЮБОМ СЛУЧАЕ ЗА ПРЕДЕЛАМИ ИСПОЛЬЗОВАНИЯ
ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ В СЛУЧАЕ
ИЗВЕЩЕНИЯ О ВОЗМОЖНОСТИ ТАКОГО УЩЕРБА.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|