Запрос SQL Select с активными записями CodeIgniter и «где sha1» возвращает первую запись строки - PullRequest
1 голос
/ 20 июля 2011

Я продублировал эту проблему на полностью чистой установке CodeIgniter 2.0.2

Следующий код был добавлен к стандартному контроллеру 'welcome', и я создал 'test_model', чтобы продемонстрировать ошибку.

Можно предположить / внести изменения в config / autoload / database: - правильное определение базового url - библиотека базы данных автозагрузки - logging установлен на 4 (все сообщения) - параметры подключения к базе данных

Эточто я добавил в controllers / welcome.php:

function test_me()
{
    $this->load->model('test_model');

    # data for sql query
    $where = array(
        'email'     => $this->input->post('email'),
        'password'  => sha1($this->input->post('password'), true);
    );

    log_message('info', '----email: '.$where['email']);
    log_message('info', '----password: '.$where['password']);

    # exec query
    $query = $this->test_model->get_user($where);

    log_message('info', '----query->num_rows() ='.$query->num_rows());

    if($query->num_rows() > 0) 
    {
        $row = $query->row();

        log_message('info', '----query->row()->email = '.$row->email);

        print $row->email;
    }
    else
        print "worked correctly.";  # returned ZERO rows

}

Это модели / test_model.php:

class Test_model extends CI_Model {

var $_user_table = 'users';     # user table name

// ------------------------------------------------------------------------

/**
 * Constructor
 *
 * @access  public
 */
public function __construct()
{
    log_message('INFO', 'User model initialized');

    parent::__construct();
}

/**
 * Get_user
 * 
 * Retrieves user data from the database
 *
 * @access  public
 * @param   array   sql select query data
 * @param   int     default return limits to 1 user
 * @param   int     offset  
 * @return  mixed   sql query result
 */
public function get_user($data, $limit = 1, $offset = 0)
{
    foreach($data as $where)
        log_message('INFO', 'Getting user data from db where: '.$where);


    # refer this as QUERY1

    $query = $this->db->query('SELECT * 
                   FROM `users` 
                   WHERE `email` = \''.$data['email'].'\' 
                   AND `password` = \''.$data['password'].'\' 
                   LIMIT 1
                   OFFSET 0
                  ');

    # refer this as QUERY2

    #$query = $this->db->get_where($this->_user_table, $data, $limit, $offset);

    log_message('info', 'get last sql query: '.$this->db->last_query());

    return $query;
}
}

В QUERY1 это просто использование прямого SQL со всемипараметры, которые передаются в QUERY2.Разница в том, что QUERY2 использует преимущества активных записей CodeIgniter.

Теперь это журнал, созданный при выполнении вышеуказанного:

INFO - 2011-07-19 23:34:01-> ---- электронная почта: INFO - 2011-07-19 23:34:01 -> ---- пароль: Ú9 £ î ^ kK2U¿ï • `¯Ø INFO - 2011-07-19 23:34:01 -> Получение пользовательских данных из БД, где:

INFO - 2011-07-19 23:34:01 -> Получение пользовательских данных из БД, где: Ú9 £ î ^ kK2U¿ï • `¯Ø

INFO - 2011-07-19 23:34:01 -> получить последний SQL-запрос: ВЫБРАТЬ * ОТ users ГДЕ email = '' И password = 'Ú9 £ î^ kK2U¿ï • `¯Ø 'ПРЕДЕЛ 1 СМЕЩЕНИЕ 0

INFO - 2011-07-19 23:34:01 -> ---- query-> num_rows () = 0

DEBUG - 2011-07-19 23:34:01 -> Окончательный вывод отправлен в браузер DEBUG - 2011-07-19 23:34:01 -> Общее время выполнения: 0,0923

Вывод браузера: работает правильно.

И вот что происходит, когда я закомментирую QUERY1 и запускаю QUERY2 (AR CI):

INFO - 2011-07-19 23: 40: 05 -> ---- электронная почта:

INFO - 2011-07-19 23:40:05 -> ---- пароль: ڹ Į ^ kK2U࠯ ֠ Я ؇

INFO- 2011-07-19 23:40:05 -> Получение пользовательских данных из БД, где: INFO - 2011-07-19 23:40:05 -> Получение пользовательских данных из БД, где: ڹ Į ^ kK2U࠯ ֠ Я ؇

INFO - 2011-07-19 23:40:05 -> получить последний SQL-запрос: ВЫБРАТЬ * ОТ (users) ГДЕ email = 0 И password = 'ڹ Į ^ kK \ r2U࠯֠ Я ؇ 'LIMIT 1

INFO - 2011-07-19 23:40:05 -> ---- query-> num_rows () = 1

INFO - 2011-07-19 23:40:05 -> ---- query-> row () -> email = myemail@gmail.com

DEBUG - 2011-07-19 23:40:05 ->Окончательный вывод отправлен в браузер. DEBUG - 2011-07-19 23:40:05 -> Общее время выполнения: 0,0965

Вывод скрипта myemail@gmail.com Это первая строкав таблице, и он всегда возвращает первую строку таблицы.Если я не использую значение LIMIT = 1 по умолчанию, num_rows () фактически равняется количеству строк в таблице.

Теперь, фон, я использую это как очевидную проверку скрипта формы, но формуне обязательно всегда заполняется.Я использую javascript для проверки, но это тот случай, когда в браузере не может быть включен javascript или если пользователь пытается заполнить поля пустыми.База данных не имеет допустимых пустых записей и не должна возвращать никаких строк.Поскольку я храню хэши sha1 в виде необработанных двоичных данных (20), используется sha1 ('', true).Как ни странно, это создает какую-то ошибку, которую я представляю с помощью Active Records в CI, и вместо того, чтобы возвращать ошибку или возвращать ноль строк (как и следовало ожидать), она возвращает КАЖДУЮ строку в таблице!

Яделать что-то не так или это ошибка или не предполагаемый способ использования активных записей?Потому что я хотел бы сохранить метод принятия массива предложений where в запросе.

Спасибо

  • ОБНОВЛЕНИЕ -

Благодаря комментариям пользователейниже, чтобы подтолкнуть меня в этом направлении.Кажется, я ошибся, что sha1 имеет какое-то отношение к этому на самом деле ... $ this-> input-> post () возвращает False, если нет данных поста (что в данном случае) и, таким образом,значение 'email' в массиве равно 'false'.

Так что теперь я на самом деле на другой квестна котором я, вероятно, сделаю репост, и именно поэтому, где email = 'false' возвращает всю таблицу?

  • ОБНОВЛЕНИЕ -

На самом деле, я никогда не видел этого раньше, потому что это НИКОГДА не происходит ... в QUERY1 (sql) он работает правильно. В QUERY2 с ActiveRecords это не так. ТАК еще есть разница.

...