Запуск веб-сценаріїв на сервері apache

завдання
Ви хочете виконати програми на Perl, PHP або Python в веб-оточенні.

Рішення
Запустіть їх за допомогою сервера Apache.

Обговорення
У цьому розділі розказано про те, як налаштувати Apache для запуску сценаріїв Perl, PHP і Python, і показані приклади веб-сценаріїв на кожному з цих мов.

Кореневої каталог Apache (будемо вважати, що це каталог / usr / local / apache) включає наступні каталоги:

bin
Містить httpd, тобто сам Apache, а також інші виконувані программи.conf
Файли, в тому числі httpd.conf, основний файл, який використовується Apache.

htdocs
Корінь дерева документів.

logs
Лог-файли.
Щоб налаштувати Apache для виконання сценаріїв, необхідно відредагувати файл httpd.conf в каталозі conf. Зазвичай виконувані сценарії характеризуються або розташуванням, або розширенням імені файлу. Розташування файлу може залежати або не залежати від мови.

Конфігурації Apache часто містять всередині кореневого каталогу сервера каталог cgi-bin, де встановлюються сценарії, які повинні запускатися як зовнішні програми.


Він задається за допомогою директиви ScriptAlias:

ScriptAlias ​​/ cgi-bin / / usr / local / apache / cgi-bin /

У такій конфігурації каталог cgi-bin може містити сценарії, написані на будь-якій мові. Тому каталог нейтральний по відношенню до мови, і сервера Apache необхідно якось зрозуміти, який інтерпретатор використовувати для виконання кожного з пасажирів каталозі сценаріїв. Для забезпечення такої інформація перший рядок сценарію повинна починатися з символів #! і шляхи до програми, яка виконує сценарій, а також, можливо, якихось опцій. Наприклад, сценарій, який починається з рядка, наведеної нижче, буде запущений за допомогою Perl, а опція -w вказує Perl на необхідність видачі попереджень з приводу сумнівною
тільних мовних конструкцій:

В UNIX для коректної роботи сценарію необхідно зробити сценарій виконуваним (за допомогою команди chmod + x).


Наведена рядок #! підходить для системи, в якій Perl встановлений як / usr / bin / perl. Якщо інтерпретатор Perl встановлений в якомусь іншому каталозі, змініть рядок відповідним чином. Якщо ви працюєте в Windows, і Perl встановлений як D:

\ Perl \ bin \ perl.exe, то рядок #! повинна виглядати так:

#! D: \ Perl \ bin \ perl -wУ користувачів Windows є й інша можливість - задати відповідність розширення імені файлу .pl інтерпретатора Perl. Тоді сценарії можуть починатися так:

#! perl -w
Директива ScriptAlias ​​визначає каталог, який може використовуватися для сценаріїв, написаних на будь-яких мовах. Є також можливість зіставити каталогу якийсь певний мовний процесор, тоді будь-який сценарій каталогу буде вважатися написаним на даній мові. Наприклад, щоб призначити каталог / usr / local / apache / cgi-perl каталогом mod_perl, можна конфігурувати Apache так:


Alias ​​/ cgi-perl / / usr / local / apache / cgi-perl /

SetHandler perl-script
PerlHandler Apache :: Registry
PerlSendHeader on
Options + ExecCGI

Тоді можна викликати розташовані в каталозі сценарії Perl так:

Використання mod_perl виходить за рамки нашого обговорення, так що не будемо про нього більше говорити.


Деякі джерела корисної інформації про mod_perl наведені в додатку C.

Каталоги, які використовуються виключно для зберігання сценаріїв, зазвичай розташовуються поза дерева документів Apache. Альтернативою використання спеціальних каталогів для сценаріїв може служити ідентифікація сценаріїв по розширенню імені файлу: імена з певним розширенням зіставляються вказаною мовною процесору. Тоді такі файли можна розміщувати в дереві документів де завгодно. Зазвичай саме так працюють з PHP. Наприклад, якщо ваш сервер Apache налаштований з вбудованою підтримкою PHP за допомогою модуля mod_php, ви можете вказати йому, що сценарії, імена яких закінчуються на .php, повинні інтерпретуватися як сценарії PHP. Для цього додамо в httpd.conf такий рядок:

AddType application / x-httpd-php .php

Якщо тепер встановити сценарій PHP myscript.php в htdocs (кореневої каталог документів Apache), то URL для виклику сценарію буде таким:

Якщо PHP запускається як зовнішня автономна програма, необхідно повідомити Apache, де її слід шукати. Наприклад, якщо ви працюєте в Windows, а PHP інстальований як D: \ Php \ php.exe, помістіть в httpd.conf сле-дмуть рядки (зверніть увагу на використання в шляхах символів прямого слеша, а не зворотного):

ScriptAlias ​​/ php / "D: / Php /"
AddType application / x-httpd-php .php
Action application / x-httpd-php /php/php.exe

Наводячи URL в прикладах, я буду вважати, що сценарії Perl і Python знаходяться в каталозі cgi-bin, а сценарії PHP - в каталозі mcb вашого дерева документів, і мають розширення .php. Тобто URL сценаріїв на цих мовах будуть виглядати так:

Якщо ви плануєте використовувати подібні налаштування, переконайтеся в тому, що в вашому кореневому каталозі Apache є каталог cgi-bin, а в кореневій папці документів Apache - каталог mcb. Потім для роботи з веб-сценаріями Perl або Python слід скопіювати їх в cgi-bin, а сценарії PHP - в mcb.Еслі ви звертаєтеся до веб-сценарію, а у відповідь отримуєте сторінку з помилкою, зверніться до балці помилок Apache, з якого можна отримати важливу інформацію про те, чому сценарій не працює. Зазвичай лог помилок зберігається в файлі error_log каталогу logs. Якщо ви не знайшли такої файл, подивіться в конфігураційному файлі httpd.conf, як встановлена ​​директива ErrorLog.

Сконфігурованої Apache для виконання сценаріїв, ви можете приступити до їх написання для генерації веб-сторінок. У решти даного розділу розповідається, як це зробити на Perl, PHP і Python. У прикладах для кожного з мов встановлюється з'єднання з сервером MySQL, виконується запит SHOW TABLES і результат відображається на веб-сторінці.

У наведених тут сценаріях вказані додаткові модулі і бібліотеки, які повинні бути в них включені. (Надалі будемо припускати, що відповідні модулі вже підключені, і показувати тільки фрагменти сценаріїв.)

Perl
Нижче наведено наш перший веб-сценарій на Perl, show_tables.pl. Він створює заголовок відповідно до зазначеного Content-Type. порожній рядок, що відокремлює заголовок від тіла сторінки, і початкову частину сторінки. Потім сценарій отримує і відображає список таблиць бази даних cookbook. Після списку таблиць виводяться завершальні HTML-теги, що закривають сторінку:

#! / Usr / bin / perl -w
# Show_tables.pl - Виконати запит SHOW TABLES і показати результат,
# Генеруючи безпосередньо HTML
use strict;
use lib qw (/ usr / local / apache / lib / perl);
use Cookbook;
# Вивести заголовок, порожній рядок і початок сторінки
print

Tables in cookbook Database

Tables in cookbook database:


EOF
# Помилка з'єднання з БД, показати список таблиць, відключитися
my $ dbh = Cookbook :: connect ();
my $ sth = $ dbh-> prepare ( "SHOW TABLES");
$ Sth-> execute ();
while (my @row = $ sth-> fetchrow_array ())
print "$ row [0]
\ N ";>
$ Dbh-> disconnect ();
# Вивести завершальні теги
print

EOF
exit (0);

Для перевірки сценарію помістіть його в каталог cgi-bin і викличте з броузера так:

У сценарії show_tables.pl HTML генерується включенням в оператори виведення литералов, що представляють теги. Інший підхід до генерації веб-сторінок реалізований в модулі CGI.pm, який спрощує створення веб-сценаріїв, не вимагаючи буквального написання тегів. Модуль CGI.pm пропонує як об'єктно-орієнтована, так і функціональний інтерфейс, дозволяючи створювати веб-сторінки будь-яким з цих методів. Сценарій show_tables_oo.pl використовує об'єктно-орієнтований інтерфейс для створення того ж звіту, що і show_tables.pl:

#! / Usr / bin / perl -w
# Show_tables_oo.pl - Виконати запит SHOW TABLES і показати результат,
# Використовуючи об'єктно-орієнтований інтерфейс CGI.pm
use strict;
use lib qw (/ usr / local / apache / lib / perl);
use CGI;
use Cookbook;
# Створити CGI об'єкт для доступу до методів CGI.pm
my $ cgi = new CGI;
# Вивести заголовок, порожній рядок і початок сторінки
print $ cgi-> header ();
print $ cgi-> start_html (-title => "Tables in cookbook Database", -bgcolor => "white");
print $ cgi-> p ( "Tables in cookbook database:");
# Помилка з'єднання з БД, показати список таблиць, відключитися
my $ dbh = Cookbook :: connect ();
my $ sth = $ dbh-> prepare ( "SHOW TABLES");
$ Sth-> execute ();
while (my @row = $ sth-> fetchrow_array ())
print $ row [0]. $ Cgi-> br ();
>
$ Dbh-> disconnect (); # Вивести завершальні теги
print $ cgi-> end_html ();
exit (0);

Сценарій включає модуль CGI.pm, використовуючи директиву use CGI, потім створює CGI-об'єкт $ cgi, за допомогою якого звертається до різних методів генерації HTML. Метод header () створює заголовок Content-Type. а метод start_html () формує початкову частину сторінки аж до відкриваючого тега (body). Після створення першої частини сторінки сценарій отримує інформацію з сервера бази даних і відображає її. Ім'я кожної таблиці супроводжується тегом
, який формується викликом методу br (). Метод end_html () виводить завершальні теги і. Встановивши сценарій в каталог cgi-bin і викликавши його з броузера, ви побачите, що він генерує таку ж сторінку, як і show_tables.pl.

Функції CGI.pm можуть приймати безліч параметрів, частина яких є обов'язковими. Щоб дозволити вам вказувати тільки необхідні параметри, CGI.pm дозволяє використовувати в списку параметрів нотацію -ім'я => значення. Наприклад, у виклику start_html () параметр title призначає заголовок сторінки, а bgcolor - колір фону. Нотація -ім'я => значення дозволяє вказувати параметри в будь-якому порядку, так що два наступних пропозиції еквіваленти:

print $ cgi-> start_html (-title => "My Page Title", -bgcolor => "white");
print $ cgi-> start_html (-bgcolor => "white", -title => "My Page Title");

Щоб використовувати функціональний, а не об'єктно-орієнтований інтерфейс CGI.pm, слід трохи змінити сценарії. Рядок use, що посилається на CGI.pm, імпортує назви методів в простір імен сценарію, і ви можете викликати їх як функції, не створюючи об'єкт CGI. Наприклад, щоб імпортувати найбільш поширені методи, сценарій повинен містити таку пропозицію:

use CGI qw (: standard);

Сценарій show_tables_fc.pl - це еквівалент щойно розглянутого show_tables_oo.pl, але написаний з використанням викликів функцій. Застосовуються ті ж методи CGI.pm, але викликаються вони як автономні функції, а не через об'єкт $ cgi:

#! / Usr / bin / perl -w
# Show_tables_fc.pl - Виконати запит SHOW TABLES і показати результат,
# Використовуючи функціональний інтерфейс CGI.pm
use strict;
use lib qw (/ usr / local / apache / lib / perl);
use CGI qw (: standard); # Імпортувати імена стандартних методів
# В простір імен сценарію
use Cookbook;
# Вивести заголовок, порожній рядок і початок сторінки
print header (); print start_html (-title => "Tables in cookbook Database", -bgcolor => "white");
print p ( "Tables in cookbook database:");
# Помилка з'єднання з БД, показати список таблиць, відключитися
my $ dbh = Cookbook :: connect ();
my $ sth = $ dbh-> prepare ( "SHOW TABLES");
$ Sth-> execute ();
while (my @row = $ sth-> fetchrow_array ())
print $ row [0]. br ();
>
$ Dbh-> disconnect ();
# Вивести завершальні теги
print end_html ();
exit (0);

