Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
5 / 5 / 1
Регистрация: 04.03.2018
Сообщений: 61

Написал скрипт для регистрации пользователей, хочу его улучшить

28.05.2018, 14:48. Показов 1158. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
1. Можно ли выполнять проверку введенных пользователей таким способом?
Может быть использовать if/elseif или вложенные if/else. Какой способ лучше?
Пример:
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
if (preg_match("/^[\w\._-]+@[\w\._-]+\.[\w]+$/", $email))
    {
        if (preg_match("/^[a-zA-Z0-9]{4,30}$/", $username))
        {
            if (preg_match("/^[a-zA-Z0-9_\.#?!@$%^&*\-\+\=]{6,100}$/", $password))
            {
                echo "OK";
            }
            else
            {
                echo 'Пароль может содержать латинские буквы (a-zA-Z), цифры (0-9) и спец. символы (_.#?!@$%^&*-+=).';
                exit;
 
            }
        }
        else
        {
            echo 'Имя пользователя может содержать латинские буквы (a-zA-Z) и цифры (0-9).';
            exit;
        }
    }
    else
    {
        echo 'E-mail указан неправильно.';
        exit;
    }
 
?>


2. Что лучше использовать mysqli или PDO.

3. Нет ли в коде не очевидных ошибок?

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
/////
 
if (isset($_POST['submit'])) {
 
    $errors = false;
    
    $email = $_POST['email'];
    $username = strtolower($_POST['username']);
    $password = $_POST['password'];
    $repassword = $_POST['repassword'];
    
    
    if (!preg_match("/^[\w\._-]+@[\w\._-]+\.[\w]+$/", $email))
    {
        $errors['invalidEmail'] = 'E-mail указан неправильно.';
        // Возможно добавить информацию в лог-файл. Чтобы отслеживать нестандартные адреса.
    }
 
    if (strlen($username) < 4 || strlen($username) > 30)
    {
        $errors['lengthUsername'] = 'Имя пользователя должно содержать от 4 до 30 символов.';
    }
    
    if (!preg_match("/^[a-zA-Z0-9]{4,30}$/", $username))
    {
        $errors['invalidUsername'] = 'Имя пользователя может содержать латинские буквы (a-zA-Z) и цифры (0-9).';
    }
    
    if (strlen($password) < 6 || strlen($password) > 100)
    {
        $errors['lengthPassword'] = 'Длина пароля должна быть от 6 до 100 символов.';
    }
    
    if ($password !== $repassword)
    {
        $errors['invalidConfirm'] = 'Пароли не совпадают.';
    }
    
    if (!preg_match("/^[a-zA-Z0-9_\.#?!@$%^&*\-\+\=]{6,100}$/", $password))
    {
        $errors['invalidPassword'] = 'Пароль может содержать латинские буквы (a-zA-Z), цифры (0-9) и спец. символы (_.#?!@$%^&*-+=).';
    }
    
    
    if ($errors === false)
    {
        //////////
    
        $isEmailExist = mysql_query(sprintf("SELECT `id` FROM `users` WHERE `email` = '%s'",
            mysql_real_escape_string($email)));
 
        if (mysql_num_rows($isEmailExist) !== 0)
        {
            $errors['existEmail'] = 'Этот E-mail уже используется в системе.';
        }
        
        ///
        
        $isUsernameExist = mysql_query(sprintf("SELECT `id` FROM `users` WHERE `username` = '%s'",
            mysql_real_escape_string($username)));
 
        if (mysql_num_rows($isUsernameExist) !== 0)
        {
            $errors['existUsername'] = 'Это имя пользователя уже используется, выберите другое имя.';
        }
        
        ////////////
        
        if ($errors === false)
        {
        
            #$password = password_hash($password, PASSWORD_DEFAULT);
            $password = crypt($password);
            $regdate = time();
            
            $registration = mysql_query(sprintf("INSERT INTO `users` (`email`, `username`, `password`, `regdate`) VALUES ('%s', '%s', '%s', '%s')",
                mysql_real_escape_string($email),
                mysql_real_escape_string($username),
                mysql_real_escape_string($password),
                mysql_real_escape_string($regdate)));
            
            if ($registration === true)
            {
                //
            }
            else
            {
                //die('Неверный запрос: ' . mysql_error());
                die('Неверный запрос');
            }
        }
    }
}
 
// Вывод ошибок
 
if (isset($errors) && $errors !== false) {
    foreach ($errors as $key => $value) {
        echo sprintf("%s<br>", $value);
    }
}
?>
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.05.2018, 14:48
Ответы с готовыми решениями:

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

