Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> То что должен знать каждый о PHP, Курс молодого бойца 
:(
    Опции темы
Secandr
Дата 28.7.2004, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Содержание:
1. Принцип работы веба.
2. Взаимодействие php с mysql, java, javascript, vbscript, ...
3. Скрипт "hello world"
4. Как передать информацию скрипту
5. Как сохранить инфомацию
6. Гостевая книга
7. Более мощная гостевая
8. Подробнее о работе веба (telnet вместо браузера, основы HTTP)
9. JОбсуждение, авторы,...

Принцип работы веба.

В основе работы веба лежит взаимодействия трёх компонент: человека, браузера и веб-сервера. В случае динамических страниц, написанных на php, добавляется четвёртый компонент – "интерпретатор" PHP.
--Resize_Images_Alt_Text--



Рассмотрим взаимодействие этих четырёх объектов.
  • Первоначально пользователь вводит URL адрес ресурса. Будем считать что человек ввёл в адресную строку Internet Explorer`а http://forum.vingrad.ru/index.php и нажал "перейти".
  • После этого браузер делает запрос к серверу на котором расположен форум, форма запроса описывается в спецификации протокола HTTP. В нашем случае будет передано имя сервера(forum.vingrad.ru) и адрес скрипта(index.php).
  • Веб-сервер получив такой запрос, смотрит на расширение .php и "переадресует" запрос к PHP.
  • PHP в свою очередь, читает и выполняет файл. Выполнив файл PHP передаёт серверу результат выполнения скрипта, то что скрипт выдал "на экран", или возвращает код ошибки.
  • Веб-сервер, получив данные от PHP, передаёт их через сеть браузеру клиента.
  • Браузер клиента, получив данные от клиента, анализирует их. Если это html, то браузер нарисует на экране веб-страницу, если это файл, то предложит сохранить его, …
В данной схеме могут отсутствовать некоторые компоненты. Например запрос к серверу может делать поисковый робот или программа для копирования сайта на жёсткий диск, в этом случае пользователь не участвует и на экран монитора ничего не выводится.

Так же может отсутствовать браузер. Рассмотрим это на примере.
Цитата
Запустите "режим эмуляции MS-DOS" (для Windows 9X) или "командную строку"(Windows 2000, XP). Наберите "telnet forum.vingrad.ru 80" без кавычек, после этого нажмите ввод.
Затем наберите "GET /index.php", без кавычек. В результате вы получите html содержащий информацию о том, что такого файла не существует. Это связано с тем что мы не верно составили запрос. Но этот пример хорошо показывает, что работать в сети можно и без браузера, правда для этого придётся выучить, как составляются запросы HTTP и выучить HTML. Помимо этого нужно обладать хорошим воображением, чтобы представить, как это будет выглядеть на экране компьютера.

Этот пример не несёт практической пользы, но показывает принцип работы веба. То есть веб-сервер знает только то что передал ему браузер. PHP знает только то, что передал ему веб-сервер. А браузер получает информацию от веб-сервера и не подозревает о существовании PHP.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Взаимодействие php с mysql, java, javascript, vbscript, ...

Часто встречаются вопросы: как передать данные от php к mysql, java, javascript, vbscript, …
Давайте разберёмся что есть что.
Нужно чётко представлять на чьей стороне будет запущен скрипт. Можно разбить языки на две группы:
Работаю на сервере: PHP, PERL, Python.
У клиента: JScript,JavaScript, vbscript.
Деление условное, но в 99% так и происходит.
Ещё хотелось бы отметить, огромную разницу между java и javascript. Не стоит сокращать названия, поскольку JScript, JavaScript, Java - разные языки.
Базы данных будут рассмотрены ниже, поскольку принципиально иначе связаны с php.

Теперь поговорим о взаимодействии. Судя по названию серверные языки выполняются на стороне сервера, и как было сказано в главе "Принцип работы веба", PHP знает только то что передал ему веб-сервер и передаёт данные не клиенту, а веб-серверу. PHP просто не знает о существовании браузера и клиента.
В свою очередь js, javascript, vbscript , обрабатываются браузером клиента и могут находится прямо в HTML`е. Раз они могут находиться в html, который генерируется сервером, соответственно PHP может сгенерировать html с javascript`амии:
Код
echo "<html><script>alert('cool')</script><body>TEST</body></html>";
Аналгично можно генерировать и vbscript.
Обратная связь немного сложнее. Для отправки данных php скрипту необходимо заставить браузер "перейти" по новой ссылки или отправить форму на сервер. При этом браузер передаст запрос веб серверу, а веб сервер скрипту.

При отсылке переменных в серверный скрипт следует обратить внимание на метод (POST или GET). У каждого есть свои преимущества и недостатки:
метод POST передает значения переменных в теле http запроса, более универсален нежели метод GET и позволяет передать большие объемы, но для отсылки запроса POSTом нужна форма. Пример есть здесь - http://forum.vingrad.ru/index.php?showtopic=26503&st=0

Метод GET позволяет передавать небольшие объемы в переменных, помещая их URL, это удобно, например, для создания универсального скрипта, который используется для различных разделов сайта:
Код
<a href="index.php?razdel=1&topic=567">Ссылка</a>

Либо передать можно небольшим скриптом:
Код
<script language="javascript">
var razdel=1;
var topic=567;
var name="index.php";
var url=name+"?razdel="+razdel+"&topic"+topic;
window.location.href=url;
</script>


Метод GET можно использовать аналогично методу POST в форме.
Код
<form action="index.php" method="GET" name="first">
<input type=hidden name=razdel value=1>
<input type=hidden name=topic value=567>
</form>

<a href="javascript:void(0);" onClick="document.form['first'].submit">Go!</a>


Так же может пригодиться функция для отправки массива из JavaScript в PHP:
Код
function SendArrayToPHP(arr, url) {
   var newurl = url + '?';
   for(var i = 0; i < arr.lenght; i++) {
       newurl = newurl + '&arr[]=' + arr[i];
   }
   window.location.href = newurl;
}

var NewArray = Array('a', 'b', 'c', 'd');
SendArrayToPHP(NewArray, 'http://example.com/example.php');

В PHP используются методы POST и GET, однако существуют и другие: PUT, HEAD, LINK, UNLINK и т.д.



Для взаимодействия mysql с php существует ряд команд: mysql_connect, mysql_query, … подробнее читайте в документации.
Ниже приведена принципиальная схема взаимодействия php с mysql. Хотя в качестве mysql может выступать любая другая база данных.
user posted image

Обратите внемание, что mysql находится ещё дальше от пользователя и о существовании mysql "знает" только php.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Скрипт "hello world"

Подразумевается, что у нас есть сервер где настроен PHP. Настройка PHP подробно рассмотрена в другом топике: http://forum.vingrad.ru/index.php?showtopic=26782

Написать первую программу на php не так сложно. Для этого вам просто необходимо создать файл в корневой папке веб-сервера, назовём его 1.php
Код
<?php
echo " hello world! I`m PHP script! ";
?>
Теперь открываете браузер и идёте по ссылке http://server/1.php В случае если вы тестируете на своей машине, то вместо server поставте 127.0.0.1
Вы должны увидеть hello world! I`m PHP script!
Если вы видите ошибку или полный код программы, то ваш сервер настроен неверно.

Теперь усложним задачу. Введём переменную:
Код
<?php
$text="hello world! I`m PHP script!";
echo $text;
?>
С переменными можно выполнять сложение, вычитание, объединение строк, …
Код
<?php
$a=5;
$b=3;
$c=$a+$b;
$d=$a.$b;
echo "a+b=$a+$b=$c ";
echo "\n<br>\n";
echo "a.b=$a.$b=$d";
?>
Так же полезно будет прочитать об операторах if, while, for, foreach. Прочитать об этих и других оператарах можно, скачав документацию http://ru2.php.net/get/php_manual_ru.chm/from/a/mirror


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Как передать информацию скрипту

Пример hello world хорош, но возникает вопрос: где же динамика, ради которой и изучается PHP. Как передать данные от клиента к скрипту, как заставить скрипт реагировать на действия пользователя?

Существует два основных способа передачи данных:
Метод GET: 1.php?параметр=значение& параметр=значение& параметр=значение
Метод POST: в этом методе параметры передаются особым образом в HTTP запросе, механизм передачи не столь важен.

Давайте немного изменим наш скрипт:
Код
<?php
$name=$_GET['name'];
echo "Вас зовут $name.";
?>
Теперь запустим скрипт как 1.php?name=Alex
После чего на экране появится "Вас зовут Alex". $_GET – глобальный массив, содержит все параметры переданные методом GET.

Теперь посмотрим как работает метод пост.
Код
<?php
$name=$_POST['name'];
echo "Вас зовут $name.";
echo "<form action='1.php' method=post><input name='name'><input type=submit></form>";
?>
Теперь запустим скрипт 1.php, на экране мы увидим "Вас зовут.". И если в поле ввести имя и нажать кнопку, то страница перезагрузится, передав методом POST ваше имя.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Как сохранить инфомацию

Как только вы начинаете писать скрипты для своего сайта, сразу встаёт вопрос, как сохранить данные.
Чаще всего для хранения данных применяют базы данных, такие как mysql, и файлы. Базы данных позволяют хранить более сложные структуры и абстрагироваться от механизмов манипуляции физическими данными, но для работы с ними требуется изучить язык запросов SQL. Файлы – не самое мощное средство хранения информации, но при этом самое простое.
PHP очень гибкий язык и работа с файлами может осуществляться различными способами, рассмотрим один из них.

Чтение из файла лучше осуществлять командой file:
Код
<?php
$lines=file('2.txt');
$text=implode('',$lines);
echo $text;
?>
Команда file читает содержимое файла в массив $lines, команда implode объединяет все строки массива в "строковую" переменную.

Запись файл осуществляется следующим образом:
Код
<?php
$text="test";
$handle = fopen("2.txt", "w");
fwrite($handle,$text);
fclose($handle);
?>
fopen – открывает файл 2.txt, а второй параметр w, говорит о том что нужно открыть файл на запись и очистить его.
fwrite – записывает в файл данные из переменной $text.
Fclose – закрывает файл.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Гостевая книга

Ниже приведён код простой гостевой книги, в ней рассматривается всё то, что было изложено выше, плюс пара новых функций. Код снабжён подробными комментариями.

Для начала вам нужно создать пустой файл text.dat
Затем создать index.php и поместить в него код приведенный ниже:
Код
<html>
<body>
<!-- Ниже идёт php код, который будет выполняться интерпретатором
php и на его место будет вставлен результат работы -->

<?php
$text_of_file=join('',file('text.dat')); //читаем содержимое файла
$message_array=explode('<>',$text_of_file); //разбиваем файл на отдельные элементы
$message_array=array_reverse($message_array); //перевернём массив, что бы последние сообщения были сверху
foreach ($message_array as $message){  //цикл по всем записям.
echo "<table border=1 width=70% align=center><tr><td>$message</td></tr></table><br><br>"; //выводим таблицу с сообщением
}

if ($_POST['text']!=''){   //Если параметр text пришедший из формы методом post не пуст
$text=htmlspecialchars($_POST['text']); //удалим спец символы html
$file_handle = fopen('text.dat','a'); //открываем файл text.dat, параметр "а" позволяет открыть файл на запись, поставить данные в конец файла и дописать файл
fwrite( $file_handle, "<>\n");  //запишем разделитель
fwrite( $file_handle, $text);  //запишем данные
fclose( $file_handle);   //закроем файл
}
?>

<!--ниже идёт простая форма которая будет выводиться без изменений-->
<div align=center>
<form method="post">
<textarea name="text"></textarea><br>
<input type="submit">
</form>
</div>
</body>
</html>

Хотелось бы отметить одну особенность php. Код написанный на php можно вставлять "внутрь" документа html, что упрощает разработку простых приложений.

PHP читает файл index.php и выполняет только ту часть файла, которая заключена в программные скобки:
Код
<?php

?>

После выполнения результат работы будет вставлен вместо кода и готовый html документ будет передан веб серверу.

Теперь преступим к разбору скрипта, на самом деле скриптом является лишь часть файла:

Код
<?php
$text_of_file=join('',file('text.dat')); //читаем содержимое файла
$message_array=explode('<>',$text_of_file); //разбиваем файл на отдельные элементы
$message_array=array_reverse($message_array); //перевернём массив, что бы последние сообщения были сверху
foreach ($message_array as $message){  //цикл по всем записям.
echo "<table border=1 width=70% align=center><tr><td>$message</td></tr></table><br><br>"; //выводим таблицу с сообщением
}

if ($_POST['text']!=''){   //Если параметр text пришедший из формы методом post не пуст
$text=htmlspecialchars($_POST['text']); //удалим спец символы html
$file_handle = fopen('text.dat','a'); //открываем файл text.dat, параметр "а" позволяет открыть файл на запись, поставить данные в конец файла и дописать файл
fwrite( $file_handle, "<>\n");  //запишем разделитель
fwrite( $file_handle, $text);  //запишем данные
fclose( $file_handle);   //закроем файл
}
?>


Работает всё очень просто, в любом случае выполняется код

Код
$text_of_file=join('',file('text.dat')); //читаем содержимое файла
$message_array=explode('<>',$text_of_file); //разбиваем файл на отдельные элементы
$message_array=array_reverse($message_array); //перевернём массив, что бы последние сообщения были сверху
foreach ($message_array as $message){  //цикл по всем записям.
echo "<table border=1 width=70% align=center><tr><td>$message</td></tr></table><br><br>"; //выводим таблицу с сообщением


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

Теперь встаёт вопрос: как хранить данные?
Одним из лучших вариантов является использование специальных разделителей, в нашем случае это символ <>, поскольку символы < и > являются зарезервированными в html мы будем избавляться от них при записи в файл, а это гарантирует, что последовательность <> будет уникальной, то есть пользователь не сможет вставить такую последовательность сам.

Проделав join мы имеем текст вида:
Цитата
Сообщение1<>Сообщение2<>Сообщение3


Но нам было бы приятнее работать с массивом
Цитата
(Сообщение1,Сообщение2,Сообщение3)


Для разбиения строки будем использовать explode, эта функция получает подстроку разделитель, в нашем случае <>, и разбивает строку на элементы массива разделенные символами <>.

Теперь нам бы хотелось, что бы последние сообщения были сверху, для этого перевернём массив функцией reverse, конечно можно было бы перевернуть массив и при помощи самописного кода состоящего из for и замены i-го элемента, но встроенный reverse будет работать быстрее, всегда при выборе между самописным кодом и встроенной функцией отдавайте предпочтение функции php.

Теперь мы имеем верно отсортированный массив и остаётся его только распечатать.

Foreach организует цикл по всем элементам массива, а echo позволяет передать результат работы и вставить его на место кода.

Далее идёт условная конструкция:

Код
if ($_POST['text']!=''){   //Если параметр text пришедший из формы методом post не пуст
$text=htmlspecialchars($_POST['text']); //удалим спец символы html
$file_handle = fopen('text.dat','a'); //открываем файл text.dat, параметр "а" позволяет открыть файл на запись, поставить данные в конец файла и дописать файл
fwrite( $file_handle, "<>\n");  //запишем разделитель
fwrite( $file_handle, $text);  //запишем данные
fclose( $file_handle);   //закроем файл
}

Смысл её в том, что если пользователь прислал сообщение методом POST, то нужно его записать.
htmlspecialchars – позволяет избавиться от < > & и других спец символов HTML`а, если не использовать этот оператор, то пользователь сможет вставить вредоносный код в вашу гостевую книгу.
Далее идёт запись в файл, обратите внимание на режим "a", он позволяет дописать ланные в файл.

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


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
  Дата 4.8.2004, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Пошаговое описание устройства простейшей гостевой книги.

Так как мы с Вами стараемся не отступать от моды, мы решили создать для своего сайта гостевую книгу. Сразу хочу сказать, что если Вам не интересно изучение языка серверных сценариев PHP, Вы можете скачать гостевую книгу по ссылке с этой статьи, или с любого сайта – каталога скриптов.

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


Функциональные возможности.

1. Возможность добавлять сообщения.
2. Постраничный вывод сообщений.
3. Администрирование гостевой книги: редактирование и удаление сообщений.
4. Флуд – контроль.


Структура и назначение файлов.

/gb/config.php - Конфигурация гостевой книги.

/gb/index.php – движок нашей гостевой книги.

/gb/kernel.php – функциональная часть гостевой книги.

/gb/shell/ - каталог с шаблонами представления данных.
/gb/shell/showmessages.php – постраничный вывод сообщений из базы данных.
/gb/shell/replyform.php – форма ответа.
/gb/shell/login.php – форма авторизации администратора.
/gb/shell/editform.php – форма для редактирования сообщений администратором.

/gb/data/messages.data – файл с записями сообщений посетителей.
/gb/data/logmessages.data – файл с данными для флуд – контроля сообщений.

Конфигурация нашей гостевой книги содержится в файле config.php. Сразу же рассмотрим все настройки, чтобы по ходу текста примерно понимать что кроется за тем или иным параметром, и для чего он необходим.
Код

$_GB_CONFIG['RootPath']    = str_replace("\\", "/", dirname(__FILE__)).'/'; /* Определяем корневой каталог гостевой книги. */

$_GB_CONFIG['ShellPath']   = $_GB_CONFIG['RootPath'].'shell/'; /* Каталог с файлами оболочки гостевой книги. */
$_GB_CONFIG['DBPath']    = $_GB_CONFIG['RootPath'].'data/'; /* Каталог с данными. Примечание: для записи в каталог необходимы права на запись 0777, а на файлы находящиеся в нем 0666. */

$_GB_CONFIG['MaxMessagesToPage'] = 10; /* Максимальное количество отображаемых сообщений на странице. */
$_GB_CONFIG['ShowQuickReplyForm'] = 1; /* Отображать форму ответа вместе с сообщениями. */
$_GB_CONFIG['SeparateMessageInDB'] = '|'; /* Разделитель полей в строках сообщений. */
$_GB_CONFIG['SeparateLogsInDB']  = '|'; /* Разделитель полей в строках с логами. */
$_GB_CONFIG['MaxNameLength']  = 20; /* Максимальная длинна имени. */
$_GB_CONFIG['MinMessageLength']  = 10; /* Минимальная длинна сообщения. */
$_GB_CONFIG['MaxMessageLength']  = 1024; /* Максимальная длинна сообщения. */
$_GB_CONFIG['CookieExpire']   = 86400 * 30; /* Время жизни cookie. */
$_GB_CONFIG['MessagesAddTimeout'] = 15; /* Таймаут задержки возможности добавлять сообщения в секундах. */

$_GB_CONFIG['AdminLogin']  = 'Admin'; /* Логин администратора. */
$_GB_CONFIG['AdminPaswd']  = '698d51a19d8a121ce581499d7b701668'; /* Пароль администратора. Примечание: по умолчанию 111. */

Примечание: пароль администратора шифруется функцией md5, для того чтобы его сменить, необходимо сгенерировать хеш при помощи, например такой конструкции:
Код

echo md5('your password');

Получившийся результат записать в качестве значения переменной $_GB_CONFIG['AdminPaswd'].

Структура основной части нашей гостевой книги находится в файлах index.php который обеспечивает сборку данных, и файл kernel.php, в котором содержатся функции для обработки данных.

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

function ReadDB($File, $Reverse = 1) {
return ($Reverse == 1) ? array_reverse(file($File)) : file($File); /* Считать файл в строки и перевернуть если задано. */
}

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

Чтобы не было вопросов, сразу предупрежу, PHP при записи в начало файла не записывает их до текста который там уже был, а затирает тот который там уже есть.
Подробнее о функциях file и array_reverse.

Код

function ReWriteDB($Messages) {
global $_GB_CONFIG; /* Объявление глобальной переменной. */
$fp = fopen($_GB_CONFIG['DBPath'].'messages.data', "w+"); /* Открытие файла на перезапись. */
flock($fp, LOCK_EX); /* Блокировка файла на время записи. */
if(sizeof($Messages) > 0)
 fputs($fp, implode("\r\n", $Messages)."\r\n"); /* перезапись базы. */
flock($fp, LOCK_UN); /* Разблокировка файла. */
fclose($fp); /* Закрытие файла. */
}

Данная функция предназначена для перезаписи базы сообщений. Как Вы видите в первой строке блока функции, объявляется глобальная переменная, так как переменные определенные не в теле функции, а в "основном" коде, необходимо объявить об их использовании с помощью ключевого слова global.
Первый и единственный аргумент этой функции передает массив со строками сообщений вида id|name|etc..., для записи нам необходимо превратить их в строку, для этого мы воспользуемся функцией implode которая в качестве первого параметра принимает разделитель с помощью которого отделяются значения ячеек массива друг от друга при конвертации их в строку, который передается во втором параметре. Эта функция очень полезна, так как она избавляет нас от создания цикла для перевода массива в строку. Далее идут стандартные процедуры открытия, блокировки, записи и закрытия файла.

Код

function GetCookie($Param) {
global $_COOKIE;
if(isset($_COOKIE[$Param])) {
 return $_COOKIE[$Param];
}
return false;
}

function GetSession($Param) {
global $_SESSION;
if(isset($_SESSION[$Param])) {
 return $_SESSION[$Param];
}
return false;
}

Так же рассмотрим две простые функции, которые избавят нас от многократно повторяющихся проверок существования ключей в глобальных массивах $_COOKIE и $_SESSION. Все очень просто, если существует ключ с именем переданным в функцию через ее аргумент $Param, то функция вернет ее значение, если нет, то вернет логическое нет, это необходимо как я уже говорил для сокращения кода посредством уменьшения выражений проверок наличия переменных, без которых на экран будут выводиться предупреждения парсера PHP о том что переменная или индекс массива (а может и сам массив) не существует.

Код

function CalculatePages($CurrentPage, $MaxMessagesToPage, $MessagesCount) {
// ...
}

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

Код

function CheckUserMessage() {
global $_GB_CONFIG; /* Объявление глобальных переменных. */
// ...
}

Несомненно, это самая большая функция. Давайте с Вами разберем ее по кусочкам, дабы не запутаться в ее нагромождениях. В случае успешного ее выполнения она вернет истину (true/1), а в случае провала ложь (false/0).

Код

$LogsMessages = file($_GB_CONFIG['DBPath'].'logmessages.data'); /* Считываем данные из файла с логами. */
if(isset($LogsMessages[0])) { /* Если логов сообщений нет, ни чего не делать, иначе проверка на идентичность. */
 for($i = 0; $i < sizeof($LogsMessages); $i++) {
  $Ex = explode($_GB_CONFIG['SeparateLogsInDB'], trim($LogsMessages[$i])); /* Разбить строку по разделителю. */
  if($Ex[1] < time()) { /* Если время хранения хеша не истекло, проверить идентичность и поместить его в новый массив для перезаписи. */
   if($Ex[0] === md5($_POST['message'])) { /* Если сообщение идентично отправленному некоторое время назад: записать сообщении об ошибке. */
    $Errors[] = 'Нельзя добавлять идентичные сообщения.';
    break;
   }
   $ClearedLogs[] = $Ex[0].$_GB_CONFIG['SeparateLogsInDB'].$Ex[1];
  }
 }
}

При записи каждого сообщения, в файл logmessages.data записывается его MD5 хеш для последующего предотвращения создания повторных сообщений. Записываемые данные хранятся то время, которое указано в конфигурации гостевой книги. Перед проверкой хеша сообщения на идентичность, сначала проверяется не истек ли срок хранения хеша, и если он не истек, то проверить и записать его в новый массив для последующей перезаписи логов: это делается для отсеивания просроченных записей.

Код

if(GetCookie('LastMessageTime')) { // Если cookie существует - проверка таймаута.
 if(GetCookie('LastMessageTime') > time()) {
  $Errors[] = 'Нельзя добавлять сообщения с промежутком меньшим чем '.round($_GB_CONFIG['MessagesAddTimeout'], 2).' сек.';
 }
}

Как мы видим из этой конструкции, в случае если пользователь отправил предыдущее сообщение с меньшим интервалом, чем установлено в конфигурации, добавляем сообщение об этом в массив $Errrors.

Если два предыдущих условия дали отрицательный результат, то идем дальше и проверяем введенные пользователем данные.
Код

if(!isset($Errors)) { /* Если ошибки отсутствуют, проверить данные. */
 if(empty($_POST['name'])) { $Errors[] = 'Вы не ввели Ваше имя.'; }
 if(strlen($_POST['name']) > $_GB_CONFIG['MaxNameLength']) { $Errors[] = 'Ваше имя не должно превышать '.$_GB_CONFIG['MaxNameLength'].' символов.'; } else { setcookie('_gb_user_name', $_POST['name'], time() + $_GB_CONFIG['CookieExpire']); } /* Длинна имени не должна превышать установленной в конфигурации. */
 if(!empty($_POST['email'])) {
  if(!eregi("^[^\\.\\-_][a-zA-Z0-9_\\.\\-]*[^\\.\\-_]@[^\\.\\-_][a-zA-Z0-9_\\.\\-]*[^\\.\\-_]\\.[a-zA-Z]{2,4}$", $_POST['email'])) { $Errors[] = 'Вы ввели некоректный адрес электронной почты'; } else { setcookie('_gb_user_email', $_POST['email'], time() + $_GB_CONFIG['CookieExpire']); }
 }
 if(!empty($_POST['www'])) {
  if(!eregi("^[^\\.\\-_][a-zA-Z0-9_\\.\\-]{1,40}[^\\.\\-_]\\.[a-zA-Z]{2,4}$", $_POST['www'])) { $Errors[] = 'Вы ввели некоректный адрес вашего сайта.'; } else { setcookie('_gb_user_www', $_POST['www'], time() + $_GB_CONFIG['CookieExpire']); }
 }
 if(!empty($_POST['icq'])) {
  if(!eregi("^[0-9]{4,11}$", $_POST['icq'])) { $Errors[] = 'Вы ввели некоректный номер icq.'; } else { setcookie('_gb_user_icq', $_POST['icq'], time() + $_GB_CONFIG['CookieExpire']); }
 }
 if(strlen($_POST['message']) < $_GB_CONFIG['MinMessageLength']) { $Errors[] = 'Ваше сообщение должно быть не менее '.$_GB_CONFIG['MinMessageLength'].' символов.'; }
 if(strlen($_POST['message']) > $_GB_CONFIG['MaxMessageLength']) { $Errors[] = 'Ваше сообщение не должно привышать '.$_GB_CONFIG['MaxMessageLength'].' символов.'; }
}

В данном коде мы проверяем как обязательные поля имя и сообщение которые пришли из формы, остальные же проверяются только в случае их заполнения, что проверяется с помощью функции empty которая в случае если переменная отсутствует или не содержит данных, возвращает истину (true/1). Так же мы делаем запись cookie со всеми правильно введенными параметрами пользователем, чтобы в последующий раз, при отправке формы ему не надо было их заполнять.

Самые непонятные для новичков строки, это строки регулярных выражений, в которых проверяется валидность www и email адресов.
Код

if(!eregi("^[^\\.\\-_][a-zA-Z0-9_\\.\\-]{1,40}[^\\.\\-_]\\.[a-zA-Z]{2,4}$", $_POST['www'])) { // ... }
// ...
if(!eregi("^[^\\.\\-_][a-zA-Z0-9_\\.\\-]*[^\\.\\-_]@[^\\.\\-_][a-zA-Z0-9_\\.\\-]*[^\\.\\-_]\\.[a-zA-Z]{2,4}$", $_POST['email'])) { // ... }

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

Код

if(isset($Errors)) {
 echo '<center><div align="left" style="width:60%"><p align="center">При добавлении Вашего сообщения возникли ошибки:</p>';
 for($i = 0; $i < sizeof($Errors); $i++) {
  echo 'Ошибка: '.$Errors[$i].'<br/>'; /* Выводим сообщения об ошибках. */
 }
 echo '</div></center>';
 return false; /* Возвращаем ложь, так как были обнаружены ошибки. */
}

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

setcookie('LastMessageTime', time() + $_GB_CONFIG['MessagesAddTimeout'], time() + $_GB_CONFIG['CookieExpire']); /* Таймаут до следующей возможности добавить сообщение пользователю. */
$ClearedLogs[] = md5($_POST['message']).$_GB_CONFIG['SeparateLogsInDB'].time() + $_GB_CONFIG['MessagesAddTimeout']; /* Лог сообщения. */
/* Далее идет стандартная процедура записи. */
$fp = fopen($_GB_CONFIG['DBPath'].'logmessages.data', "w");
flock($fp, LOCK_EX);
fputs($fp, implode("\r\n", $ClearedLogs));
flock($fp, LOCK_UN);
fclose($fp);
return true; /* Сообщаем из функции о том что все операции прошли успешно. */


Далее давайте с Вами заглянем в структуру файла index.php, чтобы понять устройство "движка" гостевой книги:

Код

<?php
ob_start();
session_start();
?>
<!-- ... заголовки HTML кода ... -->

Для обеспечения правильной работы cookie и сессий для авторизации администратора и работы флуд - контроля мы включаем буферизацию вывода (функция ob_start) и стартуем сессию (функция session_start) для определения является ли авторизованный пользователь администратором или нет.
Примечание: вызов функции ob_start должен быть произведен до того, как начнется вывод данных.
Буферизацию необходимо начинать до того как чтобы то ни было попадет в поток вывода, иначе все старания будут напрасными (даже простой пробел в начале файла перед <? может навредить).

Код

define('_GB_INITIALIZED', true);

include_once('config.php');
include_once($_GB_CONFIG['EnginePath'].'kernel.php');

В этом коде мы инициализировали константу _GB_INITIALIZED, наличие которой будет проверяться в каждом файле нашей гостевой книги для предотвращения ложного срабатывания при запуске отдельно от файла index.php. Подключили конфигурационный файл config.php, в котором описаны параметры обработки данных и прочие параметры. Подключили файл с функциональными составляющими нашей гостевой книги.
Подробнее о функциях define и include_once.

Далее следует конструкция switch которая переключает выполнение на блоки case, если переданный ей параметр совпадает с представленным в блоке case. Для того чтобы не сработали другие блоки, необходимо воспользоваться оператором break который завершит выполнение блока switch/case.
Подробнее о switch.
Код

switch((isset($_GET['action'])) ? $_GET['action'] : 'show') {

В самом блоке switch как Вы могли заметить находится хитрая конструкция вида "(условие) ? выражение : выражение", которая представляет собой упрощенную конструкцию if/else, возвращающая результат выражения. После знака "?" выполняется выражение если условие вернуло истину, в обратном случае выполняется выражение после знака ":".
Также смотрите в разделе FAQ статью "register_globals и глобальные переменные".

Код

case 'add': { /* Блок записи сообщения в базу данных. */
 if(CheckUserMessage()) {
  AddUserMessage();
  header('location:?action=show');
 }
 break;
}

Прежде чем записать полученные от пользователя данные, нам необходимо их проверить, в том числе и для предотвращения засорения гостевой киги флуд-атакой. Для проверки была написана функция CheckUserMessage о которой я писал выше, она проверяет данные переданные из формы (а вдруг нам бомбу отправили? wink.gif ), истечение тайм-аута отправки сообщений и сходство с предыдущим сообщением. Если функция вернет истину (true/1), то выполнится функция записи сообщения в базу AddUserMessage заключенная в блоке if, и пользователь будет переадресован на страницу просмотра сообщений посредством отправки заголовка браузеру при помощи функции header.
Подробнее о конструкции if.

Код

case 'edit': { /* Блок редактирования сообщения. */
 if(GetSession('AdminLogin')) {
  $Messages = ReadDB($_GB_CONFIG['DBPath'].'messages.data', 1);
  if(!isset($_POST['name'])) { /* Если данные из формы не были отправлены, то вывести форму. */
   if($msg = GetMessageOnID($Messages, (isset($_GET['id'])) ? $_GET['id'] : 0)) {
    include_once($_GB_CONFIG['ShellPath'].'editform.php');
   } else {
    echo "<center><p>Сообщений не найдено</p></center>";
   }
  } else { /* Иначе записать изменения в базу. */
   WriteDB(EditRecord($Messages, (isset($_GET['id'])) ? $_GET['id'] : false));
   $Offset = (isset($_GET['offset'])) ? $_GET['offset'] : 0;
   header('location: ?action=show&offset='.$Offset);
  }
 } else {
  echo "<center><div align="left" style="width:60%"><p align="center"><b>Ошибка:</b> для выполнения данного дествия необходима авторизация.</p>";
 }
 break;
}

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

Код

 if(GetSession('AdminLogin')) {
  // ...
 } else {
  echo "<center><div align="left" style="width:60%"><p align="center"><b>Ошибка:</b> для выполнения данного дествия необходима авторизация.</p>";
 }

Чтобы хитроумный хакер, прочитавший данную статью не смог незаконно отредактировать какое либо сообщение из Вашей гостевой книги, вбив вручную параметры в адресную строку браузера, необходимо проверить - авторизован ли он как администратор или нет. Делается это при помощи написанной нами функции GetSession, которая вернет false/0 если сессия администратора не была инициализирована.

Код

  $Messages = ReadDB($_GB_CONFIG['DBPath'].'messages.data', 0);
  if(!isset($_POST['name'])) { /* Если данные из формы не были отправлены, то вывести форму. */
   if($msg = GetMessageOnID($Messages, (isset($_GET['id'])) ? $_GET['id'] : 0)) {
    include_once($_GB_CONFIG['ShellPath'].'editform.php'); /* Подключение формы для редактирования сообщения. */
   } else {
    echo "<center><p>Сообщений не найдено</p></center>";
   }
  } else { /* Иначе записать изменения в базу. */
   WriteDB(
    EditRecord($Messages, (isset($_GET['id'])) ? $_GET['id'] : false)); // Перезапись сообщений в базе.
   $Offset = (isset($_GET['offset'])) ? $_GET['offset'] : 0;
   header('location: ?action=show&offset='.$Offset); /* Переадресация администратора на страницу где находится отредактированное им сообщение. */
  }

В первой строке данного когда считываем в переменную $Messages строки из файла при помощи функции ReadDB для последующей обработки в функциях GetMessageOnID которая ищет в базе запись по идентификатору, переданному во втором параметре функции EditRecord, которая после отправки из формы отредактированных данных передаст в функцию WriteDB массив с сообщениями для перезаписи базы.

Код

case 'delete': {
 WriteDB(
  DeleteRecord(
   ReadDB($_GB_CONFIG['DBPath'].'messages.data', 0), (isset($_GET['id'])) ? $_GET['id'] : false) ); /* Удаление сообщения по идентификатору и перезапись данных. */
 $Offset = (isset($_GET['offset'])) ? $_GET['offset'] : 0;
 header('location: ?action=show&offset='.$Offset); /* Переадресация администратора на страницу с которой было удалено сообщения. */
 break;
}

Для удаления сообщения используется функция DeleteRecord которая ищет в массиве с сообщениями то сообщение, идентификатор которого был передан в тело функции. Как мы видим, в первом аргументе функции передается результат, возвращаемый функцией ReadDB которая как мы уже знаем возвращает массив строк сообщений из файла базы.

Код

case 'reply': {
 include_once($_GB_CONFIG['ShellPath'].'replyform.php');
 break;
}

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

Код

case 'login': {
 if(isset($_POST['login'])) { /* Если данные из формы были отправлены - авторизация. */
  if(CheckLogin()) { /* Если переданные из формы логин или пароль верны, пользователь авторизуется и будет переадресован на страницу просмотра сообщений. Иначе выход. */
   header('location: ?action=show');
  } else {
   exit;
  }
 } else {
  include_once($_GB_CONFIG['ShellPath'].'login.php'); /* Подключаем форму для авторизации пользователя. */
 }
 break;
}

Как Вы наверное поняли, этот блок предназначен для авторизации администратора гостевой книги, который несет в себе два возможных действия: вывод формы для отправки скрипту логина и пароля и собственно авторизация пользователя, то есть запись в сессию параметра AdminLogin с положительным значением. Правильность логина и пароля проверяет функция CheckLogin, которая в случае успеха возвращает истину (true/1), а в случае неудачи ложь (false/0). При неудачной авторизации выполнение скрипта останавливается.

Код

default: {
 $Messages  = ReadDB($_GB_CONFIG['DBPath'].'messages.data'); /* Считать сообщения из базы. */
 $CurrentPage = (isset($_GET['offset'])) ? $_GET['offset'] : 0; /* Проверить передан ли в адресной строке браузера параметр offset который ссылается на текущую страницу и записать соответствующее значение. */
 $MessagesCount = sizeof($Messages); /* Всего сообщений в базе. */
 $Pages   = CalculatePages($CurrentPage, $_GB_CONFIG['MaxMessagesToPage'], $MessagesCount); /* С помощью данной функции мы просчитываем ссылки на страницы. */
 $PagesCount  = ceil($MessagesCount / $_GB_CONFIG['MaxMessagesToPage']); /* Всего страниц. */
 /* Подсчет и корректировка с какого сообщения начинать выовод сообщений и каким заканчивать. */
 if(($CurrentPage * $_GB_CONFIG['MaxMessagesToPage'] > 1) && ($CurrentPage * $_GB_CONFIG['MaxMessagesToPage'] < $MessagesCount)) {
  $StartShow = $CurrentPage * $_GB_CONFIG['MaxMessagesToPage'];
  if($CurrentPage * $_GB_CONFIG['MaxMessagesToPage'] + $_GB_CONFIG['MaxMessagesToPage'] > $MessagesCount) {
   $EndShow = $MessagesCount;
  } else {
   $EndShow = $CurrentPage * $_GB_CONFIG['MaxMessagesToPage'] + $_GB_CONFIG['MaxMessagesToPage'];
  }
 } else {
  $StartShow = 0;
  $EndShow = ($_GB_CONFIG['MaxMessagesToPage'] > $MessagesCount) ? $MessagesCount : $_GB_CONFIG['MaxMessagesToPage'];
 }
 /* Подключаем страницу вывода сообщений. */
 include_once($_GB_CONFIG['ShellPath'].'showmessages.php');
}

Этот странный на первый взгляд блок оператора switch является самым как мне кажется полезным, он исполняется в случае если не одна подстановка из case не равна переданной в switch, однако блок default не является обязательным.
В этом блоке содержится самая важная, на мой взгляд процедура: пересчет страниц, корректировка позиции вывода сообщений в соответствиями с заданными настройками в конфиге и формирование ссылок на все страницы с сообщениями в гостевой книге.
В подключаемом файле showmessages.php содержится код, отвечающий за вывод сообщений вместе с HTML.
Код

<?php
while($StartShow < $EndShow) {
$msg = explode($_GB_CONFIG['SeparateMessageInDB'], $Messages[$StartShow]);
?>
<!-- Некоторый HTML код в котором выводятся сообщения. -->
<?php
$StartShow++;
}
?>

<?php
if($_GB_CONFIG['ShowQuickReplyForm']) { // Если в конфиге вывод формы вместе с сообщениями 1, вывести форму, иначе ссылку на нее.
include_once($_GB_CONFIG['ShellPath'].'replyform.php');
} else {
?>
<p align="center"><div align="right" style="width:80%;"><b><a href="?action=reply">Добавить запись</a></b></div></p>
<?php
}
?>
<p align="center">Переход по страницам: <?php echo implode(' | ', $Pages); ?></p>

Как мы видим, в цикле по определенным заранее переменным выводятся сообщения от числа записанного в $StartShow и до $EndShow. Далее идет разбивка строки с помощью explode по разделителю определенному в конфиге (он не должен отличаться от того каким символом разделяются записанные данные - то есть нельзя менять его, после того как в базе уже имеются записанные данные). Результат выполнения данной операции вернет массив, который мы присвоим переменной $msg. Массив будет иметь следующий вид:
Код

$msg = array (
0 => '0.98829800_1095626523', /* Идентификатор сообщения в базе. */
1 => 'IZ@TOP', /* Имя отправителя. */
2 => '[email protected]', /* Email отправителя. */
3 => 'ultra.dax.ru', /* Адрес сайта отправителя отправителя. */
4 => '179825301', /* Номер ICQ отправителя. */
5 => 'Тестовое сообщение.', /* Сообщение. */
6 => '10.10.59.20', /* IP адрес отправителя. */
7 => '1095626523', /* Дата создания сообщения в формате unix timestamp. */
);

Преобразование даты из формата unix timestamp в нормальный вид можно произвести с помощью функции date передав ее во втором аргументе.

Код

<!-- ... конец HTML кода ... -->
<?php
ob_end_flush();
?>

И в завершение всех действий мы заканчиваем буферизацию вывода и отправляем браузеру пользователя его содержимое.
Подробнее об ob_end_flush.

Авторские права принадлежат Beer Artur (IZ@TOP) совместно с форумом программистов Vingrad. Публикация в сети только с позволения авторов.

Пример этой гостевой книги находится по адресу http://ultra.dax.ru/gb/ .
В прикрепленном файле все исходные коды гостевой книги.

Это сообщение отредактировал(а) IZ@TOP - 20.9.2004, 08:25

Присоединённый файл ( Кол-во скачиваний: 154 )
Присоединённый файл  gb.rar


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39



Подробнее о работе веба (telnet вместо браузера, основы HTTP)
Как говорилось выше, схема работы веба предельно проста: вы даёте запрос браузеру, в виде URL (ссылки). Браузер генерирует http запрос и отправляет серверу. Сервер обрабатывает запрос, если он форомлен верно и запрашивает файл php, то передаёт управление PHP. PHP генерирует html, передаёт браузеру, браузер передаёт этот html клиенту, по средствам http протокола.

Итого мы имеем три непонятных термина html, http и php. PHP был рассмотрен выше, теперь перейдём к http и html.

HTTP

Давайте попробуем поработать браузером, для этого нам понадобится telnet и "жертва" к которой мы будем обращаться.
Давайте попробуем перейти на сайт http://www.ya.ru/, он мал по размерам, что нам поможет.
Запускаем конадную строку cmd.exe (Windows 2000,XP) или command.com (Windows 9X).
Теперь пишем
Код
telnet www.ya.ru 80

подразумевается, что вы подключены к Интернету напрямую – без прокси.
Итак мы вызвали программу telnet, которая бозволит нам соединиться с 80 портом на сервере www.ya.ru
Теперь необходимо сформировать запрос серверу. Он выглядит так:
Код
GET http://www.ya.ru/ HTTP1.0

затем нажмите два раза enter
Запрос состоит из наименования протокола(GET), путь к ресурсу http://www.ya.ru/ и указания версии протокола(1.0).
Два раза enter необходимо нажать, потому как запрос может состоять из нескольких строк. По стандартам запрос должен всегда заканчиваться пустой строкой.

После этого запроса, мы получим ответ:
Цитата
HTTP1.0 200 OK
Server: thttpd/2.24 26oct2003
Content-Type: text/html; charset=windows-1251
Date: Thu, 19 Aug 2004 09:03:27 GMT
Last-Modified: Thu, 06 May 2004 08:26:26 GMT
Accept-Ranges: bytes
Connection: close
Content-Length: 1222

<html>
<head>
<title>ъndex</title>
<link rel="SHORTCUT ICON" href="/favicon.ico">
<base target="_top">
</head>
<body bgcolor="white" text="black" link="999999" vlink="999999" alink="999999" onLoad="if( self.parent.frames.length != 0 ) self.parent.location = document.location">
**************
**************
**************
</body>
</html>


Ответ состоит из двух частей: заголовка http и тела(html). Сначала сервер сообщает техническую информацию:
Цитата
HTTP1.0 200 OK – протокол ответа и отстутствие ошибок
Server: thttpd/2.24 26oct2003 – наименование и версия сервера
Content-Type: text/html; charset=windows-1251 – что получит пользователь, в нашем случае html с русским текстом в кодировке windows`а
Date: Thu, 19 Aug 2004 09:03:27 GMT – дата генерации файла
Last-Modified: Thu, 06 May 2004 08:26:26 GMT – дата последнего редактирования файла
Accept-Ranges: bytes
Content-Length: 1222 – размер файла 1222 байта
Connection: close – соединение после передачи данных будет закрыто


Дальше идёт пустая строка и полезная информация.
По заголовку можно определить размер файла, а значит посчитать процент загруженной информации. Если вы кешируете страницы, то прочитав что страницу последний раз меняли 6 мая, можно не загружать её, а взять из Кеша. Так же можно зарание выбрать кодировку – это windows-1251.

После того как мы побыли в роле браузера, стало понятнее, как браузер рассчитывает процент загрузки, как выбирает кодировку, но осталось самое загадочное – как из набора букв и цифр вида <a href="/">top</a> получается всё то, что мы видим на экране своего браузера.



HTML

Для представления информации в WEB используется язык HTML (Hiper Text Markup Language)- язык гипертекстовой разметки документов. Он является потомком языка SGML, который позволяет описывать различные данные, но, в отличие от простого HTML, очень сложен.

HTML-документ имеет древовидную структуру. Т.е. состоит из элементов, которые имеют общий корень, и независимые дочерние элементы. В общем случае документ выглядит так:

Код
<html>
<head>
<title>World</title>
</head>
<body>
<p>Hello,<br> world!!!</p>
</body>
</html>


Имена, заключенные в скобки <...> называют дескрипторами, чаще тегами. Бывают парные (<html>....</html>) и непарные (<br>) теги. Парные теги отличаются от непарных, тем что они могут иметь дочерние элементы или узлы.

Рассмотрим, приведенный выше документ. Корневым элементом является html- это обязательный для всех HTML-документов элемент, он имеет два дочерних - head и body, в элементе head содержится информация о документе, как правило, пользователь её непосредственно не видит в окне браузера, элемен title - это заголовок, он отображается в заголовке окна браузера. В элементе body содержится тело документа. В нашем случае мы имеем обин абзац текста, он заключен в теги <p></p>, причем после запятой стоит перенос на следующую строку он выполняется тегом <br>.

Также, теги могут иметь аттрибуты - параметры, которые влияют на отображение содержимого элемента. Сделаем так, чтобы документ был "белым по черному":

Код
<html>
<head>
<title>World</title>
</head>
<body bgcolor="#000000">
<p><font color="#FFFFFF">Hello,<br> world!!!</font></p>
</body>
</html>


Теперь текст и фон поменяли цвет, потому как мы поменяли значения цвета аттрибутами bgcolor и color. Аттрибуты имеют вид имя="значение". Для цвета значение начинается с # и состоит из трех шестнадцатеричных чисел в формате RGB (т.е. #FF0000 - ярко-красный цвет).
Рассмотрим еще несколько элементов необходимых для создания страницы:
<img src="some.jpg"> - это непарный тег, вставляющий в документ изображение, которое содержится в файле some.jpg .
<a href="some.html">Жми сюда!</a> - вот это уже если не самый главный, то самый весомый элемент - гиперссылка, этот элемент позволяет совершить переход на другой HTML документ, при этом не важно располагается он на том же WEB-сервере или где-то в Зимбабве.

Код
<html>
<head>
<title>World</title>
</head>
<body bgcolor="#000000">
<p><font color="#FFFFFF">Hello,<br> world!!!</font></p>
<p><img src="some.jpg"></p>
<p><a href="some.html">Жми сюда!</a></p>
</body>
</html>


Теперь создадим форму (поля, значения в которых, может менять пользователь), которая отправит несколько строчек скрипту на сервере:

Код
<form action="example.php" method="POST">
<input type="text" name="text1" value="Наша форма">
<input type="text" name="text2">
<input type="text" name="text3">
<input type="text" name="text4">
<input type="submit" value="Отправить">
</form>


все элементы внутри тегов form принадлежат форме, и, если они правильно составлены, будут отосланы серверу. Аттрибуты action и method отвечают за то куда и как будут отправлены данные из формы. В action указывается url скрипта, а в method - метод передачи переменных.
Тег <input> создает поле ввода, радиокнопку, флажок или другой элемент ввода данных. Разновидность определяется аттрибутом type, в нашем случае - это строка текста. name - имя поля, так будет называтся переменная в скрипте, когда эти данные будут обрабатываться и, наконец, value - значение, которое по умолчанию вписано в это поле и которое будет передано скрипту, если пользователь не изменит содержимое.
Аттрибут type="submit" придает элементу input вид кнопки, при нажатии на которую происходит передача переменных.

Код
<html>
<head>
<title>World</title>
</head>
<body bgcolor="#000000">
<p><font color="#FFFFFF">Hello,<br> world!!!</font></p>
<p><img src="some.jpg"></p>
<p><a href="some.html">Жми сюда!</a></p>
<form action="example.php" method="POST">
<input type="text" name="text1" value="Наша форма">
<input type="text" name="text2">
<input type="text" name="text3">
<input type="text" name="text4">
<input type="submit" value="Отправить">
</form>
</body>
</html>


Вы видите, что поля ввода сейчас вытянуты как караван в одну строчку. Создадим таблицу и вложим эти поля в ячейки.

Код
<html>
<head>
<title>World</title>
</head>
<body bgcolor="#000000">
<p><font color="#FFFFFF">Hello,<br> world!!!</font></p>
<p><img src="some.jpg"></p>
<p><a href="some.html">Жми сюда!</a></p>

<table width="80%">
<form action="example.php" method="POST"></td>
<tr>
<td><input type="text" name="text1" value="Наша форма"></td>
<td><input type="text" name="text2"></td>
</tr>
<tr>
<td><input type="text" name="text3"></td>
<td><input type="text" name="text4"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Отправить"></td>
</tr>
</form>
</table>

</body>
</html>


Теперь поля расположены в два столбца, а кнопка находится под ними.
С тегами <table> </table>, надеюсь, понятно - они создают таблицу, а что делают теги <td>..</td> и <tr>..</tr>? Они и форматируют содержимое как таблицу - теги <tr>..</tr> - создают строку, а теги <td>..</td> - ячейку внутри строки.
Еще в этой таблице есть аттрибут colspan, он производит объединение указанного количества ячеек по столбцам.

Вот и все основы, если интересно больше - читайте учебники, ФАКи и т.д.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 4.8.2004, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 3
Всего: 39




Авторы статьи:
Secandr
Ignat
IZ@TOP


Топик для обсуждения (Задавайте вопросы, сообщайте об ошибках, дополняйте!!!): http://forum.vingrad.ru/index.php?showtopic=26940


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
  
Закрытая темаСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Избранное | Следующая тема »


 




[ Время генерации скрипта: 0.2066 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.