PHP

Скрипт форума на PHP своими руками. Часть 3

Мы разобрались с показом главной страницы, отдельного форума и конкретной темы. Теперь займемся пользователями сайта. И первый вопрос, который мы рассмотрим - регистрация нового пользователя. За это отвечают три функции: getAddNewUserForm(), addNewUser() и activateUser(). Рассмотрим их все по порядку.

Функция getAddNewUserForm() возвращает html формы для регистрации нового пользователя:
<?php 
// Функция возвращает форму для регистрации нового пользователя на форуме 
function getAddNewUserForm() 
{ 
  if ( isset( $_SESSION['captcha_keystring'] ) ) unset( $_SESSION['captcha_keystring'] ); 
  $html = ''; 
  // Если при заполнении формы были допущены ошибки 
  if ( isset( $_SESSION['addNewUserForm'] ) ) { 
    $info = file_get_contents( './templates/infoMessage.html' ); 
    $info = str_replace( '{infoMessage}', $_SESSION['addNewUserForm']['error'], $info ); 
    $html = $html.$info."n"; 
    $name      = htmlspecialchars( $_SESSION['addNewUserForm']['name'] ); 
    $email     = htmlspecialchars( $_SESSION['addNewUserForm']['email'] ); 
    $timezone  = $_SESSION['addNewUserForm']['timezone']; 
    $icq       = htmlspecialchars( $_SESSION['addNewUserForm']['icq'] ); 
    $url       = htmlspecialchars( $_SESSION['addNewUserForm']['url'] ); 
    $about     = htmlspecialchars( $_SESSION['addNewUserForm']['about'] ); 
    $signature = htmlspecialchars( $_SESSION['addNewUserForm']['signature'] ); 
    unset( $_SESSION['addNewUserForm'] ); 
  } else { 
    $name      = ''; 
    $email     = ''; 
    $timezone  = 0; 
    $icq       = ''; 
    $url       = ''; 
    $about     = ''; 
    $signature = ''; 
  } 
   
  // Считываем в переменную файл шаблона, содержащего  
  // форму для добавления нового пользователя 
  $tpl = file_get_contents( './templates/addNewUserForm.html' ); 
  $action = $_SERVER['PHP_SELF'].'?action=addNewUser'; 
  $tpl = str_replace( '{action}', $action, $tpl); 
  $tpl = str_replace( '{name}', $name, $tpl); 
  $tpl = str_replace( '{email}', $email, $tpl); 
  $tpl = str_replace( '{icq}', $icq, $tpl); 
  $tpl = str_replace( '{url}', $url, $tpl); 
  $tpl = str_replace( '{about}', $about, $tpl); 
  $tpl = str_replace( '{signature}', $signature, $tpl); 
  $kcaptcha = './kcaptcha/kc.php?'.session_name().'='.session_id(); 
  $tpl = str_replace( '{kcaptcha}', $kcaptcha, $tpl); 
  $tpl = str_replace( '{keystring}', '', $tpl); 
   
  $options = ''; 
  for ( $i = -12; $i <= 12; $i++ ) { 
    if ( $i < 1 )  
      $value = $i.' часов'; 
    else 
      $value = '+'.$i.' часов'; 
    if ( $i == $timezone ) 
      $options = $options . '<option value="'.$i.'" selected>'.$value.'</option>'."n"; 
    else 
      $options = $options . '<option value="'.$i.'">'.$value.'</option>'."n"; 
  } 
  $tpl = str_replace( '{options}', $options, $tpl); 
  $tpl = str_replace( '{servertime}', date( "d.m.Y H:i:s" ), $tpl ); 
   
  $html = $html . $tpl; 
  return $html; 
} 
?>

Файл шаблона addNewUserForm.html:
<form name="addNewUserForm" action="{action}" method="POST" enctype="multipart/form-data"> 

<table class="showTable"> 
<tr> 
  <th colspan="2">Регистрация</th> 
</tr> 
<tr> 
  <td width="40%"><strong>Имя:</strong></td> 
  <td width="60%"><input type="text" name="name" maxlength="30" value="{name}" /></td> 
</tr> 
<tr> 
  <td><strong>Адрес e-mail:</strong></td> 
  <td><input type="text" name="email" maxlength="60" value="{email}" /></td> 
</tr> 
<tr> 
  <td><strong>Пароль:</strong></td> 
  <td><input type="password" name="password" maxlength="30" value="" /></td> 
</tr> 
<tr> 
  <td><strong>Подтвердите пароль:</strong></td> 
  <td><input type="password" name="confirm" maxlength="30" value="" /></td> 
</tr> 
<tr> 
  <td><strong>Номер в ICQ:</strong></td> 
  <td><input type="text" name="icq" maxlength="12" value="{icq}" /></td> 
</tr> 
<tr> 
  <td><strong>Домашняя страничка:</strong></td> 
  <td><input type="text" name="url" maxlength="60" value="{url}" /></td> 
</tr> 
<tr> 
  <td><strong>Интересы:</strong></td> 
  <td><textarea name="about" cols="50" rows="3">{about}</textarea></td> 
</tr> 
<tr> 
  <td> 
  <strong>Подпись:</strong><br/> 
  Это текст, который будет добавлен к размещаемым вами сообщениям. 
  </td> 
  <td><textarea name="signature" cols="50" rows="3">{signature}</textarea></td> 
</tr> 
<tr> 
  <td> </td> 
  <td><img src="{kcaptcha}" alt="" /></td> 
</tr> 
<tr> 
  <td><strong>Код подтверждения:</strong></td> 
  <td><input type="text" name="keystring" maxlength="6" value="{keystring}" /></td> 
</tr> 
<tr> 
  <td> 
  <strong>Коррекция временных зон:</strong><br/> 
  Введите необходимую разницу в часах относительно времени на форуме, и все время будет отображаться с учетом 
  разницы в вашей временной зоне. 
  </td> 
  <td> 
  <select name="timezone"> 
  {options} 
  </select> 
  Текущее время на сервере: {servertime} 
  </td> 
</tr> 
<tr> 
  <td> 
  <strong>Аватар:</strong><br/> 
  Показывает небольшое изображение под информацией о вас в сообщениях. 
  </td> 
  <td> 
  <input type="file" name="avatar" /> 
  </td> 
</tr> 
<tr> 
  <td colspan="2" align="center"><input type="submit" name="submitForm" value="Отправить" /></td> 
</tr> 
</table> 

<form>