Помогите разработать скрипт регистрации пользователей
Помогите разработать скрипт на PHP регистрации пользователей с элементом CAPTCHA.

Нужен скрипт регистрации пользователей на PHP
помогите зделать регистрацию на сайте я зделал но чтото не правильно

8
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
28.05.2018, 15:08
1. Лишняя вложенность это плохо, второй вариант лучше.
2. Принципиальной разницы нет.
3. Используются параметры из пост запроса но не проверяется их наличие
Начальное значение $errors лучше давать null или [], чтобы не запутывать лишним изменением типа
Вложенности следует избегать. Вместо
PHP
1
2
3
if ($cond) {
    // много кода
}
Лучше
PHP
1
2
3
4
if (!$cond) {
     return; // или exit()
}
// много кода
Вариант с password_hash был лучше чем crypt, только надо использовать PASSWORD_BCRYPT при php < 7.2 и PASSWORD_ARGON2I при >= 7.2
Кеш пароля не обязательно экранировать перед вставкой. То же и с regdate
1
 Аватар для wmysterio
295 / 244 / 128
Регистрация: 24.12.2014
Сообщений: 708
28.05.2018, 15:15
2. Для меня PDO удобнее
3.
Цитата Сообщение от webiswork Посмотреть сообщение
|| strlen($password) > 100
Не ошибка, но ограничивать длину в большую сторону не надо. Я бы, например, не смог зарегистрироваться, так как пароли у меня больше 200 символов. Вам главное, чтобы был не меньше 6 или сколько Вы там желаете
Цитата Сообщение от webiswork Посмотреть сообщение
crypt($password);
Мне кажется, лучше использовать метод "password_hash" - он автоматически генерирует соль и в случаем смены алгоритма всем пользователям не нужно будет восстанавливать пароль.
Цитата Сообщение от webiswork Посмотреть сообщение
preg_match("/^[a-zA-Z0-9_\.#?!@$%^&*\-\+\=]{6,100}$/", $password)
Не надо явно указывать какие символы должны быть в пароле пользователя. Вам надо только требовать минимальную длину, чтобы были буквы в обеих регистрах и числа. Спецсимволы каждый использует по своему и его может и не быть в перечислении регулярки.
1
5 / 5 / 1
Регистрация: 04.03.2018
Сообщений: 61
28.05.2018, 17:32  [ТС]
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Используются параметры из пост запроса но не проверяется их наличие
Добавил проверку, но в любом случае код после проверки выполнится (как минимум появится сообщения Notice) так как не используется ни exit, ни return.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$errors = false;
 
if (!isset($_POST['email']) || !isset($_POST['username']) || !isset($_POST['password']))
{
    $errors['notFilledRequired'] = 'Заполнены не все обязательные поля.';
}
   
---> $email = $_POST['email'];
---> $username = strtolower($_POST['username']);
---> $password = $_POST['password'];
---> $repassword = $_POST['repassword'];
    
    
---> if (!preg_match("/^[\w\._-]+@[\w\._-]+\.[\w]+$/", $email))
---> {
--->     $errors['invalidEmail'] = 'E-mail указан неправильно.';
--->     // Возможно добавить информацию в лог-файл. Чтобы отслеживать нестандартные адреса.
---> }
 
...
Что лучше в данном случае?
Получается что здесь два варианте либо использовать exit/return или добавить дополнительное условие:

PHP
1
if ($errors === false)
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$errors = false;
 
if (!isset($_POST['email']) || !isset($_POST['username']) || !isset($_POST['password']))
{
    $errors['notFilledRequired'] = 'Заполнены не все обязательные поля.';
}
 
if ($errors === false)
{
    $email = $_POST['email'];
    $username = strtolower($_POST['username']);
    $password = $_POST['password'];
    $repassword = $_POST['repassword'];
    
    
    if (!preg_match("/^[\w\._-]+@[\w\._-]+\.[\w]+$/", $email))
    {
         $errors['invalidEmail'] = 'E-mail указан неправильно.';
         // Возможно добавить информацию в лог-файл. Чтобы отслеживать нестандартные адреса.
    }
}
...
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Вариант с password_hash был лучше чем crypt, только надо использовать PASSWORD_BCRYPT при php < 7.2 и PASSWORD_ARGON2I при >= 7.2
Цитата Сообщение от wmysterio Посмотреть сообщение
Мне кажется, лучше использовать метод "password_hash" - он автоматически генерирует соль и в случаем смены алгоритма всем пользователям не нужно будет восстанавливать пароль.
Исправил, оставил первый вариант с password_hash. Я правильно понимаю что константа PASSWORD_DEFAULT выбирает наиболее стоикий алгоритм и в данном случае тоже самое что и PASSWORD_BCRYPT.

