apv@i-connect.ru
На CPAN == Comprehensive Perl Archive Network. Homepage CPAN -- http://www.cpan.org/ -- там берут все, связанное с перлом. Собственно исходники новейшей версии перла берут из файла http://www.perl.com/CPAN/src/latest.tar.gz (на самом деле с www.perl.com стоит редирект на ближайший, по мнению www.perl.com, mirror).
Там же, где и все, относящееся к перлу -- на CPAN. Полный список всех модулей и библиотек -- http://www.cpan.org/CPAN.html
Есть. Полный список зеркал находится в ftp://ftp.nluug.nl/pub/languages/perl/CPAN/MIRRORED.BY, там можно найти funet или что там поближе, или даже российские зеркала, например ftp://ftp.sai.msu.su/pub/lang/perl/CPAN/ (иногда в дауне).
Обычно модуль приходит в формате tar+gzip, типа module-0.01.tar.gz. Вам необходимо его развернуть: tar zxf module-0.01.tar.gz и перейти в образовавшуюся директорию, например module-0.01: cd module-0.01 Обычно там находятся несколько файлов. Для вас будут важными следующие:
что это за модуль
как его поставить
перловый скрипт для генерации Makefile
Обычно инсталляция происходит следующим образом:
perl Makefile.PL
генерация Makefile
make all
сборка модуля
make test
тестирование модуля
make install
инсталляция модуля
Необходимо внимательно смотреть, не возникли ли какие ошибки во время первых трех команд. Внимание: вы должны иметь административные привилегии для инсталлирование модуля в системе (обычно как root).
Но, если вы их не имеете, то можете инсталлировать модуль у себя. Для этого вам необходимо выбрать, где это будет делаться. Для примера, в $HOME/lib/perl5. Необходимо создать эти директории, если их нет:
mkdir ~/lib mkdir ~/lib/perl5Затем, при генерации Makefile для модуля, вы должны указать, где вы хотите инсталлировать модуль:perl Makefile prefix=$HOME Все остальные шаги без изменений. В результате вы получите альтернативное место, где у вас будут находиться модули. Например, у меня это выглядит так:
artur@disco:~ (681) ls -alFg ~/lib/perl5/
total 704
drwxr-sr-x 8 artur staff 512 Oct 06 15:53 ./
drwxr-sr-x 9 artur staff 1024 Oct 08 10:50 ../
drwxr-sr-x 4 artur staff 512 Mar 31 1998 aix/
drwxr-sr-x 2 artur staff 512 Aug 06 13:40 CPAN/
-r--r--r-- 1 artur staff 126951 Jul 24 19:37 CPAN.pm
drwxr-sr-x 3 artur staff 512 Mar 31 1998 man/
drwxr-sr-x 31 artur staff 1024 Sep 09 15:41 site_perl/
Для того, чтобы их использовать, есть несколько путей:
perl -I$HOME/lib/perl5 -I$HOME/lib/perl5/site_perl script.pl
PERL5LIB=$HOME/lib/perl5:$HOME/lib/perl5/site_perlexport PERL5LIB для csh (tcsh)
setenv PERL5LIB $HOME/lib/perl5:$HOME/lib/perl5/site_perl
use lib "/home/you/lib/perl5"; use lib "/home/you/lib/perl5/site_perl";Данный случай подходит к CGI-скриптам, которые не наследуют ваших переменных окружения.
Скачивание и установка вручную -- достаточно сложное занятие,
требующее постоянного вмешательства с вашей стороны.
Можно простым способом: сделать su (желательно), запустить
perl -MCPAN -e shell
. Если это первый запуск модуля CPAN,
вам зададут серию вопросов на тему URL вашего любимого зеркала CPAN. После
этого все просто: если вы знаете название модуля или библиотеки, то
набираете, скажем, install Net::NNTP
. Тогда этот модуль (для работы с
NNTP) сам ищется на CPAN, сам скачивается, компилируется,
устанавливается. Все, поставили, можно выходить и использовать вновь
установленный модуль. Если название точно не известно, то набираем
там же help и используем различные команды поиска типа i NNTP.
При использовании CPAN-модуля вам необходимо сконфигурировать его
таким образом, чтобы он сам инсталлировал модули туда, куда вы
укажете. Для этого вам необходимо подредактировать файл
~/.cpan/CPAN/MyConfig.pm:
указать в строке
&makepl_arg& =& q[prefix=/home/you],
и теперь всегда при автоматической инсталляции модули будут ставится к
вам в $HOME/lib/perl5
Более подробно обо всем этом можно прочитать в документации к
ExtUtils::MakeMaker.
NB: Современный Модуль СPAN все сам спросит и сделает.
Две классические книги по перлу, первая имеется в русском переводе и продается в магазинах:
Рандал Шварц, Том Кристиансен. Изучаем перл (aka Llama book)
Лэрри Уолл, Том Кристиансен, Рандал Шварц. Programming Perl (aka Camel book, на русском, кажется, еще нет)
Llama book - учебник для начинающих, Camel book - справочное руководство.
**New: Есть еще русский перевод Perl Cookbook под названием Т. Кристиансен, Н. Торкингтон "Perl: Библиотека программиста" - СПб, Издательство "Питер", 2000. ISBN 5-8046-094-X
И еще книжка: М. Райт и др. "CGI/Perl". Ее я не рекомендую, как и все от Райта.
Перл приходит с полным набором документации и набором программ для перевода в разные форматы. Обычно для подробного ознакомления с некоторой особенностью перла пишут "perldoc perlсвойство" или "man perlсвойство". Базовый набор "свойств" таков:
Перл для win32 поставляется с программой perldoc (пользоваться: "perldoc perlfunc" и т. д.) а также с документацией в HTML: если хочешь perldoc perlfunc, ищи perlfunc.html.
Формат стандартной документации по перлу (pod) обладает
возможностью встраивания прямо в тексты программ, а программа perldoc
-- возможностью извлечения этой документации. Поэтому, чтобы получить
документацию по модулю Math::Trig
, просто запустите perldoc Math::Trig
-- perldoc найдет этот модуль и покажет документацию из него. Если
модуль не является частью какой-то библиотеки, а существует сам по
себе, например, CGI.pm тогда просто perldoc CGI.pm или даже perldoc
CGI. NB: программа perldoc не очень расторопна, поэтому при установке
перла под UNIX производится создание manpages для всех модулей, так
что man CGI или man Math::Trig покажет быстрее, чем perldoc.
Да, он тоже входит в набор стандартной документации. Отправная точка -- perldoc perlfaq, это оглавление, из которого можно узнать, что FAQ состоит из девяти больших частей.
Про это говорят в perldoc perlpod, в man pod2man.
Да. На мой взгляд, серия статей Рандала Шварца для Unix Review Perl Columns -- лучшее введение в перл, и намного интереснее и полезнее книг Llama и Camel (мнения авторов не всегда совпадают с мнением координатора -- Аммосов). Почитать их можно на http://w3.stonehenge.com:80/merlyn/UnixReview/.
Почему я считаю это лучшим введением в перл? Потому что это отдельные небольшие статьи, каждая из которых иллюстрирует конкретные возможности перла на примере написания программы для достаточно простой задачи. Все же статьи охватывают практически весь спектр возможностей перла -- от написания скрипта в одну строку, который может поменять Иванов на Сидоров во всех файлах в дереве директорий, до основ объектно-ориентированного программирования и принципов создания собственных модулей и библиотек.
Если нет возможности купить в магазине, то есть кое-что и в Интернете: книга Маслова "Введение в перл", например. http://citforum.ru/koi/internet/perl_tut/ Есть и другие, особо хороших не видел.
man perlfunc или "perldoc -f имя_функции | pod2text"
С помощью так называемых файловых тестов, которые имеют вид (-тест "имя файла"), например:
размер файла
существует ли файл
доступен ли на запись
количество дней со дня модификации
является ли терминалом
Способ для Unix oт Alex Efros
open MAIL, '|/path/to/your/sendmail -t'; # Pipe к sendmail
print MAIL "From: mailrobot@my.host\n",
"To: webmaster@my.host\n",
"Subject: Wow! I got some mail for you!!!\n\n",
$message;
close MAIL;
У меня не Unix! Что делать?
Вероятно, Вам поможет модуль Net::SMTP
Возьмите на CPAN модуль MIME::Tools и прочтите от него README. (MIME-tools.xxxxx.tar.gz)
Гарантированно -- никак. Вы можете проверить адрес на правильность синтаксиса при помощи Email::Valid. И все. Если нужен гарантированно правильный e-mail для web-сайта, вы можете воспользоваться методом от Алексея Тутубалина: требовать пароль для доступа к информации, а сам пароль высылать по электронной почте. Тогда человек должен будет указать свой e-mail, конечно же, если ему интересна эта информация с вашего сайта.
Простейший случай:
Сам модуль представляет из себя файл с именем MyModule.pm
следующего содержания:
MyModule.pm
package MyModule;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(идентификаторы для экспорта: подпрограммы, имена переменных и
пр.);
# Теперь после того, как вы напишите use MyModule в своей программе, у вас все
# упомянутые здесь идентификаторы станут видны. Этот метод не рекомендуется,
# так как вы "засоряете" именное пространство программы.
# И/или
@EXPORT_OK = qw(идентификаторы для экспорта: подпрограммы, имена переменных и
пр.);
# Идентификаторы, прописанные здесь будут видны в Вашей программе как
# MyModule::Идентификатор (подпрограммы) или $MyModule::Идентификатор
# (переменные)
# Или, Вы можете написать use MyModule qw(Ид1 Ид2 $Ид3); и все будет как в
# первом случае. Это рекомендуемый вариант.
... ваши подпрограммы и пр ....
1; # Обязательно
Программа, его использующая:
myprg.pl
use MyModule qw(...);
# Ну и далее
Подробности смотрите в perlmod(1), Exporter(3pm), Camel Book
Надо использовать функцию substr. Например, получить 15й символ из строки $string:
$char = substr($string, 15, 1);
Установить 15й символ строки $string:
substr($string, 15) = 'A';Можно даже использовать более чем односимвольные последовательности:
$ss = substr($string, 15, 5); substr($string, 15) = 'Хо-Хо';
CGI -- Common Gateway Interface. Стандарт интерфейса внешних программ с http-сервером.
HTTP -- клиент-серверный протокол, следовательно со стороны CGI-программы, как серверного процесса, все взаимодействие выглядит следующим образом
Пункты 1 и 3 я вкратце опишу здесь, а 2, надеюсь, сделаете сами :-). Начнем с п.3, как наиболее простого.
Обычно клиенту выдают текст в формате HTML (ничто не мешает Вам отправить ему и картинку/видео/etc). Для того, чтобы сервер и клиент вас поняли, необходимо сказать, что вы выдаете, c помощью заголовка Content-Type: mime-type/mime-subtype. Обратите внимание на регистр и последовательность -- если вы скажите нечто типа Content_type, то сервер вас скорее всего не поймет. (Сообщение типа "500 Internal Server Error" будет симптомом).
Пример:
print "Content-Type: text/html\n";
# Мы выдаем текст в формате HTML. Также можно: text/plain -- простой текст, в
# браузере отобразится аналогично тексту, заключённому между тегами
# <pre></pre>. image/gif -- Картинка, формат gif video/mpeg --
# mpeg-видео И целая куча других форматов, см. файл mime.types из apache
print "\n";
# <-- еще одна пустая строка, обозначает конец вывода наших
# заголовков. ВАЖНО!
# Теперь мы можем написать свой текст клиенту
print qq{
<html>
<head>
<title>Моя первая CGI программа</title>
</head>
<body>
<h1>Моя первая CGI программа</h1>
</body>
</head>
};
Взаимодействие с клиентом обеспечивается так: Он заполняет форму своими значениями, нажимает на кнопку "submit", броузер кодирует данные соответствующим образом и отправляет их серверу.
Производится тегами <form> и </form>. Тег определения форм имеет следующие атрибуты
скрипт на сервере, который будет запущен на сервере для обработки данных формы.
тип взаимодействия с сервером. Может иметь значения GET и POST. Плюс, еще некоторые специальные, которые вы можете посмотреть в rfc
Формы не могут быть вложенными.
Элементы ввода
Определяются тегами <input>, <textarea> и <select> тег <input>:
Элемент ввода "Опция"
Элемент ввода, который не виден пользователю
в Netscape Navigator позволяет загрузить файл на сервер
Изображение. Если по нему щелкнуть, это вызовет submit формы и серверу будут выданы две переменные вида name.x и name.y, где name -- то, что вы пропишете в name=... тега <input>
Элемент ввода Пароль. Позволяет ввести строку, которая на экране отображается звездочками. Никаких методов защиты при передаче на сервер не применяется
Радиокнопки
Кнопка сброса значений формы на начальные
Кнопка отправки формы на сервер
строка ввода
Все теги <input> имеют атрибут name -- Наименование элемента. Служит для идентификации при передаче на сервер, а также другие типа value, width, etc, название и назначение которых можно опять-таки посмотреть в учебнике.
Тег <textarea> -- Поле многострочного ввода.
Тег <select> -- списочный выбор
Пример:
<form action=/cgi-bin/myscript.pl method=GET>
Имя: <input type=string name=name><p>
Пол: <input type=radio name=gender value=male>Мужской
<input type=radio name=gender value=female>Женский
<input type=submit><input type=reset>
</form>
Это определяется методом формы, GET или POST
В случае GET сервер установит переменную окружения QUERY_STRING в виде name1=vaue1&name2=value2&..&nameN=valueN.
В случае POST аналогичная строка будет записана на стандартный ввод. Ее длину можно получить через переменную окружения CONTENT_LENGTH.
В обоих случаях данные будут закодированы по следующему алгоритму:
tr/+/ /;
s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge;
(списано из CGI.pm)
На самом деле, можно не возится со всем этим, а использовать модуль CGI.pm (Имеется в поставке Perl 5.004 и более поздних. Если у вас perl версии 4 или 1, нужно срочно взять на CPAN новую версию perl)
Предположим мы делаем поисковую систему, тогда у нас должен быть HTML с формой и программа, которая будет выполнять поиск.
search.html
<html>
<head>
<title>Поиск</title>
</head>
<<body>
<h1>Чего искать?</h1>
<form action=/cgi-bin/search.pl method=get>
Строка для поиска: <input type=text name=string width=70><p>
Искать в <input type=checkbox name=searchin value=internet>Интернет
<input type=checkbox name=searchin value=intranet>Интранет
<input type=checkbox name=searchin value=extranet>Экстранет<p>
<input type=submit value=Давай!><input type=reset value="Нет, не надо">
</form>
</body>
</html>
Программа:
#!/usr/bin/perl -- поменяйте, как надо
use CGI qw(:standard);
print "Content-Type: text/html\n\n"; # Не забудьте про два "\n"
$string = param("string");
@searchin = param("searchin"); # searchin это checkbox и его значения
# возвращаются списком
# Искать мы сегодня ничего не будем
print "<html>
<body>
<h1>Мы сегодня ничего не ищем</h1>
Но, если бы искали, то: <br>
Искали бы строку <b>$string</b><br>\n";
print "В <b>" . join(" ", @searchin) . "</b>\n";
print "
</body>
</html>
";
Да, кстати, если вы собираетесь писать в файлы с помощью CGI-программ, не забывайте про file locking (См. часть C за подробностями).
Выдавайте заголовки в таком виде:
print "Content-Type: type/sub-type\n"; # Подставьте Ваш тип/подтип print "Pragma: no-cache\n"; # Для HTTP/1.0 клиентов print "Cache-Control: no-cache\n"; # Для HTTP/1.1 print "Expires: Thu Jan 1 00:00:00 1970\n\n"; # Это уже любой броузер должен # понять
В заголовке напишите:
print "Status: 302\n"; # Или 301. Разница состоит в том, что по стандарту 301 значит "перемещён # навсегда", а 302 -- "перемещён временно" print "Location: ВАШ Новый URL\n"; # URL должен быть указан абсолютный print "URI: ВАШ новый URL\n\n"; # Для http/1.0Подробности: см. rfc1945(http/1.0), rfc2068(http/1.1)
В поставку CGI.pm входит пример file_upload.cgi. За подробностями смотрите CGI(3).
Учтите, что если у вас система, которая разделяет бинарные и текстовые файлы -- вам понадобится использовать binmode.
Также, помните, что "Русский Apache" не будет производить перекодировку multipart форм.
Возьмите на CPAN библиотеку libwww-perl и смотрите lwpcook(3), там написаны основы использования библиотеки и есть примеры.
Плюшки работают следующим образом: программа CGI добавляет в свой ответ директиву Set-Cookie, а клиент (если он поддерживает плюшки), при следующих запросах возвращает их в заголовке Cookie. Сами плюшки представляют из себя пары имя=значение.
Set-Cookie: имя=значение; expires=дата; path=путь; domain=домен; secure
Сервер может установить не более 20 плюшек, размер всей плюшки не может превышать 4Kb.
единственный обязательный параметр. И имя, и значение могут быть строками текста, не содержащими символов перевода строки, пробелов, ; и табуляции. Если необходимо их использовать, можно эти символы закодировать при помощи стандартного uri-кодирования.
устанавливается дата истечения срока действия плюшки. После этой дата плюшка клиентом не возвращается. Если дата не установлена, то плюшка действует до завершения работы браузера.
обозначает путь на сервере, для которого возвращается эта плюшка, если не указано, то только для того, который ее создал.
домен, для которого возвращается эта плюшка. Может быть доменом уровня 2 и выше, т.е. .example.ru, а не .ru. Если не установлен, то плюшка возвращается только серверу, который выдал плюшку.
указывает, что плюшка должна возвращаться только по защищенному соединению (SSL).
Cookie: имя1=значение1; имя2=значение2;....;имяn=значениеnПрограммы CGI могут получить пары имя-значение через переменную окружения HTTP_COOKIE. В модуле CGI.pm значение можно получить при помощи метода cookie().
В деталях, механизм плюшек описан в rfc2109 (HTTP State Management Mechanism. D. Kristol, L. Montulli. February 1997.)
Пример: 1. Установка плюшки
setcookie.pl
#!/usr/bin/perl
print "Content-Type: text/html\n";
print "Set-Cookie: mycookie=some+string\n\n";
print "<html><head><title>Установка плюшки</title></head>\n";
print "<body><h1>Установка плюшки</h1>\n";
print "<a href=getcookie.pl>Щелкни здесь,</a> чтобы посмотреть, что
получилось.
print "</body></html>";
2. Получение плюшки
getcookie.pl;
#!/usr/bin/perl
use CGI qw(:standard);
print "Content-Type: text/html\n\n";
print "<html><head><title>Получение плюшки</title></head>\n";
print "<body><h1>Плюшка</h1>\n";
print "mycookie = ", getcookie('mycookie');
print "</body></html>";
Надо отредактировать конфигурационные файлы (я рассчитываю, что у вас default конфиги apache) (NB: Apache/1.3.6 и выше по умолчанию конфигурируется только файлом httpd.conf. Директивы все остались прежние, просто их слили в один файл)
srm.conf
Директива ScriptAlias
ScriptAlias /cgi-bin/ /usr/local/apache/cgi-bin/
и в файле access.conf прописать
<Directory /usr/local/apache/cgi-bin/>
Options ExecCGI
</Directory>
(если пригляделся, там нужно только раскоментировать опции)
Это позволит вам помещать программы в каталог
/usr/local/apache/cgi-bin/ и они будут видны по URL
http://you/cgi-bin/program_name
Добавить в srm.conf директиву AddHandler cgi-script .cgi
и вы сможете вызывать cgi-программу из любого каталога. Но она должна иметь
окончание .cgi и для нее должно быть разрешено исполнение CGI
(Options ExecCGI в access.conf, написано выше).
Оба способа можно без проблем использовать совместно.
Прежде чем читать дальше, убедитесь в том, что:
error_log для того и служит, чтобы туда смотреть :-)
Возникает, если сервер не может отдать вам содержимое по причине отсутствия полномочий.
Проверьте:
Возникает в случае внутренней ошибки.
Проверьте:
print "Content-Type: text/html\n";
print "<HTML>\n";
Надо писать:
print "Content-Type: text/html\n\n"; # Два "\n"
print "<HTML>\n";
Также, эта ошибка возникает, если CGI-программа завершилась с ненулевым кодом возврата, что часто встречается в случае некомпилируемости вашего скрипта perl'ом.
Совет: делайте
use CGI::Carp qw(fatalsToBrowser)
во время отладки, тогда вам выдадут сообщение об ошибке perl.
apache устанавливает переменную окружения REMOTE_HOST, если ему разрешено проводить dns запросы для определения имени. Для 1.3.x по-умолчанию это выключено. Включается/выключается директивой HostNameLookups, которая может принимать 3 значения: on -- проводить запросы, off -- не запрашивать dns и double -- делать двойные запросы: запрашивать имя хоста, а затем по имени запрашивать ip адрес, для безопасности.
Переменная окружения REMOTE_USER устанавливается apache в случае, если скрипт защищен паролем. Как это сделать рассказано на http://www.apacheweek.com/features/userauth и http://www.apacheweek.com/features/dbmauth
Это perl, вкомпилированный в apache, что придает многие преимущества:
Правда, ничего не дается даром и самый важный недостаток mod_perl -- огромный расход памяти: если обычный apache занимает при работе обычно меньше мегабайта, то apache с mod_perl размером в 10-15 Mb -- вполне нормальное явление. Но, при правильной настройке, значительная часть этой памяти будет shared между копиями процессов.
Основной сайт про mod_perl - http://perl.apache.org, в частности великолепный mod_perl Guide на http://perl.apache.org/guide/.
Программа CGI исполняется один раз, за тем умирает. Под mod_perl же она загружается и исполняется до смерти сервера (в случае использования Apache::Registry, см. далее), поэтому она требует более аккуратного описания - закрывать файлы, не использовать много памяти, и тд.
Более подробно о переписывании программ CGI под mod_perl - http://perl.apache.org/guide/porting.html.
Да, можно. CGI не зависит от используемого языка программирования.
Это далеко неполный список. (Почти полностью списано из CGI_metaFAQ от brian d foy).
Вы можете использовать простой текстовый файл с разделителями. Например, если мы пишем нечто типа телефонной книги, то вполне вероятно предположить, что ни в чьем имени, ни в номере телефона не встретится последовательность ::, так что именно ее и можно использовать в качестве разделителей.
Файл с данными может выглядеть так:
phones.data
Иванов И.И.::888-0000::Какая-то улица, 17, кв 40
Сидоров П.И.::888-8429::Другая улица, 5, кв 21
...... и тд.
тогда программа, которая читает данные, может быть примерно такого вида:
dump_phones.pl
#!/usr/bin/perl
$filename = 'phones.data';
# открываем файл
open DATA, $filename or die "Невозможно открыть $filename: $!";
# читаем построчно из файла
while (<DATA>) {
chomp; # удаление символа конца строки
# теперь в $_ есть строка и мы ее разделяем на переменные
($name, $phone, $address) = split(/::/);
# и выведем на печать
print "Имя: $name, телефон: $phone, адрес: $address\n";
}
close DATA;
Больше проблем возникает в случае, если надо удалить или отредактировать запись, но и их можно довольно просто и элегантно решить, если использовать механизм редактирования на месте (inplace edit) -- при использовании операции "ромб"(<>), можно читать из одного файла, а писать в другой:
change_phones.pl
#!/usr/bin/perl
$^I = '~'; # запускаем inplace edit
while (<>) { # Обратите внимание, что мы не открывали файл: при такой
#конструкции имя файла берется из командной строки
chomp;
($name, $phone, $address) = split(/::/);
if (.... некоторое условие, при котором мы оставляем наши данные ... )
{
print "$name::$phone::$address\n"; # теперь данные есть в новом файле
}
}
если запустить это программу как
change_phones.pl phones.data,то в текущем каталоге будут два файла: phones.data, с записями, которые удовлетворили нашим условиям и phones.data -- предыдущая копия.
Также, во многих случаях, всю программу такого типа можно записать как one-liner:
perl -i~ -n -e 'print if(... условие)'
Для чтения двоичных файлов в Perl можно использовать функции read и unpack. К примеру, если использовать двоичный файл для хранения телефонной книги такого формата:
40 символов -- фамилия, И.О.
10 символов -- номер телефона,
60 символов -- адрес,
то строка описания формата для unpack будет выглядеть так:
$format_str = 'A40 A10 A60', а сама программа, аналогичная первому примеру:
binary_phones.pl
#!/usr/bin/perl
$format_str = 'A40 A10 A60';
open DATA, 'binary.dat' or die "$!";
while (read(DATA, $buf, 40+10+60)) { # <DATA> не покатит: такая
# конструкция будет читать до символа перевода строки, а это не то, что нужно
($name, $phone, $address) = unpack($format_str, $buf);
# Теперь в $name, $phone, $address есть данные и с ними можно делать
# все, что захочется
}
close DATA;
Чтобы вывести в файл такую запись можно использовать конструкцию типа
print FILE pack($format_str, $name, $phone, $address);
Да, можно. На http://www.fi.muni.cz/~adelton/ есть модуль XBase, который позволяет читать/писать dbf. При чтении он даже поддерживает индексы. Кроме того, в комплект поставки также входит модуль DBD::XBase, при помощи которого можно оперировать dbf на SQL (более подробно про DBI -- далее).
К файлам MS Access нельзя обращаться из perl напрямую, по крайней мере, в настоящее время.
К MS Access можно обращаться по ODBC, при помощи DBD::ODBC.
Представьте себе ситуацию когда одновременно работают несколько копий одной и той же программы (к примеру, cgi-скрипты, обслуживающие запросы), читающие/пишущие в один файл, тогда рано или поздно возникнет ситуация при которой один скрипт прочитал данные, произвел над ними некоторые действия и собрался записать их назад в файл, но в это же время другой скрипт тоже прочитал данные, тоже произвел над ними действия, но (!) он прочитал старые данные, которые он и запишет поверх данных, выданных другим скриптом. Таким образом, в файле останутся данные записанные одним из скриптов -- в лучшем случае, в худшем -- структура файла будет испорчена. Чтобы этого избежать в Unix и большинстве других ОС есть системный вызов flock(2) или аналогичный.
К примеру, скрипт который записывает имена вызывающих хостов в файл. (На деле такой список, конечно, можно получить из журнала регистрации web-сервера).
lock_exm.pl
#!/usr/bin/perl
use Fcntl; # Импорт констант
open (HOSTS, '>>hosts.log'); # Файл открыт для добавления записи
flock(HOSTS, LOCK_EX);
# Теперь файл заблокирован: Если любой другой скрипт тоже вызовет flock на
# этом файле, его flock не вернет управление в программу, пока мы не
# разблокируем файл. Обратите внимание: flock -- декларативная функция, если
# один из скриптов ее не использует при записи, то вся ваша блокировка не
# работает.
print HOSTS $ENV{REMOTE_HOST}, "\n"; # записали строку
close HOSTS; # Файл при закрытии разблокируется автоматически
# Вывести сообщение для пользователей
print "Content-Type: text/plain\n\n";
print "Название вашего хоста записано\n";
Более подробный рассказ о flock и пример доступны на http://w3.stonehenge.com/merlyn/WebTechniques/col04.html
Судя по perlfaq5(1), можно использовать модуль File::Lock с CPAN.
DBI -- это интерфейс прикладных программ к СУБД, использующим SQL в качестве языка запросов. Сам DBI определяет только набор функций, переменных и соглашений. Вся непосредственная работа выполняется Database Drivers (DBD) -- модулями, обеспечивающими связь с СУБД. DBI только обеспечивает стандартный интерфейс для этих драйверов.
Полная схема архитектуры при работе DBI выглядит примерно так:
+----------------------+
| Прикладная программа |
+----------------------+
| DBI |
+----------------------+
| DBD |
+----------------------+
| СУБД |
+----------------------+
обеспечивается при помощи метода connect класса DBI:
$dbh = DBI->connect($dsn, $user, $auth, {options});
Это объект, при помощи его методов осуществляются взаимодействия с СУБД.
Строка, определяющая к какой базе данных подсоединятся и другие параметры. Зависит от DBD. На сегодняшний момент стандарта нет, но рекомендовано использовать стиль ODBC:
&dbi:<имя DBD>:databasename=<название БД>;host=<Имя хоста>;port=<порт>&;
Имя пользователя.
Нечто, авторизующее пользователя. Обычно пароль.
Параметры DBI, передаются через анонимный хеш. В настоящее время понимаются три параметра:
если установлен, то при любой ошибке DBI убивает программу
если установлен, то при ошибке DBI вызывает warn
определяет порядок работы с транзакциями.
Например:
$dbh = DBI->connect('dbi:Pg:dbname=apavel', 'apavel', 'SomeSecret', {RaiseError=>1, AutoCommit=>0});Означает: Подсоедение к СУБД PostgreSQL, к базе данных apavel, с именем пользователя apavel и паролем. Все ошибки будут вызывать die, что удобно при отладке, а все изменения будут внесены только при подтверждении (commit) транзакций.
Отсоединение обеспечивается при помощи метода disconnect: $dbh->disconnect();
При работе с базами данных при помощи DBI используются курсоры -- специальные объекты, обеспечивающие последовательный доступ к результатам запросов. (В простейших случаях можно обойтись и без них, я расскажу об этом дальше.)
Пример таблицы, используемый в дальнейшем:
foo.sql
create table foo (
bar varchar(50),
baz int
)
$cursor = $dbh->prepare('select bar, baz from foo');
# теперь $cursor -- курсор, и его необходимо исполнить
$cursor->execute;
# После исполнения запроса, результат можно получить из курсора при помощи
# метода fetchrow_array
while (($bar, $baz) = $cursor->fetchrow_array) {
print "bar is: $bar, baz: $baz\n";
}
Очень часто бывает надо подготовить какой-либо запрос, а потом использовать его с разными значениями данных. DBI предлагает для механизм placeholders: В запросе на месте таких данных указываются вопросительные знаки, а сами значения передаются в метод execute() курсора. Например:
$cursor = $dbh->prepare('select bar from foo where baz=?'); $cursor->execute($baz);Особенно удобно это в случае вставки данных:
$cursor = $dbh->prepare('insert into foo(bar, baz) values(?, ?)'); while ( ... ) { $cursor->execute($bar, $baz); }
Таким образом, СУБД разбирает запрос только один раз, а затем просто исполняет его, что экономит время. (Естественно, это верно только для DBMS с раздельными parse и execute, сейчас ни MySQL, ни PostgreSQL такое не поддерживают, поэтому их реализации DBD просто сохраняют запрос переданный $dbh->prepare() и затем подставляют в него данные при каждом $sth->execute().)
DBI предоставляет несколько методов для такого рода работы: Методы для запросов:
Возвращает одну строку запроса в виде массива
Возвращает весь ответ сервера в виде массива ссылок на массивы.
исполняет запрос
Пример:
#получить значение bar при baz=3
($bar) = $dbh->selectrow_array('select bar from foo where baz=3');
# установить baz в некоторое значение при bar='somestring'
$dbh->do("update set baz=1 where bar='somestring'");
Можно несколькими способами: 1. Просто прокручивая курсор:
$c = $dbh->prepare('select baz, bar from foo');
$c->execute;
# если нужна последовательность с 26 по 50
for ($k = 0; $k < 26; $k++) {
$c->fetchrow_array;
}
# теперь можно вывести данные
print "<table border=1><tr><th>bar</th><th>baz</th></tr>\n";
while (($bar, $baz) = $c->fetchtrow_array) {
print "<tr><td>$bar</td><td>$baz</td></tr>\n";
}
$c->finish; # Закрыть курсор
print "</table>";
2. Используя курсоры СУБД
# Показан синтаксис PostgeSQL
$dbh->do('declare mycursor cursor for select bar, baz from foo');
$dbh->do('move 25');
# И теперь будем получать данные
$c = $dbh->prepare('fetch forward 25 in mycursor');
while (($bar, $baz) = $c->fetchrow_array) {
print ....;
}
$c->finish;
$dbh->do('close mycursor');
3. Для MySQL можно использовать директиву LIMIT
$c = $dbh->prepare('select bar, baz from foo limit 26,25');
while (($bar, $baz) = $c->fetchrow_array) {
print ....;
}
$c->finish;
Вроде как можно при помощи DBD::FreeTDS
Потому что на windows нет flock(2).
Используйте File::Lock с CPAN.
Windows это не unix. Они fork не умеют.
Perl для этого опирается на механизм locale. К счастью, это работает и на windows:
Если надо работать с CP866, пишем
use locale; use POSIX; &POSIX::setlocale(&POSIX::LC_ALL, "Russian_Russia.866"); print uc "Да, здесь будут заглавные буквы";
если KOI8 (sic!):
&POSIX::setlocale(&POSIX::LC_ALL, "Russian_Russia.20866");
если с CP1251 -- просто
use locale;
Со всеми тремя кодировками работают и uc/lc, и /\w/
Проверено под NT на perl 5.005_02, собраном через VC++ 5.0 из исходников, скачанных с CPAN/ports/win32/Standard/
Этому может быть миллион разных причин, но самая часто встречающаяся -- unix и наследники CP/M используют разные последовательности конца строки.
Если вы их загружаете по ftp, включите режим ASCII.