На первой странице указано играть «быстро», на второй — «очень быстро», на третьей — «гораздо быстрее», на четвертой — «быстро как только возможно» и все таки на пятой — «еще быстрее».
И. Ильф, Е. Петров «Золотой теленок»

 

 

Чтобы приложение, которым пользуется большое количество людей, работало быстро и четко, программист должен позаботиться об эффективности программ. К примеру, результат интернет-голосования можно отображать на экране с различной скоростью: от "быстро" до "быстро как только возможно" и даже " еще быстрее".

 

В №12/2001 К+П мы рассмотрели один из вариантов реализации интернет-голосования. Напомним, что идея заключалась в следующем: данные, введенные пользователем в форму для голосования, передавались на сервер, где обрабатывались CGI сценарием, написанным на языке Perl. Диаграмма же строилась при помощи Java-аплета. Является ли такое решение самым эффективным? Скорее нет, чем да. Ведь аплет выполняется на клиентском компьютере и для его работы запускается виртуальная Java машина, что само по себе занимает какое-то время. Кроме того, при каждом вызове html-страницы диаграмма строится заново, даже если результаты голосования не изменились.


В этой статье мы рассмотрим другой вариант интернет-голосования: данные будут обрабатываться на сервере PHP скриптом, который сгенерирует диаграмму в виде графического файла. Полученный рисунок в формате PNG будет передаваться на клиентскую машину и отображаться браузером.


Инструмент


Для создания графических изображений требуются специальные библиотеки подпрограмм, использующие, как правило, информацию о конкретном графическом устройстве пользователя. Например, рисование в Pascal-программе возможно при подключении модуля graph и наличии соответствующего драйвера; Windows-программа для рисования в окне получает контекст графического устройства; Java-аплет также получает объект Graphics от системы для вывода графики. Все рассмотренные примеры имеют одну общую черту: соответствующая программа работает на той же машине, где формируется изображение. Нам же нужно сформировать файл с изображением на веб-сервере, который к графическому устройству пользователя отношения не имеет.


К счастью, выход из этой ситуации есть. Томас Баутелл (Thomas Boutell) разработал графическую библиотеку GD, предоставляющую программисту возможность использования знакомых процедур рисования в расчете на запись полученного изображения в файл. Функции библиотеки GD могут быть вызваны в том случае, если для используемого языка программирования разработан соответствующий интерфейс. Такой интерфейс разработан и для языка Perl, но мы решили в качестве инструмента для разработки системы голосования использовать гипертекстовый препроцессор PHP1, также предоставляющий доступ к библиотеке GD и получающий все большую популярность среди интернет программистов и, что не менее важно, хостинг-провайдеров.


PHP, как и Perl, является языком интерпретирующего типа, однако перед каждым запуском сценария выполняется его трансляция в компактный код, размещаемый в памяти и значительно ускоряющий выполнение программы. В отличие от CGI скриптов, сценарий PHP может находиться в одном файле с html-текстом и более того — переплетаться с ним: можно сказать, что любой html-документ сам по себе является правильной программой на PHP.


Форма


Как театр — с вешалки, интернет голосование начинается с формы (см. рис. 1).

 


Скорее всего, голосование само по себе не является целью веб-дизайнера, а представляет собой некое дополнение к основной теме сайта. В таком случае html-код формы для голосования включается в текст одной из страниц (например, в index.htm):

 


Как указано в атрибуте action тега form , при нажатии накнопку «Проголосовать» данные из формы будут передаваться на сервер PHP-скрипту voting.php — именно в его задачу входит обработка этих данных и, при необходимости, формирование изображения. Обратите внимание, что кнопка «Проголосовать» получила в форме собственное имя — vote . При нажатии на кнопку это имя будет передано на сервер, в результате чего скрипт сможет распознать, был он вызван из формы или другим способом. Например, для просмотра результатов голосования мы используем тотже скрипт, передавая ему в качестве параметра переменную getres, равную единице (последняя строка html-кода).


Скрипт


Одно из основных преимуществ PHP для веб-программиста состоит в том, что много рутинной работы выполняется автоматически. Так, все параметры http-запроса без всяких усилий со стороны программиста становятся доступными в скрипте, как обычные переменные. Можно легко проверить, существует ли переменная с заданным именем, используя функцию IsSet. Так, блок операторов в нашем скрипте, стоящий после if(IsSet($vote)), выполнится только в том случае, если скрипт вызывается после нажатия пользователем кнопки «Проголосовать».


Чтобы проверить, не пытается ли пользователь проголосовать повторно, будем хранить в отдельном файле IP-адреса компьютеров, с которых ранее осуществлялись голосования, и проверять адрес нового пользователя на наличие в этом списке. Конечно, такой подход не идеален: во-первых, при динамическом выделении провайдером IP-адресов один и тот же пользователь в различных сеансах подключения к Сети может получить разные адреса и проголосовать таким образом дважды; с другой стороны, пользователь, получающий доступ в интернет через того же провайдера может быть лишен возможности проголосовать. Во-вторых, с увеличением числа проголосовавших будет расти время проверки адреса. Поэтому будем сохранять IP адреса лишь последних 10 пользователей.

 

Более  изящным было бы использование механизма cookies, но многие пользователи запрещают запись cookies на свой компьютер. Так что для «обеспечения равных возможно стей» приходится полагаться только на свои силы. 


Если пользователь голосует впервые, мы должны засчитать его голос. Данные о голосовании хранятся в отдельном файле (voting.dat). Этот файл текстовый, причем информация о каждом «кандидате» хранится в трех строчках:

  • первая строка — значение параметра CITY формы для голосования (в нашем случае — название города, записанное заглавными латинскими буквами);
  • вторая — подпись, которая будет выведена на диаграмму (у нас — название города, записанное кириллицей);
  • третья — число проголосовавших за этот пункт (город).

Для обновления данных нужно просмотреть все записи в файле и найти ту, в которой содержимое первой строки совпадает с переданным значением, то есть с содержимым переменной $CITY скрипта, — для этой записи количество проголосовавших нужно увеличить.

 


Обновив данные, приступаем к созданию самого изображения (см. рис. 2). Под диаграмму отведем 60 % ширины рисунка; остальная часть отводится под легенду. Сверху и снизу оставим поля размером по 10 % высоты рисунка. Цвета столбцов диаграммы выбираем случайным образом. Созданное изображение сохраняется в файле формата png. Этот формат обеспечивает сжатие изображения без потери качества и является хорошей альтернативой формату gif, который поддерживался старыми версиями библиотеки GD. Остается лишь вывести в браузер html-код загрузки готового изображения.


Если пользователь вызывает скрипт щелчком по ссылке «Посмотреть результаты», то в программу передается параметр getres со значением 1. Для проверки того, что со ответствующая переменная имеет ненулевое значение, можно использовать оператор if ($getres) — однако в том случае, если такой переменной нет (например, если скрипт был вызван просто вводом его URL в адресной строке браузера), будет выведено предупреждающее сообщение. Что бы подавить вывод такого сообщения, PHP позволяет установить перед «опасным» местом специальный знак — @, в результате чего наш оператор примет вид if ($getres). После этого в скрипте должен следовать набор инструкций, выводящих в браузер html-код загрузки изображения.


Наконец, если наш сценарий был вызван непосредственно, то, очевидно, будет разумным, если он будет выдавать в окно браузера тот html-документ, который содержит форму для голосования (мы считаем, что это index.htm).

 

Вот полный текст скрипта:

 

 

Еще быстрее...

 

Главным недостатком CGI сценариев, которые использовались нами для реализации интернет-голосования, считается неэффективное использование ресурсов сервера.


Вызов сценария (вне зависимости от того, написан он на Perl или PHP) приводит к порождению нового процесса на сервере. Вместо этого программа сервер может порождать, например, новые потоки, реализующие нужные действия. После загрузки исполняемого кода потока с диска он остается в оперативной памяти, в результате чего существенно сокращается время каждого последующего обращения. Такой механизм может быть реализован на языке компилирующего типа (например, С++) в виде ISAPI расширений — динамически загружаемых библиотек специального формата. Правда, ошибки в этом случае могут сказаться на функционировании самого сервера, поэтому использование ISAPI расширений возможно лишь с согласия хостинг-провайдера.

 

GD и кириллица

 

Библиотека GD содержит 5 стандартных шрифтов, отличающихся размерами символов, но не имеющих в своем составе букв кириллицы. Библиотека позволяет использовать растровые шрифты пользователя, а также TrueType шрифты (приналичии библиотеки FreeType). Поэтому следует узнать у хостинг провайдера, установлены ли на сервере файлы кириллических шрифтов, и где они находятся. В крайнем случае, можно создать собственный шрифт, воспользовавшись тем же PHP. Файл шрифта имеет следующую структуру: первые четыре байта занимает число символов в шрифте, следующие четыре — номер первого символа шрифта (обычно 32 — пробел), далее ширина и высота каждого символа в пикселях (оба поля — по 4 байта), после чего следует информация о начертании каждого символа шрифта, по одному байту на пиксель: нулевой байт соответствует отсутствию точки, ненулевой ее наличию. Поскольку файл — бинарный, он должен быть сгенерирован на машине, как минимум, с процессором той же архитектуры, что и на сервере (от этого зависит формат представления чисел). Для генерации файла шрифта на самом сервере нужно:


1. Выяснить раскладку букв кириллицы, используемую сервером. Для этого достаточно запустить на нем такой скрипт:

 


2. В соответствии с раскладкой букв, подготовить описание символов в виде матриц выбранного размера и написать еще один PHP сценарий. Вот пример начала такого скрипта, создающего шрифт с размером символа 8 ×12:

 


Если после описания всех символов скрипт получится слишком большим — возможно, его придется разбить на несколько частей, поочередно дописывающих в файл свою порцию символов (иначе может возникать пресловутая ошибка 500 — внутренняя ошибка сервера).

2004.07.01
19.03.2009
В IV квартале 2008 г. украинский рынок серверов по сравнению с аналогичным периодом прошлого года сократился в денежном выражении на 34% – до $30 млн (в ценах для конечных пользователей), а за весь календарный год – более чем на 5%, до 132 млн долл.


12.03.2009
4 марта в Киеве компания Telco провела конференцию "Инновационные телекоммуникации", посвященную новым эффективным телекоммуникационным технологиям для решения задач современного бизнеса.


05.03.2009
25 февраля в Киеве компания IBM, при информационной поддержке "1С" и Canonical, провела конференцию "Как сохранить деньги в условиях кризиса?"


26.02.2009
18-19 февраля в Киеве прошел юбилейный съезд ИТ-директоров Украины. Участниками данного мероприятия стали ИТ-директора, ИТ-менеджеры, поставщики ИТ-решений из Киева, Николаева, Днепропетровска, Чернигова и других городов Украины...


19.02.2009
10 февраля в Киеве состоялась пресс-конференция, посвященная итогам деятельности компании "DiaWest – Комп’ютерний світ" в 2008 году.


12.02.2009
С 5 февраля 2009 г. в Киеве начали работу учебные курсы по использованию услуг "электронного предприятия/ учреждения" на базе сети информационно-маркетинговых центров (ИМЦ).


04.02.2009
29 января 2009 года в редакции еженедельника "Computer World/Украина" состоялось награждение победителей акции "Оформи подписку – получи приз!".


29.01.2009
22 января в Киеве компания "МУК" и представительство компании Cisco в Украине провели семинар для партнеров "Обзор продуктов и решений Cisco Small Business"

 

 
 
Copyright © 1997-2008 ИД "Комиздат".