Компьютеры Windows Интернет

В чем разница между HTTP_HOST и SERVER_NAME в PHP? Глобальный массив $_SERVER в PHP Извлечение переменной окружения HTTP_X_FORWARDED_FOR

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

В своей статье я предлагаю таблицу с основными переменными суперглобального массива $_SERVER. Таблица подобно той, что была сделана для функций PHP для работы со строками.

Чтобы посмотреть все элементы массива $_SERVER, нужно: а) либо вызвать функцию print_r(), которая распечатает массив; б) либо вызвать функцию phpinfo(), которая выведет информацию о PHP-интерпретаторе.

Кратко о $HTTP_SERVER_VARS

Суперглобальный массив $_SERVER пришёл на смену массиву $HTTP_SERVER_VARS в PHP версии 4.1.0. $HTTP_SERVER_VARS сейчас не используется, но знать о нём стоит. Прежде всего, старая версия не являлась автоглобальной. Второе отличие заключается в том, что некоторые элементы массива $_SERVER не существуют в $HTTP_SERVER_VARS, хотя в большинстве случаев их переменные совпадают.

Элемент

Краткое описание

Пример

$_SERVER["DOCUMENT_ROOT"]

Содержит путь к корневому каталогу сервера.

$_SERVER["HTTP_HOST"]

$_SERVER["SERVER_NAME"]

$_SERVER["SCRIPT_FILENAME"]

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

C:\folder\index.php

/www/folder/index.php

$_SERVER["PHP_SELF"]

$_SERVER["SCRIPT_NAME"]

Содержит имя скрипта.

$_SERVER["REQUEST_URI"]

Содержит имя скрипта, начиная от корневого каталога фиртуального хоста, а также переданные ему методом GET параметры.

/www/folder/index.php?page=2&num=5

$_SERVER["QUERY_STRING"]

Содержит параметры, переданные скрипту методом GET.

Для адреса

http://site.com/index.php?page=2&num=5

будет выведено

$_SERVER["REQUEST_METHOD"]

Содержит метод запроса, который применяется для вызова скрипта.

GET или POST

$_SERVER["HTTP_REFERER"]

Содержит адрес страницы, с которой пришёл посетитель.

http://yandex.ru/yandsearch

$_SERVER["HTTP_USER_AGENT"]

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

Nokia – NOKIA; Sony Ericsson – ERICSSON или SONYERICSSON; Samsung – SAMSUNG или SEC-; Motorola – MOT; LG – LG или LG-; Alcatel – ALCATEL; Panasonic – PANASONIC; Sagem – SAGEM; Pantech – PANTECH; Siemens – SIE; BenQ – BENQ; NEC – NEC; Sharp – SHARP.

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) (IE 6 и Windows XP )

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) Opera 9.50 (Opera 9.5 и Windows 2000 )

$_SERVER["REMOTE_ADDR"]

Содержит IP-адрес клиента.

$_SERVER["SERVER_ADDR"]

Содержит IP-адрес сервера.

$_SERVER["HTTP_ACCEPT"]

Описывает предпочтения клиента относительно типа документа. Содержимое этого элемента извлекается из HTTP-заголовка Accept, который передаётся серверу клиентом.

Формат вывода: MIME-тип [[; q], другой MIME-тип [; q] ... ]

Предпочитаемых MIME-типов может быть несколько, тогда они перечисляются через запятую. * используется для задания шаблона, группировки. q – коэффициент предпочтения, по умолчанию 1, изменяется от 0 до 1.

image/jpeg, image/x-xbitmap, application/x-shockwave-flash

image/*; q=0.5, image/jpeg (предпочитает жпег всем остальным форматам)

$_SERVER["HTTP_ACCEPT_LANGUAGE"]

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

ru, en; q=0.9 (предпочтение русского, но если его нет - и английский сойдёт)

$_SERVER["HTTP_ACCEPT_CHARSET"]

Подобен предыдущим. Содержит заголовок Accept-Charset

$_SERVER["HTTP_ACCEPT_ENCODING"]

Подобен предыдущим. Содержит заголовок Accept-Encoding

$_SERVER["SERVER_PORT"]

Содержит прослушиваемый порт сервера.

$_SERVER["SERVER_SOFTWARE"]

Содержит информацию о веб-сервере.

Apache/2.2.4 (Win32)

$_SERVER["SERVER_PROTOCOL"]

Содержит версию HTTP-протокола.

$_SERVER["GATEWAY_INTERFACE"]

Содержит версию CGI, используемую веб-сервером.

$_SERVER["REQUEST_TIME"]

Время начала запроса веб-страницы в UNIX-формате. Доступна, начиная с PHP 5.1.0

Полный адрес страницы с параметрами:

Таблицу со всеми функциями можно скачать по ссылке в формате *.doc.

Будьте особо внимательны к переменной $_SERVER["REQUEST_URI"] и не забывайте её проверять! Дело в том, что её использование может быть не особо безопасным. К примеру, на Вашем сайте некоторые урлы формируются с использованием этого параметра. Тогда можно прописать в строке браузера ссылку http://site.com/index.php?”>alert(document.cookie). В результате будет выведено окно, где будет показано содержимое файла кукисов. Данный пример безобиден, но это является дырой, с помощью которой хакер может воспользоваться брешью, к примеру, чтобы украсть данные другого пользователя. Посему - проверяйте переменную на недопустимые символы, а особенно > и on => 200 => on => htmlweb.ru => https => 443 => close => Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) => */* => beget=begetok; => gzip,deflate => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin => => Apache/2.4.25 (Debian) mpm-itk/2.4.7-04 OpenSSL/1.0.2l => htmlweb.ru => 185.12.92.137 => 80 => 144.76.78.4 => /var/www/htmlweb/data/www/htmlweb.ru => http => => /var/www/htmlweb/data/www/htmlweb.ru => [email protected] =>.php => 35242 => /php/function/$_server.php => CGI/1.1 => HTTP/1.0 => GET => => /php/function/%24_server.php => /index.php => /index.php => 1560059525.711 => 1560059525) 1

$_SERVER["DOCUMENT_ROOT "]

Элемент $_SERVER["DOCUMENT_ROOT"] содержит путь к корневой директории сервера, если скрипт выполняется в виртуальном хосте, в данном элементе указывается путь к корневой директории виртуального хоста. Т.е. в конфигурационном файле httpd.conf виртуальный хост имеет директиву DocumentRoot, которой присвоено значение "D:/main", элемент $_SERVER["DOCUMENT_ROOT"] будет содержать значение "D:main".

$_SERVER["REMOTE_ADDR "]

В элемент $_SERVER["REMOTE_ADDR"] помещается IP-адрес клиента. При тестировании на локальной машине - этот адрес будет равен 127.0.0.1. Однако при тестировании в сети переменная вернёт IP-адрес клиента или последнего прокси-сервера через который клиент попал на сервер. Если клиент использует прокси-сервер узнать его IP-адрес можно при помощи переменной окружения HTTP_X_FORWARDED_FOR, значение которой можно получить при помощи функции getenv().

Замечание

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

Извлечение переменной окружения HTTP_X_FORWARDED_FOR

echo @getenv(HTTP_X_FORWARDED_FOR);

$_SERVER["SCRIPT_FILENAME "]

В элемент $_SERVER["SCRIPT_FILENAME"] помещается абсолютный путь к файлу от корня диска. Так, если сервер работает под управлением операционной системы Windows, то такой путь может выглядеть следующим образом "d:main estindex.php", т.е. путь указывается от диска, в UNIX-подобной операционной системы путь указывается от корневой директории /, например "/var/share/www/test/index.php".

/var/www/htmlweb/data/www/сайт/index.php

$_SERVER["SERVER_NAME "]

В элемент $_SERVER["SERVER_NAME"] помещается имя сервера, как правило, совпадающее с доменным именем сайта, расположенного на нём. Например,

