Mailsend
send. Отправка сообщения по электронной почте | |
^mail:send[сообщение]
Метод отправляет сообщение на заданный адрес электронной почты. Можно указать несколько адресов через запятую.
Пример:
^mail:send[
$.from[Вася <vasya@hotmail.ru>]
$.to[Петя <petya@hotmail.ru>]
$.subject[как дела]
$.text[Как у тебя дела? У меня - изумительно!]
]
В результате будет отправлено сообщение для petya@hotmail.ru с содержимым "Как у тебя дела? У меня - изумительно!".
сообщение - хеш, в котором могут быть заданы такие ключи:
· | поле_заголовка |
· | text |
· | html |
· | file |
· | charset |
· | options [3.1.2]
|
Внимание: рекомендуется в поле заголовка errors-to задавать адрес, на который может придти сообщение об ошибке доставки письма. По-умолчанию «postmaster».
charset - если задан этот ключ, то заголовок и текстовые блоки сообщения будут перекодированы в указанную кодировку. По умолчанию сообщение отправляется в кодировке, заданной в $request:charset (т.е. не перекодируется).
Пример:
$.charset[koi8-r]
options - эти опции будут переданы в командную строку программе sendmail (только под UNIX).
Также можно задать все поля заголовка сообщения, передав их значение в таком виде (короткая форма):
$.поле_заголовка[строка]
или с параметрами (полная форма):
$.поле_заголовка[
$.value[строка]
$.параметр[строка]
]
Примеры:
$.from[Вася <vasya@hotmail.ru>]
$.to[Петя <petya@hotmail.ru>]
$.subject[Как у тебя дела? У меня - изумительно!]
$.x-mailer[Parser 3]
Кроме заголовка можно передать один или оба текстовых блока: text, html. А также любое количество блоков file и message (см.
ниже).
Если будет передано оба текстовых блока, будет сформирована секция MULTIPART/ALTERNATIVE, при прочтении полученного сообщения современные почтовые клиенты покажут HTML, а устаревшие - простой текст.
Короткая форма:
$.text[строка]
Полная форма…
$.text[
$.value[строка]
$.поле_заголовка[значение]
]
…где value - значение тестового блока, и можно задать все поля заголовка сообщения, передав их как и в хеше сообщение (см. выше).
Внимание: можно не передавать заголовок content-type, он будет сформирован автоматически. Этот заголовок не влияет на перекодирование, а влияет только на ту кодировку, в которой почтовый клиент будет отображать сообщение.
Отправка HTML. Короткая форма:
$.html{строка}
Полная форма:
$.html[
$.value{строка}
$.поле_заголовка[значение]
]
Фигурные скобки нужны для переключения вида преобразования по умолчанию на HTML.
Вложение файла. Короткая форма:
$.file[файл]
Полная форма:
$.file[
$.value[файл]
$.name[имя_файла]
]
Файл - объект класса file, который будет прикреплен к сообщению. MIME-тип данных (content-type заголовок части) определяется по таблице MIME-TYPES (см. Конфигурационный метод).
Имя_файла - имя, под которым файл будет передан.
Файл будет передан в uuencode форме.
Вложение сообщения:
$.message[сообщение]
Формат сообщения такой же, как у параметра всего метода.
Вложений может быть несколько, для чего после имени следует добавить целое число. Пример:
$.file
$.file2
$.message
$.message2
Пример с альтернативными блоками и вложениями:
^mail:send[
$.from[Вася <vasya@hotmail.ru>]
$.to[Петя <petya@hotmail.ru>]
$.subject[как дела]
$.text[Как у тебя дела? У меня изумительно!]
$.html{Как у тебя дела? У меня <b>изумительно</b>!}
$.file[^file::load[binary;perfect_life1.jpg]]
$.file2[
$.value[^file::load[binary;perfect_life2.jpg]]
$.name[изумительная_жизнь2.jpg]
]
]
В результате будет отослано сообщение для petya@hotmail.ru с содержимым «Как у тебя дела? У меня - изумительно!» в простом тексте и HTML. К сообщению будут приложены две подтверждающие фотографии, на которых…
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 01.04.2004 |
Mainclass
Класс MAIN, обработка запроса | |
Parser обрабатывает запрошенный документ следующим образом:
1.
Считываются, компилируются и инициализируются Конфигурационный файл; затем все файлы с именем auto.p, поиск которых производится начиная от корня веб-пространства, и ниже по структуре каталогов, вплоть до каталога с запрошенным документом; наконец, сам запрошенный документ.
Все вместе они составляют определение класса MAIN.
Инициализация заключается в вызове метода auto каждого загруженного файла. Если определение этого метода содержит параметр, при вызове в нем будет передано имя загруженного файла.
Примечание: результат работы метода посетителю не выводится.
2.
Затем вызывается без параметров метод main класса MAIN.
Т.е. в любом из перечисленных файлов может быть определен метод main, и будет вызван тот, который был определен последним - скажем, определение этого метода в запрошенном документе перекрывает все остальные возможные определения, и будет вызван именно он.
Результат работы этого метода будет передан пользователю, если не был определен метод postprocess.
Если в файле не определен ни один метод, то все его тело считается определением метода main.
Примечание: задание $response:body[нестандартного ответа] переопределяет текст, получаемый пользователем.
3.
Если в классе MAIN определен метод postprocess, то результат работы метода main передается единственным параметром этому методу, и пользователь получит уже его результат работы.
Таким образом вы получаете возможность «дополнительной полировки» результата работы вашего кода.
Простой пример
Добавление такого определения, скажем, в файл auto.p в корне вашего веб-пространства…
@postprocess[body]
^body.match[шило][g]{мыло}
…приведет к замене одних слов на другие в результатах обработки всех страниц.
Matdegreesetc
degrees, radians. Преобразования градусы-радианы | |
Методы выполняют преобразования из градусов в радианы и обратно.
^math:degrees(число радиан) | - возвращает число градусов, соответствующее заданному числу радиан | ||
^math:radians(число градусов) | - возвращает число радиан, соответствующее заданному числу градусов |
Пример
^math:degrees($math:PI/2) | - получаем 90 (градусов) | ||
^math:radians(180) | - получаем p |
Mathabssign
abs, sign. Операции со знаком | |
Выполняют операции со знаком числа.
^math:abs(число) | - возвращает абсолютную величину числа (модуль) | ||
^math:sign(число) | - возвращает 1, если число положительное, -1, если число отрицательное и 0, если число равно 0 |
Пример
^math:abs(-15.506) | - получаем 15.506 | ||
^math:sign(-15.506) | - получаем -1 |
Mathclass
Класс math | |
Класс math не имеет конструкторов для создания объектов, он обладает только статическими методами и предназначен для вычисления математических выражений. При работе с этим классом необходимо учитывать ограничения на разрядность для класса double.
Mathcrypt
crypt. Хеширование паролей | |
^math:crypt[password;salt]
Хеширует password с учетом salt.
Параметры:
· | password - исходная строка; |
· | salt - строка, определяющая алгоритм хеширования и вносящая элемент случайности в результат хеширования, состоит из начала и тела. Начало определяет алгоритм хеширования, тело вносит элемент случайности. Если тело не будет указано, Parser сформирует случайное. |
Неразумно хранить пароли пользователей, просто записывая их на диск или в базу данных - ведь если предположить, что злоумышленник украдет файл или таблицу с паролями, он легко сможет ими воспользоваться. Поэтому принято хранить не пароли, а их хеши - результат надежного однозначного необратимого преобразования строки пароля. Для проверки введенного пароля к нему применяют то же преобразование, передавая в качестве salt сохраненный хеш, а результат сверяют с сохраненным.
Вносить элемент случайности необходимо, поскольку иначе потенциальный злоумышленник может заранее сформировать таблицу хешей многих частоиспользуемых паролей. Вторая причина: элемент случайности вносится на начальном этапе алгоритма хеширования, что существенно осложняет подбор пароля даже при использовании специальных аппаратных ускорителей.
Внимание: обязательно задавайте случайное тело salt, или позвольте Parser сделать это за вас, попросту не указывая тело salt, указывая только начало salt.
Таблица доступных алгоритмов:
Алгоритм | Описание | Начало salt | Тело "salt" | ||||
MD5 | встроен в Parser, доступен на всех платформах | $apr1$ | до 8 случайных букв (в любом регистре) или цифр | ||||
MD5 | если поддерживается операционной системой (UNIX) | $1$ | до 8 случайных букв (в любом регистре) или цифр | ||||
DES | если поддерживается операционной системой (UNIX) | (нет) | 2 случайных буквы (в любом регистре) или цифры | ||||
другие | какие поддерживаются операционной системой (UNIX) | читайте документацию на вашу операционную систему, функция crypt | читайте документацию на вашу операционную систему, функция crypt |
br>
Внимание: в Parser для использования в тексте символа '$' его необходимо предварить символом '^'.
Примечание: Веб-сервер Apache допускает в файлах с паролями (.htpasswd) использовать хеши сформированные по любому из алгоритмов, представленных в таблице, включая алгоритм, встроенный в Parser.
Пример создания .htpasswd файла
@main[]
$users[^table::create{name password
alice xxxxxx
bob yyyyyy
}]
$htpasswd[^table::create[nameless]{}]
^users.menu{
^htpasswd.append{$users.name:^math:crypt[$users.password;^$apr1^$]}
}
^htpasswd.save[nameless;.htpasswd-parser-test]
Пример проверки пароля
$right[123]
$from_user[123]
$crypted[^math:crypt[$right;^$apr1^$]]
#обратите внимание на то, что $crypted при каждом обращении разный
$crypted<br>
^if(^math:crypt[$from_user;$crypted] eq $crypted){
Казнить нельзя, помиловать
}{
Казнить, нельзя помиловать
}
Подробная информация о MD5 доступна здесь: http://www.ietf.org/rfc/rfc1321.txt
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 12.02.2004 |
Mathexplog
exp, log. Логарифмические функции | |
^math:exp(число) | - экспонента по основанию e | ||
^math:log(число) | - натуральный логарифм |
Методы вычисляют значения логарифмических функций от заданного числа
Примечание (если вы совсем забыли родную школу):
логарифм по произвольному основанию base вычисляется как log(число)/log(base).
в шестнадцатеричном виде без разделителей,
md5. MD5-отпечаток строки [3.0.8] |
Из переданной строки получает «отпечаток» размером 16 байт.
Выдает его представление в виде строки - байты представлены в шестнадцатеричном виде без разделителей, в нижнем регистре.
Считается, что практически невозможно
· | создать две строки, имеющие одинаковый «отпечаток»; |
· | восстановить исходную строку по ее «отпечатку». |
В качестве имени cache-файла возьмем «отпечаток» строки $request:uri, это обеспечит взаимно-однозначное соответствие имени строке запроса, а также избавит нас от необходимости укорачивать строку запроса и очищать ее от спецсимволов.
^cache[$cache_directory/^math:md5[$request:uri]]($cache_time){
…
}
Подробная информация о MD5 доступна здесь: http://www.ietf.org/rfc/rfc1321.txt
Mathpow
pow. Возведение числа в степень | |
^math:pow(число;степень)
Возводит число в степень.
Пример
^math:pow(2;10) - получаем 1024 ( 210 =1024 )
Mathrandom
random. Случайное число | |
^math:random(верхняя_граница)
Метод возвращает случайное число, попадающее в интервал от 0 до заданного числа, не включая заданное.
Примечание: на некоторых операционных системах выдает псевдослучайное число.
Пример
^math:random(1000)
Получим случайное число из диапазона от 0 до 999.
Mathroundetc
round, floor, ceiling. Округления | |
^math:round(число) | - округление до ближайшего целого | ||
^math:floor(число) | - округление до целого в меньшую сторону | ||
^math:ceiling(число) | - округление до целого в большую сторону |
Методы возвращают округленное значение заданного числа класса double.
Пример
^math:round(45.50) | - получаем 46 | ||
^math:floor(45.60) | - получаем 45 | ||
^math:ceiling(45.20) | - получаем 46 | ||
^math:round(-4.5) | - получаем -4 | ||
^math:floor(-4.6) | - получаем -5 | ||
^math:ceiling(-4.20) | - получаем -4 |
Mathsinetc
sin, asin, cos, acos, tan, atan. Тригонометрические функции | |
^math:sin(радианы) | - арксинус | ||
^math:asin(число) | - синус | ||
^math:cos(радианы) | - косинус | ||
^math:acos(число) | - аркосинус | ||
^math:tan(радианы) | - тангенс | ||
^math:atan(число) | - арктангенс |
Методы вычисляют значения тригонометрических функций от заданного числа.
Пример
^math:cos(^math:radians(180)) - получаем -1 (cos p = -1).
Mathstats
Статические поля | |
Число Пи
$math:PI - число p
Mathtruncfrac
trunc, frac. Операции с целой/дробной частью числа | |
^math:trunc(число) | - возвращает целую часть числа | ||
^math:frac(число) | - возвращает дробную часть числа |
Пример
^math:trunc(85.506) | - получаем 85 | ||
^math:frac(85.506) | - получаем 0.506 |
uid64. 64-битный уникальный идентификатор [3.0.8] |
Выдает случайную строку вида…
BA39BAB6340BE370
Примечание: на некоторых операционных системах выдает псевдослучайную строку.
См. ^math:uuid[].
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 12.02.2004 |
Mathuuid
uuid. Универсальный уникальный идентификатор [3.0.8] | |
^math:uuid[]
Выдает случайную строку вида…
22C0983C-E26E-4169-BD07-77ECE9405BA5
Примечание: на некоторых операционных системах выдает псевдослучайную строку.
Удобно использовать, когда трудно обеспечить или вообще нецелесообразно использовать сквозную нумерацию объектов.
Например, при распределенных вычислениях.
UUID также известен как GUID.
Пример
В разных филиалах компании собираются заказы, которые периодически отправляются в центральный офис. Чтобы обеспечить уникальность идентификатора заказа используем UUID.
# в разных филиалах происходит наполнение таблицы orders и order_details
# создаем уникальный идентификатор
$order_uuid[^math:uuid[]]
# добавляем запись о заказе
^void:sql{
insert into orders
(order_uuid, date_ordered, total)
values
('$order_uuid', '$date_ordered', $total)
}
#цикл по заказанным продуктам вокруг добавления записи о продукте
^void:sql{
insert into order_details
(order_uuid, item_id, price)
values
('$order_uuid', $item_id, $price)
}
# с какой-то периодичностью выбирается часть таблицы orders (и order_details)
# отправляется (^mail:send[…]) в центральный офис,
# где части таблиц попадают в общие таблицы orders и order_details
# БЕЗ проблем с повторяющимся order_id
Примечание: Parser создает UUID основываясь на случайных числах, а не времени. Параметры:
· | variant = DCE; |
· | version = DCE Security version, with embedded POSIX UIDs. |
xxxxxxxx-xxxx-4xxx-{8,9,A,B}xxx-xxxxxxxxxxxx
Подробная информация о UUID доступна здесь: http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
Matsqrt
sqrt. Квадратный корень числа | |
^math:sqrt(число)
Вычисляет квадратный корень числа.
Пример
^math:sqrt(16) - получаем 4
Примечание [если вы совсем забыли родную школу]:
корень n-ной степени вычисляется как возведение в степень 1/n.
Memoryclass
Класс memory [3.1] | |
Класс предназначен для работы с памятью Parser.
Его использование поможет вам экономить память в ваших скриптах.
Для любознательных: в Parser используется известный и хорошо зарекомендовавший себя консервативный сборщик мусора Boehm-Demers-Weiser, см. http://www.hpl.hp.com/personal/Hans_Boehm/gc/.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 16.02.2004 |
Memorycompact
compact. Сборка мусора [3.1] | |
^memory:compact[]
Собирает так называемый «мусор» в памяти, освобождая ее для повторного использования вашим кодом.
Мусором считается память, более не используемая вашим кодом, т.е. та, на которую в вашем коде нет ссылок.
Например,
$table[^table::sql{запрос}]
$table[]
# освободит память, занимаемую результатом выполнения SQL-запроса
^memory:compact[]
Parser не собирает мусор автоматически, полагаясь в данном вопросе на кодера: поставьте вызов compact в той точке (точках), где ожидаете наибольшей выгоды, например, перед XSL преобразованием.
$status:memory поможет вам в отладке и поиске мест, наиболее выгодных для сборки мусора.
Важно: необходимо как можно более интенсивно использовать локальные переменные, и обнулить глобальные, которые вам не будут нужны для дальнейшей работы кода. Это поможет compact освободить больше.
Важно: не гарантируется, что будет освобождена абсолютно вся неиспользуемая память.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 03.07.2003 |
Numlit
Числовые литералы | |
Запись числовых литералов допускается в следующем виде:
1
-8
(целое)
1.23
-4.56
(дробное)
0xA8 равно 168
(форма шестнадцатиричной записи)
Примечание: регистр букв не важен.
Obj
Объект класса | |
Создание объекта
^класс::конструктор[параметры]
Конструктор создает объект класса, наделяя его полями и методами класса. Параметры конструкторов подробно описаны в соответствующем разделе.
Примечание: результат работы конструктора - созданный объект, обычный результат работы метода игнорируется (никуда не попадает).
Вызов метода
^объект.метод[параметры]
Вызов метода класса, к которому принадлежит объект. Параметры конструкторов подробно описаны в соответствующем разделе.
Если не указан объект, то конструкция является вызовом метода текущего класса (если у класса нет метода с таким именем, будет вызван метод базового класса) или оператора. При совпадении имен вызывается оператор.
Методы бывают статические и динамические.
Динамический метод - код выполняется в контексте объекта (экземпляра класса).
Статический метод - код выполняется в контексте самого класса, то есть метод работает не с конкретным объектом класса, а со всем классом (например, классы MAIN, math, mail)
Значение поля объекта
$объект.поле
Получение значения поля объекта.
Системное поле объекта: CLASS
$объект.CLASS - хранит ссылку на класс объекта.
Это необходимо при задании контекста компиляции кода (см. «process. Компиляция и исполнение строки».
Opcache
cache. Сохранение результатов работы кода | |
^cache[файл](число секунд){код}
^cache[файл](число секунд){код}{обработчик проблем} [3.1.2]
^cache[файл][дата устаревания]{код}
^cache[файл][дата устаревания]{код}{обработчик проблем} [3.1.2]
Оператор сохраняет строку, которая получится в результате работы кода. При последующих вызовах обычно происходит считывание ранее сохраненного результата, вместо повторного вычисления, что сильно экономит время обработки запроса и снижает нагрузку на ваши сервера.
Крайне рекомендуется подключать модули (^use[…]) изнутри кода оператора cache, а не делать это статически (@USE).
По-возможности, работайте с базой данных (^connect[…]) также внутри кода оператора cache - вы существенно снизите нагрузку на ваш SQL-сервер и повысите производительность ваших сайтов.
Файл - имя файла-кеша. Если такой файл существует и не устарел, то его содержимое выдается клиенту, если не существует - выполняется код, и результат сохраняется в файл с указанным именем.
Число секунд - время хранения результата работы кода в секундах. Если это число равно нулю, то результат не сохраняется, а файл с предыдущем сохраненным результатом уничтожается.
Дата устаревания - время, до которого хранится результата работы кода. Если она в прошлом, то результат не сохраняется, а файл с предыдущим сохраненным результатом уничтожается.
Код - код, результат которого будет сохранен.
Обработчик проблем - здесь можно обработать проблему, если она возникнет в коде. В этом отношении оператор похож на try, см. раздел «Обработка ошибок». В отличие от try, можно задать $exception.handled[cache] - это дает указание Parser обработать ошибку особенным образом: достать из файла ранее сохраненный результат работы кода, проигнорировав тот факт, что этот результат устарел.
Внутри кода допустимы команды, изменяющие время хранения результата работы кода:
^cache(число секунд)
^cache[дата устаревания]
Берется минимальное время хранения кода.
Пример
^cache[/data/cache/test1](5){
Нажимайте reload, меняется каждые 5 секунд: ^math:random(100)
}
Изменение времени хранения
^cache[/data/cache/test2](5){
по ходу работы вы выяснили,
что страницу сохранять не нужно: ^cache(0)
}
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 01.04.2004 |
Opconnect
connect. Подключение к базе данных | |
^connect[строка подключения]{код}
Оператор connect осуществляет подключение к серверу баз. Код оператора обрабатывается Parser, работая с базой данных в рамках установленного подключения.
Parser (в виде модуля к Apache или IIS) кеширует соединения с SQL-серверами, и повторный запрос на соединение с той же строкой подключения не производится, а соединение берется из кеша, если оно еще действительно.
Вариант CGI также кеширует соединение, но только на один запрос, поэтому явно допустимы конструкции вида:
^connect[строка подключения]{…}
^connect[строка подключения]{…}
При этом не будет двух соединений, и это полезно, когда, скажем, изредка соединение нужно, и заранее неизвестно нужно или нет - заранее его можно не делать, а делать визуально многократно, зная, что оно фактически не разрывается.
Передать SQL-запрос БД может один из следующих методов или конструкторов языка Parser:
table::sql
string:sql
void:sql
hash::sql
int:sql
double:sql
Замечание: для работы оператора connect необходимо наличие настроенного драйвера баз данных (см. раздел Настройка).
Форматы строки соединения для поддерживаемых серверов баз данных описаны в приложении.
Пример
^connect[mysql://admin:pwd@localhost/p3test]{
$news[^table::sql{select * from news}]
}
Opdef
def. Проверка определенности объекта | |
Оператор возвращает булевое значение (истина/ложь) и отвечает на вопрос «определен ли объект?» Проверяемым объектом может любой объект Parser: таблица, строка, файл, объект пользовательского класса и т.д.
def объект
не определенными (не def) считаются пустая строка, пустая таблица, пустой хеш и код.
Пример
$str[Это определенная строка]
^if(def $str){
Строка определена
}{
Строка не определена
}
Важно: для проверки «содержит ли переменная код» и «определен ли метод» используйте оператор is, а не def. Таким образом. ^if(def $hash.delete){-}{в hash нет элемента «delete»}.
Opeval
eval. Вычисление математических выражений | |
^eval(математическое выражение)
^eval(математическое выражение)[форматная строка]
Оператор eval вычисляет математическое выражение и позволяет вывести результат в нужном виде, задаваемом форматной строкой (см. Форматные строки).
Пример
^eval(100/6)[%.2f]
вернет: 16.67.
Внимание: настоятельно советуем задавать комментарии к частям сложного математического выражения (см. «Комментарии к частям выражения»).
Opevalcomment
Комментарии к частям выражения | |
Допустимо использование комментариев к частям математического выражения, которые начинаются со знака #, и продолжаются до конца строки исходного файла или до конца выражения.
Пример
^if(
$age>=$MINIMUM_AGE # не слишком молод
&& $age<=$MAXIMUM_AGE # и не слишком стар
){
Годен
}
Внимание: настоятельно советуем задавать комментарии к частям сложного математического выражения. Бывает, что даже вам самим через какое-то время бывает трудно в них разобраться.
Opfor
for. Цикл с заданным числом повторов | |
^for[счетчик](от;до){тело}
^for[счетчик](от;до){тело}[разделитель]
^for[счетчик](от;до){тело}{разделитель}
Оператор for повторяет тело цикла, перебирая значения счетчика от начального значения до конечного. С каждым выполнением тела значение счетчика автоматически увеличивается на 1.
Счетчик - имя переменной, которая является счетчиком цикла
От и до - начальное и конечное значения счетчика, математические выражения, задающие соответственно начало и конец диапазона значений, принимаемых счетчиком. Если конечное значение счетчика меньше начального, тело цикла не выполнится ни разу
Разделитель - код, который выполняется перед каждым непустым не первым телом
Замечание: поскольку имена счетчиков могут повторяться, полезно объявлять их локальными переменными метода, где используется цикл for.
Пример
^for[week](1;4){
<a href="/news/archive.html?week=$week">Новости за неделю №$week</a>
}[<br>]
Пример выводит ссылки на недели с первой по четвертую, после очередной строки ставится тег перевода строки.
Opif
if. Выбор одного варианта из двух | |
^if(логическое выражение){код, если значение логического выражения «истина»}
^if(логическое выражение){
код, если значение логического выражения «истина»
}{
код, если значение логического выражения «ложь»
}
Оператор вычисляет значение логического выражения. Затем, в зависимости от полученного результата, либо выполняется или не выполняется код (первый вариант использования оператора if), либо для исполнения выбирается код, соответствующий полученному значению логического выражения (второй вариант). На код не накладывается никаких ограничений, в том числе внутри него может содержаться еще один или несколько операторов if.
Внимание: настоятельно советуем задавать комментарии к частям сложного логического выражения (см. «Комментарии к частям выражения»).
Opin
in. Проверка, находится ли документ в каталоге | |
in "/каталог/"
Возвращает результат "истина/ложь" в зависимости от того, находится ли текщий документ в указанном каталоге.
Пример
^if(in "/news/"){
Мы в разделе новостей
}{
<a href="/news/">Новости</a>
}
Opis
is. Проверка типа | |
объект is тип
Возвращает результат "истина/ложь" в зависимости от того, относится ли левый операнд к заданному типу.
Полезно использовать этот оператор в случае, если переменная может содержать единственное значение или набор значений (хеш), а также для проверки определенности методов.
Тип - имя типа, им может быть системное имя (hash, junction, …), или имя пользовательского класса.
Простая проверка типа
@main[]
$date[1999-10-10]
#$date[^date::now[]]
^if($date is string){
^parse[$date]
}{
^print_date[$date.year;$date.month;$date.day]
}
@parse[date_string][date_parts]
$date_parts[^date_string.match[(\d{4})-(\d{2})-(\d{2})][]]
^print_date[$date_parts.1;$date_parts.2;$date_parts.3]
@print_date[year;month;day]
Работаем с датой:<br>
День: $day<br>
Месяц: $month<br>
Год: $year<br>
В этом примере в зависимости от типа переменной $date либо выполняется синтаксический анализ строки, либо методу print_date передаются поля объекта класса date:
Проверка наличия в переменной кода
Т.к. оператор def не считает переменные, содержащие код, определенными, для проверки наличия в переменной кода необходимо использовать is:
$something{^do[]}
^if($something is junction){
# выполнение кода
$something
}
Проверка определенности метода
Значение $имя_метода, это тоже junction, поэтому проверять существование метода необходимо также оператором is, а не def:
@body[]
тело
@main[]
Старт
^if($body is junction){
^body[]
}{
Метод «body» не определен!
}
Финиш
Opprocess
process. Компиляция и исполнение строки | |
^process{строка}
^process[контекст]{строка}
^process[контекст]{строка}[опции] [3.1.2]
Строка будет скомпилирована и выполнена как код на Parser, в указанном контексте, или в текущем контексте.
В качестве контекста можно указать объект или класс.
Удобно использовать, если какие-то части кода или собственные методы необходимо хранить не в файлах .html, которые обрабатываются Parser, а в каких-то других, или базе данных.
Также можно указать ряд опций (хеш):
· | $.main[новое имя для метода main, описанного в коде строки}
|
· | $.file[имя файла, из которого взята данная строка}
|
· | $.lineno(номер строки в файле, откуда взята данная строка. может быть отрицательным)
|
Простые примеры
^process{@extra[]
Здоровья прежде всего…
}
Метод extra будет добавлен к текущему классу, и его можно будет вызывать в дальнейшем.
^process[$engine:CLASS]{@start[]
Мотор…
}
Метод start будет добавлен к пользовательскому классу engine.
$running_man[^man::create[Вася]]
^process[$running_man]{
Имя: $name<br>
}
Код будет выполнен в контексте объекта $running_man, соответственно, может воспользоваться полем name этого объекта, выдаст «Вася».
Оператор include
@include[filename][file]
$file[^file::load[text;$filename]]
^process[$caller.self]{^taint[as-is][$file.text]}[
$.file[$filename]
]
Код загружает указанный файл и выполняет его в контексте вызова include. Опция file позволяет указать имя файла, откуда был загружен код. Если возникнет ошибка, вы увидите это «имя файла».
Сложный пример
Часто удобно поместить компилируемый код в некоторый метод с именем, вычисляющимся по ходу работы:
# это исходный код, обратите внимание, на ^^
$source_code[2*2=^^eval(2*2)]
# по ходу работы выясняется, что необходимо создать метод с именем method1
$method_name[method1]
# компилируем исходный код, помещяем его в новый метод
^process{$source_code}[
$.main[$method_name]
]
…
# далее по коду можно вызывать метод method1
^method1[]
Данный пример будет продолжать работать, даже если в $source_code будет определен ряд методов, поскольку опция main задает новое имя методу main.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 01.04.2004 |
Oprem
rem. Вставка комментария | |
^rem{комментарий}
Весь код, содержащийся внутри оператора, не будет выполнен. Используется для комментирования блоков кода.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 11.04.2002 |
Opsfd
-f и -d. Проверка существования файла и каталога | |
-f имя_файла - проверка существования файла на диске.
-d имя_каталога - проверка существования каталога на диске.
Возвращает результат "истина/ложь" в зависимости от того, существует ли указанный файл или каталог по заданному пути.
Пример
^if(-f "/index.html"){
Главная страница существует
}{
Главная страница не существует
}
Opswitch
switch. Выбор одного варианта из нескольких | |
^switch[строка для сравнения]{
^case[вариант1]{действие для 1}
^case[вариант2]{действие для 2}
^case[вариант3;вариант 4]{действие для 3 или 4}
…
^case[DEFAULT]{вариант по умолчанию}
}
^switch(математическое выражение){
^case(вариант1){действие для 1}
^case(вариант2){действие для 2}
^case(вариант3;вариант 4){действие для 3 или 4}
…
^case[DEFAULT]{вариант по умолчанию}
}
Оператор switch сравнивает строку или результат математического выражения со значениями, перечисленными в case. В случае совпадения выполняется код, соответствующий совпавшему значению. Если совпадений нет, выполняется код, соответствующий значению DEFAULT (пишется только заглавными буквами).
Если код для DEFAULT не определен и нет совпадений со значениями, перечисленными в case, ни один из вариантов кода, присутствующих в операторе switch, выполнен не будет.
Пример
^switch[$color]{
^case[red]{Необходимо остановиться и подумать о вечном…}
^case[yellow]{Настало время собраться и приготовиться!}
^case[green]{Покажи им, кто король дороги!}
^case[DEFAULT]{Вы дальтоник, или это вовсе не светофор.}
}
Opthrow
throw. Сообщение об ошибке | |
^throw[type;source]
^throw[type;source;comment]
Оператор throw сообщает об ошибке типа type, произошедшей по вине source, с комментарием comment.
Эта ошибка может быть перехвачена и обработана при помощи оператора try.
Не перехватывайте ошибки только для их красивого вывода, пусть этим централизованно займется метод unhandled_exception, вызываемый Parser если ни одного обработчика ошибки так и не будет найдено. Кроме прочего, произойдет запись в журнал ошибок веб-сервера, который можно регулярно просматривать на предмет имевших место проблем.
Пример
@method[command]
^switch[$command]{
^case[add]{
добавляем…
}
^case[delete]{
удаляем…
}
^case[DEFAULT]{
^throw[bad.command;$command;Wrong command $command, good are add&delete]
}
}
@main[]
$action[format c:]
^try{
^method[$action]
}{
^if($exception.type eq bad.command){
$exception.handled(1)
Неправильная команда '$exception.source', задана
в файле $exception.file, в $exception.lineno строке.
}
}
Результатом работы примера будет
Неправильная команда 'format c:', задана
в файле c:/parser3tests/www/htdocs/throw.html, в 15 строке.
Обращаем ваше внимание на то, что пользователи вашего сайта не должны увидеть технические подробности в сообщениях об ошибках, тем более содержащие пути к файлам, это некрасиво и ненадежно.
Вывод $exception.file дан в качестве примера и настоятельно не рекомендуется к использованию на промышленных серверах - только для отладки.
Optry
try. Перехват и обработка ошибок | |
^try{код, ошибки которого попадают…}{…в этот обработчик в виде $exception}
Если по ходу работы кода возникла ошибка, создается переменная $exception, и управление передается обработчику.
$exception, это такой hash:
$exception.type | строка, тип ошибки. Определен ряд системных типов, также тип ошибки может быть задан в операторе throw. | ||
$exception.source | строка, источник ошибки (ошибочное имя файла, метода, …) | ||
$exception.file $exception.lineno $exception.colno | файл, содержащий source, номера строки и колонки в нем | ||
$exception.comment | комментарий к ошибке, по английски | ||
$exception.handled | истина или ложь, флаг «обработана ли ошибка» необходимо зажечь этот флаг в обработчике, если вы обработали переданную вам ошибку |
Обработчик обязан сообщить Parser, что данную ошибку он обработал, для чего только для нужных типов ошибок он должен зажечь флаг:
$exception.handled(1)
Если обработчик не зажег этого флага, ошибка считается необработанной, и передается следующему обработчику, если он есть.
Если ошибка так и не будет обработана, если есть, вызывается метод unhandled_exception и ему передается информация об ошибке, стек вызовов, приведших к ошибке, и выдаются результаты его работы. А также производится запись в журнал ошибок веб-сервера.
Пример
^try{
$srcDoc[^xdoc::create{$untrustedXML}]
}{
^if($exception.type eq xml){
$exception.handled(1)
Ошибочный XML,
<pre>$exception.comment</pre>
}
}
Opuntainttaint
untaint, taint. Преобразование данных | |
^untaint{код}
^untaint[вид преобразования]{код}
^taint[текст]
^taint[вид преобразования][текст]
Оператор taint помечает весь переданный ему текст, как нуждающийся в преобразовании заданного вида. Оператор untaint выполняет переданный ему код и помечает, как нуждающиеся в преобразовании, те части результата выполнения кода, которые не являлись частью кода на Parser, а поступили извне, например, из полей формы.
Если вид преобразования не указан, оператор untaint делает преобразование вида as-is, а оператор taint помечает текст как tainted (неопределенно «грязный», без указания вида преобразования).
Само преобразование Parser выполняет позже, при выдаче результата обработки документа пользователю, перед выполнением SQL-запроса или отправкой письма.
Преобразование заключается в замене одних символов на другие в соответствии с внутренними таблицами пребразований. Предусмотрены следующие виды преобразований:
as-is
file-spec
http-header
mail-header
uri
sql
js
xml
html
optimized-as-is
optimized-xml
optimized-html
Выполняемые замены для каждого вида преобразования сведены в таблице ниже.
Важное замечание: «чистый» код также подвергается автоматическому преобразованию. Parser выполняет оптимизацию по «white spaces» (символы пробела, табуляция, перевода строки). Идущие подряд перечисленные символы заменяются только одним, который встречается в коде первым. В общем виде можно представить весь набираемый код следующим образом:
^untaint[optimized-html]{здесь находится код, набранный скриптовальщиком}
Необходимо учитывать это при создании кода! Схема автоматического преобразования Parser - optimized-html.
Пример:
Пример на ^^untaint.<br>
<form>
<input name=field>
<input type=submit>
</form>
$tainted[$form:field]
"Грязные" данные - $tainted<br>
"Чистые" данные - ^untaint{$tainted}
В результате выполнения этого кода поступившие через поля формы данные не будут преобразовываться Parser и выдадутся в том виде, в каком они поступили. В квадратных скобках оператора untaint задается вид выполняемого преобразования. Здесь мы опускаем квадратные скобки в методе untaint и используем параметр по умолчанию [as-is].
Как уже было сказано выше, большую часть работы по преобразованию данных Parser выполняет автоматически. Внешние данные, которые используются в «чистом» коде преобразуются к optimized-html.
Оператор taint также помечает преобразование данных в соответствии с указанной таблицей, но, в отличие от untaint, используется для «чистых» данных, т.е. созданных кодером, либо поступивших извне и уже обработанных untaint. Еще раз обращаем внимание, что преобразование происходит только в момент выдачи данных во внешнюю среду (пользователю, в файл или базу данных). Если не задан вид преобразования, данные останутся "грязными", но никаких замен сделано не будет.
Пример
Пример ^^taint.<br>
$town[Москва]
<a href="town.html?^taint[uri][$town]">$town</a>
В результате данные, хранящиеся в переменной town, будут преобразованы к типу URI. Русские буквы будут заменены на шестнадцатеричные коды символов и представлены в виде %ХХ.
Таблицы преобразований
as-is | изменений в тексте не делается |
file-spec | символы * ? ' " < > | преобразуются в "_XX", где XX - код символа в шестнадцатеричной форме |
uri | символы за исключением цифр, строчных и прописных латинских букв, а также следующих символов: _ - . " преобразуется в %XX где XX - код символа в шестнадцатеричной форме |
http-header | то же, что и URI |
mail-header | если известен charset (если неизвестен, не будут работать up/low case), то фрагмент, начиная с первой буквы с восьмым битом и до конца строки, будет представлен в подобном виде: Subject: Re: parser3: =?koi8-r?Q?=D3=C5=CD=C9=CE=C1=D2?= |
sql | в зависимости от SQL-сервера для Oracle/ODBC меняется ' на '' для PgSQL меняется ' на '' и \ на \\ для MySQL делается средствами самого MySQL |
js | " преобразуется в \" ' преобразуется в \' \ преобразуется в \\ символ конца строки преобразуется в \n символ с кодом 0xFF предваряется \ |
xml | & преобразуется в & > преобразуется в > < преобразуется в < " преобразуется в " ' преобразуется в ' |
html | & преобразуется в & > преобразуется в > < преобразуется в < " преобразуется в " |
optimized-as-is optimized-xml optimized-html | дополнительно к заменам выполняется оптимизация по "white spaces" (символы пробела, табуляция, перевода строки). Идущие подряд перечисленные символы заменяются только одним, который встречается в коде первым |
br>
Ряд taint преобразований Parser делает автоматически, так, имена и пути файлов всегда автоматически file-spec преобразуются, и когда вы пишите…
^file::load[filename]
…Parser выполняет…
^file::load[^taint[file-spec][filename]]
Аналогично, при задании HTTP-заголовков и заголовков писем, происходят http-header и mail-header преобразования соответственно. А при DOM-операциях текстовые параметры всех методов автоматически xml преобразуются.
Также Parser выполняет ряд автоматических untaint преобразований:
вид |
что преобразуется |
sql |
тело SQL-запроса |
xml |
XML код при создании объекта класса xdoc |
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 28.05.2004 |
Opuse
use. Подключение модулей | |
^use[файл]
Оператор позволяет использовать модуль из указанного файла. Если путь к файлу начинается с "/", то считается, что это путь от корня веб-пространства. В любом другом случае Parser будет искать модуль по путям, определенным в переменной $CLASS_PATH в Конфигурационном методе.
Для подключения модулей также можно воспользоваться конструкцией:
@USE
имя файла 1
имя файла 2
…
Разница между этими конструкциями в том, что использование @USE подключает файлы с модулями до начала выполнения кода, в то время как оператор use может быть вызван непосредственно из тела программы, например:
^if(условие){
^use[модуль1]
}{
^use[модуль2]
}
Замечание: попытки подключить уже подключенные ранее модули не приводят к повторным считываниям файлов с диска. Однако нужно иметь ввиду, что для этого полное имя файла подключаемого модуля должно с точностью до символа совпадать с именем файла уже подключенного ранее модуля. В случае написания ^use[module.p] и ^use[sub/../module.p] будет считаться, что идет попытка подключить разные модули.
Крайне рекомендуем использовать возможность сохранения результатов работы кода, используя оператор use для подключения необходимых модулей в коде оператора cache.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 25.02.2004 |
Opuserdefined
Операторы, определяемые пользователем | |
Иногда вам будет казаться, что каких-то операторов в языке не хватает. Parser позволяет вам определить собственные операторы, которые затем можно будет использовать наравне с системными.
Операторами в Parser считаются методы класса MAIN, добавляя новые методы в этот класс вы расширяете базовый набор операторов.
Внимание: при описании оператора можно использовать и не локальные переменные, при этом вы будете читать и записывать в поля класса MAIN.
Пользовательские операторы могут определяться и в отдельных текстовых файлах без заголовка @CLASS, которые подключаются к нужным разделам сайта. Если в таком файле определить оператор (написав, скажем, @include[]), то при обращении ^include[…] всегда будет вызываться пользовательский оператор.
Будьте внимательны! Если определить оператор, одноименный с системным, то всегда будет вызываться пользовательский. При этом системный оператор вызвать нельзя никак. Стоит делать как можно меньше пользовательских операторов, используя вместо них статические методы пользовательских классов.
Создавать классы и пользоваться их методами гораздо удобнее, чем пользовательскими операторами. Простой пример: есть несколько разделов сайта, и для каждого из них нужно сделать раздел помощи. Создав несколько файлов, описывающих разные классы, можно получить одноименные методы разных классов. Вызывая методы как статические, мы имеем совершенно ясную картину, что к какому разделу относится:
^news:help[]
^forum:help[]
^search:help[]
Примеры
Поместите этот код…
@default[a;b]
^if(def $a){$a}{$b}
… в файл operators.p, в корень вашего веб-сайта.
Там, где вам необходимы дополнительные операторы, подключите этот модуль. Например, в корневом auto.p, напишите…
@USE
/operators.p
…теперь не только в любой странице, но, что главное, в любом вашем классе можно будет воспользоваться конструкцией
^default[$form:name;Аноним]
Подробности в разделе Создание методов и пользовательских операторов.
Opwhile
while. Цикл с условием | |
^while(условие){тело}
Оператор while повторяет тело цикла, пока условие истинно. Если условие заведомо ложно, тело цикла не выполнится ни разу.
Пример
$little_negros(10)
^while($little_negros > 0){
<br>
$little_negros негритят пошли купаться в море.
Один из них ^little_negros.dec[] утоп,
ему срубили гроб, и вот вам результат -
$little_negros негритят.
}
Params
Передача параметров | |
Параметры могут передаваться в разных скобках и, соответственно, будут по-разному обрабатываться:
(выражение) | - вычисление параметра происходит при каждом обращении к нему внутри вызова метода | ||
[код] | - вычисление параметра происходит один раз перед вызовом метода | ||
{код} | - вычисление происходит при каждом обращении к параметру внутри вызова метода |
Пример на различие скобок, в которых передаются параметры:
@main[]
$a(20)
$b(10)
^sum[^eval($a+$b)]
<hr>
^sum{^eval($a+$b)}
@sum[c]
^for[b](100;110){
$c
}[<br>]
Здесь хорошо видно, что в первом случае код был вычислен один раз перед вызовом метода sum, и методу передался результат кода - число 30. Во втором случае вычисление кода происходило при каждом обращении к параметру, поэтому результат менялся в зависимости от значения счетчика.
Параметров может быть сколь угодно много или не быть совсем. Если в однотипных скобках несколько параметров, то они могут отделяться друг от друга точкой с запятой. Допустимы любые комбинации различных типов параметров.
Например…
^if(условие){когда да;когда нет}
…эквивалентно…
^if(условие){когда да}{когда нет}
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 03.12.2002 |
Parserconfig
Конфигурационный файл | |
Пример файла включен в поставку (см. auto.p.dist).
Этот файл - основной, с которого начинается сборка класса MAIN. Может содержать Конфигурационный метод, который выполняется первым, до метода auto, и задает важные системные параметры.
После выполнения конфигурационного метода можно задать кодировку ответа и кодировку, в которой набран код (по умолчанию в обоих случаях используется кодировка UTF-8):
Рекомендуемый код:
@auto[]
#source/client charsets
$request:charset[windows-1251]
$response:charset[windows-1251]
$response:content-type[
$.value[text/html]
$.charset[$response:charset]
]
Примечание: для корректной работы методов upper и lower класса string с национальными языками (в том числе русским) необходимо корректное задание $request:charset.
Также здесь рекомендуется определить путь к классам вашего сайта:
$CLASS_PATH[/../classes]
И строку соединения с SQL-сервером, используемым на вашем сайте (пример для ODBC):
$SQL.connect-string[odbc://DSN=www_mydomain_ru^;UID=user^;PWD=password]
Примечание: вашем коде вы будете использовать ее так:
^connect[$SQL.connect-string]{…}
Советуем поместить сюда же определение метода unhandled_exception, который будет выводить сообщение о возможных проблемах на вашем сайте.
Внимание: конечно, Конфигурационный файл можно не использовать, а Конфигурационный метод поместить в файл auto.p в корне веб-пространства, однако в разных местах размещения сервера (например: отладочная версия и основной сервер) конфигурации скорее всего будут различными, и очень удобно, когда эти различия находятся в отдельном файле и вне веб-пространства.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 20.02.2004 |
Parserconfmethod
Конфигурационный метод | |
Если в файле определен метод conf,он выполняется первым, до auto, и задает важные системные параметры:
· | файлы, описывающие кодировки символов, |
· | ограничение на размер HTTP POST-запроса, |
· | сервер/программу отправки почты, |
· | SQL-драйвера и их параметры, |
· | таблицу соответствия расширения имени файла и его mime-типа. |
Определение метода:
@conf[filespec]
filespec - полное имя файла, содержащего метод.
Всегда доступна и не нуждается в загрузке файла кодировка UTF-8, являющаяся для Parser кодировкой по умолчанию.
Чтобы сделать доступными для использования Parser другие кодировки, необходимо указать файлы их описывающие, делается это так:
$CHARSETS[
$.windows-1251[/полный/путь/к/windows-1251.cfg]
…
]
См. Описание формата файла, описывающего кодировку.
Максимальный размер POST данных:
$LIMITS[
$.post_max_size(10*0x400*0x400)
]
Параметр отправки писем (см. ^mail:send[…])…
…под Windows и UNIX (под UNIX [3.1.2]) адрес SMTP-сервера
$MAIL[
$.SMTP[mail.office.design.ru]
]
…под UNIX в safe-mode версиях, настроить программу отправки можно только при сборке Parser из исходных кодов, в бинарных версиях, распространяемых с сайта parser.ru, задана команда
/usr/sbin/sendmail -i -t -f postmaster
Только в unsafe-mode версиях можно задать программу отправки почты самому:
$MAIL[
$.sendmail[/custom/mail/sending/program params]
]
и, по умолчанию, используется эта…
/usr/sbin/sendmail -t -i -f postmaster
…или эта…
/usr/lib/sendmail -t -i -f postmaster
…команда, в зависимости от вашей системы.
При отправке письма вместо «postmaster» будет подставлен адрес отправителя из письма из обязательного поля заголовка «from».
Также можно задать таблицу SQL-драйверов:
$SQL[
$.drivers[^table::create{protocol driver client
mysql /full/disk/path/parser3mysql.dll /full/disk/path/libmySQL.dll
odbc /full/disk/path/parser3odbc.dll
pgsql /full/disk/path/parser3pgsql.dll /full/disk/path/libpq.dll
oracle /path/to/parser3oracle.dll C:\Oracle\Ora81\BIN\oci.dll?PATH+=^;C:\Oracle\Ora81\bin
}]
]
В колонке client таблицы drivers допустимы параметры клиентской библиотеке, отделяемые знаком ? от имени файла библиотеки, в таком виде:
имя1=значение1&имя2=значение2&…
а также имя+=значение.
Эти переменные будут занесены(=) или добавлены к имеющемуся значению(+=) в программное окружение (environment) перед инициализацией библиотеки. В частности, удобно добавить путь к Oracle библиотекам здесь, если этого не было сделано в системном программном окружении (system environment).
Таблица типов файлов:
#файл, создаваемый ^file::load[…],
#при выдаче в $response:body задаст этот $response:content-type
$MIME-TYPES[^table::create{ext mime-type
zip application/zip
doc application/msword
xls application/vnd.ms-excel
pdf application/pdf
ppt application/powerpoint
rtf application/rtf
gif image/gif
jpg image/jpeg
jpeg image/jpeg
png image/png
tif image/tiff
html text/html
htm text/html
txt text/plain
mts application/metastream
mid audio/midi
midi audio/midi
mp3 audio/mpeg
ram audio/x-pn-realaudio
rpm audio/x-pn-realaudio-plugin
ra audio/x-realaudio
wav audio/x-wav
au audio/basic
mpg video/mpeg
avi video/x-msvideo
mov video/quicktime
swf application/x-shockwave-flash
}]
Расширения имен файлов в таблице должны быть написаны в нижнем регистре. Поиск по таблице нечувствителен к регистру, т.е. файл FACE.GIF получит mime-тип image/gif.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 29.03.2004 |
Parserexceptions
Системные ошибки | |
type | Пример возникновения | Описание | |||
parser.compile | ^test[} | Ошибка компиляции кода. Непарная скобка, и т.п. | |||
parser.runtime | ^if(0). | Методу передано неправильное количество параметров или не тех типов, и т.п. | |||
parser.interrupted | Загрузка страницы прервалась (пользователь остановил загрузку страницы или истекло время ожидания) | ||||
number.zerodivision | ^eval(1/0), ^eval(1\0) или ^eval(1%0) | Деление или остаток от деления на ноль | |||
number.format | ^eval(abc*5) | Преобразование к числу нечисловых данных | |||
file.missing | ^file:delete[skdfjs.delme] | файл отсутствует | |||
file.access | ^table::load[.] | Нет доступа к файлу | |||
image.format | ^image::measure[index.html] | Файл изображения имеет неправильный формат (возможно, расширение имени не соответствует содержимому, или файл пуст?) | |||
sql.connect | ^connect[mysql://baduser:pass@host/db]{} | Сервер баз данных не может быть найден или временно недоступен | |||
sql.execute | ^void:sql{bad select} | Ошибка исполнения SQL запроса | |||
xml | ^xdoc::create{<forgot?>} | Ошибочный XML код или операция | |||
smtp.connect | SMTP сервер не может быть найден или временно недоступен | ||||
smtp.execute | Ошибка отправки письма по SMTP протоколу | ||||
email.format | Ошибка в email адресе: адрес пустой или содержит неправильные символы | ||||
email.send | Ошибка запуска почтовой программы | ||||
http.host | ^file::load[http://notfound/there] | Сервер не найден | |||
http.connect | ^file::load[http://not_accepting/there] | Сервер найден, но не принимает соединение | |||
http.response | ^file::load[http://ok/there] | Сервер найден, соединение принял, но выдал некорректный ответ (нет статуса, заголовка) | |||
http.status | ^file::load[http://ok/there] | Cервер выдал ответ со статусом не равным 200 (не успешное выполнение запроса) | |||
http.timeout | Загрузка документа с HTTP-сервера не завершилась в отведенное для нее время |
Parserscript
Использование Parser в качестве интерпретатора скриптов | |
/путь/к/parser3 файл_со_скриптом
x:\путь\к\parser3 файл_со_скриптом
Выполнять скрипты можно и без веб-сервера, достаточно запустить интерпретатор Parser, передав ему в командной строке параметр - имя скрипта. При этом корнем веб-пространства считается текущий каталог.
При этом ошибки попадут в стандартный поток ошибок, который можно перенаправить в желаемый файл так:
команда 2>>error_log
Внимание: не забывайте его время от времени очищать.
На UNIX можно также использовать стандартный подход с заданием команды запуска интерпретатора в первой строке скрипта:
#!/путь/к/parser3
#ваш код
Проверка: ^eval(2*2)
Не забудьте зажечь биты атрибута, разрешающие исполнение владельцу и группе. Команда:
chmod ug+x файл
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 24.02.2004 |
Requestbody
body. Получение текста запроса | |
$request:body
Получение текста HTTP POST-запроса.
Вариант использования: можно написать свой XML-RPC сервер (см. http://xmlrpc.org).
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 16.10.2002 |
Requestcharset
charset. Задание кодировки документов на сервере | |
$request:charset[кодировка]
Задает кодировку документов, обрабатываемых на сервере.
При обработке запроса считается, что в этой кодировке находятся все файлы на сервере.
По умолчанию используется кодировка UTF-8.
Список допустимых кодировок определяется Конфигурационным методом.
Рекомендуется определять кодировку документов в Конфигурационном файле.
См. также «Задание кодировки ответа».
Requestclass
Класс request | |
Класс содержит статические поля, которые позволяют получать информацию, передаваемую браузером веб-серверу (по HTTP протоколу).
Для работы с полями форм (<FORM>) и строкой после второго ? (/?a=b?thisText) используйте класс form.
Часть информации о запросе доступна через переменные окружения, см. «Получение значения поля запроса».
Requestdocroot
document-root. Корень веб-пространства [3.1.2] | |
$request:document-root[/дисковый/путь/к/корню/вашего/веб-пространства]
По-умолчанию, $request:document-root равен значению, которое задается в веб-сервере.
Однако иногда его удобно заменить.
См. также «Пути к файлам и каталогам».
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 01.04.2004 |
Requestquery
query. Получение строки запроса | |
$request:query
Возвращает строку после ? в URI (значение переменной окружения QUERY_STRING).
Для работы с полями форм (<FORM>) и строкой после второго ? (/?a=b?thisText) используйте класс form.
Пример
Предположим, пользователь запросил такую страницу: http://www.mysite.ru/news/articles.html?year=2000&month=05&day=27
Тогда:
$request:query
вернет:
year=2000&month=05&day=27
Requesturi
uri. Получение URI страницы | |
$request:uri
Возвращает URI документа.
Пример
Предположим, пользователь запросил такую страницу: http://www.mysite.ru/news/articles.html?year=2000&month=05&day=27
Тогда:
$request:uri
вернет:
/news/articles.html?year=2000&month=05&day=27
Responsebody
body. Задание нового тела ответа | |
$response:body[DATA]
Замещает все тело ответа значением DATA.
DATA - строка (string) или файл (file). Если передан файл с известным content-type (см. поля объекта класса file), этот заголовок передается в пользователю.
См. также $response:download.
Пример замены всего тела на результат работы скрипта
$response:body[^file::cgi[script.cgi]]
Заменит весь ответ результатом работы программы script.cgi.
Пример выдачи создаваемой картинки
$square[^image::create(100;100;0x000000)]
^square.circle(50;50;10;0xFFFFFF)
$response:body[^square.gif[]]
В браузере будет выведен черный квадрат с белой окружностью. Кроме того, автоматически будет установлен нужный тип файла (content-type) по таблице MIME-TYPES.
Responsecharset
charset. Задание кодировки ответа | |
$response:charset[кодировка]
Задает кодировку ответа.
После обработки запроса результат перекодируется в эту кодировку.
По умолчанию используется кодировка UTF-8.
Список допустимых кодировок определяется Конфигурационным методом.
Рекомендуется определять кодировку документов в Конфигурационном файле.
См. также «Задание кодировки документов на сервере».
Responseclass
Класс response | |
Класс позволяет дополнять стандартные HTTP-ответы сервера. Класс не имеет конструкторов для создания объектов.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 02.12.2002 |
Responseclear
clear. Отмена задания новых заголовков HTTP-ответа | |
^response:clear[]
Метод отменяет все действия по переопределению полей ответа.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 16.10.2002 |
Responsedownload
download. Задание нового тела ответа | |
$response:download[DATA]
Идентичен $response:body, но выставляет флаг, который браузер воспринимает как «Предложить пользователю сохранить файл на диске».
Браузеры умеют отображать файлы некоторых типов прямо внутри своего окна (например: .doc, .pdf файлы).
Однако бывает необходимо дать возможность посетителю скачать файл по простому нажатию на ссылку.
Пример: выдача PDF файла
Посетитель заходит на страницу с таким HTML…
<a href="/download/documentation.html">Скачать документацию</a>
download_documentation.html:
$response:download[^file::load[binary;documentation.pdf]]
…и нажимает на ссылку, браузер предлагает ему Скачать/Запустить.
Responsefields
Заголовки HTTP-ответа | |
$response:поле[значение]
$response:поле
Поле соответствует заголовку HTTP-ответа, выдаваемого Parser. Его можно как задавать, так и считывать. Значением может быть дата, строка или хеш с обязательным ключом value. Дата может использоваться и в качестве значения поля и в качестве значения атрибута поля, при этом она будет стандартно отформатирована.
Примечание: имя поля, при задании значения, преобразуется к нижнему регистру, а при считывании ищется в нижнем регистре.
Пример перенаправления браузера пользователя на стартовую страницу
$response:location[/]
$response:refresh[
$.value[0]
$.url[/]
]
Пример задания заголовка expires в значение «завтра»
$response:expires[^date::now(+1)]
Sokr
Принятые обозначения | |
ABCDEFGH - Код Parser в примерах для визуального отличия от HTML (Courier New, 10). Для удобства работы с электронной документацией дополнительно выделен цветом.
ABCDEFGH - Файлы и каталоги, рассматриваемые в рамках урока.
ABCDEFGH - Дополнительная и справочная информация.
[3.1] - Номер версии Parser, начиная с которой доступна данная функция или опция.
В справочнике символ "|" равнозначен союзу ИЛИ.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 04.03.2004 |
Stats
Статические поля и методы | |
Вызов статического метода
^класс:метод[параметры]
Вызов статического метода класса.
Примечание: точно так же вызываются динамические методы родительского класса (см. Создание пользовательского класса).
Значение статического поля
$класс:поле
Получение значения статического поля класса.
Задание статического поля
$класс:поле[значение]
Задание значения статического поля класса.
Statusclass
Класс status | |
Класс предназначен для анализа текущего состояния скрипта на Parser.
Его использование поможет вам найти узкие места в ваших скриптах.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 12.05.2003 |
Statusmemory
memory. Информация о памяти под контролем сборщика мусора [3.1] | |
Это поле - хеш с информацией о памяти, находящейся под контролем сборщика мусора.
Поле | Значение (в килобайтах) | Детали | |||
used | Занято | В это число не включен размер cлужебных данных самого сборщика мусора. | |||
free | Свободно | Свободная память скорее всего фрагментирована. | |||
ever_allocated_since_compact | Было выделено с момента последней сборки мусора. См. memory:compact. | Между сборками мусора это число только растет. Факты освобождения памяти без сборки мусора на него не влияют, только сборки мусора. | |||
ever_allocated_since_start | Было выделено за все время обработки запроса | Это число только растет. Ни факты сборки мусора, ни освобождения памяти между сборками мусора на него не влияют. |
Рекомендуемый способ анализа
Временно добавьте вызовы…
^musage[before XXX]
^musage[after XXX]
…вокруг интересующего вас блока вот этого метода…
@musage[comment][v;now;prefix;message;line]
$v[$status:memory]
$now[^date::now[]]
$prefix[[^now.sql-string[]] $env:REMOTE_ADDR: $comment]
$message[$v.used $v.free $v.ever_allocated_since_compact $v.ever_allocated_since_start $request:uri]
$line[$prefix $message ^#0A]
^line.save[append;/musage.log]
$result[]
…и проанализируйте журнал.
Важно: в ходе работы Parser захватывает у операционной системы дополнительные блоки памяти по мере необходимости. Поэтому есть моменты, когда и used и free, увеличиваются. Это нормально.
Примечание: для записи журнала не рекомендуется использовать веб-пространство.
Statuspid
pid. Идентификатор процесса | |
Идентификатор процесса (process) операционной системы, в котором работает Parser.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 23.03.2004 |
Statusrusage
rusage. Информация о затраченных ресурсах | |
Это поле - хеш с информацией о ресурсах сервера, затраченных на данный момент системой на обработку вашего Parser-скрипта.
Не все операционные системы умеют возвращать эти значения (WinNT/Win2000/WinXP умеет все, Win98 умеет только tv_sec и tv_usec [3.0.8]).
Ключ | Единица | Описание значения | Как уменьшить? | ||||
utime | секунда | Чистое время, затраченное текущим процессом (не включает время, когда работали другие задачи) | Упростить манипуляции с данными внутри Parser (улучшить алгоритм, переложить часть действий на SQL-сервер) | ||||
stime | секунда | Время, сколько система читала ваши файлы, каталоги, библиотеки | Уменьшить количество и размер необходимых для работы файлов, не подключать ненужные для обработки данного документа модули | ||||
maxrss | блок | Память, занимаемая процессом | Уменьшить количество загружаемых ненужных данных. Найти и исправить все «select * …», задав список действительно необходимых полей. Не загружать из SQL-сервера ненужные записи, отфильтровать как можно больше средствами самого SQL-сервера. | ||||
Точное системное время. Позволяет оценить траты времени на ожидание ответа от SQL-, HTTP-, SMTP-серверов. Сколько прошло с Epoch… | Упростить SQL запросы, для MySQL воспользуйтесь EXPLAIN, см. http://www.mysql.com/doc/en/EXPLAIN.html; для Oracle: EXPLAIN PLAN, см. документацию по серверу; для других SQL-серверов: см. их документацию. | ||||||
tv_sec | секунда | …целых секунд; | |||||
tv_usec | микросекунда (10E-6) | …еще прошло микросекунд (миллионных долей секунды) |
Рекомендуемый способ анализа
Временно добавьте в конец вашего скрипта вызов…
^rusage[total]
…вот этого метода…
@rusage[comment][v;now;prefix;message;line;usec]
$v[$status:rusage]
$now[^date::now[]]
$usec(^v.tv_usec.double[])
$prefix[[^now.sql-string[].^usec.format[%06.0f]] $env:REMOTE_ADDR: $comment]
$message[$v.utime $v.stime $request:uri]
$line[$prefix $message ^#0A]
^line.save[append;/rusage.log]
$result[]
…и проанализируйте журнал.
Для более точного анализа, добавьте вызовы…
^rusage[before XXX]
^rusage[after XXX]
…вокруг интересующего вас блока.
Примечание: для записи журнала не рекомендуется использовать веб-пространство.
WinNT/2K/XP
Под этими OS доступен ряд дополнительных значений:
Ключ | Единица | Описание значения | Как уменьшить? |
ReadOperationCount ReadTransferCount | штук байт | Количество операций чтения с диска и суммарное количество считанных байт | Уменьшить количество и размер необходимых для работы файлов, не подключать ненужные для обработки данного документа модули. Больше использовать SQL-сервер, меньше файлы. |
WriteOperationCount WriteTransferCount | штука байт | Количество операций записи на диск и суммарное количество записанных байт | |
OtherOperationCount OtherTransferCount | штука байт | Количество других операций с диском (не чтения/записи) и суммарное количество переданных байт | |
PeakPagefileUsage QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage | байт | Максимальное количество памяти в файле подкачки (swap-файле) | см. комментарий к maxrss выше. |
Statustid
tid. Идентификатор потока | |
Идентификатор потока (thread) операционной системы, в котором работает Parser.
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 23.03.2004 |
Stringclass
Класс string | |
Класс для работы со строками. В выражении строка считается определенной (def), если она не пуста. Если в строке содержится число, то при попытке использовать его в математических выражениях содержимое строки будет автоматически преобразовано к double. Если строка пуста, ее числовое "значение" в математических выражениях считается нулем.
Создание объекта класса string:
$str[Строка, которая содержится в объекте]
Copyright © 1997?2004 Art. Lebedev Studio | http://www.artlebedev.ru | Дата обновления: 12.02.2004 |