Есть ли способ передать аргументы в запрос в CodeIgniter *без* использования ActiveRecord?

#sql #database #codeigniter #arguments

Вопрос:

Это то, что я хотел бы сделать, но это кажется невозможным: (правка: изменил одинарные кавычки на двойные)

 function get_archives($limit, $offset) 
{
    $query = $this->db->query("
        SELECT  archivalie.id, 
                archivalie.signature, 
                type_of_source.description AS type_of_source_description, 
                media_type.description AS media_type_description,
                origin.description AS origin_description

        FROM    archivalie, 
                type_of_source, 
                media_type,
                origin

        WHERE   archivalie.type_of_source_id = type_of_source.id                                                        
        AND     type_of_source.media_type_id = media_type.id  
        AND     archivalie.origin_id = origin.id                                                                     

        ORDER BY    archivalie.id ASC
        LIMIT       $limit, $offset
    "); 


    // etc...

}
 

Это приводит к этой ошибке:
(правка: новое сообщение об ошибке с использованием двойных кавычек и номером смещения, переданным в URL-адресе)

 ERROR: LIMIT #,# syntax is not supported HINT: Use separate LIMIT and OFFSET clauses.
 

Это работает только в том случае, если вы передаете переменные, используя формат ActiveRecord:

 $this->db->select('archivalie.id, archivalie.signature, etc, etc');
// from, where, etc.
$this->db->limit($limit, $offset);        
$query = $this->db->get();
 

Ответ №1:

 $query = $this->db->query('
SELECT  archivalie.id, 
        archivalie.signature, 
        type_of_source.description AS type_of_source_description, 
        media_type.description AS media_type_description,
        origin.description AS origin_description
FROM    archivalie, 
        type_of_source, 
        media_type,
        origin
WHERE   archivalie.type_of_source_id = type_of_source.id                                                        
AND     type_of_source.media_type_id = media_type.id  
AND     archivalie.origin_id = origin.id                                                                     
ORDER BY    archivalie.id ASC
LIMIT       ?
OFFSET      ?',array($limit,$offset));
 

Ответ №2:

Это сработало:

 $query = $this->db->query("
    SELECT  archivalie.id, 
            archivalie.signature, 
            type_of_source.description AS type_of_source_description, 
            media_type.description AS media_type_description,
            origin.description AS origin_description

    FROM    archivalie, 
            type_of_source, 
            media_type,
            origin

    WHERE   archivalie.type_of_source_id = type_of_source.id                                                        
    AND     type_of_source.media_type_id = media_type.id  
    AND     archivalie.origin_id = origin.id                                                                     

    ORDER BY    archivalie.id ASC
    LIMIT       $limit
    OFFSET      $offset
");
 

Но для назначения значения по умолчанию требуется проверка, если в URL-адресе отсутствует смещение. От моего контроллера:

 # Check/assign an offset
$offset = (!$this->uri->segment(3)) ? 0 : $this->uri->segment(3);

# Get the data
$archives = $this->archive->get_archives($config['per_page'], $offset);
 

Ответ №3:

Это связано с типом данных параметра. Если вы не хотите, чтобы Codeigniter добавлял одинарные кавычки`’, убедитесь, что вы передаете целое число.

 $page = '10'; // for some reason this arrives as a string
$sql = "select * from customers limit 10 offset ?";
$result = $this->db->query($sql, array(intval($page));
 

Ответ №4:

Если бы вы использовали двойные кавычки вместо одинарных, это сработало бы, но вы были бы открыты для инъекционной атаки, если бы переменные не были очищены должным образом.

Комментарии:

1. Возможно, я что-то упускаю, но почему одинарные и двойные кавычки будут иметь значение для атак с использованием SQL-инъекций?

2. Я с Томасом. Я не понимаю, что Грег имеет в виду под этим.

3. Поскольку вы передаете переменную непосредственно в инструкцию SQL, вы должны сначала ее экранировать.

4. Вопрос был изменен после того, как я ответил, кстати