Так как в документации 3 варианта:
PASSWORD_DEFAULT - используется алгоритм bcrypt
PASSWORD_BCRYPT - использует алгоритм CRYPT_BLOWFISH
PASSWORD_ARGON2I - Использовать алгоритм хеширования Argon2

Цитата Сообщение от wmysterio Посмотреть сообщение
Не ошибка, но ограничивать длину в большую сторону не надо. Я бы, например, не смог зарегистрироваться, так как пароли у меня больше 200 символов. Вам главное, чтобы был не меньше 6 или сколько Вы там желаете
Согласен, но в документации написано что:
Использование алгоритма PASSWORD_BCRYPT приведёт к обрезанию поля password до максимальной длины 72 символа.
Увеличил максимальную длину пароля до 1024 символов. Хотя в любом случае пароль будет обрезаться до 72 символов.
Думаю что максимальную длину лучше проверить, например пользователь может ввести в поле пароля текст длинной 1000000 символов и хотя длина хеша не изменяется, в случае если будет использоваться другой алгоритм, хеширование может занять намного больше времени или вообще вызвать ошибку.

Цитата Сообщение от wmysterio Посмотреть сообщение
Не надо явно указывать какие символы должны быть в пароле пользователя. Вам надо только требовать минимальную длину, чтобы были буквы в обеих регистрах и числа. Спецсимволы каждый использует по своему и его может и не быть в перечислении регулярки.
Можно убрать регулярное выражение и проверять только длину пароля. password_hash корректно обрабатывает строки содержащие например unicode-символы?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
28.05.2018, 18:54
webiswork,
PHP
1
2
$email = $_POST['email'] ?? null; // php 7
$email = isset($_POST['email']) ? $_POST['email'] : null; // php 5
PASSWORD_BCRYPT предпочтительнее т.к явно указывается что за алгоритм будет использован
1
 Аватар для wmysterio
295 / 244 / 128
Регистрация: 24.12.2014
Сообщений: 708
28.05.2018, 20:48
Цитата Сообщение от webiswork Посмотреть сообщение
Использование алгоритма PASSWORD_BCRYPT приведёт к обрезанию поля password до максимальной длины 72 символа
Ну и пусть обрезает сколько нужно. Нам важно только хэш пароля
Цитата Сообщение от webiswork Посмотреть сообщение
Увеличил максимальную длину пароля до 1024 символов
Не указывайте максимальную длину вовсе. Только минимальную. В базе можете указать длину ровно и больше длины хэша, который возвращает "password_hash".
Цитата Сообщение от webiswork Посмотреть сообщение
хеширование может занять намного больше времени
И пусть будет дольше. С целью безопасности, быстрые алгоритмы или хуже костыльные ( смесь md5, sha1 ) облегчит кому-то жизнь при переборе паролей, ну если такой безумец найдётся.
Цитата Сообщение от webiswork Посмотреть сообщение
и проверять только длину пароля
Этого не достаточно. Нужно писать функцию для оценки надёжности пароля, с учётом регистра букв, наличия числа и спец-символа. И регулярки, "mb_strtolower" и "mb_strtoupper" ( и им подобные ) не будут гарантировать правильность того, что пароли в одном регистре, например. Надо подёргать пользователя и заставить выбрать надёжный пароль. Если контент на сайте ему важен, то он выполнить базовые требования и придумает себе пароль.
1
28.05.2018, 21:09

Не по теме:

Цитата Сообщение от wmysterio Посмотреть сообщение
Этого не достаточно. Нужно писать функцию для оценки надёжности пароля, с учётом регистра букв, наличия числа и спец-символа.
Ваш пароль должен содержать цифры, буквы, знаки пунктуации, завязку, развитие, кульминацию и неожиданный финал.
Кликните здесь для просмотра всего текста

0
28.05.2018, 21:18

Не по теме:

Jewbacabra, ну, что-то типа этого получается :D надо знать меру с таким подходом, как у меня

0
5 / 5 / 1
Регистрация: 04.03.2018
Сообщений: 61
29.05.2018, 11:29  [ТС]
Какой вариант предпочтительнее для авторизации пользователя?