Содержимое элемента $_SERVER["SERVER_NAME"] часто совпадает с содержимым элемента $_SERVER["HTTP_HOST"]. Помимо имени сервера суперглобальный массив $_SERVER позволяет выяснить ещё ряд параметров сервера, например IP-адрес сервера, прослушиваемый порт, какой Web-сервер установлен и версию HTTP протокола. Эта информация помещается в элементы $_SERVER["SERVER_ADDR"], $_SERVER["SERVER_PORT"], $_SERVER["SERVER_SOFTWARE"] и $_SERVER["SERVER_PROTOCOL"], соответственно. Ниже приводится пример с использованием данных элементов.

Использование элементов массива $_SERVER echo "Имя сервера - ".$_SERVER["SERVER_NAME"]."
"; echo "IP-адрес сервера - ".$_SERVER["SERVER_ADDR"]."
"; echo "Порт сервера - ".$_SERVER["SERVER_PORT"]."
"; echo "Web-сервер - ".$_SERVER["SERVER_SOFTWARE"]."
"; echo "Версия HTTP-протокола - ".$_SERVER["SERVER_PROTOCOL"]."
";

Имя сервера - сайт
IP-адрес сервера - 185.12.92.137
Порт сервера - 80
Web-сервер - Apache/2.4.25 (Debian) mpm-itk/2.4.7-04 OpenSSL/1.0.2l
Версия HTTP-протокола - HTTP/1.0

$_SERVER["REQUEST_METHOD "]

В элемент $_SERVER["REQUEST_METHOD"] помещается метод запроса, который применяется для вызова скрипта: GET или POST.

Echo $_SERVER["REQUEST_METHOD"];

$_SERVER["QUERY_STRING "]

В элемент $_SERVER["QUERY_STRING"] заносятся параметры, переданные скрипту, если строка запроса представляет собой адрес

Например при обращении к:
в элемент $_SERVER["QUERY_STRING"] попадёт весь текст после знака "?":

Echo $_SERVER["QUERY_STRING"];

id=1&test=wet&id_theme=512

$_SERVER["PHP_SELF "]

В элемент $_SERVER["PHP_SELF"] помещается имя скрипта, начиная от корневой директории виртуального хоста, т.е. если строка запроса представляет собой адрес http://www.mysite.ru/test/index.php?id=1&test=wet&id_theme=512 то элемент $_SERVER["PHP_SELF"] будет содержать фрагмент "/test/index.php" . Как правило, этот же фрагмент помещается в элемент $_SERVER["SCRIPT_NAME"].

$_SERVER["REQUEST_URI "]

В элемент $_SERVER["REQUEST_URI"] содержит имя скрипта, начиная от корневой директории виртуального хоста и параметры, т.е. если строка запроса представляет собой адрес: http://www.mysite.ru/test/index.php?id=1&test=wet&id_theme=512 то элемент $_SERVER["REQUEST_URI"] будет содержать фрагмент "/test/index.php?id=1&test=wet&id_theme=512" . Для того, чтобы восстановить в скрипте полный адрес, который помещён в строке запроса, достаточно использовать комбинацию элементов массива $_SERVER, представленную ниже

Полный адрес к скрипту echo "http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
  • Перевод
  • Tutorial

Одним из крутейший новшеств в php 5.4 является встроенный сервер, созданный специально для разработки и тестирования. Теперь вы можете писать и тестировать свой код не имея полноценного веб-сервера - просто запустите встроенный сервер, протестируйте свой код, и выключите его, когда закончите.
Сервер, так же, предоставляет возможность и для творческого использования. Например, вы можете распространять портативное web-приложение на CD или USB, или даже как десктопное приложение, созданное на PHP без использования GTK или других графических библиотек.

В мануале PHP подчеркивается, что встроенный сервер предназначен для разработки и рекомендуется не использовать его на боевом сервере. Отсутствуют какие-либо INI директивы отвечающие за сервер (за исключением раскрашивания вывода в консоли), и, кажется, что основная идея документации: «у нас теперь тоже есть Web сервер, отстаньте от нас».
Несмотря на это, я считаю, что встроенные сервер может быть ценным инструментом для разработки и тестирования. К примеру, на моей машине я использую предустановленный Apache с кастомной конфигурацией, подходящей для меня, но иногда я хочу попробовать какие-либо новые Web-приложения. Со встроенным web-сервером я могу протестировать приложение прямо из папки «downloads» или временной папки и переместить в обычную среду, только тогда, когда это будет необходимо.
Но для начала, это не так просто, ведь многие написанные приложения используют.htaccess и mod_rewrite. Но я уверен, что кто-то (может быть один из вас, почему бы и нет?) напишет адаптер для этого, и я хотел бы быть первым, кто протестируют его.
В этой статье я объясню некоторые основные примеры использования встроенного сервера и покажу вам как сделать его полезным для разработки и тестирования.

Используем встроенный сервер Итак, для использования сервера нам необходим php 5.4 или выше. Для проверки версии PHP, выполните:
php -v
Так же вы можете определить доступен ли сервер в вашей сборке выполнив:
php -h
и найдите там описание параметров "-S" и "-t", которые используются только для сервера.
Для проверки сервера вы можете создать в текущей директории файл index.php, который будет содержать в себе вызов функции phpinfo() и затем запустить сервер:
$ php -S 127.0.0.1:8080 PHP 5.4.0RC7 Development Server started at Fri Feb 26 18:49:29 2012 Listening on 127.0.0.1:8080 Document root is /home/ec2-user Press Ctrl-C to quit.
И теперь вы можете увидеть содержимое отданной встроенным web-сервером:

В консоль же будет писаться каждый запрос клиента:
80.180.55.37:36318 : / 80.180.55.37:36584 : /
Возвращаясь назад, разберем параметр командной строки "-S", который используется для указания адреса, с которого сервер будет доступен. Возможные значения:
localhost - сервер будет доступен только с локальной машины,
0.0.0.0 - на любому интерфейсе машины,
Любой внешний или серый IP - только на указанном IP
Параметр "-t" устанавливает указанную директорию «directory root». Например:
$ php -S :8090 -t /home/ec2-user/public
Кроме того,. вы может указать имя конкретного файла-роутера. Например:
$ php -S >localhost or your public IP>:8080 -t /home/ec2-user/public public/index.php
Вывод этого роутера будет парситься и выполняться сервером. Простой пример:

Затем получите доступ ко всем действительным URL-адресам для вашего сайта и проверьте разницу.

Мне потребовалось некоторое время, чтобы понять, что люди подразумевают под " SERVER_NAME более надежным". Я использую общий сервер и не имею доступа к директивам виртуального хоста. Итак, я использую mod_rewrite в.htaccess для сопоставления различных HTTP_HOST в разных каталогах. В этом случае это значение HTTP_HOST имеет смысл.

Ситуация аналогична, если вы используете виртуальные хосты на основе имен: директива ServerName внутри виртуального хоста просто говорит, какое имя хоста будет сопоставлено этому виртуальному хосту. Суть в том, что в обоих случаях имя хоста, предоставленное клиентом во время запроса (HTTP_HOST), должно совпадать с именем на сервере, которое само отображается в каталог. Независимо от того, выполняется ли сопоставление с директивами виртуального хоста или с правилами htaccess mod_rewrite, здесь вторично. В этих случаях HTTP_HOST будет таким же, как SERVER_NAME . Я рад, что Apache настроен таким образом.

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

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

Предполагая, что у вас есть простая настройка (CentOS 7, Apache 2.4.x и PHP 5.6.20) и только один веб-сайт (не предполагающий виртуальный хостинг)...

В смысле PHP $_SERVER["SERVER_NAME"] - это элемент PHP, зарегистрированный в суперкласме $_SERVER на основе вашей конфигурации Apache (директива **ServerName** с UseCanonicalName On) в httpd.conf(будь то из включенной конфигурации виртуального хоста файл, что угодно и т.д.). HTTP_HOST выводится из заголовка HTTP host . Рассматривайте это как пользовательский ввод. Фильтр и проверка перед использованием.

Вот пример того, где я использую $_SERVER["SERVER_NAME"] в качестве основы для сравнения. Следующий метод относится к конкретному дочернему классу, который я назвал ServerValidator (дочерний элемент Validator). ServerValidator проверяет шесть или семь элементов в $_SERVER перед их использованием.

При определении того, является ли HTTP-запрос POST, я использую этот метод.

Public function isPOST() { return (($this->requestMethod === "POST") && // Ignore $this->hasTokenTimeLeft() && // Ignore $this->hasSameGETandPOSTIdentities() && // Ingore ($this->httpHost === filter_input(INPUT_SERVER, "SERVER_NAME"))); }

К моменту вызова этого метода будет выполняться вся фильтрация и проверка соответствующих элементов $_SERVER (и соответствующих наборов свойств).

($this->httpHost === filter_input(INPUT_SERVER, "SERVER_NAME")

Проверяет, что значение $_SERVER["HTTP_HOST"] (в конечном счете полученное из запрошенного HTTP-заголовка host) соответствует $_SERVER["SERVER_NAME"] .

Теперь я использую суперглобальный разговор, чтобы объяснить мой пример, но это потому, что некоторые люди не знакомы с INPUT_GET , INPUT_POST и INPUT_SERVER в отношении filter_input_array() .

Суть в том, что я не обрабатываю запросы POST на моем сервере, если не выполнены все четыре условия. Следовательно, с точки зрения запросов POST отказ в предоставлении HTTP host заголовка (присутствия, проверенного для более ранних) заклинаний doom для строгих браузеров HTTP 1.0 . Кроме того, запрашиваемый хост должен соответствовать значению ServerName в httpd.conf, а по расширению - значению $_SERVER("SERVER_NAME") в супермаклоне $_SERVER . Опять же, я бы использовал INPUT_SERVER с функциями фильтра PHP, но вы ломали мой дрейф.

Как указано в balusC, SERVER_NAME не является надежным и может быть изменен в конфигурации apache, конфигурации сервера сервера и брандмауэра, которые могут находиться между вами и сервером.

Следующая функция всегда возвращает реальный хост (пользовательский типизированный хост) без порта, и он почти надежен:

Function getRealHost(){ list($realHost,)=explode(":",$_SERVER["HTTP_HOST"]); return $realHost; }

поделиться

Для начала мы усовершенствуем страничку регистрации, добавив возможность загружать аватар. Исходное изображение должно быть формата jpg, gif или png. Так же оно должно быть не более 2 Мб. Не беспокойтесь, после его сжатия скриптом, размер аватара будет около 3 кб и формат jpg. Откройте страницу reg. php и допишите в теге < form > строчку enctype="multipart/form-data" ,как в примере:


Регистрация

Ваш пароль *:




Выберите аватар. Изображение должно быть формата jpg, gif или png:




Теперь сохраняем reg.php

2.Затем необходимо создать еще одно поле в таблице users . Заходим в phpmyadmin , выбираем нужную базу и таблицу.


Выставляем все значения, как на рисунке:

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

3.Переходим к файлу save _ user . php и дописываем следующий код после удаления пробелов у логина и пароля:

//удаляем лишние пробелы
$login = trim($login);

// дописываем новое********************************************

//добавляем проверку на длину логина и пароля
if (strlen($login) < 3 or strlen($login) > 15) {
exit ("Логин должен состоять не менее чем из 3 символов и не более чем из 15.");
}
if (strlen($password) < 3 or strlen($password) > 15) {
exit ("Пароль должен состоять не менее чем из 3 символов и не более чем из 15.");
}

if (!empty($_POST["fupload"])) //проверяем, отправил ли пользователь изображение
{
$fupload=$_POST["fupload"]; $fupload = trim($fupload);
if ($fupload =="" or empty($fupload)) {
unset($fupload);// если переменная $fupload пуста, то удаляем ее
}
}
if (!isset($fupload) or empty($fupload) or $fupload =="")
{
//если переменной не существует (пользователь не отправил изображение),то присваиваем ему заранее приготовленную картинку с надписью "нет аватара"
$avatar = "avatars/net-avatara.jpg"; //можете нарисовать net-avatara.jpg или взять в исходниках
}
else
{
//иначе - загружаем изображение пользователя
$path_to_90_directory = "avatars/";//папка, куда будет загружаться начальная картинка и ее сжатая копия

If(preg_match("/[.](JPG)|(jpg)|(gif)|(GIF)|(png)|(PNG)$/",$_FILES["fupload"]["name"]))//проверка формата исходного изображения
{
$filename = $_FILES["fupload"]["name"];
$source = $_FILES["fupload"]["tmp_name"];
$target = $path_to_90_directory . $filename;
move_uploaded_file($source, $target);//загрузка оригинала в папку $path_to_90_directory
if(preg_match("/[.](GIF)|(gif)$/", $filename)) {
$im = imagecreatefromgif($path_to_90_directory.$filename) ; //если оригинал был в формате gif, то создаем изображение в этом же формате. Необходимо для последующего сжатия
}
if(preg_match("/[.](PNG)|(png)$/", $filename)) {
$im = imagecreatefrompng($path_to_90_directory.$filename) ;//если оригинал был в формате png, то создаем изображение в этом же формате. Необходимо для последующего сжатия
}

If(preg_match("/[.](JPG)|(jpg)|(jpeg)|(JPEG)$/", $filename)) {
$im = imagecreatefromjpeg($path_to_90_directory.$filename); //если оригинал был в формате jpg, то создаем изображение в этом же формате. Необходимо для последующего сжатия
}
//СОЗДАНИЕ КВАДРАТНОГО ИЗОБРАЖЕНИЯ И ЕГО ПОСЛЕДУЮЩЕЕ СЖАТИЕ ВЗЯТО С САЙТА www.codenet.ru
// Создание квадрата 90x90
// dest - результирующее изображение
// w - ширина изображения
// ratio - коэффициент пропорциональности
$w = 90; // квадратная 90x90. Можно поставить и другой размер.
// создаём исходное изображение на основе
// исходного файла и определяем его размеры
$w_src = imagesx($im); //вычисляем ширину
$h_src = imagesy($im); //вычисляем высоту изображения
// создаём пустую квадратную картинку
// важно именно truecolor!, иначе будем иметь 8-битный результат
$dest = imagecreatetruecolor($w,$w);
// вырезаем квадратную серединку по x, если фото горизонтальное
if ($w_src>$h_src)
imagecopyresampled($dest, $im, 0, 0,
round((max($w_src,$h_src)-min($w_src,$h_src))/2),
0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
// вырезаем квадратную верхушку по y,
// если фото вертикальное (хотя можно тоже серединку)
if ($w_src

4. Необходимо добавить одну таблицу в ту же базу. В ней будут хранится ip-адреса, которые допустили ошибки при входе. Таким образом мы сможем ограничить доступ тем, кто ошибся больше трёх раз подряд на минут 15. Думаю программам, подбирающим пароли, долго придется возиться.
Зайдем в phpmyadmin и создадим новую таблицу с 3-мя полями:


ip - ip-адрес.
date - дата неудачного входа за последние 15 минут у пользователя с данным ip. col - количество ошибок за последние 15 минут у пользователя с данным ip.
Отлично! Готово, теперь изменим файл проверки логина и пароля, ведь теперь у нас пароль зашифрован. Открываем testreg.php и удаляем все, что дальше удаления пробелов с логина и пароля. Далее добавляем следующий код:

//удаляем лишние пробелы
$login = trim($login);
$password = trim($password);

// заменяем новым********************************************
// подключаемся к базе
include ("bd.php");// файл bd.php должен быть в той же папке, что и все остальные, если это не так, то просто измените путь
// минипроверка на подбор паролей
$ip=getenv("HTTP_X_FORWARDED_FOR");
if (empty($ip) || $ip=="unknown") { $ip=getenv("REMOTE_ADDR"); }//извлекаем ip
mysql_query ("DELETE FROM oshibka WHERE UNIX_TIMESTAMP() - UNIX_TIMESTAMP(date) > 900");//удаляем ip-адреса ошибавшихся при входе пользователей через 15 минут.
$result = mysql_query("SELECT col FROM oshibka WHERE ip="$ip"",$db);// извлекаем из базы количество неудачных попыток входа за последние 15 у пользователя с данным ip
$myrow = mysql_fetch_array($result);
if ($myrow["col"] > 2) {
//если ошибок больше двух, т.е три, то выдаем сообщение.
exit("Вы набрали логин или пароль неверно 3 раз. Подождите 15 минут до следующей попытки.");
}
$password = md5($password);//шифруем пароль
$password = strrev($password);// для надежности добавим реверс
$password = $password."b3p6f";
//можно добавить несколько своих символов по вкусу, например, вписав "b3p6f". Если этот пароль будут взламывать методом подбора у себя на сервере этой же md5,то явно ничего хорошего не выйдет. Но советую ставить другие символы, можно в начале строки или в середине.
//При этом необходимо увеличить длину поля password в базе. Зашифрованный пароль может получится гораздо большего размера.

$result = mysql_query("SELECT * FROM users WHERE login="$login" AND password="$password"",$db); //извлекаем из базы все данные о пользователе с введенным логином и паролем
$myrow = mysql_fetch_array($result);
if (empty($myrow["id"]))
{
//если пользователя с введенным логином и паролем не существует
//Делаем запись о том, что данный ip не смог войти.
$select = mysql_query ("SELECT ip FROM oshibka WHERE ip="$ip"");
$tmp = mysql_fetch_row ($select);
if ($ip == $tmp) {//проверяем, есть ли пользователь в таблице "oshibka"
$result52 = mysql_query("SELECT col FROM oshibka WHERE ip="$ip"",$db);
$myrow52 = mysql_fetch_array($result52);
$col = $myrow52 + 1;//прибавляем еще одну попытку неудачного входа
mysql_query ("UPDATE oshibka SET col=$col,date=NOW() WHERE ip="$ip"");
}
else {
mysql_query ("INSERT INTO oshibka (ip,date,col) VALUES ("$ip",NOW(),"1")");
//если за последние 15 минут ошибок не было, то вставляем новую запись в таблицу "oshibka"
}

exit ("Извините, введённый вами логин или пароль неверный.");
}
else {
nbsp; //если пароли совпадают, то запускаем пользователю сессию! Можете его поздравить, он вошел!
$_SESSION["password"]=$myrow["password"];
$_SESSION["login"]=$myrow["login"];
$_SESSION["id"]=$myrow["id"];//эти данные очень часто используются, вот их и будет "носить с собой" вошедший пользователь

//Далее мы запоминаем данные в куки, для последующего входа.
//ВНИМАНИЕ!!! ДЕЛАЙТЕ ЭТО НА ВАШЕ УСМОТРЕНИЕ, ТАК КАК ДАННЫЕ ХРАНЯТСЯ В КУКАХ БЕЗ ШИФРОВКИ
if ($_POST["save"] == 1) {
//Если пользователь хочет, чтобы его данные сохранились для последующего входа, то сохраняем в куках его браузера
setcookie("login", $_POST["login"], time()+9999999);
setcookie("password", $_POST["password"], time()+9999999);
}}
echo "";//перенаправляем пользователя на главную страничку, там ему и сообщим об удачном входе
?>

5. Полностью изменим главную страничку. Необходимо на ней вывести аватар пользователя, вывести ссылку на выход из аккаунта и добавить чекбокс для запоминания пароля при входе.
Index.php




Главная страница


Главная страница



6. Необходимо сделать возможность выйти из аккаунта пользователям, которые вошли. На главной странице уже была ссылка на выход. Но этого файла пока не существует. Так создадим новый файл exit.php с кодом:

Ну вот и все! Пользуйтесь на здоровье! Удачи!