В итоге набрел на статью "Авторизация посетителей на PHP", в которой по шагам, потихонечку написано как кому чего делать чтобы у него было счастье.
Ну а теперь самое интересное, наткнулся на код обработки формы.
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$rLogin = trim($_POST['rLogin']);
$rPass = trim($_POST['rPass']);
$rPass2 = trim($_POST['rPass2']);
$rEmail = trim($_POST['rEmail']);
if ($rLogin == '') {
die("Поле 'Логин' не заполнено\n");
// Логин может состоять из букв, цифр и подчеркивания
}elseif (!preg_match("/^\w{3,}$/", $rLogin)) {
die("В поле 'Логин' введены недопустимые символы\n");
}
if ($rEmail == '') {
die("Поле 'E-mail' не заполнено\n");
// Проверяем e-mail на корректность
}elseif (!preg_match("/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/", $rEmail)) {
die("Указанный 'E-mail' имеет недопустимый формат\n");
}
if ($rPass == '' || $rPass2 == '') {
die("Поле 'Пароль' не заполнено\n");
}elseif($rPass !== $rPass2) {
die("Поля 'Пароль' и 'Повтор пароля' не совпадают\n");
// Пароль может состоять из букв, цифр и подчеркивания
}elseif(!preg_match("/^\w{3,}$/", $rPass)) {
die("В поле 'Пароль' введены недопустимые символы\n");
}
// В базе данных у нас будет храниться md5-хеш пароля
$mdPassword = md5($rPass);
// А также временная метка (зачем - позже)
$time = time();
// Устанавливаем соединение с бд(не забудьте подставить ваши значения сервер-логин-пароль)
$link = mysql_connect('localhost', $dbuser, $dbpass);
if (!$link) {
die("Не могу соединиться с базой данных");
}else {
// Выбираем базу данных
mysql_select_db('authorize', $link);
// Записываем в базу (не используем addslashes - экранировать нечего)
mysql_query("INSERT INTO users (login, pass, email, timestamp)
VALUES ('$rLogin','$mdPassword','$rEmail',$time)",$link);
if (mysql_error($link) != "") {
die("Пользователь с таким логином уже существует, выберите другой\n");
}
echo "Юзер добавлен\n";
mysql_close($link);
}
}
?>
В общем, про использование прямых запросов сразу молчим, но что наглядно, форма из 4-х полей, а уже 3 вложенных условия, да и вообще логика не простая.
Самое что главное, если заменить способы валидации, то к своему стыду получается что я писал подобный код не так давно. И только натолкнувшись на совсем сумасшедшую логику, прикрутил Exceptions и чудо
1. Объем кода уменьшился в два раза.
2. Количество вложенных условий сократилось до 1-го
3. Ошибки стало проще выводить.
Ну и применительно к данному коду, применя преобразовния не меняющие логику получим что то вроде. .
class DbException extends Exception {};
if ($_SERVER['REQUEST_METHOD'] != 'POST')
{
try
{
foreach ( array('rLogin' => 'Логин' , 'rPass' => 'Пароль' , 'rPass2' => 'Повторный пароль', 'rEmail' => 'E-mail' ) as $val => $fieldName)
{
if ( isset($_POST[$val] ) )
$val = trim($_POST[$val]); //create rLogin, rPass, rPass2, rEmail variables
else
throw new Exception("Поле $fieldName не заполнено\n");
}
if (!preg_match("/^\w{3,}$/", $rLogin))
throw new Exception("В поле 'Логин' введены недопустимые символы\n");
if (!preg_match("/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/", $rEmail))
throw new Exception("В поле 'Логин' введены недопустимые символы\n");
if($rPass !== $rPass2)
throw new Exception("Поля 'Пароль' и 'Повтор пароля' не совпадаютn");
if(!preg_match("/^\w{3,}$/", $rPass))
throw new Exception("В поле 'Пароль' введены недопустимые символы\n");
$mdPassword = md5($rPass);
// А также временная метка (зачем - позже)
$time = time();
// Устанавливаем соединение с бд(не забудьте подставить ваши значения сервер-логин-пароль)
$link = mysql_connect('localhost', $dbuser, $dbpass);
if (!$link)
throw new DbException("Не могу соединиться с базой данных");
// Выбираем базу данных
mysql_select_db('authorize', $link);
// Записываем в базу (не используем addslashes - экранировать нечего)
mysql_query("INSERT INTO users (login, pass, email, timestamp) VALUES ('$rLogin','$mdPassword','$rEmail',$time)",$link);// поле timestamp можно сделать чтобы по умолчанию подставлялось базой, такие вещи лучше перекладывать на базу.
if (mysql_error($link) != "")
DbException("Пользователь с таким логином уже существует, выберите другой\n");
echo "Юзер добавлен\n";
mysql_close($link);
}
catch (DbException $e)
{
die("DB ERROR: " . $e->getMEssage());
}
catch ( Exception $e)
{
die( "Form validation error: ". $e->getMessage());
}
}
?>
В итоге.
- Кода меньше.
- Читается проще.
- Вывод ошибок в одном месте.
- При необходимости разные виды ошибок ловим в нужных нам местах.