Как использовать инструкцию mysqli prepare для входа в систему с помощью электронной почты или имени пользователя (не PDO)?

Я видел много ответов о входе в php с помощью имени пользователя или электронной почты, но я не могу найти разрешение «Mysqli Prepare Statement», все они использовали PDO ...

У меня вопрос, почему я не могу использовать два ? для выбора имени пользователя или адреса электронной почты?

Мой код здесь:

База данных

table user
--id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
--username varchar(20),
--password varchar(255),
--email varchar(30),

html

<form action = "login.php" id = "login_form" method = "post">
    <input type = "text" name = "account" placeholder = "username or email" />
    <input type = "password" name = "password" placeholder = "password" />
    <div class = "login_submit">
      <button type = "submit" name = "submit">Login</button>
    </div>
</form>

PHP

<?php
$con = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT);
$con->query('SET CHARACTER SET utf8');

if (isset($_POST['submit'])) {
    $account = $_POST['account'];
    $get_password = $_POST['password'];
    $login_query = 'SELECT username,password,email FROM user WHERE username = ? OR email = ?';
    $login_stmt = $con->stmt_init();

    if ($login_stmt->prepare($login_query)) {
        $login_stmt->bind_param('ss', $account, $account);
        $login_stmt->execute();
        $login_stmt->bind_result($username, $password, $email);
        $login_result = $login_stmt->get_result();
        while ($login_row = $login_result->fetch_assoc()) {
            $check_password = $login_row['password'];
        }
    } else {
        echo 'Login Error';
        exit();
    }

if ($login_result->num_rows == 0) {
    $account_error = $lang_account_not_exist;
    $login_permit = false;
} elseif (!password_verify($get_password, $check_password)) {
    $password_error = $lang_wrong_password;
    $login_permit = false;
}

РЕДАКТИРОВАТЬ

bind_result($username, $password, $email);

"почему я могу использовать два ? ..." => Нет смысла разрешать только один ? в подготовленном операторе.

Dormilich 02.05.2018 15:47

Они заполнители. Когда mysqli (и PDO, поскольку он также может использовать синтаксис?) Выполняет запрос, он сообщает вашей базе данных, что нужно использовать значения, которые вы передаете в bind_param вместо вопросительных знаков, по порядку.

aynber 02.05.2018 15:48

В вашей базе данных есть username и email, оба установлены на то, что пользователь ввел в $_POST['account'].

RiggsFolly 02.05.2018 15:50

Сделайте некоторую проверку ошибок. Добавьте ini_set('display_errors', 1); ini_set('log_errors',1); error_reporting(E_ALL); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); в начало вашего скрипта. Это заставит любые ошибки mysqli_ генерировать исключение, которое вы можете увидеть в браузере, а другие ошибки также будут видны в вашем браузере.

RiggsFolly 02.05.2018 15:50

Может быть, сейчас самое время обратиться к руководству? php.net/manual/en/mysqli-stmt.bind-param.php

Magnus Eriksson 02.05.2018 15:50
$login_stmt->bind_result($password); не требуется, что может вызвать другие проблемы
RiggsFolly 02.05.2018 15:51

Я не вижу кода, который действительно устанавливает соединение с базой данных в том, что вы нам показываете. Вы подключаетесь к базе данных ?? mysqli_connect()

RiggsFolly 02.05.2018 15:53

@RiggsFolly Я добавил этот код, $ con

carry0987 02.05.2018 15:56

Проблема с mysqli_stmt::bind_result(). Вы выбираете 3 столбца, но связываете только 1 переменную.

aynber 02.05.2018 15:57

@aynber Я не думаю, что это вообще должно быть там, или я ошибаюсь

RiggsFolly 02.05.2018 15:58

Уверен, что $login_stmt = $con->stmt_init(); тоже не нужен

RiggsFolly 02.05.2018 15:58

@RiggsFolly Я не использую mysqli, поэтому не уверен. Я думаю, что OP должен либо полностью отказаться от него, либо передать правильное количество переменных.

aynber 02.05.2018 15:59

@aynber Поскольку мой проект слишком велик, чтобы заменить mysqli на PDO, я хочу знать, как он работает на mysqli ...

carry0987 02.05.2018 16:02

@RiggsFolly stmt_init() - это функция, которую я нашел здесь: Ссылка на сайт, так что .. она не нужна?

carry0987 02.05.2018 16:05

@Dormilich извини, это моя вина, я имею в виду why I can not use two ?

carry0987 02.05.2018 16:11

@ carry0987 Что говорится в сообщении об ошибке?

Dormilich 02.05.2018 16:14

Ага, правильно сформулированный вопрос меняет ответ. Вы может используете 2 ? в своем операторе подготовки. Проблема не в этом. Подготовка / bind_param / execute работает нормально, но (как упоминалось ранее) ошибка возникает из-за привязки bind_result 1 переменной к 3 столбцам.

aynber 02.05.2018 16:18

@Dormilich он сказал PHP Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement

carry0987 02.05.2018 16:18

@aynber Я добавляю 3 переменные, теперь она не сообщает об ошибках, но все равно не могу войти в систему ...

carry0987 02.05.2018 16:21

Если ошибки нет, вам нужно будет устранить неполадки. Зарегистрируйте / echo / var_dump в своем коде, чтобы узнать, куда он идет и что делает, и что содержат ваши переменные.

aynber 02.05.2018 16:23

@ carry0987 Ознакомьтесь с Руководством по использованию mysqli_stmt::bind_result(). Смешанные стратегии выборки могут привести к неожиданным результатам.

Dormilich 02.05.2018 16:26

@Dormilich Я увидел проблему, я использую неопределенную переменную с именем $ login_username, теперь я исправил это, большое спасибо!

carry0987 02.05.2018 17:15

@aynber Я использую var_dump и увидел проблему, спасибо за напоминание!

carry0987 02.05.2018 17:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
23
923
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вероятно, ваша проблема НЕ в

$login_stmt->bind_param('ss', $account, $account);

Как вы думаете.

Выглядит нормально, пока не ваш $_POST['account'] - это массив, а не отдельная переменная, в чем я сомневаюсь. В этом случае он там не сработает. Но ваш оператор WHERE и bindparam выглядят правильно

Однако это неверно:

$login_stmt->bind_result($password);

Потому что вы пытаетесь привязать только одну переменную, и в вашем операторе SELECT (SELECT username,password,email) возвращаются 3 столбца.

Поскольку вам действительно не нужны email и username в вашем коде, просто измените свой запрос следующим образом:

$login_query = 'SELECT password FROM user WHERE username = ? OR email = ?';

и это должно работать

Другие вопросы по теме