Допустим, есть таблица users В ней поля: first_name, last_name, phone, email, login, password я пишу скрипт регистрации, делаю проверку на заполненность всех полей формы, если все заполнены, я проверяю не занят ли такой логин в БД. Формирую запрос Код (PHP): $sql = "SELECT id from users WHERE login = '$login' LIMIT 1"; $res = mysqli_query($link, $sql); $row = mysqli_num_rows($res); // Если занят, то придет '1', если свободен, то придет '0' if ($row) { // создаем в сессионном массиве рег элемент со описанием ошибки $_SESSION['reg']['res'] = "<p class='error'>Такой логин уже занят, пожалуйста, придумайте другой логин</p>"; // Создаем сессионные переменные, чтобы пользователь не вводил заново данные $_SESSION['reg']['first_name'] = $first_name; $_SESSION['reg']['last_name'] = $last_name; $_SESSION['reg']['phone'] = $phone; $_SESSION['reg']['email'] = $email; } в else я, естественно, уже провожу регистрацию(хеширую пароль и так далее)... так вот, в чем вопрос, как мне правильнее все организовать, если я хочу проверить не только логин, но и email, телефон, чтобы в БД не было одинаковых email и phone, мне необходимо делать два отдельных запроса на наличии email и phone и выводить соответствующие ошибки? или как это вообще делается? Направьте пожалуйста
1. делаете запрос на существование в бд любого из полей $sql = "SELECT * from users WHERE login = '$login' OR emeail = '$email' OR phone = '$phone' LIMIT 3"; потом в скрипте смотреть данные, что пришли, и уточнять, какой именно из параметров совпал. А может совпало и несколько. Не очень мне нравится. 2. можете сделать как у вас, но с тремя запросами. 3. А можете переделать на AJAX, повесить на input событие onchange. Т.е. пользователь вводит данные, сбрасывает фокус с инпута (переключается на другой инпут, допустим), срабатывает событие onchange, отсылается аякс-запрос к скрипту. Допустим, ввели данные в поле логин, уходит аякс-запрос на freeLogin.php, в последнем делается запрос к бд, проверяется логин (ну как у вас сейчас), и возвращает результат. Преимущества: 1. без перезагрузки страницы 2. можно СРАЗУ уведомить пользователя, что логин и тд заняты (а не вводить все поля, потому нажимать кнопочку "отправить" и только потом увидеть: "ой, а мой логин, телефон и почта уже заняты"). Правда, по-хорошему в скрипте самой регистрации всё равно надо проверять все поля (1 или 2 методом, опять же). Добавлено спустя 46 секунд: ОФФТОП: когда? когда я пропустил свой 404-юбилей?
логин, эмейл и телефон теоретически же могут быть в разных записях. А повторений каждого быть не должно, поэтому 3.
ну если лимит 3 стоит, то, найдя третий результат, он не пойдёт дальше по базе искать ведь. Меньше время работы, чтоль. Или я не так понимаю?)
ТОЧНО — ТЫ НЕ ТАК ПОНИМАЕШЬ. тебе вообще не надо добывать сами записи как SELECT *, а достаточно SELECT COUNT(*) или даже SELECT 1 и тогда if (mysqli_num_rows($result)) сработает как проверка "такие записи уже существуют". ведь тебе не нужны ни сами значения, ни даже знание сколько их там. важен только факт — они есть или их нет. Voila! Ну если очень хочется, то можно поставить LIMIT 1 Добавлено спустя 51 минуту 6 секунд: update: что действительно важно, так это наличие индексов, гарантирующих непротиворечивость данных. если важно чтобы login или email встречались не более одного раза, делайте UNIQUE KEY. тогда даже ошибка в скрипте не приведет к появлению фиговой записи. следствие: когда есть уникальны индекс, вот в таких конструкциях …WHERE login = '$login' LIMIT 1 тоже нет необходимости. т.к. полюбому вернется не более одной записи.
Спасибо за все ответы, советы. Особенно про уникальные индексы, об этом я не подумал, когда проектировал структуру БД, на будущее буду иметь ввиду
artoodetoo, хорошо, погуглю, почитаю. А вывод трёх полей данными вместо каунта я предполагал в расчёте на то, что в скрипте надо будет проверять, что именно совпало и выводить пользователю. До более мудрой мысли я не дошёл. P.S.: друг, я мелким шрифтом хорошо понимаю
1. Плохое решение, - лучше с JOIN. 2. Самый неправильный совет. Почитайте про JOIN. 3. Неправильный совет - не решает задачу. Самое правильное решение предложил artoodetoo - уник.инддексы. Оно и самое простое может быть, - достаточно "Insert ignore..." + "->affected_rows".
Вот, благодаря автору и я учусь. Я ж не ставлю из себя зазнайку. Зато теперь сам знаю, что так неправильно. Хорошо же.
Ребят, я конечно, извиняюсь, но я не совсем понял, я всё же хочу вникнуть, поэтому спрошу сразу Я устанавливаю уникальные ключи полям login, phone, email Я понимаю, что в БД не добавится запись, если пользователь введет значение, которое уже есть в таблице. Но мне ведь всё равно необходимо делать проверку, я же не могу сразу делать INSERT, а потом уже смотреть, добавились ли значения или нет, поэтому мне необходимо проверить, нет ли таких данных уже в таблице Соответственно я всё же делаю проверку типа Код (PHP): SELECT 1 FROM users WHERE login = '$login' OR email = '$email' OR phone = '$phone' (Я бы написал запрос с JOIN, но я пока не могу, как только я пойму что к чему тут, я сделаю с помощью JOIN) Смотрю, если пришла "1", соответственно ЧТО-ТО из поступившей информации совпадает, а как же мне пользователю сообщить, что что-то в системе уже зарегистрировано, если я этим запросом по сути никаких конкретных данных не получаю? Я получаю лишь факт совпадения. Еще раз прошу прощения, может я слишком глуп и не понимаю очевидных вещей, но не хочу оставлять этот момент недопонятым п.с. Как я это вижу все таки: если первый запрос дает мне всё же единицу, мне необходимо делать еще один запрос типа Код (PHP): SELECT login, phone, email FROM users WHERE login = '$login' OR email = '$email' OR phone = '$phone' Я достаю login, phone, email, а потом сравниваю с полученными значениями и уведомляю пользователя о КОНКРЕТНОЙ ошибке, поправьте пожалуйста где я ошибаюсь Но зачем мне делать два запроса?
мне кажется или ты хочешь обсудить вопрос "почему мне не хочется этого делать?". да хз почему! наверное потому что гемор с реальным проектом тебе не знаком и ты преувеличиваешь значимость каких-то деталей. изначально ты спрашивал как одним запросом понять не присутствуют ли в уже таблице уникальные по своей природе регистрационные данные — ты получил ответ.
зачем тебе два запроса? Этого одного не хватит? 1. Достал эти данные 2. Если результат пустой - делаешь инсерт 3. если результат не пустой - смотришь какое поле конкретно (а их может быть и несколько, и даже все) совпало и выдаёшь пользователю ошибку. Я ж выше про это писал