CodeIgniter 使用手冊版本 2.2.0


Active Record 類別

CodeIgniter 使用一個 Active Record 資料庫模式的修改版本。 這個模式允許資訊在你的資料庫中靠最少的程式被接收、新增與更新。 在一些狀況下, 只需要一兩行的程式就足以執行資料庫動作。 CodeIgniter 不需要每個資料表擁有他自己的類別檔案, 它取而代之提供一個更簡單的介面。

不只是簡單, 既然查詢語法是由各個資料庫界面所產生的, 一個使用 Active Record 功能的重大的益處是它允許你建立不依賴特定資料庫的應用程式。既然所有的值都會由系統自動跳脫(escape), 它也讓查詢更安全。

注意: 如果你想寫自己的查詢, 你可以在資料庫設定檔裡取消使用這個類別。這樣可以讓核心的資料庫程式庫以及界面耗用更少的資源。

 挑選(Selecting)資料

以下函數讓你建立 SQL SELECT 語句。

注意:如果你使用 PHP 5, 那你可以使用方法串接(method chaining)來讓語法更精簡。這在本頁最後會說明。

$this->db->get();

執行select查詢並返回結果。可以用來取得資料表中所有紀錄:

$query = $this->db->get('mytable');

// 產生: SELECT * FROM mytable

第二與第三個參數讓你可以設定 limit 與 offset 子句:

$query = $this->db->get('mytable', 10, 20);

// 產生: SELECT * FROM mytable LIMIT 20, 10 (使用MySQL。其它資料庫有不太一樣的語法。)

你會注意到, 上面的函數賦值給一個叫做 $query 的變數, 它可以用來顯示結果:

$query = $this->db->get('mytable');

foreach ($query->result() as $row)
{
    echo $row->title;
}

請訪問 result 函數 頁面來獲得關於產生結果的討論。

$this->db->get_where();

下面可以取代 db->where() 函數, 除了可以讓你在第二個參數加上 "where" 子句以外, 其餘與上面這個函數相同:

$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);

請參閱底下關於 "where" 函數的詳細資訊。

注意: get_where() 之前叫做 getwhere(), 舊的函數名稱已經被移除。

$this->db->select();

允許你自訂查詢中的 "select" 部份:

$this->db->select('title, content, date');

$query = $this->db->get('mytable');

// 產生: SELECT title, content, date FROM mytable

注意: 如果你要選擇資料表中所有欄位(*), 那你不需要使用這個函數。當省略時, CodeIgniter 假設你要的是 SELECT * 。

$this->db->select() 可額外接受第二個參數。如果你傳入 FALSE, CodeIgniter 將不使用反單引號(`, 在英文鍵盤左上方)來保護你的欄位或資料表名稱。這在你需要一個合成的 select 敘述時會很有用。

$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE);
$query = $this->db->get('mytable');

$this->db->select_max();

可以為你的查詢做出 "SELECT MAX(欄位)" 的部份。你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_max('age');
$query = $this->db->get('members');
// 產生: SELECT MAX(age) as age FROM members

$this->db->select_max('age', 'member_age');
$query = $this->db->get('members');
// 產生: SELECT MAX(age) as member_age FROM members

$this->db->select_min();

可以為你的查詢做出 "SELECT MIN(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_min('age');
$query = $this->db->get('members');
// 產生: SELECT MIN(age) as age FROM members

$this->db->select_avg();

可以為你的查詢做出 "SELECT AVG(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_avg('age');
$query = $this->db->get('members');
// 產生: SELECT AVG(age) as age FROM members

$this->db->select_sum();

可以為你的查詢做出 "SELECT SUM(欄位)" 的部份。如同 select_max() , 你可以額外加入第二個參數來重新命名結果欄位。

$this->db->select_sum('age');
$query = $this->db->get('members');
// 產生: SELECT SUM(age) as age FROM members

$this->db->from();

允許你撰寫查詢的 FROM 部份:

$this->db->select('title, content, date');
$this->db->from('mytable');

$query = $this->db->get();

// 產生: SELECT title, content, date FROM mytable

注意: 如同之前看到的, 你的查詢的 FROM 部份可以在 $this->db->get() 函數中指定, 所以喜歡哪個就用哪個。

$this->db->join();

允許你撰寫查詢的 JOIN 部份:

$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');

$query = $this->db->get();

// 產生:
// SELECT * FROM blogs
// JOIN comments ON comments.id = blogs.id

如果你需要在一個查詢中使用多個 JOIN , 你可以多次呼叫這個函數。

你可以透過函數的第三個參數來指定 join 的型態。可用的選項有: left、right、outer、inner、left outer 以及 right outer 。

$this->db->join('comments', 'comments.id = blogs.id', 'left');

// 產生: LEFT JOIN comments ON comments.id = blogs.id

$this->db->where();

This function enables you to set WHERE clauses using one of four methods: 這個函數讓你能用以下四個方法之一來設定 WHERE 子句:

注意: 所有傳到這個函數的值都會自動跳脫(escape), 以產生更安全的查詢。

  1. 簡單的 鍵/值 方法: $this->db->where('name', $name);

    // 產生: WHERE name = 'Joe'

    注意它會為你加上等於符號。

    如果你多次呼叫這個函數, 那它會把這些用 AND 串在一起:

    $this->db->where('name', $name);
    $this->db->where('title', $title);
    $this->db->where('status', $status);

    // WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
  2. 自訂的 鍵/值 方法:

    你可以在第一個參數包含一個運算子來控制比較的方法:

    $this->db->where('name !=', $name);
    $this->db->where('id <', $id);

    // 產生: WHERE name != 'Joe' AND id < 45
  3. 關聯陣列方法: $array = array('name' => $name, 'title' => $title, 'status' => $status);

    $this->db->where($array);

    // 產生: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'

    你也可以在這個方法包含你要用的運算子:

    $array = array('name !=' => $name, 'id <' => $id, 'date >' => $date);

    $this->db->where($array);
  4. 自訂字串:

    你可以手動撰寫你要的子句:

    $where = "name='Joe' AND status='boss' OR status='active'";

    $this->db->where($where);

$this->db->where() 可接受額外的第三個參數。如果你傳入 FALSE, CodeIgniter 將不會嘗試使用反單引號(`, 在英文鍵盤左上方)來保護你的欄位或資料表名稱。

$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);

$this->db->or_where();

除了使用 OR 來串接傳入的查詢條件, 這個函數與上面的相同:

$this->db->where('name !=', $name);
$this->db->or_where('id >', $id);

// 產生: WHERE name != 'Joe' OR id > 50

注意: or_where() 之前叫做 orwhere() , 舊的函數名稱已經移除。

$this->db->where_in();

產生一個 WHERE field IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 AND 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->where_in('username', $names);
// 產生: WHERE username IN ('Frank', 'Todd', 'James')

$this->db->or_where_in();

產生一個 WHERE field IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 OR 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_in('username', $names);
// 產生: OR username IN ('Frank', 'Todd', 'James')

$this->db->where_not_in();

產生一個 WHERE field NOT IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 AND 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->where_not_in('username', $names);
// 產生: WHERE username NOT IN ('Frank', 'Todd', 'James')

$this->db->or_where_not_in();

產生一個 WHERE field NOT IN ('item', 'item') 的 SQL 查詢, 如果合適的話就用 OR 來串接。

$names = array('Frank', 'Todd', 'James');
$this->db->or_where_not_in('username', $names);
// 產生: OR username NOT IN ('Frank', 'Todd', 'James')

$this->db->like();

這個函數讓可能產生 LIKE 子句, 可用來做搜尋。

注意: 所有傳到這個函數的值都會自動跳脫(escape)。

  1. 簡單的 鍵/值 方法: $this->db->like('title', 'match');

    // 產生: WHERE title LIKE '%match%'

    If you use multiple function calls they will be chained together with AND between them: 如果你多次呼叫這個函數, 它會把這些用 AND 串接在一起:

    $this->db->like('title', 'match');
    $this->db->like('body', 'match');

    // 產生: WHERE title LIKE '%match%' AND body LIKE '%match%
    如果你想要控制萬用字元 (%)出現的位置, 你可以使用額外的第三個參數。可以使用的選項有 'before'、'after' 以及 'both' (這是預設值)。 $this->db->like('title', 'match', 'before');
    // 產生: WHERE title LIKE '%match'

    $this->db->like('title', 'match', 'after');
    // 產生: WHERE title LIKE 'match%'

    $this->db->like('title', 'match', 'both');
    // 產生: WHERE title LIKE '%match%'
  2. If you do not want to use the wildcard (%) you can pass to the optional third argument the option 'none'. $this->db->like('title', 'match', 'none');
    // Produces: WHERE title LIKE 'match'
  3. 關聯陣列方法: $array = array('title' => $match, 'page1' => $match, 'page2' => $match);

    $this->db->like($array);

    // 產生: WHERE title LIKE '%match%' AND page1 LIKE '%match%' AND page2 LIKE '%match%'

$this->db->or_like();

除了使用 OR 來串接傳入的條件, 著個函數與上面的相同:

$this->db->like('title', 'match');
$this->db->or_like('body', $match);

// 產生: WHERE title LIKE '%match%' OR body LIKE '%match%'

注意: or_like() 之前叫做 orlike(), 舊的函數名稱已經移除。

$this->db->not_like();

除了會產生 NOT LIKE 敘述之外, 這個函數與 like() 相同。

$this->db->not_like('title', 'match');

// 產生: WHERE title NOT LIKE '%match%

$this->db->or_not_like();

除了使用 OR 來串接傳入的條件, 這個函數與 not_like() 相同。

$this->db->like('title', 'match');
$this->db->or_not_like('body', 'match');

// 產生: WHERE title LIKE '%match% OR body NOT LIKE '%match%'

$this->db->group_by();

Permits you to write the GROUP BY portion of your query: 讓你撰寫你查詢中的 GROUP BY 部份:

$this->db->group_by("title");

// 產生: GROUP BY title

你也可以用正列傳給它多個值:

$this->db->group_by(array("title", "date"));

// 產生: GROUP BY title, date

注意: group_by() 之前叫做 groupby(), 舊的函數名稱已經移除。

$this->db->distinct();

在查詢中加入"DISTINCT" 關鍵字

$this->db->distinct();
$this->db->get('table');

// 產生: SELECT DISTINCT * FROM table

$this->db->having();

允許你撰寫你查詢中的 HAVING 部份。有兩種可用的語法, 使用一個或兩個參數:

$this->db->having('user_id = 45');
// 產生: HAVING user_id = 45

$this->db->having('user_id', 45);
// 產生: HAVING user_id = 45

你也可以用陣列來傳給它多個值:

$this->db->having(array('title =' => 'My Title', 'id <' => $id));

// 產生: HAVING title = 'My Title', id < 45

如果你在使用的資料庫 CodeIgniter 會幫你跳脫(escape)查詢, 你可以透過傳給它額外的第三個參數為 FALSE 來避免跳脫內容。

$this->db->having('user_id', 45);
// 產生: HAVING `user_id` = 45 in some databases such as MySQL
$this->db->having('user_id', 45, FALSE);
// 產生: HAVING user_id = 45

$this->db->or_having();

與 haveing() 相同, 但是使用 "OR" 來分隔多個子句。

$this->db->order_by();

讓你設定 ORDER BY 子句。第一個參數包含你要排序的欄位, 第二個參數則讓你指定排序的方向。可用的選項有 ascdescrandom

$this->db->order_by("title", "desc");

// 產生: ORDER BY title DESC

你也能傳入你自訂的字串當作第一個參數:

$this->db->order_by('title desc, name asc');

// 產生: ORDER BY title DESC, name ASC

如果你需要對多個欄位排序, 也可以多次呼叫這個函數。

$this->db->order_by("title", "desc");
$this->db->order_by("name", "asc");

// 產生: ORDER BY title DESC, name ASC

注意: order_by() 之前叫做 orderby(), 舊的函數名稱已經移除。

注意: 亂數排序(radom ordering) 目前在 Oracle 與 MSSQL 上面還沒有支援, 它們預設會改用 'ASC' 。

$this->db->limit();

讓你限制查詢要返回的列數:

$this->db->limit(10);

// 產生: LIMIT 10

第二個參數讓你設定結果的偏移。

$this->db->limit(10, 20);