Далее в нашем списке - функция addNewUser(), которая добавляет нового пользователя (т.е. новую запись в таблицу TABLE_USERS):
<?php 
// Функция добавляет нового пользователя форума (запись в таблице БД TABLE_USERS) 
function addNewUser() 
{ 

  // Если не переданы данные формы - значит функция была вызвана по ошибке 
  if ( !isset( $_POST['name'] ) or 
       !isset( $_POST['password'] ) or 
       !isset( $_POST['confirm'] ) or 
       !isset( $_POST['email'] ) or 
       !isset( $_POST['timezone'] ) or 
       !isset( $_POST['icq'] ) or 
       !isset( $_POST['url'] ) or 
       !isset( $_POST['about'] ) or 
       !isset( $_POST['signature'] ) or 
       !isset( $_POST['keystring'] ) or 
       !isset( $_FILES['avatar'] )  
    ) 
  { 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=addNewUserForm' ); 
    die(); 
  } 

  // Обрезаем переменные до длины, указанной в параметре maxlength тега input 
  $name      = substr( $_POST['name'], 0, 30 ); 
  $password  = substr( $_POST['password'], 0, 30 ); 
  $confirm   = substr( $_POST['confirm'], 0, 30 ); 
  $email     = substr( $_POST['email'], 0, 60 ); 
  $icq       = substr( $_POST['icq'], 0, 12 ); 
  $url       = substr( $_POST['url'], 0, 60 ); 
  $about     = substr( $_POST['about'], 0, 1000 ); 
  $signature = substr( $_POST['signature'], 0, 500 ); 
  $keystring = substr( $_POST['keystring'], 0, 6 ); 

  // Обрезаем лишние пробелы 
  $name      = trim( $name ); 
  $password  = trim( $password ); 
  $confirm   = trim( $confirm ); 
  $email     = trim( $email ); 
  $icq       = trim( $icq ); 
  $url       = trim( $url ); 
  $about     = trim( $about ); 
  $signature = trim( $signature ); 
  $keystring = trim( $keystring ); 

  // Проверяем, заполнены ли обязательные поля 
  $error = ''; 
  if ( empty( $name ) ) $error = $error.'<li>не заполнено поле "Имя"</li>'."n"; 
  if ( empty( $password ) ) $error = $error.'<li>не заполнено поле "Пароль"</li>'."n"; 
  if ( empty( $confirm ) ) $error = $error.'<li>не заполнено поле "Подтвердите пароль"</li>'."n"; 
  if ( empty( $email ) ) $error = $error.'<li>не заполнено поле "Адрес e-mail"</li>'."n"; 
  if ( empty( $keystring ) ) $error = $error.'<li>не заполнено поле "Код"</li>'."n"; 
  // Проверяем, не слишком ли короткий пароль 
  if ( !empty( $password ) and strlen( $password ) < MIN_PASSWORD_LENGTH ) 
    $error = $error.'<li>длина пароля должна быть не меньше &apos;.MIN_PASSWORD_LENGTH.&apos; символов</li>'."n"; 
  // Проверяем, совпадают ли пароли 
  if ( !empty( $password ) and !empty( $confirm ) and $password != $confirm )  
    $error = $error.&apos;<li>не совпадают пароли</li>&apos;."n"; 
  // Проверяем поле "код" 
  if ( !empty( $keystring ) ) { 
    // Проверяем поле "код" на недопустимые символы 
    if ( !ereg( "[23456789abcdeghkmnpqsuvxyz]+", $keystring ) ) 
      $error = $error.&apos;<li>поле "Код" содержит недопустимые символы</li>'."n"; 
    // Проверяем, совпадает ли код с картинки 
    if ( !isset( $_SESSION[captcha_keystring'] ) or $_SESSION['captcha_keystring'] != $keystring ) 
      $error = $error.'<li>не совпадает код с картинки</li>'."n"; 
  } 
  unset( $_SESSION[&apos;captcha_keystring'] ); 

  // Проверяем поля формы на недопустимые символы 
  if ( !empty( $name ) and !preg_match( "#^[- _0-9a-zа-я]+$#i", $name ) ) 
    $error = $error.&apos;<li>поле "Имя" содержит недопустимые символы</li>&apos;."n"; 
  if ( !empty( $password ) and !preg_match( "#^[-_0-9a-z]+$#i", $password ) ) 
    $error = $error.&apos;<li>поле "Пароль" содержит недопустимые символы</li>&apos;."n"; 
  if ( !empty( $confirm ) and !preg_match( "#^[-_0-9a-z]+$#i", $confirm ) ) 
    $error = $error.&apos;<li>поле "Подтвердите пароль" содержит недопустимые символы</li>&apos;."n"; 
  if ( !empty( $icq ) and !preg_match( "#^[0-9]+$#", $icq ) ) 
    $error = $error.&apos;<li>поле "ICQ" содержит недопустимые символы</li>&apos;."n"; 
  if ( !empty( $about ) and !preg_match( "#^[-[].;:,?!/)(_"s0-9а-яa-z]+$#i", $about ) ) 
    $error = $error.&apos;<li>поле "Интересы" содержит недопустимые символы</li>&apos;."n"; 
  if ( !empty( $signature ) and !preg_match( "#^[-[].;:,?!/)(_"s0-9а-яa-z]+$#i", $signature ) ) 
    $error = $error.&apos;<li>поле "Подпись" содержит недопустимые символы</li>&apos;."n"; 

  // Проверяем корректность e-mail 
  if ( !empty( $email ) and !preg_match( "#^[0-9a-z_-.]+@[0-9a-z-.]+.[a-z]{2,6}$#i", $email ) ) 
    $error = $error.'<li>поле "Адрес e-mail" должно соответствовать формату somebody@somewhere.ru</li>'."n"; 
     
  // Проверяем корректность URL домашней странички     
  if ( !empty( $url ) and !preg_match( "#^(http://)?(www.)?[-0-9a-z]+.[a-z]{2,6}/?$#i", $url ) ) 
    $error = $error.'<li>поле "Домашняя страничка" должно соответствовать формату http://www.homepage.ru</li>'."n";

  // Выясняем не зарегистрировано ли уже это имя 
  // Возможно три ситуации, которые необходимо предотвратить: 
  // 1. Вводится ник, полностью совпадающий с уже существующим 
  // 2. Вводится уже существующий кирилический ник, в котором 
  //    одна или несколько букв заменены на латинские 
  // 3. Вводится уже существующий латинский ник, в котором 
  //    одна или несколько букв заменениы на кирилические 
   
  // Массив кирилических букв 
  $rus = array( "А","а","В","Е","е","К","М","Н","О","о","Р","р","С","с","Т","Х","х" ); 
  // Массив латинских букв 
  $eng = array( "A","a","B","E","e","K","M","H","O","o","P","p","C","c","T","X","x" ); 
  $new_name = preg_replace( "#[^- _0-9a-zа-я]#i", "", $name ); 
  // Заменяем русские буквы латинскими 
  $eng_new_name = str_replace( $rus, $eng, $new_name );  
  // Заменяем латинские буквы русскими 
  $rus_new_name = str_replace( $eng, $rus, $new_name );  
  // Формируем SQL-запрос 
  $query = "SELECT * FROM ".TABLE_USERS."  
            WHERE name LIKE '".mysql_real_escape_string( $new_name )."' OR 
                  name LIKE '".mysql_real_escape_string( $eng_new_name )."' OR 
                  name LIKE '".mysql_real_escape_string( $rus_new_name )."';"; 
  $res = mysql_query( $query ); 

  if ( !$res ) { 
    $msg = 'Ошибка при регистрации нового пользователя'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.&apos;<br/>&apos;.mysql_errno().&apos;: '.mysql_error().&apos;<br/>&apos;. 
           &apos;(Файл &apos;. __FILE__ .&apos;, строка &apos;. __LINE__ .&apos;)'; 
    return showErrorMessage( $msg, $err, true, '' ); 
  } 

  if ( mysql_num_rows( $res ) > 0 ) 
    $error = $error.&apos;<li>имя "'.$new_name.'" уже зарегистрировано</li>&apos;."n"; 

  if ( !empty( $_FILES[&apos;avatar']['name'] ) ) { 
    $ext = strrchr( $_FILES['avatar']['name'], "." ); 
    $extensions = array( ".jpg", ".gif", ".bmp", ".png" ); 
    if ( !in_array( $ext, $extensions ) )  
      $error = $error.'<li>недопустимый формат файла аватара</li>'."n"; 
    if ( $_FILES['avatar']['size'] > MAX_AVATAR_SIZE )  
      $error = $error.'<li>размер файла аватора больше '.(MAX_AVATAR_SIZE/1024).' Кб</li>'."n"; 
  } 

  $timezone = (int)$_POST['timezone']; 
  if ( $timezone < -12 or $timezone > 12 ) $timezone = 0; 

  // Если были допущены ошибки при заполнении формы - перенаправляем посетителя на страницу регистрации 
  if ( !empty( $error ) ) { 
    $_SESSION[&apos;addNewUserForm'] = array(); 
    $_SESSION[&apos;addNewUserForm'][error&apos;] = &apos;<p class="errorMsg">При заполнениии формы были допущены ошибки:</p>&apos;. 
    "n".&apos;<ul class="errorMsg">'."n".$error.&apos;</ul>&apos;."n"; 
    $_SESSION['addNewUserForm']['name'] = $name; 
    $_SESSION['addNewUserForm']['email'] = $email; 
    $_SESSION['addNewUserForm']['timezone'] = $timezone; 
    $_SESSION['addNewUserForm']['icq'] = $icq; 
    $_SESSION['addNewUserForm']['url'] = $url; 
    $_SESSION['addNewUserForm']['about'] = $about; 
    $_SESSION['addNewUserForm']['signature'] = $signature; 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=addNewUserForm' ); 
    die(); 
  } 

  if ( !empty( $url ) and substr($url, 0, 7) != 'http://' ) $url = 'http://'.$url; 
   
  // Уникальный код для активации учетной записи 
  $code = md5( uniqid( rand(), 1 ) ); 
  // Все поля заполнены правильно - продолжаем регистрацию 
  $query = "INSERT INTO ".TABLE_USERS." 
            ( 
            name, 
            passw, 
            email, 
            timezone, 
            url, 
            icq, 
            about, 
            signature, 
            photo, 
            puttime, 
            last_visit, 
            themes, 
            status, 
            activation 
            ) 
            VALUES 
            ( 
            '".mysql_real_escape_string( $name )."', 
            '".mysql_real_escape_string( md5( $password ) )."', 
            '".mysql_real_escape_string( $email )."', 
            ".$timezone.", 
            '".mysql_real_escape_string( $url )."', 
            '".$icq."', 
            '".mysql_real_escape_string( $about )."', 
            '".mysql_real_escape_string( $signature )."', 
            '', 
            NOW(), 
            NOW(), 
            0, 
            'user', 
            '".$code."' 
            );"; 
  $res = mysql_query( $query ); 
  if ( !$res ) { 
    $msg = 'Ошибка при регистрации нового пользователя'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
          '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
    return showErrorMessage( $msg, $err, true, '' ); 
  } 

  $id = mysql_insert_id(); 
  if ( !empty( $_FILES['avatar']['name'] ) and  
       move_uploaded_file ( $_FILES['avatar']['tmp_name'], './photo/'.$id ) ) chmod( './photo/'.$id, 0644 ); 

  // Посылаем письмо пользователю с просьбой активировать учетную запись 
  $headers = "From: ".$_SERVER['SERVER_NAME']." <".ADMIN_EMAIL.">n"; 
  $headers = $headers."Content-type: text/html; charset="windows-1251"n"; 
  $headers = $headers."Return-path: <".ADMIN_EMAIL.">n"; 
  $message = '<p>Добро пожаловать на форум '.$_SERVER['SERVER_NAME'].'!</p>'."n"; 
  $message = $message.'<p>Пожалуйста сохраните это сообщение. Параметры вашей учётной записи таковы:</p>'."n"; 
  $message = $message.'<p>Логин: '.$name.'<br/>Пароль: '.$password.'</p>'."n"; 
  $message = $message.'<p>Для активации вашей учетной записи перейдите по ссылке:</p>'."n"; 
  $link = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?action=activateUser&code='.$code;   
  $message = $message.'<p><a href="'.$link.'">Активировать учетную запись</a></p>'."n"; 
  $message = $message.'<p>Не забывайте свой пароль: он хранится в нашей базе в зашифрованном  
             виде, и мы не сможем вам его выслать. Если вы всё же забудете пароль, то сможете  
             запросить новый, который придётся активировать таким же образом, как и вашу  
             учётную запись.</p>'."n"; 
  $message = $message.'<p>Спасибо за то, что зарегистрировались на нашем форуме.</p>'."n"; 
  $subject = 'Регистрация на форуме '.$_SERVER['SERVER_NAME']; 
  $subject = '=?koi8-r?B?'.base64_encode(convert_cyr_string($subject, "w","k")).'?='; 
  mail( $email, $subject, $message, $headers ); 
   
  $msg = 'На Ваш e-mail выслано письмо с просьбой подтвердить регистрацию.  
          Чтобы завершить регистрацию и активировать учетную запись, зайдите  
          по адресу, указанному в письме.'; 
  $html = file_get_contents( './templates/infoMessage.html' ); 
  $html = str_replace( '{infoMessage}', $msg, $html ); 
  return $html; 
} 
?>

Последняя в нашем списке - функция activateUser(). Как нетрудно догадаться, она активирует учетную запись нового пользователя:
<?php 
function activateUser() 
{ 
  // Если не передан параметр $code - значит функция вызвана по ошибке 
  if ( !isset( $_GET['code'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 
  // Т.к. код зашифрован с помощью md5, то он представляет собой  
  // 32-значное шестнадцатеричное число 
  $code = substr( $_GET['code'], 0, 32 ); 
  $code = preg_replace( "#[^0-9a-f]#i", '', $code ); 

  $query = "SELECT id_author  
            FROM ".TABLE_USERS."  
            WHERE activation='".mysql_real_escape_string( $code )."' LIMIT 1"; 
  $res = mysql_query( $query ); 
  if ( !$res ) { 
    $msg = 'Ошибка при активации учетной записи. Обратитесь к администратору.'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
          '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
    return showErrorMessage( $msg, $err, true, '' ); 
  } 
  if ( mysql_num_rows( $res ) > 0 ) { 
    $id = mysql_result( $res, 0, 0 ); 
    $query = "UPDATE ".TABLE_USERS."  
              SET activation='', last_visit=NOW()  
              WHERE id_author=".$id; 
    $res = mysql_query( $query ); 
    if ( !$res ) { 
      $msg = 'Ошибка при активации учетной записи. Обратитесь к администратору.'; 
      $err = 'Ошибка при выполнении запроса: <br/>'. 
             $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
             '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
      return showErrorMessage( $msg, $err, true, '' ); 
    } 
  } 
  return showInfoMessage( 'Ваша учетная запись активирована.', 'action=loginForum' ); 
} 
?>

Возможно, у вас возник вопрос, а что же это за функция showInfoMessage()? Отвечаю - это небольшая вспомогательная функция. Ее назначение - выдать пользователю информационное сообщение, например "Ваша учетная запись активирована" и сделать редирект на нужную страницу (в случае функции activateUser() - на страницу авторизации). Вот ее исходный код:
<?php 
// Вспомогательная функция - после выполнения пользователем каких-либо действий 
// выдает информационное сообщение и делает редирект на нужную страницу с задержкой 
function showInfoMessage( $message, $queryString ) 
{ 
  if ( !empty( $queryString ) ) $queryString = '?'.$queryString; 
  header( 'Refresh: '.REDIRECT_DELAY.'; url='.$_SERVER['PHP_SELF'].$queryString ); 
  $html = file_get_contents( './templates/infoMessage.html' ); 
  $html = str_replace( '{infoMessage}', $message, $html ); 
  return $html; 
} 
?>

Шаблон infoMessage.html
<table class="showTable"> 
<tr> 
  <th>Информация</th> 
</tr> 
<tr> 
  <td> 
  {infoMessage} 
  </td> 
</tr> 
</table>

Продолжение следует...
Теги:
форум
Добавлено: 01 Января 2015 17:43:02 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...