1.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
    if ($errors === false) // Если не возникло ошибок при проверке введенных данных
    {
        /* ... */
    
        $isEmailExist = mysql_query(sprintf("SELECT * FROM `users` WHERE `email` = '%s'",
            mysql_real_escape_string($email)));
 
        if (mysql_num_rows($isEmailExist) !== 1)
        {
            $errors['existEmail'] = 'Этот E-mail не используется в системе.';
        }
        else
        {
            $row = mysql_fetch_assoc($isEmailExist);
            
            if (password_verify($password, $row['password'])) {
                echo 'Пароль правильный!';
                $updateLastActivity = mysql_query(sprintf("UPDATE `users` SET `users` = '%s' WHERE `id` = '%s'",
                    time(),
                    mysql_real_escape_string($row['id'])));
 
                $_SESSION['userid'] = $row['id'];
 
                header("Location: /account");
                exit;
            } else {
                echo 'Пароль неправильный.';
            }
        }
        
        /* ... */
        
        if ($errors === false)
        {
            $lastactivity = time();
            ...
            
            if ($registration)
            {
                //
            }
            else
            {
                //die('Неверный запрос: ' . mysql_error());
                die('Произошла ошибка.');
            }
        }
    }
?>
2.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
    if ($errors === false) // Если не возникло ошибок при проверке введенных данных
    {
        /* ... */
    
        $isEmailExist = mysql_query(sprintf("SELECT * FROM `users` WHERE `email` = '%s'",
            mysql_real_escape_string($email)));
 
        if (!$isEmailExist)
        {
            $errors['errorQuery'] = 'Произошла неизвестная ошибка.';
        }
 
        if (mysql_num_rows($isEmailExist) !== 1)
        {
            $errors['existEmail'] = 'Этот E-mail не используется в системе.';
        }
        
        /* ... */
        
        if ($errors === false)
        {
            $row = mysql_fetch_assoc($isEmailExist);
            
            if (password_verify($password, $row['password']))
            {
                echo 'Пароль правильный!';
                $updateLastActivity = mysql_query(sprintf("UPDATE `users` SET `users` = '%s' WHERE `id` = '%s'",
                    time(),
                    mysql_real_escape_string($row['id'])));
 
                $_SESSION['userid'] = $row['id'];
                
                header("Location: /account");
                exit;
            }
            else
            {
                echo 'Пароль неправильный.';
            }
        }
    }
?>
Если проверять запросы на успешное выполнение, нужно будет добавить ещё один уровень if ($errors === false)

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
        if ($errors === false)
        {
            $row = mysql_fetch_assoc($isEmailExist);
            
            if (password_verify($password, $row['password']))
            {
                /* ... */
 
                // Возможно здесь целесообразно использовать транзакции try (commit) catch (rollback)
 
                $updateLastActivity = mysql_query(sprintf("UPDATE `users` SET `lastactivity` = '%s' WHERE `id` = '%s'",
                    time(),
                    mysql_real_escape_string($row['id'])));
 
                if (!$updateLastActivity) {
                    $errors['updateLastActivity'] = 'Не удалось обновить информацию';
                }
 
                ///
 
                $updateAnotherField = mysql_query(sprintf("UPDATE `users` SET `anotherFfield` = '%s' WHERE `id` = '%s'",
                    'anotherFieldData',
                    mysql_real_escape_string($row['id'])));
 
                if (!$updateAnotherField ) {
                    $errors['updateAnotherField '] = 'Не удалось обновить информацию';
                }
                
                /* ... */
 
                if ($errors === false)
                {
                    $_SESSION['userid'] = $row['id'];
                
                    header("Location: /account");
                    exit;
                }
 
            }
            else
            {
                echo 'Пароль неправильный.';
            }
        }
?>
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.05.2018, 11:29
Помогаю со студенческими работами здесь

написал скрипт для уменьшения картинок
написал скрипт для уменьшения картинок, но не могу его подключить, тестировал &quot;автономно&quot;, с четко указанным файлом, картинку...

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

Улучшить скрипт для плагина под notepad++
Есть: Всем известная программа notepad++. Под неё существует плагин для юзерских питон-скриптов. Вот этот: PythonScript ...

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

Ищу Плагин для регистрации пользователей
Хочу позволить пользователям регистрироваться и добавлять свои статьи. На данный момент склоняюсь лишь к выбору WP-RECALL. В идеале хочу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в конфигурации КА2. Данные берутся из регистра сведений, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru