За последние 24 часа нас посетили 21704 программиста и 1045 роботов. Сейчас ищут 707 программистов ...

Деликатный вопрос, на счет скрипта, регистрация php mysql

Тема в разделе "PHP для новичков", создана пользователем _ne_scaju_, 24 апр 2017.

  1. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Класс надо попробовать хоть что-то сделать на js и ajax.
    Сразу можно сказать что я 0 в этих языках...
    Давайте попробуем так:
    Вот у меня есть запрос проверяю пользователя, есть ли он в базе или нету:
    PHP:
    1. $login = htmlspecialchars($_POST['login']);
    2. /*Бла бла бла*/
    3. $stmt = $pdo->prepare('SELECT `user_id` FROM `users` WHERE `user_login` = "'.$login.'"');
    4. $stmt->bindValue($login, $_POST['login'], PDO::PARAM_STR);
    5. $stmt->execute();
    6. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    7. if(count($rows) > 0){
    8. $err[] = 'Логин: '. $_POST['login'] .' уже занят';
    9. }
    Можно ли записать запрос вот таким образом, для уменьшения кода?
    PHP:
    1. $login = htmlspecialchars($_POST['login']);
    2. /*Бла бла бла*/
    3. $stmt = $pdo->prepare('SELECT `user_id` FROM `users` WHERE `user_login` = ?');
    4. $stmt->execute([$login]);
    5. $rows = $stmt->fetch();
    6. if(count($rows) > 0){
    7. $err[] = 'Логин: '. $_POST['login'] .' уже занят';
    8. }
    Если можно, что делать с ним дальше, чтобы как то обработать js, ajax для проверки.
     
  2. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    Все доброй ночи, кто мне подскажет как делается такое:
    1. Был у меня один скрипт, в нем у меня был и обработчик и форма.
    2. Я их поделил на 2 файла, теперь у меня обработчик reg.php и форма form_reg.php
    3. Я в ссылках указываю путь к форме, а в форме указываю путь к обработчику.
    4.У меня получается так, если пользователь вызвал форму, и начинает вводить данные, например забыл ввести что-то, ему высвечивается ошибочка, например: не все поля заполнены, и при этом форма прячется, а как же оставить и форму и ошибки на одной странице?
    5. Если писать обработчик, и саму форму в одном файле то если высвечивается ошибка, то форма остается на месте.
    6. Вопрос, почему я так хочу сделать?
    Ответ такой:
    Так будет быстрее обрабатываться форма при вызове ее если находятся по разным файлам.
    Ну а если они находятся в одном файле то, затратно временем будет, оно даже видно что скрипт не много думает, из-за того что там и форма и обработчик находятся.
     
  3. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Можешь при ошибке из reg.php перенаправлять обратно на form_reg.php.
     
  4. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Вот примерно об этом я и спрашиваю.
    Но ошибки останутся с формой?
    Как это делается правильно?
    Смотрим на скриншот, уже спать пора))) А я в пеинте, рисую :D

    При регистрации если юзер допусти ошибку, форма прячется, а мне надо чтобы ошибки и форма оставалась.
     

    Вложения:

    • 1111.png
      1111.png
      Размер файла:
      7,8 КБ
      Просмотров:
      4
    #54 _ne_scaju_, 28 апр 2017
    Последнее редактирование: 28 апр 2017
  5. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    два варианта:
    1. Кидать форму на сервер ajax-ом, через JavaScript, а обработчик чтоб возвращал ошибки, выводить их опять же на JavaScript
    2. Кидать ошибки в сессию, и перенаправлять опять на файл, выводящий форму. В нём должна быть проверка, типа: если есть ошибки в сессии, показать их.
    Только возьми в кой-то веки и сам почитай про AJAX и сессии, выбери подход, и сделай форму. Ну реально, ничего сложного нету ни в первом ни во втором варианте, мозг надо задействовать минимально. Веб-программирование - это вообще, очень-очень просто, если речь не идёт о highload. У нас большинство алгоритмов сводится к "прочитать из базы, выплюнуть пользователю" и "получить от пользователя, кинуть в базу"
     
    _ne_scaju_ и Sergey_Tsarev нравится это.
  6. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Я бы использовал оба варианта. Вдруг у какого-нибудь чудака отключен JS.
     
    _ne_scaju_ нравится это.
  7. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    ну вы же умные, в программировании, а мне тяжело, как то)
     
  8. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @_ne_scaju_, восстановление пароля будет выглядеть примерно так:

    Форма восстановления пароля recovery.htm
    HTML:
    1. <!DOCTYPE html>
    2.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    3.     <title>Восстановление пароля</title>
    4. </head>
    5.     <form method="post" action="recovery_action.php">
    6.         <label>Почта:</label>
    7.         <input type="email" name="email">
    8.         <input type="submit" value="Восстановить">
    9.     </form>
    10. </body>
    11. </html>

    Скрипт восстановления пароля recovery_action.php
    PHP:
    1. <?php
    2. //подключаемся к базе данных
    3.  
    4. include_once $_SERVER['DOCUMENT_ROOT'].'/connect_db.php';
    5.  
    6.  
    7. if ($_POST['email']):
    8.  
    9.     $email = $_POST['email'];
    10.  
    11.     //фильтруем данные
    12.  
    13.     //проверяем, есть ли пользователь с таким email'ом
    14.  
    15.     $check_email = $pdo->prepare('SELECT COUNT(0) AS ROW_COUNT FROM `users` WHERE `email` = ?');
    16.     $check_email->execute([$email]);
    17.  
    18.     //подсчитываем количество строк в ответе
    19.     $num = $check_email->fetch();
    20.     $count = $num['ROW_COUNT'];
    21.  
    22.     if($count > 0):
    23.    
    24.         //получаем данные о пользователе из таблицы users
    25.         $query = $pdo->prepare('SELECT * FROM `users` WHERE `email` = ?');
    26.         $query->execute([$email]);
    27.         $result = $query->fetch();
    28.  
    29.         $id = $result['id'];
    30.         $time = time(); //записываем в переменную текущее время
    31.         $recovery_key = md5(uniqid(rand(), true)); //генерируем уникальную строку для восстановления
    32.    
    33.         //вносим запись в таблицу recovery
    34.  
    35.         $recovery = $pdo->prepare('INSERT INTO `recovery` (`id`, `recovery_key`, `time`) VALUES (?, ?, ?)');
    36.         $recovery->execute([$id, $recovery_key, $time]);
    37.    
    38.         //отправляем письмо
    39.  
    40.         $to= $email; //получатель
    41.         $subject = 'Восстановление пароля'; //тема
    42.         $message = 'Для изменения пароля перейдите по ссылке:
    43.                    http://site.ru/recovery.php?recovery_key='.$recovery_key; //текст
    44.  
    45.         //заголовки
    46.         $headers= "MIME-Version: 1.0\r\n";
    47.         $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
    48.  
    49.         //отправляем
    50.         mail($to, $subject, $message, $headers);
    51.    
    52.         echo 'На ваш почтовый ящик отправлено письмо с ссылкой для изменения пароля!';
    53.    
    54.     else:
    55.         echo 'Такой адрес в системе не зарегистрирован!';
    56.     endif;
    57.  
    58. else:
    59.     echo 'Поля не заполнены!';
    60. endif;
    61. ?>

    Скрипт генерации нового пароля recovery.php
    PHP:
    1. <?php
    2. //подключаемся к базе данных
    3.  
    4. include_once $_SERVER['DOCUMENT_ROOT'].'/connect_db.php';
    5.  
    6. if ($_GET['recovery_key']):
    7.  
    8.     $recovery_key = $_GET['recovery_key'];
    9.  
    10.     //фильтруем данные
    11.  
    12.     //делаем запрос к таблице recovery и
    13.     //проверям есть ли там запись с таким ключом
    14.  
    15.     $check = $pdo->prepare('SELECT COUNT(0) AS ROW_COUNT FROM `recovery` WHERE `recovery_key` = ?');
    16.     $check->execute([$recovery_key]);
    17.  
    18.     //подсчитываем количество строк в ответе
    19.     $num = $check->fetch();
    20.     $count = $num['ROW_COUNT'];
    21.  
    22.     if($count > 0):
    23.  
    24.         //делаем запрос к таблице recovery и получаем данные в виде ассоциативного массива
    25.         $query = $pdo->prepare('SELECT * FROM `recovery` WHERE `recovery_key` = ?');
    26.         $query->execute([$recovery_key]);
    27.         $result = $query->fetch();
    28.    
    29.         //проверяем просрочена ли активация или нет
    30.    
    31.         $limit_time = 3000; //время жизни активации в секундах
    32.         $id = $result['id'];
    33.    
    34.         if((time()-$result['time']) <= $limit_time):
    35.        
    36.             //генерируем новый пароль
    37.        
    38.             $new_password = rand(10000, 99999999);
    39.        
    40.             $recovery = $pdo->prepare('UPDATE `users` SET `password` = ? WHERE `id` = ?');
    41.             $recovery->execute([$new_password, $id]);
    42.        
    43.             //удаляем запись из таблицы recovery
    44.        
    45.             $delete = $pdo->prepare('DELETE FROM `recovery` WHERE `id` = ?');
    46.             $delete->execute([$id]);
    47.        
    48.             echo 'Пароль изменен!';
    49.        
    50.         else:
    51.        
    52.             //удаляем запись из таблицы recovery
    53.        
    54.             $delete = $pdo->prepare('DELETE FROM `recovery` WHERE `id` = ?');
    55.             $delete->execute([$id]);
    56.        
    57.             echo 'Ссылка просрочена!';
    58.        
    59.         endif;
    60.    
    61.     else:
    62.         echo 'Неправильный ключ восстановления!';
    63.     endif;
    64.  
    65. else:
    66.     echo 'Не указан ключ восстановления!';
    67. endif;
    68. ?>
     
    _ne_scaju_ нравится это.
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Строчки 15 и 25 можно объединить в один запрос.
     
    _ne_scaju_ и denis01 нравится это.
  10. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @mkramer, согласен) я для наглядности написал подробно, что бы была понятна логика.
     
  11. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Огромное спасибо за ответ и помощь. Завтра буду под свои таблицы создавать изменять твой скрипт, и ещё заниматься копипастом.
    Если честно я стараюсь вникнуть в любой код чужой и разобраться в нем.
    Мне понравился твой принцип оформления кода. А особенно открывающийся и закрывающийся endif. Надо для себя подчеркнуть, такое оформление, и может быть использовать его.

    И к комментариям на счет 15 и 25 строки, типа объединить их в один, а то-есть что сделать надо?
     
  12. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    https://php.ru/manual/control-structures.alternative-syntax.html

    Вместо этого:
    PHP:
    1. $check_email = $pdo->prepare('SELECT COUNT(0) AS ROW_COUNT FROM `users` WHERE `email` = ?');
    2.     $check_email->execute([$email]);
    3.    
    4.     //подсчитываем количество строк в ответе
    5.     $num = $check_email->fetch();
    6.     $count = $num['ROW_COUNT'];
    7.    
    8.     if($count > 0):
    9.        
    10.         //получаем данные о пользователе из таблицы users
    11.         $query = $pdo->prepare('SELECT * FROM `users` WHERE `email` = ?');
    12.         $query->execute([$email]);
    13.         $result = $query->fetch();
    Можно написать так:
    PHP:
    1. $query = $pdo->prepare('SELECT * FROM `users` WHERE `email` = ?');
    2. $query->execute([$email]);
    3. $result = $query->fetch();
    4.    
    5. if($result):
     
    _ne_scaju_ нравится это.
  13. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Понятно, что надо было сделать, как объединить в один) убрать один запрос а то он повторяет тот же запрос что и ниже, за исключением что он подсчитывает сколько количество строк вернул запрос.
    Правильно ли я понимаю?
    Сегодня буду разбираться в твоём коде.
    Спасибо за ответ.
     
    #63 _ne_scaju_, 29 апр 2017
    Последнее редактирование: 29 апр 2017
  14. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    --- Добавлено ---
    @Sergey_Tsarev
    Можно ли при регистрации проверить занят ли такой email таким запросом?
    PHP:
    1. $query = $pdo->prepare('SELECT * FROM `users` WHERE `email` = ?');
    2. $query->execute([$email]);
    3. $result = $query->fetch();
    4. if($result):
    5. $err[] ='email такой существует';
    6. endif;
    Если нельзя подскажите как можно.
     
  15. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    А попробовать никак? Можно, конечно :) Только здесь целесообразнее счётчик запросить, поскольку тут нам не нужны все поля, а только факт присутствия. А ещё можно поставить уникальный ключ на e-mail, что @Fell-x27 любит советовать, тогда база сама будет проверять перед вставкой, есть такой e-mail или нет, а тебе останется проверить, выполнился ли запрос
     
    mahmuzar нравится это.
  16. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Нет. Запрос не повторяется. COUNT просто возвращает число строк в результате запроса. Этот запрос будет работать быстрее. Его хорошо использовать, когда тебе не нужна работа с данными, а нужно только получить количество записей в таблице, соответствующих твоим условиям.

    И ещё поговаривают, что лучше так не писать:
    PHP:
    1. SELECT * FROM
    А лучше перечислить все необходимые тебе для работы поля, например:
    Код (Text):
    1. SELECT `id`, `email`, `status` FROM
     
  17. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Привет не подскажет из-за чего образуется ошибка notice: undefined variable: err in...
    Прочитать вроде могу, не объявлена переменная err
    Ну на самом деле она у меня объявлена, но в другом файле, который подключен к этому.
    И пишет мне ошибку не пойму почему...
     
  18. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @_ne_scaju_, так сложно сказать. Нужно код смотреть.
     
  19. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    Ок буду возле инета скину код.
    Я сегодня разобрался не много как работает ваш скрипт, спасибо за него отдельно, и уже прикрутил его.
    Но вот эти не значительные ошибки notice мешают.
     
  20. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    А все же скиньте мне пожалуйста страницу где можно на самых лёгких примерах построить проверку и вывод ошибок js.
    Или почитать об этом.
    Спасибо.
     
    #70 _ne_scaju_, 29 апр 2017
    Последнее редактирование: 29 апр 2017
  21. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @Sergey_Tsarev
    А может быть эта ошибка из-за такого:
    Есть файл в нем я подключаются БД, и сама функция для вывода ошибок.
    И вот этот файл я подключаю в принципе везде где надо выводить ошибки и подключение к БД.

    В данном случае подключение этого файла делаю в скрипте register.php
    PHP:
    1. <?php
    2. //Путь скрипта где я указываю подключение к БД и подключение функции которая выводить ошибки.
    3. include 'file/inc.php
    4. ?>
    5. <?php
    6. //Вот тут проверяют была ли нажата кнопка
    7. //Дальше идут всякие проверки
    8. if(empty($_POST['email'])){
    9. $err[] = 'vvedite email';
    10. }//И так дальше...
    11. //И в самом конце когда проверка окончена делаю обращение к этой функции в ней находится несколько функций, одна из которых отвечает за вывод ошибок.
    12. //Пример если ошибок нет пропускаем дальше
    13. if(count($err) > 0){
    14. echo 'errorMessage($err)';//выводим количество ошибок
    15. }
    16. else{
    17. //Ну и тут идут запросы разные
    18. }
    19. ?>
    Может эта ошибка notice образуется по сути из-за того что к функцие обращаюсь 2 раза?
    Первое я ее подключил через include и второе я к ней обращаюсь errorMessage.
     
  22. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    И что, по твоему, в этой строчке происходит?

    И логики у тебя как всегда.... У тебя переменная $err получает значение только если была ошибка, а если её не было - она не определена, вот 13 строчка и кидает нотис. Заинициализурй просто $err сразу на пустой массив
     
  23. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    Ой не эта строчка подсчитывает ошибки а выше. Ты мне советуешь что не пойму. Написать условие для не определенной $err?
     
  24. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Инициализировать $err пустым массивом прежде чем начинать проверять и записывать туда ошибки. Что тут непонятного? Вроде по-русски пишу.

    А строчка, которую я тебе указал, выведет совсем не то, что ты явно думал. Прочитай ещё раз про строки в php, и тогда поймёшь почему.
     
  25. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    Понял на что ты намекаешь, мне надо было написать так:
    Сделать надо так:
    PHP:
    1. $err = array();
    А потом аж
    Проверку делать
    PHP:
    1. if($err>0)
    2. errorMessage();
    Правильно понял ли я тебя?