PHP: различия между версиями

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
м Откат правок 178.217.212.154 (обс.) к версии 85.142.161.138
Строка 793: Строка 793:


//Заметьте, нету команд echo - эту команду можно использовать только после того, как отправились все куки
//Заметьте, нету команд echo - эту команду можно использовать только после того, как отправились все куки
// P.S. Если на странице используются куки, и у вас кривые руки, лучше не использовать кодировку UTF-8
// P.S. Если на странице используются куки, лучше не использовать кодировку UTF-8





Версия от 16:15, 14 января 2013

PHP (произносится пи-эйч-пи́) — скриптовый язык программирования, созданный для генерации HTML-страниц на веб-сервере и работы с базами данных. На сегодняшний момент поддерживается подавляющим большинством представителей хостингов. Входит в LAMP — «стандартный» набор для создания вебсайтов.

PHP программы

Программы PHP могут выполняться двумя способами: как Web-приложение HTTP-сервером или как консольные программы. Поскольку, нашей задачей является программирование web-приложений, мы преимущественно будем рассматривать первый способ.

Дело в том, что PHP, как правило, используется сугубо для программирования приложений, связанных с Интернетом. Однако, PHP можно еще использовать в качестве интерпретатора командной строки, в основном в *nix-системах. Последнее возможно при помощи CORBA и COM интерфейсов, а также при помощи расширения PHP-GTK. При таком использовании PHP возможно решение следующих задач:

  • создание приложений интерактивной командной строки;
  • создание кросс-платформенных GUI приложений при помощи библиотек PHP-GTK, PHP-Qt или WinBinder;
  • автоматизация некоторых задач под Windows и Linux.

Рассмотрим процесс выполнения php-сценария при обращении браузера к серверу. Итак, вначале браузер запрашивает страницу с расширением .php, после чего web-сервер пропускает программу через машину PHP и выдаёт результат в виде html-кода. Причем, если взять стандартную страницу HTML, изменить расширение на .php и пропустить её через машину PHP, последняя просто перешлёт её пользователю без изменений. Чтобы включить в этот файл команды PHP, необходимо заключить команды PHP в специальные теги, которые могут быть нескольких видов, но на практике используется только один:

<?php
...
?>

и его сокращённая форма, которая работает при short_open_tag = 1 в php.ini:

<?
...
?>
примечание: закрывающий тег ?> в самом конце файла можно не ставить

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

<?php
if (5 < 3) {
  print '<p>Hello, world!</p>';
?>
<p>Hello!</p>
Эта строка не интерпретируется как код PHP
и выводится только если  блок кода выполняется
<?
  print '<p>Hello, world!</p>';
}

Функция print в PHP применяется для вывода фактически всего, что встречается на web-страницах (текста, разметки HTML, чисел). Смысл ее действия, мы думаем, понятен из приведенного примера. Если включена поддержка сокращённой инструкции обработки, то вместо

<? print 'Test' ?>

можно писать

<?='Test'?>

Комментарии

PHP предоставляет несколько методов для вставки комментариев. Проще всего пользоваться двойным слэшем (//), после чего PHP машина игнорирует все, что расположено до конца строки. Также можно пользоваться многострочными комментариями в стиле С (/*…*/). Для однострочных комментариев можно еще пользоваться символом решетки (#) (комментарий скриптовых языков UNIX).

<?php
print '<p>Hello</p>'; // комментарий
print '<p>Hello</p>'; # комментарий
/** 
 * и это тоже комментарии
 */
?>

Следует помнить о том, что стили комментариев PHP действуют только внутри ограничителей PHP. Если PHP встретит эти символы комментариев вне ограничителей, то они, как и любой текст, будут помещены на html-страницу. Например:

<?php
print '<p>Hello</p>'; // нормальный комментарий
?>
// а вот этот комментарий отобразится браузером.
<!-- Комментарий  HTML. Будет виден в исходном коде HTML, но не в браузере  -->

Заметим, что комментарии можно вставлять не только после конца оператора, а, например, и вот так:

<?php
$a = 'Hello, world';
print strstr($a, 'H');
// эту функцию мы рассмотрим позднее

Переменные

В РНР переменные начинаются со знака доллара ($). За этим знаком может следовать любое количество буквенно-цифровых символов и символов подчеркивания, но первый символ не может быть цифрой. Следует также помнить, что имена переменных в РНР чувствительны к регистру, в отличие от ключевых слов.

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

Переменная инициализируется в момент присваивания ей значения и существует до тех пор, пока выполняется программа (то есть, в случае web-страницы это означает, что до тех пор, пока не завершен запрос.), или она не будет удалена функцией unset().

Функции вывода

В PHP существует несколько способов вывести что-либо в веб страницу:

  • Операторы echo и print
    Работают одним и тем же образом, но print всегда возвращает 1, в то время как echo ничего не возвращает. Выводят значение аргумента.
  • print_r()
    Позволяет корректно выводить массивы
  • var_dump()
    Выводит переменную вместе с типом. Очень удобный инструмент для отладки

Вывод различных функций

Аргумент echo print_r() var_dump()
1 1 1 int(1)
false     bool(false)
array( 1, 2, 3 ) Array Array

(

   [0] => 1
   [1] => 2
   [2] => 3

)

array(3) {
 [0]=>
 int(1)
 [1]=>
 int(2)
 [2]=>
 int(3)

}

"Test" Test Test string(4) "Test"

Типы данных в РНР

Как уже было сказано, PHP предоставляет определенную гибкость в отношении типов переменных, то есть с одной и той же переменной на протяжении программы можно работать и как со строкой, и как с числом. Однако, несмотря на это в РНР существуют набор основных типов данных, которые могут явно указываться при работе с переменными:

  • integer; (Целые числа)
  • string; (Строки)
  • boolean; (Двоичные данные (Истина или Ложно))
  • double;
  • array; (Массивы)
  • object; (Объекты)
  • NULL; (Пустой тип)
  • Resource; (Ресурсы)

Есть функция gettype(), возвращающая тип, который РНР назначил переменной:

<?php
$var1= '5';
$var2 = 5;
echo gettype($var1) // string
     . '<br>'
     . gettype($var2); // integer

В первом случае РНР вернет string, во втором integer.

Стоит заметить, что операция «.» (точка) используется для склеивания (конкатенации) строк.

Существует также функция settype(), которая явно устанавливает тип:

<?php
$var = '5';
echo gettype($var);
settype($var, 'integer');
echo '<br>'
     . gettype($var);

Выполнение этого фрагмента кода приведет к такому же результату, как и предыдущего.

Кроме функции settype() преобразование типов в РНР можно осуществлять при помощи операторов преобразования типов. Преобразование типов осуществляется путем указания перед переменной ее нового типа, взятого в скобки:

$var = (int)$var;

Соответственно, выполнение следующего кода приведет к тому, что РНР вернет integer:

<?php
$var = '5'; // тип string
$var = (int)$var; // преобразуем в int
echo gettype($var);

Внешние переменные

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

Сначала PHP инициализирует массивы $_ENV (переменные окружения) и $_SERVER[1]. Массив $_SERVER содержит следующие ключи (индексы массива):

  • $_SERVER['HTTP_USER_AGENT'] — браузер клиента
  • $_SERVER['HTTP_ACCEPT'] — принимаемые MIME-типы. Может служить для определения возможностей браузера
  • $_SERVER['PHP_SELF'] — путь к файлу, содержащему выполняющийся скрипт, относительно корневого каталога (папки) сервера. Пример: /w/index.php

Затем РНР заполняет переменную $_GET, являющуюся массивом, которая создаётся при анализе строки запроса. Строка запроса хранится в элементе массива $_SERVER['QUERY_STRING'] и представляет собой информацию, следующую за символом «?» в запрошенном URL. РНР разбивает строку запроса по символам «&»[2] на отдельные элементы, а затем ищет в каждом из этих элементов знак «=». Если знак «=» найден, то создается переменная с именем из символов, стоящих слева от знака равенства. Рассмотрим следующую форму:

<form action="http://localhost/PHP/test.php" method="get">
  HDD: <input type="text" name="HDD"><br>
  CDROM: <input type="text" name="CDROM"><br>
  <input type="submit">
</form>

Если Вы в этой форме в строке HDD наберете, к примеру, «Maxtor», а в строке CDROM «Nec», то она сгенерирует следующую форму запроса: http://localhost/PHP/test.php?HDD=Maxtor&CDROM=Nec

В нашем случае РНР создаст следующие элементы массива с соответствующими индексами (ключами): $_GET['HDD'] = 'Maxtor' и $_GET['CDROM'] = 'Nec'.

Вы можете работать с этими переменными из Вашего скрипта (у нас — test.php) как с обычными переменными. В нашем случае они просто выводятся на экран:

<?php
echo "<p>HDD is {$_GET['HDD']}</p>";
echo "<p>CDROM is {$_GET['CDROM']}</p>";

Если запрос страницы выполняется при помощи метода POST, то появляется группа POST-переменных, которые интерпретируются также и помещаются в массив $_POST.

Константы

Константы объявляются в РНР при помощи функции define():

define('CONSTANT', value)

Первый параметр этой функции — имя константы, второй — её значение. При использовании константы на неё ссылаются по имени:

<?php
  define('CONSTANT1', 15);
  define('CONSTANT2', "\x20"); // щестнадцатеричный код символа пробела
  define('CONSTANT3', 'Hello');
  echo CONSTANT1;
  echo CONSTANT2;
  echo CONSTANT3;

По традиции имена констант пишут буквами верхнего регистра. И хотя это только традиция, мы Вам рекомендуем ей следовать, поскольку плохие программисты получаются в том числе и из тех, кто не следовал хорошим традициям. Существует функция defined(), которая проверяет, определена ли константа:

<?php
define('CONSTANT', 'Hello');
if (defined('CONSTANT')) {
  echo '<p>CONSTANT is defined</p>';
}

Операторы

Математические операторы

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

  • Унарный минус (-) — изменяет знак числа
  • Сложение, вычитание, умножение (+, -, *) — действуют также как и в обычной математике
  • Деление (/) всегда возвращает вещественное число, вне зависимости от результата.
  • Деление по модулю (%) — остаток от деления

Инкремент и декремент

  • $a++ возвращает старое значение $a и увеличивает $a на 1
  • ++$a увеличивает $a на 1 и возвращает новое значение $a
  • $a-- возвращает старое значение $a и уменьшает $a на 1
  • --$a уменьшает $a на 1 и возвращает новое значение $a

Операторы сравнения

Существуют следующие операторы сравнения:

$a == $b true если $a равно $b
$a === $b true если $a равно $b и они имеют один и тот же тип
$a != $b или $a <> $b true если $a не равно $b
$a > $b true если $a больше $b
$a < $b true если $a меньше $b
$a >= $b true если $a больше или равно $b
$a <= $b true если $a меньше или равно $b

Операторы присвоения

Для присвоения переменной нового значения используется оператор «=»:

$a = $b + $c - 127;

Также существуют сокращённые операторы присвоения(+=, -=, .=, /=, *=, %=):

$a = $a + 1;
# равносильно
$a += 1;

if…else

Оператор if позволяет выполнять определённый код только при выполнении определённого условия:

<?php
$a = 1;
$b = null;
$c = 2 * 3;
$d = true;
if ($a) {
 echo "if(\$a);<br>";
}
if($b) {
 echo "if(\$b);<br>";
}
if($c) {
 echo "if(\$c);<br>";
}
if(!$d) {
 echo "if(!\$d);<br>";
}
if($a < $c) {
 echo "\$a < \$c;<br>";
}

Этот код выводит следующие строки:

if($a);
if($c);
$a < $c;

Для того, чтобы выполнять код только если условие не выполнилось, можно использовать блок else:

<?php
if (isset($_GET['test'])) {
 echo 'Query contains "test" parameter';
} else {
 echo 'Query doesn\'t contain "test" parameter';
}

Можно использовать инструкцию elseif:

<?php
if ($_GET['test'] == "foo") {
 echo 'test = "foo"';
} elseif( isset( $_GET['test'] ) {
 echo 'Query contains "test" parameter, but it isn\'t "foo"';
} else {
 echo 'Query doesn\'t contain "test" parameter';
}

Переключатель switch

<?php
$a = "A";
switch ($a) {
    case 'A':
        echo 'Переменная имеет значение "А"';
        break;
    case 'B':
        echo 'Переменная имеет значение "B"';
        break;
    default:
        echo 'Ответ не найден';
}

Данный пример выведет «Переменная имеет значение „A“»

Операторы цикла

Операторы цикла задают многократное исполнение операторов в теле цикла. В PHP определены 4 разных оператора цикла:

  • цикл с предусловием: while (condition) { statements; }
  • цикл с постусловием: do { statements; } while(condition);
  • итерационный цикл: for (expression1; expression2; expression3) { statements; }
  • итерационный цикл foreach: foreach (array as [$key =>] $value) { statements; }

Если 3 первых оператора цикла берут свое начало от С-подобных языков, то последний оператор позаимствован у языка Perl.

While

Оператор while называется оператором цикла с предусловием. При входе в цикл вычисляется выражение условия, и, если его значение отлично от нуля, выполняется тело цикла. Затем вычисления выражения условия и операторов тела цикла выполняется до тех пор, пока значение выражения условия не станет равным нулю. Оператором while удобно пользоваться для просмотра всевозможных последовательностей, если в конце них находится заранее известный символ. (Это очень удобно в C++, к примеру для определения длины строки, поскольку в С++, по определению, строка есть последовательность символов типа char, заканчивающаяся нулевым символом).

Пример простейшего цикла while:

<?php
$var = 5;
$i = 0;
while (++$i <= $var) {
  echo $i . '<br />';
}

Этот код выдает в окне браузера цифры от одного до пяти.

Для выхода из цикла применяется оператор break. При обнаружении этого оператора текущая итерация цикла прекращается, и последующие итерации не происходят. При выполнении следующего примера, несмотря на то, что переменная $var = 7, в окне браузера появятся цифры от 1 до 5.

<?php
$var = 7;
$i = 0;
while (++$i <= $var) {
  echo $i . '<br />';
  if ($i == 5) break;
}

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

<?php
$var = 7;
$i = 0;
while (++$i <= $var) {
  if ($i == 5) {
    continue;
  }
  echo $i . '<br />';
}

В этом примере выводятся цифры от 1 до 7, кроме цифры 5.

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

Бесконечный цикл реализуется при помощи оператора while следующим образом:

while(1) {
  ...
}

Это то же самое, что и запись while(true) {...}. Примечание: В PHP стандартное время исполнения скрипта — 30 секунд (эту настройку можно изменить в php.ini). То есть по прошествии 30 секунд с начала выполнения скрипта, его действие будет прервано. Таким образом, время выполнения бесконечного цикла — полминуты.

Do…while

Этот оператор называется оператором цикла с постусловием. При входе в цикл в любом случае выполняется тело цикла (то есть цикл всегда будет выполнен хотя бы один раз), затем вычисляется условие, и если оно не равно 0, вновь выполняется тело цикла. В нижеследующем примере нуль всегда будет добавлен в список, независимо от условия (++$i <= $var):

<?php
$var = 5;
$i = 0;
do {
  echo $i . '<br />';
} while (++$i <= $var)

Результат:

0<br />
1<br />
2<br />
3<br />
4<br />
5<br />

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

Бесконечный цикл реализуется так:

do ; while(1);

For

Как уже говорилось, итерационный цикл имеет следующий формат:

for (expression1; expression2; expression3) {
  statements;
}

Здесь expression1 (инициализация цикла) — последовательность определений и выражений, разделяемая запятыми. Все выражения, входящие в инициализацию, вычисляются только один раз при входе в цикл. Как правило, здесь устанавливаются начальные значения счетчиков и параметров цикла. Смысл выражения-условия expression2 такой же как и у циклов с предусловиями. При отсутствии выражения-условия предполагается, что его значение всегда истинно. Выражения expression3 вычисляются в конце каждой итерации после выполнения тела цикла.

В следующем скрипте, мы по традиции выведем числа от 0 до 5:

<?php
$var = 5;
$i = 0;
for ($i = 0; $i <= $var; $i++) {
  echo $i . '<br>';
}

Результат аналогичен, показанному на предыдущем рисунке.

Бесконечный цикл можно организовать следующим образом:

for(;;);

Foreach

Оператор цикла foreach предназначен для работы с элементами массива. Следующий код превратит все элементы массива в единицы.

<?php
  $arr = array (1, 2, 3, 4);
  $i = 0;
  foreach ($arr as &$a)
    $a -= $i++;

Также предусмотрена возможность работы с ассоциативными массивами. При обработке следующего кода в переменной $name будет храниться ассоциативный индекс элемента, а в переменной $value — его значение. Проще говоря, ($arr[$name] == $value).

<?php
  // ...
  foreach ($arr as $name => $value) {
      /* тело цикла */
  }

Тернарный оператор ?:

Тернарный оператор «?:» это вид условного оператора, он проверяет Выражение 1 и если оно верно, то присваивает значение Выражения 2, иначе — Выражения 3.

<?php
  $a = true;
  $b = false;
  $c = 11;
  $d = 10;
  $f = $a ? $c : $d; // Переменной $f присвоится значение переменной $c, т. к. значение выражения $a истинно
  $g = $b ? $c : $d; // Здесь наоборот - $g будет присвоено значение $d
  $h = (!empty($n)) ? $n : $c+$d; // Сперва проверится существование переменной $n,
                                  // а т. к. она не существует, переменной $h присвоится сумма $c и $d, т. е. 21
?>

Строковые функции PHP

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

Вообще говоря, по определению, строка — это последовательность символов типа char, которая заканчивается нулевым символом. Поэтому, можно, конечно, радоваться тому, что при работе со строками, нам не приходится жонглировать указателями в стиле C/C++, однако не стоит забывать о том, что цена этому удобству — быстродействие. Поэтому некоторые приводимые здесь функции мы будем обсуждать в том числе и с точки зрения их быстродействия.

Функция htmlspecialchars

string htmlspecialchars(string $str)

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

Пример

корректное формирование и вывод гиперссылки, содержащей определённые параметры:

$link_search_subject = "Экранирование";
$link_label = "Поиск по слову <<$link_search_subject>>";

echo 
    '<a href="'.htmlspecialchars("http://ru.wikibooks.org/wiki/Служебная:Search?search=".urlencode($link_search_subject)."&go=".urlencode("Перейти")).'">'.
        htmlspecialchars($link_label).
    '</a>';

заметьте, что следующий (ниже представленный) код, содержит грубое нарушение, так как формирует гиперссылку с аттрибутом содержащим незаконченную (не закрытую) ссылку на сущность (&…;) :

$link_search_subject = "Экранирование";

echo 
    '<a href="http://ru.wikibooks.org/wiki/Служебная:Search?search='.urlencode($link_search_subject).'&go='.urlencode("Перейти").'">'. // НАРУШЕНИЕ!!
        "Поиск по слову Экранирование".
    '</a>';

это довольно часто встречаемая ошибка.

Функции поиска в тексте

substr()

Функция substr() возвращает часть строки. Например:

echo substr('Simple text', 3, 7);

Где 3 — точка отсчета, а 7 — длина изымаемой строки. Если же требуется вести отсчет от конца строки, используйте отрицательное значение.

Пример

Эта функция разобьет число по трём разрядам:

function my_int($value)
{
  $len = strlen($value);
  if ($len <= 3) {
      return $value;
  } else {
      return my_int(substr($value, 0, $len-3)) . ' ' . substr($value, $len-3, 3);
  }
}
 
echo my_int(12345678); //=> 12 345 678

strpos()

int strpos (string haystack, string needle [, int offset])

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

Если подстрока needle не найдена, strpos() возвращает FALSE.

Пример:

Эта функция определяет модель браузера:

function getCurrentBrowser() {
    $browser = strtoupper($_SERVER['HTTP_USER_AGENT']);
    if (strpos($browser, 'MSIE') !== false) { $browser = 'Internet Explorer';} 
    else if (strpos($browser, 'FIREFOX') !== false){ $browser = 'Firefox'; } 
    else if (strpos($browser, 'KONQUEROR') !== false){ $browser = 'Konqueror'; } 
    else if (strpos($browser, 'LYNX') !== false){ $browser = 'Lynx'; } 
    else { $browser = $_SERVER['HTTP_USER_AGENT']; }
    return $browser;
}

strrpos()

Возвращает позицию последнего вхождения символа

int strrpos (string haystack, string needle [, int offset])

Возвращает позицию последнего вхождения needle в строку haystack. В PHP 4 используется только первый символ строки needle.

Начиная с PHP 5 необязательный аргумент offset позволяет указать, с какого по счету символа строки haystack начинать поиск. Отрицательное значение предписывает прекратить поиск при достижении определенной позиции до конца строки.

Если подстрока needle не найдена, возвращает FALSE.


Пример:

Эта функция достаёт из URL имя файла (только пример, в жизни можно использовать функцию basename()):

function getfname($url)
{
    $pos = strrpos($url, '/', 8); // начиная с 8 символа, т.к. в "http://" искать не нужно
    $filename = '';
    if ($pos === false) {
        // Ошибка, url задан неверно.
        return false;
    } else {
        $filename = substr($url, $pos + 1);
    }
    return $filename;
}

strstr(), stristr()

string strstr (string $haystack, string $needle)

Возвращает подстроку строки haystack начиная с первого вхождения подстроки needle до конца строки. Функция stristr() выполняет ту же функцию, но не чувствительна к регистру.

Пример:

<?php
$text = 'www.wikibooks.org';
$strstr = strstr($text, '.');
print $strstr;
?>

Данный пример выведет «.wikibooks.org».

strchr()

Эта функция является псевдонимом функции strstr().

strrchr()

string strrchr (string $haystack, char $needle)

Возвращает подстроку строки haystack начиная с последнего вхождения needle до конца строки.

Если подстрока needle не найдена, возвращает FALSE.

Если needle состоит более чем из одного символа, используется только первый символ.

Если needle не является строкой, он приводится к целому и трактуется как код символа.

Пример:

<?php
$text = 'www.wikibooks.org';
$strrchr = strrchr($text, '.');
print $strrchr;
?>

Данный пример выведет «.org».

substr_count()

int substr_count (string $haystack, string $needle)

Возвращает число вхождений подстроки needle в строку haystack.

Можно использовать или текст в кавычках (или апострофах) или переменные.

Пример:

<?php
print substr_count('www.wikibooks.org', 'o');
?>

Данный пример выведет «3».

strspn()

strspn - находит длину начального сегмента маски.

int strspn (string str1, string str2)

Возвращает длину начального сегмента str1, состоящего полностью из символов строки str2.

Пример:

<?
$var = strspn("42 is the answer, what is the question ...", "1234567890");

?>

присваивает 2 переменной $var, поскольку строка "42" будет самым длинным сегментом, содержащим символы из "1234567890".

strcspn()

Обратная функции strspn() Функция strcspn() Определяет отсутствие начальных символов в строке.

Функция strcspn() возвращает длину начального фрагмента строки str1, состоящего полностью не из символов, которые есть в строке str2.

Система пользователей

Алгоритмы системы пользователей — В этой статье будет описаны алгоритмы системы пользователей и их коды на языке PHP.

Регистрация

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

<?php
//register
//Подключение к MySQL
mysql_connect("localhost", "root", "") or die(mysql_error);
//Подключение к базе данных deskside
mysql_select_db("deskside") or die(mysql_error);
$find_id_sql = mysql_query("SELECT * FROM users ORDER BY id ASC");
$find_id_row = mysql_num_rows($find_id_sql);
$find_names = mysql_query("SELECT * FROM users WHERE login='".$_POST['login']."'");
$find_row = mysql_num_rows($find_names);

$id_counter = 1;

//Вычисление последнего ID
	while ($find_id_row = mysql_fetch_assoc($find_id_sql)){
	$id_counter += 1;
	}

$user_already = false; //Проверка, есть ли уже такой пользователь
if ($_POST['register']){

while ($find_row = mysql_fetch_assoc($find_names)){ //Проверка, есть ли уже такой пользователь

	if ($find_row['login'] == $_POST['login']){
		$user_already = true;  //Если есть, то так и пишем

	}
}
	if($user_already){
		echo "Такой пользователь уже есть <br> <a href=\"http://deskside/main.php?page=register\">Пройти регистрацию заново</a>";
	}else{  //Если такого пользователя всё таки нет, то регистрируем нового пользователя с таким именем
			if ($_POST['password'] == $_POST['second_password']){ //Проверка совпадений паролей
			//Совпали
				echo "Регистрация проведена успешно";
				$md5_password = md5($_POST['password']); //хэширования пароля для базы данных
                                //
				mysql_query("INSERT INTO users (`id`, `login`, `password`, `e-mail`, `name`) VALUES ('".$id_counter."', '".$_POST['login']."', '".$md5_password."', '".$_POST['e-mail']."', '".$_POST['name']."')"); 

				
			}else{
				echo "Ошибка регистрации. Возможно, пароли не совпадают! <br> <a href=\"http://deskside/main.php?page=register\">Пройти регистрацию заново</a>";	

			}
	}
}

if($_POST['register']){

//Если пользователь уже нажал кнопку РЕГИСТРАЦИЯ, то зачем ему заново показывать форму????

}else{ 

//Если он уже кликнул, то мы не показываем форму, а выводим либо сообщение о подтверждении, либо об ошибке

echo ' 
<div style="margin-left:20px">
<form method="post">
	Логин: <input type="text" name="login"> <br>
	Пароль: <input type="password" name="password"> <br>
	Пароль еще раз: <input type="password" name="second_password"> <br>	
	E-Mail Адрес: <input type="text" name="e-mail"> <br>
	Ваше имя: <input type="text" name="name"> <br>
	<input type="submit" name="register" value="Зарегестрироваться">
</form>
</div>
';
}
?>

Авторизация пользователя

Алгоритм авторизации пользователя

Вход пользователя будет производиться по следующему алгоритму:

  1. Пользователь заполняет форму: Логин, Пароль.
  2. Данные запоминаются в переменной $_POST, после чего будут обрабатываться на сессии[3].
  3. Уже в сессии хэшируется введенный пользователем пароль алгоритмом MD5.
  4. Подключение к базе данных SQL и импорт данных со строки пользователя (Допустим, пользователь ввел имя пользователя admin) admin, затем запись всей строки в массив $table - такой вариант поможет сократить много нервов и строк.
  5. Сравнение зашифрованного пароля, который в базе данных с зашифрованным, введенным пользователем.
  6. Если пароли совпадают, записываются COOKIE с информацией о авторизации пользователя. ("user_enter" & "user_login").
  7. Закрытие сессии методом перенаправления на другую страницу. - header (Location: ...);
Форма входа
<?php
session_start();
/*

Этот шаблон можно вставлять в любую часть сайта, она будет работать в любом случае.

*/

?>

<form action="session.php" method="POST">

Логин: <input type="text" name="login"> <br>
Пароль: <input type="password" name="password"><br>
<input type="submit" value="Вход">

</form>


Сессия (session.php)
<?php

//Заметьте, нету команд echo - эту команду можно использовать только после того, как отправились все куки   
// P.S.   Если на странице используются куки, лучше не использовать кодировку UTF-8


session_start();

		if ($_POST['exit']){	//Если пользователь кликнул "Выход"	
                     // Чистим куки о его авторизации и логине

			unset($_COOKIE['user_enter']);
			unset($_COOKIE['user_login']);	
		}

//Подключение к MySQL
mysql_connect("localhost", "root", "1234") or die(mysql_error);    // localhost - стандартный сервер баз данных   |  root - логин MySQL   |   1234 - Пароль для пользователя MySQL

//Подключение к базе данных
mysql_select_db("base") or die(mysql_error);   //base - имя базы данных

$check_password = mysql_query("SELECT * FROM `base`.`users` WHERE (login='".$_POST['login']."')"); // SQL Запрос для проверки пароля
$row_check_password = mysql_num_rows($check_password);


while($row_check_password = mysql_fetch_assoc($check_password)){  //Получение данных о пользователе

	$table['id'] = $row_check_password['id'];       // ID Пользователя
	$table['login'] = $row_check_password['login'];    // Логин пользователя
	$table['password'] = $row_check_password['password'];    //Пароль пользователя в зашифрованном виде
	$table['blog_name'] = $row_check_password['blog_name'];       //Имя блога пользователя
}

//Проверка паролей

if ($_POST['enter']){

	$md5_password = md5($_POST['password']);  //хэширование пользовательского пароля

	if ($md5_password == $table['password'] && $_POST['login'] == $table['login']){ //Если хэш пароля пользователя и логин совпадают с хэшем пароля и логином из базы данных

		//Пользователь вошёл в систему
		setcookie("user_enter", true);      //кука - пользователь авторизировался
		setcookie("user_login", $_POST['login']);   //кука - логин пользователя
		setcookie("user_blog", $table['blog_name']);   //кука - имя блога пользователя

	}else{	
		//Пароль не подтвердился
		setcookie("user_login", "no_enter");    // кука - логин пользователя "не вошёл"
		setcookie("user_enter", false);	    // кука - пользователь не вошёл

	}
}

header('Location: http://deskside/main.php?page=home'); //Перенаправление на главную страницу
?>

Вывод данных пользователя

Для вывода данных пользователя будут использоваться куки, но поскольку они могут содержать только латинские буквы и цифры, они будут использоваться только как идентификатор имени пользователя и подтверждения его авторизации. Пользователю нужно выводить максимум информации о его ошибках, если ваш проект будет очень большим и пользователь при входе будет вводить не только логин и пароль, а ещё 20 полей, то пользователю будет не очень удобно при опечатке смотреть на такое сообщение: "Возможно вы ошиблись при заполнении данных, попробуйте ещё раз". Ему будет гораздо приятнее, если ему выведут сообщение с возможным полем опечатки и самой опечаткой. Но в нашем варианте будет рассматриваться только вариант с логином и паролем. Естественно невозможно использовать один и тот-же текст для вывода разной информации. Всего их три, если пользователь авторизировался, если пароли не совпадают и если пользователь ещё не авторизировался и хочет ввести свои данные. Проще всего будет просто выводить шаблон на страницу ($login_form)

Пользователь авторизировался
if ($_COOKIE['user_enter']){

$login_form ='
<form method="post">
	Вы вошли как <b>'.$login.'</b> <br><br>
	<a href="http://deskside/main.php?page=register">Регистрация</a> <br>
	<a href="http://deskside/main.php?page=profile">Профиль</a> <br>
	<input type="submit" name="exit" value="Выход">
</form>
';

}
Пароли не совпали
if($_COOKIE['user_login'] == "no_enter" And $_COOKIE['user_enter'] == false){

$login_form = '
<form method="post">
	Ошибка! Пароль неправильный!
	<br>
	<hr>
	<b><input type="submit" name="exit" value="Ввести снова"></b> <br>
	<a href="http://deskside/main.php?page=register">Регистрация</a>
</form>
';
}
Форма авторизации
$login_form = '
<table>
	<tr>	
		<td>&nbsp;</td>
		<td>&nbsp;</td>
		<td>&nbsp;</td>	
	</tr>
	<tr>
		<td>&nbsp;</td>
		<td class="style10">
				<form action="session.php" method="POST">
					Логин: <br>
					<input type="text" name="login"> <br>
					Пароль: <br>
					<input type="password" name="password">
					<br>
					<hr>
					<input type="submit" name="enter" value="Войти">
					<br>
					<br>
					<a href="http://deskside/main.php?page=register">Регистрация</a>
				</form>
		</td>
		<td>&nbsp;</td>
	</tr>
	<td>
		<td>&nbsp;</td>
		<td>&nbsp;</td>
		<td>&nbsp;</td>
	</td>
</table>
';

Примечания

  1. На самом деле, порядок инициализации суперглобальных массивов зависит от настроек в файле php.ini
  2. Символ разделения также может меняться в файле php.ini. Часто используется символ «;».
  3. Приемущество сессий в том, что обычный пользователь даже не заметит, как его перенаправили на другую страницу, а значит будет сложнее взломать PHP код. На странице входа отображается только перенаправление на session.php и форма входа. Если конечно не посмотрит внимательно на HTML код, но это ему ничего не даст, по скольку он не сможет взять из файла session.php сам PHP код

Ссылки