Я создал функцию, которая будет проверять полномочия пользователя на определенных страницах. Он должен возвращать 0 или 1. Это функция, которую я использую на страницах.
Эта часть не проблема, хотя, поскольку это работает как задумано.
$admin_model = $this->loadModel('AdminModel');
if($admin_model->checkAdmin($_SESSION['username']) == 0) {
header('Location: ' . URL);
exit();
}
Вот в чем проблема. Моя учетная запись имеет полномочия M и поэтому должна возвращать значение 1, но вместо этого она возвращает 0.
public function checkAdmin($account) {
$sql = "SELECT * FROM ACCOUNTS WHERE
account = :account AND authority = 'L' OR
account = :account AND authority = 'M' OR
account = :account AND authority = 'N' OR
account = :account AND authority = 'O' OR
account = :account AND authority = 'P'";
$query = $this->db->prepare($sql);
$query->execute(array(':account' => $account));
return $query->rowCount();
}
Я также попытался использовать этот запрос в SQL Management Studio, и он работает. Почему же этот запрос не работает в PHP?
SELECT * FROM ACCOUNTS WHERE
account = 'ibab' AND authority = 'L' OR
account = 'ibab' AND authority = 'M' OR
account = 'ibab' AND authority = 'N' OR
account = 'ibab' AND authority = 'O' OR
account = 'ibab' AND authority = 'P';
@MichaelBerkowski в комментариях отлично показал непосредственную проблему с вашим кодом, который использует один и тот же именованный параметр в подготовленном выражении более одного раза, что недопустимо.
Один из способов решить эту проблему — переписать ваш запрос в более сжатой форме, чтобы передать значение учетной записи только один раз.
SELECT *
FROM accounts
WHERE account = :account
AND authority IN('L','M','N','O','P')
Кстати, в исходном запросе вы должны были использовать круглые скобки для разделения групп AND и OR.
ОБНОВИТЬ: Как упоминалось в комментариях @ ÁlvaroG.Vicario, нет необходимости возвращать весь набор результатов, если конечной целью является просто выяснить, есть ли у вас какие-либо записи или нет. Вы можете использовать COUNT()
для этого. Вы даже можете добавить TOP 1
(при условии, что вы используете SQL Server), если вы планируете иметь несколько записей авторизации.
SELECT TOP 1 COUNT(*) flag
FROM accounts
WHERE account = :account
AND authority IN('L','M','N','O','P')
Это всегда даст вам 1 или 0 в flag
колонка.
Вот SQLFiddle демонстрация
Других решений пока нет …