有没有办法在 CodeIgniter *不*使用 ActiveRecord 的情况下将参数传递给查询?

Posted

技术标签:

【中文标题】有没有办法在 CodeIgniter *不*使用 ActiveRecord 的情况下将参数传递给查询?【英文标题】:Is there a way to pass arguments to a query in CodeIgniter *without* using ActiveRecord? 【发布时间】:2010-09-16 07:37:42 【问题描述】:

这是我想做的,但似乎不可能: (编辑:将单引号改为双引号)

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】:

如果你使用双引号而不是单引号,它会起作用,但如果变量没有被正确清理,你就会受到注入攻击。

【讨论】:

也许我遗漏了什么,但为什么单引号和双引号会对 SQL 注入攻击产生影响? 我和托马斯在一起。我不明白 Greg 的意思。 因为您将变量直接传递到 SQL 语句中 - 您应该首先对其进行转义。 我回答后问题已更改

以上是关于有没有办法在 CodeIgniter *不*使用 ActiveRecord 的情况下将参数传递给查询?的主要内容,如果未能解决你的问题,请参考以下文章

codeigniter 文件上传 - 可选?

Codeigniter 3:不要在表单验证错误时重新加载表单

有没有办法让Codeigniter控制器返回图像?

如何在 codeIgniter 中对文件使用分页

在Codeigniter中运行多个以分号分隔的查询

如何在codeigniter中获取上一页网址