// 產生: LIMIT 20, 10 (使用 MySQL 。其他資料庫有稍微不同的語法)

$this->db->count_all_results();

讓你可以判斷特定的 Active Record 查詢的結果列數。查詢可接受 Active Record 的限制條件, 像是 where()、or_where()、like()、or_like() 等。查詢範例:

echo $this->db->count_all_results('my_table');
// 產生整數結果, 像是 25

$this->db->like('title', 'match');
$this->db->from('my_table');
echo $this->db->count_all_results();
// 產生整數結果, 像是 17

$this->db->count_all();

讓你可以判斷特定資料表的列數。提供資料表名稱作為它的第一個參數。參考範例:

echo $this->db->count_all('my_table');

// 產生整數結果, 像是 25
 

新增(Inserting)資料

$this->db->insert();

根據你提供的資料產生一個 insert 字串, 然後執行查詢。你可以傳入一個 陣列 或是一個 物件 給函數。這是一個使用陣列的範例:

$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$this->db->insert('mytable', $data);

// 產生: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

第一個參數要包含資料表的名稱, 第二個參數是一個包含要存入值的關聯陣列。

這是一個使用物件的範例:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->insert('mytable', $object);

// 產生: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')

第一個參數會包含資料表名稱, 第二個參數是包含要存入值的物件。

注意:所有的值都會自動跳脫(escape)以產生較安全的語法。

$this->db->insert_batch();

根據你提供的資料產生一個 insert 字串, 然後執行新增。你可以傳入一個 陣列 或是一個 物件 給函數。這是一個使用陣列的範例:

$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name' ,
      'date' => 'My date'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name' ,
      'date' => 'Another date'
   )
);

$this->db->insert_batch('mytable', $data);

// 產生: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')

第一個參數會包含資料表名稱,第二個參數是一個包含要存入值的關聯陣列。

注意: 所有的值都會自動跳脫(escape)以產生較安全的語法。

$this->db->set();

這個函數讓你能設定要 新增(insert) 或是 更新(update) 的值。

你也可以直接傳入一個資料陣列給新增(insert)或是更新(update)的函數:

$this->db->set('name', $name);
$this->db->insert('mytable');

// 產生: INSERT INTO mytable (name) VALUES ('{$name}')

如果你多次呼叫這個函數, 它會在新增或是更新時適當地組合:

$this->db->set('name', $name);
$this->db->set('title', $title);
$this->db->set('status', $status);
$this->db->insert('mytable');

set() 也可以接收額外的第三個參數 ($escape) , 如果你傳入 FALSE , 可以防止它跳脫你的資料。為了顯示這樣會有什麼不同, 以下是使用與不使用這個參數的例子:

$this->db->set('field', 'field+1', FALSE);
$this->db->insert('mytable');
// 產生: INSERT INTO mytable (field) VALUES (field+1)

$this->db->set('field', 'field+1');
$this->db->insert('mytable');
// 產生: INSERT INTO mytable (field) VALUES ('field+1')

你也可以傳入一個關聯陣列給這個函數:

$array = array('name' => $name, 'title' => $title, 'status' => $status);

$this->db->set($array);
$this->db->insert('mytable');

或是一個物件:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->set($object);
$this->db->insert('mytable');
 

更新(Updating)資料

$this->db->update();

產生一個更新字串, 並根據你提供的資料來執行查詢。你可以傳一個 陣列(array) 或是一個 物件(object)給這個函數。這裡有一個使用陣列的例子:

$data = array(
               'title' => $title,
               'name' => $name,
               'date' => $date
            );

$this->db->where('id', $id);
$this->db->update('mytable', $data);

// 產生:
// UPDATE mytable
// SET title = '{$title}', name = '{$name}', date = '{$date}'
// WHERE id = $id

或是傳給它物件:

/*
    class Myclass {
        var $title = 'My Title';
        var $content = 'My Content';
        var $date = 'My Date';
    }
*/

$object = new Myclass;

$this->db->where('id', $id);
$this->db->update('mytable', $object);

// 產生
// UPDATE mytable
// SET title = '{$title}', name = '{$name}', date = '{$date}'
// WHERE id = $id

注意: 所有的值都會自動跳脫以產生較安全的查詢。

你要注意到 $this->db->where() 函數的使用, 它能讓你設定 WHERE 子句。你也可以直接用字串方式傳遞這個資訊給更新函數:

$this->db->update('mytable', $data, "id = 4");

或是用一個陣列:

$this->db->update('mytable', $data, array('id' => $id));

你也可以用前面介紹過的 $this->db->set() 函數來進行更新。

$this->db->update_batch();

Generates an update string based on the data you supply, and runs the query. You can either pass an array or an object to the function. Here is an example using an array:

$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name 2' ,
      'date' => 'My date 2'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name 2' ,
      'date' => 'Another date 2'
   )
);

$this->db->update_batch('mytable', $data, 'title');

// Produces:
// UPDATE `mytable` SET `name` = CASE
// WHEN `title` = 'My title' THEN 'My Name 2'
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// ELSE `name` END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date` END
// WHERE `title` IN ('My title','Another title')

The first parameter will contain the table name, the second is an associative array of values, the third parameter is the where key.

Note: All values are escaped automatically producing safer queries.

 

刪除(Deleting)資料

$this->db->delete();

產生刪除的 SQL 字串並執行查詢。

$this->db->delete('mytable', array('id' => $id));

// 產生:
// DELETE FROM mytable
// WHERE id = $id

第一個參數是資料表名稱。第二個參數是 where 子句。你也可以使用 where() 或是 or_where() 函數, 而不是用第二個參數傳資料給它:

$this->db->where('id', $id);
$this->db->delete('mytable');

// 產生:
// DELETE FROM mytable
// WHERE id = $id

如果你想刪除不只一個資料表的資料, 你也可以傳遞資料表名稱的陣列給 delete() 。

$tables = array('table1', 'table2', 'table3');
$this->db->where('id', '5');
$this->db->delete($tables);

如果你要刪除一個資料表中的所有資料, 你可以使用 truncate() 函數或是 empty_table()

$this->db->empty_table();

產生一個刪除(delete)的 SQL 字串並且執行查詢。 $this->db->empty_table('mytable');

// 產生:
// DELETE FROM mytable

$this->db->truncate();

產生一個刪除資料表(truncate)的 SQL 字串並且執行查詢。

$this->db->from('mytable');
$this->db->truncate();
// or
$this->db->truncate('mytable');

// 產生:
// TRUNCATE mytable

注意: 如果 TRUNCATE 命令無法使用, truncate() 會執行 "DELETE FROM table" 。

 方法串接

方法串接可以利用連接多個函數來讓你你的語法更為簡化。考慮一下這個參考範例:

$this->db->select('title')->from('mytable')->where('id', $id)->limit(10, 20);

$query = $this->db->get();

注意: 方法串接只有在 PHP 5 以上才能使用。

 

 Active Record 快取

雖然不是"真"的快取, Active Record 讓你能儲存(或是"快取")查詢的特定部份讓接下來的程式可以重複使用。正常狀況下, 當 Active Record 呼叫執行完畢時, 所有的資訊都會為了下一次呼叫而重置。使用快取, 你可以避免這個重置, 讓資訊可以簡單地重複使用。

快取的呼叫是會累積的。如果你做了兩次快取的 select() 呼叫然後兩次非快取的 select() 呼叫, 結果會是四次 select() 呼叫。

$this->db->start_cache()

這個函數必須在快取前呼叫。所有類型正確的的 Active Record 查詢都會被儲存起來以備使用。

$this->db->stop_cache()

呼叫這個函數可以停止快取。

$this->db->flush_cache()

這個函數可以刪除所有 Active Record 快取中的資料。

這是參考範例:

$this->db->start_cache();
$this->db->select('field1');
$this->db->stop_cache();

$this->db->get('tablename');

//產生: SELECT `field1` FROM (`tablename`)

$this->db->select('field2');
$this->db->get('tablename');

//產生: SELECT `field1`, `field2` FROM (`tablename`)

$this->db->flush_cache();

$this->db->select('field2');
$this->db->get('tablename');

//產生: SELECT `field2` FROM (`tablename`)

注意:以下的敘述可以被快取:select、from、join、join、where、like、group by、having、order by、set 。