Помістіть сценарій show_tables_fc.pl в каталог cgi-bin і переконайтеся в тому, що він формує такий же висновок, як і show_tables_oo.pl.

Далі в книзі для веб-сценаріїв Perl використовується функціональний інтерфейс CGI.pm. Якщо вас цікавить додаткова інформація про CGI.pm, ви можете виконати з командного рядка наступні команди, які забезпечать доступ до наявної документації:

% Perldoc CGI
% Perldoc CGI :: Carp

Інші джерела інформації про це модулі, як друковані, так і доступні в Інтернеті, наведені в додатку C.

PHP
Як це не дивно для веб-орієнтованої мови, PHP не надає можливостей скороченого завдання тегів. Але оскільки PHP є вбудовуваним мовою, ви можете просто буквально писати HTML в сценарії, не користуючись пропозицією print. Розглянемо сценарій show_tables.php, який переключається між режимами HTML і PHP:




Tables in cookbook Database

(Body bgcolor = "white")

Tables in cookbook database:

Щоб протестувати сценарій, помістимо його в каталог mcb дерева документів веб-сервера і викличемо його так:

На відміну від Perl-версій сценаріїв виведення списку таблиць MySQL, сценарій PHP не містить коду для виведення заголовка Content-Type. так як PHP формує його автоматично. (Якщо вас не влаштовує такий стан справ, і ви хочете виводити свої заголовки, зверніться до опису функції header () в керівництві по PHP.)

Якщо не брати до уваги тегів розриву рядків, весь вміст HTML в сценарії show_tables.php розміщується за межами тегів. так що інтерпретатор PHP просто виводить його без інтерпретування. Наведемо версію сценарію, яка формує весь HTML за допомогою пропозицій print:

\ N ");
print ( "\ n");
print ( "Tables in cookbook Database \ n");
print ( "\ n");
print ( "\ n");
print ( "

Tables in cookbook database:

\ N ");
# Помилка з'єднання з БД, показати список таблиць, відключитися
$ Conn_id = cookbook_connect ();
$ Result_id = mysql_query ( "SHOW TABLES", $ conn_id);
while (list ($ tbl_name) = mysql_fetch_row ($ result_id))
print ( "$ tbl_name
\ N ");
mysql_free_result ($ result_id);
mysql_close ($ conn_id);
print ( "\ n");
print ( "\ n");
?>

Іноді розумно застосувати один підхід, іноді - інший, а іноді навіть обидва відразу в одному і тому ж сценарії. Якщо розділ HTML не посилається на жодні значення змінних і виразів, то, ймовірно, краще записати його в режимі HTML. В іншому випадку краще використовувати пропозицію print або echo, щоб уникнути частого перемикання між режимами HTML і PHP.

Python
Стандартна інсталяція Python включає корисні для веб-програмування модулі cgi і urllib. Однак насправді вони нам поки не потрібні, оскільки єдине, що буде робити наш перший веб-сценарій на Python, - генерація простого HTML-коду. Напишемо на Python версію сценарію, котрий виводить список таблиць MySQL:

#! / Usr / bin / python
# Show_tables.py - Виконати запит SHOW TABLES і показати результат
import sys
sys.path.insert (0, "/ usr / local / apache / lib / python")
import MySQLdb
import Cookbook
# Вивести заголовок, порожній рядок і початок сторінки
print "" "Content-Type: text / html


Tables in cookbook Database

(Body bgcolor = "white")

Tables in cookbook database:


"" "
# Помилка з'єднання з БД, показати список таблиць, відключитися
conn = Cookbook.connect ()
cursor = conn.cursor ()
cursor.execute ( "SHOW TABLES")
for (tbl_name,) in cursor.fetchall ():
print tbl_name + "
"
cursor.close ()
conn.close ()
# Вивести завершальні теги
print "" "
(/ Body)

"" "

Помістіть сценарій в каталог Apache cgi-bin і викличте його так: