AboutPC
Реклама в журнале
 [скрыть меню]

Раздел "Веб-дизайн". Содержание:

Статьи:

Вперед Необходимый минимум SSI
Вперед Как сдружить SSI и Perl
Вперед Как правильно надо писать скрипты
Вперед Параллельное выполнение скриптов может нарушить целостность информации в файлах
Вперед Графический счетчик на PHP

Раздел "Веб-дизайн". Рассылка от ведущего раздела:

 

Раздел "Веб-дизайн". Статьи:

В конец страницы

Необходимый минимум SSI

Автор:Alexey Godovnik
E-mail:godovnik@mail.ru

Наряду с неоспоримыми достоинствами бесплатного хостинга, есть и существенные недостатки. Больше всего меня раздражает отсутствие SSI. Если и вас тоже, сообщаю: Выход есть! И довольно простой, как в поговорке про все гениальное.

Для тех, кто не в курсе, поясняю. Вам наверняка хоть раз в жизни приходилось собирать мозаику. Ну, или хотя бы соединять вместе несколько частей в одно целое. В этом и заключается идея SSI - собирать свой сайт из HTML-фрагментов. Для чего это нужно? Как правило, на каждом сайте некоторые детали присутствуют на всех страничках сайта. У меня, например, таким является оглавление слева. И web-мастеры при создании новых документов просто переписывают их туда. А если вдруг захочется изменить внешний вид, приходится вносить изменения во все файлы. А если сайт содержит много информации, то реконструкция сайта превращается в тягомотину. Можно, конечно, использовать фреймы (про них рассказано в "HTML за полчаса", но у них есть свои недостатки.

Предлагаемый мною способ, конечно, далек от совершенства, но он лучше, чем ничего, да и не так уж плох (на мой субъективный взгляд).

Итак, все дело в следующем: как вы знаете (а если не знаете, то я с удовольствием вас информирую), в HTML документ можно встраивать скрипты, написанные на различных языках. Один из них - JavaScript - довольно прост (о нем рассказано в статье Основы JavaScript) и имеет то преимущество, что его понимают все браузеры, а для выполнения используются ресурсы компютеров ваших посетителей.

Так вот, скрипт на JavaScript не обязательно встраивать в HTML документ, что бы там ни было написано в инструкции по его использованию. Он может располагаться в отдельном файле, следовательно, на него можно ставить ссылку/сноску из любого другого документа, следовательно, его можно написать только один раз и использовать в неограниченном количестве документов.

Наши файлы-кусочки будут иметь содержание

document.write('ваш HTML-код');

или

document.write("ваш HTML-код");

количество таких записей неограничено, внутри кавычек/апострофов вы пишете строчку с вашим HTML. Естественно, что если вам надо использовать кавычки, вы берете первый вариант, а если апострофы, то второй. Файл с кусочком встраиваемого HTML сохраняете в виде name.js, где вместо name используете любую комбинацию цифр и латинских букв.

Когда вы написали все фрагменты, начинаем их склеивать. В том месте, где должен быть нужный элемент, пишем

<script language="JavaScript" src=source></script>

,где source - адрес этого фрагмента.

Таким образом, ваша страничка (в идеальном варианте) будет иметь следующий вид

<html><head>
<title>Название страницы</title>
<meta name="description" content="описание странички">
<mete name="keywords" content="ключевые слова через пробел">
<script language="JavaScript" src="body.js"></script>
<script language="JavaScript" src="content1.js"></script>
...
<script language="JavaScript" src="contentX.js"></script>
</body></html>

По-моему, вполне элегантно.

Только старайтесь, чтобы ваши кусочки были осмысленными, самостоятельными и логически законченными. Потому что если написать какой-нибудь открывающий тег в одном, а закрывающий в другом фрагменте, скорее всего не сработает.

Не бойтесь того, что общий размер странички увеличивается из-за многократного повторения document.write. Так как страничка состоит из нескольких кусочков, ее загрузка будет происходить даже немного быстрее.

Если захотите что-либо уточнить, пишите. НО!!! Я не буду отвечать на вопросы типа "я все сделал так как написано, но ничего не работает". Значит, не совсем так. Шевелите извилинами и ищите ошибки. Самая распространная - многие забывают, что в адресах и в JavaScript большие и маленькие буквы РаЗлИчАюТсЯ.

Передача и обработка данных средствами SSI

Передача данных (1-й способ)

Данные передаются точно так же, как и для обычных html файлов - через URL либо с помощью формы методом GET. В принципе, и обрабатывать их можно точно так же. Но, если вы хотите изменять SSI-вставку в зависимости от переданных данных, читайте дальше.

Особенности

Для SSI данные лучше передавать в виде name=value. Метод GET формы так и делает, а вот если вы самостоятельно формируете строку запроса, она должна выглядеть так:

file.shtml?var1=value1&var2=value2 и т.д. 
Получение данных

Нам мало передать данные. Нам надо еще и получить их. Для того, чтобы увидеть, что мы там себе передали, включите в файл строку

<!--#printenv -->

Эта строка нам в дальнейшем не понадобится. Она нужна лишь для того, чтобы увидеть, передается ли хоть что-нибудь. В дальнейшем, если что-то не так пойдет, вставьте эту строку в файл и проверьте, может вы где-то не так буковку написали.

Самый простой способ использования

Допустим, у вас на сайте есть FAQ, но ответы на вопросы такие объемные, что хотелось бы выводить их по одному и при этом, если потом приспичит поменять дизайн, чтобы долго не возиться. Мы делаем одну страничку (назовем ее faq.shtml), оформляем ее как положено, а в том месте, где должен быть ответ, пишем

<!--#include virtual="${file}" -->

Учтите, что может быть, для вашего сервера надо использовать не фигурные, a круглые скобки или даже вообще без них обойтись.

Теперь ответы на вопросы пишем каждый в своем html-файле, в котором нет ничего, кроме текста да тегов, с ним связанных (B, FONT и т.д), и желательно не использовать атрибуты COLOR, чтобы потом не мучаться.

Ссылки на ответы надо делать следующим образом

<a href="faq.shtml?file=url">

где url - адрес html-файла, содержащего ответ, можно относительный - только смотрите не запутайтесь.

В принципе, весь сайт можно организовать по такому принципу. Если вы любите менять дизайн, то чтобы это сделать, достаточно будет изменить всего один файл - и вот у вас новый сайт. Обработка данных

Все это хорошо. Но хочется еще чего-нибудь похитрее. Если вы уже знакомы с SSI, дальше нового вы не узнаете, если нет - читайте.

В файлах SSI можно использовать переменные. Они объявляются так

<!--#set var="name" value="value" -->

Передача данных

file.shtml?username=Alexey&birth=1974

эквивалентно

<!--#set var="username" value="Alexey" -->
<!--#set var="birth" value="1974" -->

Возможности по использованию этих бесценных сведений в SSI довольно ограничены, но мы можем попытаться с ними что-нибудь сделать.

Можно просто вставить переменную в документ.

<!--#echo var="name" -->

Например, используя переданные ранее данные, можно написать

Привет, <!--#echo var="username" -->

В результате чего на экране появится Привет, Alexey

Пример посложнее. Если в файле написать

<!--#set var="title" value="заголовок" -->

то потом в вызывающем файле можно использовать

<title><!--#echo var="title" --></title>

Таким образом, мы можем передавать из включаемых файлов в вызываемые различные конфиденциальные сведения. Пользователь не видит инструкции SSI - они обрабатываются сервером и передаются уже в итоговом, "готовом к употреблению" виде.

Можно поизвращаться и попробовать проанализировать переданные данные и на их основе что-нибудь сделать.

Условные операторы выглядят так

<!--#if expr="condition" -->
<!--#elif expr="condition" -->
<!--#else -->
<!--#endif -->

Элемент endif является обязательным. elif можно повторять сколько угодно раз. После if и elif пишется HTML-код, который будет подставляться при истинности условия. После else пишется код, который подставится, если ни одно из имеющихся ранее условий не выполнилось.

Например

<!--#if expr=($username="Alexey") -->
<h1>Привет, <!--#echo var="username" --></h1>
<!--#else -->
<b>Привет, <!--#echo var="username" --></b>
<!--#endif -->

Такой нехитрый код выводит приветствие, но если человека зовут Alexey, буквы будут чуть-чуть побольше. Передача данных (2-й способ)

Можно передавать данные и средствами SSI. Плюс у этого метода в том, что он, в отличие от первого способа, проходит незамеченным для пользователя. Чтобы передать данные, надо их присвоить какой- нибудь переменной. Все переменные, объявленные в файле, доступны и в вызываемых, и в вызывающих файлах. Но!!! Само cобой разумеется, что надо сначала подключить файл, а потом использовать имеющиеся в нем данные, а в подключаемых файлах использовать можно только то, что имеется к моменту подключения. Второй способ организации сайта

Он немножко сложнее, но (имхо) прогрессивнее.

Все свои статьи пишем в формате html, но избегаем применения тегов, меняющих цвет, и не указываем body. Сохраняем (допустим в файле text.html), и запоминаем адрес этого сайта. Никому его не говорим - он будет для сугубо внутреннего использования.

Теперь создаем "публичный" файл для этой статьи, его мы будем заносить в каталоги и рекомендовать знакомым. Он состоит всего из нескольких строчек.

<html>
<!--#set var="description" value="описание" -->
<!--#set var="title" value="Заголовок" -->
<!--#set var="keywords" value="ключевые слова" -->
<!--#set var="file" value="url статьи" -->
<!--#include virtual="файл интерфейса.shtml" -->

Как видите, мы указали в нем заголовок, ключевые слова, описание и "приватный" файл, в котором содержится статья (text.html). Можно еще написать то, что вы там еще обычно пишете в заголовке. Я чаще всего ограничиваюсь одним title. Как-то спокойно отношусь к тому, что релевантность маленькая окажется :-).

Теперь создаем файл интерфейса (*,shtml). Начало его выглядит так:

<html><head>
<title><!--#echo var="$title" --></title>
<meta name="description" content="<!--#echo var="$description" -->">
<meta name="keywords" content="<!--#echo var="$keywords" -->">
</head>

Далее оформляем внешний вид - вешаем баннеры, вставляем счетчики, добавляем новости и т.д. Наконец в том уголке, где должна быть статья, пишем

<!--#include virtual="$file" -->

Теперь для радикального изменения дизайна всего сайта достаточно изменить лишь наш файл интерфейса. Нюансы

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

Вставьте строку <!--#printenv --> и посмотрите, есть ли вообще у вас хоть какие-то переменные. Если есть, но использовать их не получается, попробуйте другой способ написания:

"name"
"$name"
$name
"${name}"
"$(name)"

Один из них сработает.

Если у вас не работает даже printenv, Возможно, вам сначала нужно сделать из своего компьютера сервер. Самый простой способ - установить программу Small Http Server. Проста в установке и использовании, инструкция на русском языке. После установки сможете тестировать на своем компе CGI, SSI, PHP и т.д.

Назад В начало страницы На главную страницу В конец страницы Вперед 

В конец страницы

Как сдружить SSI и Perl

Автор:Р-code
Сайт:www.cdx.ru

Обычно, в CGI хостерами запрещается выполнение SSI. И как тут быть, если ваши страницы строятся из нескольких кусков текста? Например меню и шапка вашего сайта берется из одного файла все время, а конец страниц еще из другого.

Если есть SSI, то мы просто пишем в каждом файле вначале:
<!--#include virtual="/top.shtml"-->
и в конце:
<!--#include virtual="/end.shtml"-->
имея в виду, что в top.shtml у нас шапка, а в end.shtml - конец.

Ну вот написали, все у нас работает. Далее нам понадобилось например вставлять эти же самые файлы при выводе в CGI скрипте.

Но и здесь можно написать процедурку, что-то в виде:
sub outp {
my $file=$_[0];
open (F, "$file");
my @FILE=;
close(F);
foreach (@FILE) {print $_}
}

И далее в скрипте писать:
&outp("top.shtml");
и
&outp("end.shtml");
для вывода в скрипте шапки и конца генерируемой страницы.

Все это хорошо работает, пока вы не станете использовать в top.shtml и end.shtml SSI вставки. Они в CGI скриптах у многих хостеров работать не будут. Выходим из данной проблемы следующим способом:

1. в top.shtml и end.shtml через SSI вставляем только CGI скрипты. Есть это статический текст - сразу вставляем его в эти файлы, а не пишем что-то вроде <!--#include virtual="/day.txt"-->

2. Скрипты, что мы хотим вставлять в top и end, переделываем:

Например, если скрипт у нас называется c.cgi, изменяем в нем:
#!/usr/bin/perl

print "Content-Type:text/html\n\n";
require "c.pm";
далее в c.pm записываем сам скрипт. То есть делаем из него библиотеку. На этом шаге у нас для shtml файлов все заработало как надо. Ну в общем как и было. У нас же не работали вставки на CGI скриптах.

3. Переделываем нашу процедуру outp в следующий вид:

sub outp {
my $file=$_[0];
open (F, "$file");
my @FILE=<F>;
close(F);
foreach (@FILE) {
if (/<!--\#include virtual="\/(.+)\.cgi"-->/) {
require "$1.pm";
}
else {
print $_
}
}
}

В таком виде процедура наша при виде строки со вставкой CGI скрипта вызовет библиотеку с аналогичным названием.

Вот и все, теперь в top.shtml и end.shtml можно вставлять cgi скрипты и не беспокоиться о том, что в самих скриптах они не сработают.

Назад В начало страницы На главную страницу В конец страницы Вперед 

В конец страницы

Как правильно надо писать скрипты

Автор:Р-code
Сайт:www.cdx.ru

9 правил, которые помогут вам при создании скриптов

1. Проверяйте все входные данные, которые передаются по форме. Например, если в переменной должна прийти дата - проверьте являются ли пришедшие данные датой. Даже если в форме предлагается выбор этих самых дат. Помните, форму всегда можно сохранить локально и поправить ее на свое усмотрение.

2. Проверяйте входные данные, чтоб они были только в пределах диапазона, указанного вами. Например, если это год рождения, то он не может иметь значение 1200, 2010.

3. Длина слов. Учитывайте то, что пользователи могут ввести в вашу форму все что они захотят. Обычно длинное словосочетание букв без пробела браузерами отображается без переноса на новую строку. Это может испортить вид ваших страниц при показе таких данных.

Либо запрещайте ввод таких длинных слов, либо разделяйте длинные слова принудительно. Либо при выводе укорачивайте слова, которые мешают ширине колонок и т.д.

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

5. Поле пароля.
Никогда не показывайте в форме пароля его текущее значение. Помните о том, что в этом случае пароль может попасть остаться в компьютере в так называемом каталоге временных файлов Интернета. А если это общественный компьютер? Тогда следующий кто сядет за него может легко узнать пароль. Кроме того форму с паролями обязательно отправляйте по методу POST.

6. Модерирование.
В вашем скрипте обязательно должно быть предусмотрено модерирование. Это относится больше к доскам объявлений, но не помешает и для других скриптов. Если ваша доска объявлений тематическая, то пиши не пиши об этом, пользователи все равно будут пытаться заслать на него объявления левого содержания(спам). Пользователям, которые пришли на вашу доску в надежде прочитать объявления например о компьютерной барахолке, не шибко понравится чтение объявлений о недвижимости.

Модерирование можно сделать пост-(когда вначале попадают, а после модерируются) или модерируемой(когда сообщения попадают после модерирования). Первое более предпочтительно, ибо те, кто пишет нормальные сообщения сразу могут выставить свои сообщения. Во втором случае необходимо частое присутствие на вашем скрипте. Чтоб все время следить, иначе пользователи, что послали сообщение и не увидели его в течение нескольких дней могут подумать о том, что ваш ресурс закрыт, мало обновляется.

7. Кавычки.
Заменяйте в получаемых данных все кавычки на ESCAPE-последовательность. Например, кавычку на ". Данные в форму можно ввести так, что браузер при отображении может много чего натворить с вашей страницей. Например, можно вставить скрипт на Java, изменить оформление. Кроме того если это у вас форум или гостевая, можно заменять два пробела на пробел с  , для того чтоб количество пробелов отображалось верное.

8. Пароли.
Храните пароли на сайте в закодированном виде. Если пользователь забыл пароль, - меняйте его на адракадабру и выдавайте по e-mail. При этом обязательно выдавайте вначале ссылку для подтверждения, иначе кто-либо ради например мести, может поменять чужому аккаунту пароль. Пусть даже тот пользователь и будет знать пароль, но помните, это жуть как неудобно, когда ты узнаешь, что вместо нормального пароля к которому ты привык, тебе придется использовать абракадабру.

9. Метки, разделители.
Всегда заменяйте метки и разделители, которые вы используете для сохранения информации или отображения, на что-то подобное. Иначе ваши данные могут испортиться, повредиться. Даже если ваша метка выглядит как какая-то абракадабра, все равно имеется какой-то мизерный шанс, что его пользователь введет в форму.

Назад В начало страницы На главную страницу В конец страницы Вперед 

В конец страницы

Параллельное выполнение скриптов может нарушить целостность информации в файлах

Здесь рассматривается вопрос, что бывает, если запустить некий скрипт почти одновременно (что происходит, например, при большой нагруженности сервера) несколько раз, т.е. запустить несколько копий одного и того же скрипта. И к чему это может привести.

Ошибка программы простого текстового счетчика

Давайте сделаем такую программу. Итак, у нас есть какая-то страница, на которой хочется повесить счетчик. Обудим алгоритм:

  • считать число из файла
  • записать увеличенное число обратно
  • вывести его на экран

Согласитесь, программа простая, но может привести к ошибке, что и показано ниже.

<?
// верхняя часть страницы
// код счетчика:

$counter=file("counter.txt"); // прочитали файл в массив $counter
$f=fopen("counter.txt","w+"); // открыли файл на запись
fputs($f,$counter[0]+1); // записали "число + 1"
fclose($f); // закрыли файл
echo $counter[0]+1; // вывели число на экран
// нижняя часть страницы
?>

Если вызывать данную программу очень часто, значение счетчика иногда будет обнуляться. Это произойдет из-за того, что в некоторый момент программа прочитает из файла пустое значение, к которому потом прибавляется единица ("пусто" + число 1 = число 1). Собственно, это и есть сброс счетчика.

Рассмотрим подробно, когда это произойдет. Представьте, что в один момент времени стартовали 2 копии данного скрипта. Одновременно ничего нигде не проиходит, в т.ч. и запуск скриптов, но время между запуском может быть очень маленькое. Процессор выполняет скрипты с разной скоростью, т.е. вы не должны удивляться тому, в каком порядке далее будут рассматриваться команды. Итак, ход программы (на примере "скрипта N1" и "скрипта N2"):

скрипткомандакомментарий (что сделает данная команда)
1 запуск первого скрипта --
1 $counter=file("counter.txt"); в переменной (массиве $counter) теперь храниться текущее число счетчика. Допустим, там было 1234, тогда это число будет в переменной $counter[0].
2 запуск второго скрипта --
1 $f=fopen("counter.txt","w+");
  • открывает файл
  • обнуляет его
  • если файл не был создан, создает его (если позволят права). Но файл создан нами заранее, этот вариант исключен.
  • 2 $counter=file("counter.txt"); читает содержимое пустого файла и записывает в массив $counter пустой массив. Переменная $counter[0] не существует.
    1 fputs($f,$counter[0]+1); пишет в файл число 1234 (т.к. в $counter[0] лежит число 1234)
    2 $f=fopen("counter.txt","w+"); см. комментарий выше
    1 fclose($f); и конец работы --
    2 fputs($f,$counter[0]+1); записывает в файл число 1, т.к результат сложения несуществующей переменной и числа 1 равен числу 1
    2 fclose($f); и конец работы --

    Как видите, если 2 параллельно работающих скрипта, выполнять именно в такой последовательности, то файл будет обнулен. Если вы попробуете этого добиться, вылняя частую перезагрузку страницы в браузере, то у вас скорее всего ничего не выйдет. Чтобы убедиться, что файл будет таки обнулен, воспользуйтесь утилитой ab (которая умеет генерировать, в течении длительного времени большое число, параллельных запросов к скиптам), либо впишите после каждой команды "sleep(1);" - команду остановки программы на 1 секунду, и понажимайте "Обновить" в браузере. Во втором случае вы это сразу и увидите.

    Чтобы решить проблему, нужно исключить опасный момент. Другими словами надо заблокировать доступ к файлу счетчика, чтобы все другие параллельно запущенные скрипты, приостановили свою работу. Делается это с помощью flock, который блокирует доступ из других PHP-скриптов (но не из других процессов ОС). Другие скрипты при попытке открыть файл остановятся и будут ждать снятия блокировки.

    <?
    // верхняя часть страницы
    // код счетчика:
    $f2=fopen("counter.txt","r"); // чтобы файл заблокировать, его надо открыть
    // открыли файл на чтение
    flock($f2,2); // заблокировали файл
    $counter=file("counter.txt"); // прочитали файл в массив $counter
    $f=fopen("counter.txt","w+"); // открыли файл на запись
    fputs($f,$counter[0]+1); // записали "число + 1"
    fclose($f); // закрыли файл
    echo $counter[0]+1; // вывели число на экран
    flock($f2,3); // сняли блокировку (при закрытии
    // снимается автоматически)
    fclose($f2); // и закрыли файл (при выходе
    // закрывается автоматически)
    // нижняя часть страницы
    ?>

    Программу с блокировкой можно было бы написать и в более красим (коротком) виде, но и такой вариант сойдет. Цифры "2" и "3" в функции flock обозначают следующее:

    flock (дексриптор файла, режим)

    режим:

    • 1 - другие процессы могут отрыть только в режиме чтения
    • 2 - другие процессы ничего не могут
    • 3 - снять блокировку

    Итак, на простейшем примере (проще придумать трудно) показаны проблемы параллельного запуска скриптов.

    Назад В начало страницы На главную страницу В конец страницы Вперед 

    В конец страницы

    Графический счетчик на PHP

    Создавая текстовый счетчик, мы ограничены свойствами текста в браузере. Если же Вы хотите чегото из ряда вон выходящего, удовлетворяющего Вашему полету фантазии, то Вам подойдет как раз описываемая тема.

    Данный пример демонстрирует работу простого графического счетчика. По функциональности он совершенно идентичен текстовому счетчику.

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

    Это изображение надо сохранить под именем counter.png

    В скрипте использована библиотека GD, перед тем как пользоваться этой библиотекой, узнайте у хостера, подключена ли эта библиотека. Теперь сам скрипт:

    <?php
    
    $dat_file="counter.dat"; // Файл счетчика
    $log_file="counter.log"; // Файл списка IP
    // Открывем файл счетчика и считываем текущий счет
    // в переменную $count
    $f=fopen($dat_file,"r");
    $count=fgets($f,100);
    fclose($f);
    
    $count=ereg_replace(" ","",$count); // Удаляем символ конца строки
    $count++; // Увеличиваем счетчик
    // Записываем данные обратно в файл
    $f=fopen($dat_file,"w");
    fputs($f,"$count ");
    fclose($f);
    
    // Создаем новое изображение из файла
    $im = ImageCreateFromPNG('counter.png');
    // Назначаем черный цвет
    $black = ImagecolorAllocate($im,0,0,0); 
    // Выводим счет на изображение
    Imagestring($im,1,5,20,$count,$black);
    // Выводим изображение в стандартный поток вывода
    Header("Content-type: image/png");
    ImagePng($im);
    
    // Записываем IP посетителя
    $f=fopen($log_file,"a+");
    $ip=getenv("REMOTE_ADDR");
    fputs($f,"$ip ");
    fclose($f);
    ?>  
    

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

    Для вывода счетчика в html используйте <IMG SRC="counter.php" WIDTH="88" HEIGHT="31" BORDER=0>.

    Назад В начало страницы На главную страницу В конец страницы Вперед 

     
    design: ФуксЪ, Solmex 
    Реклама в журнале