2013-05-29 26 views
0

我在使用Codeigniter 2.1構建的網站上搜索功能時遇到問題。具體來說,我在分頁和每頁限制15個項目時遇到了問題。如何在CodeIgniter 2.1的數據庫API中實現搜索和分頁?

我的控制器:

   public function program_search() 
      { 
     if ($this->input->post('term')){ 
     $this->front->set('title', 'Search Results'); 
     $this->front->set('res' , $this->wc_search->search($this->input->post('term'))); 

     $this->load->library('pagination'); 

     $config['base_url'] = base_url().'/site/program_search_results/'; 

     $this->db->where('JobRef',$this->input->post('term')); 
     $this->db->or_where('WorkType',$this->input->post('term')); 
     $this->db->or_where('Parish',$this->input->post('term')); 
     $this->db->or_where('Location',$this->input->post('term')); 

     $config['total_rows'] = $this->db->count_all_results('wc_program'); 
     $config['per_page'] = 10; 
     $config['num_links'] = 20; 
     $config['full_tag_open'] = '<div id="pagination">'; 
     $config['full_tag_close'] = '</div>'; 

     $this->pagination->initialize($config);  

     $this->front->buffer('content', 'site/program_search_results'); 
     $this->front->render(); 
    } 
    else 
    { 
     $this->front->set('title', 'Program Search'); 
     $this->front->buffer('content', 'site/program_search'); 
     $this->front->render(); 
    } 
} 

然後在我的模型,我有:

  public function search($term) 
     { 
    $data = array(); 
    $this->default_select(); 
    $this->db->like('JobRef', $term); 
    $this->db->or_like('Area', $term); 
    $this->db->or_like('Parish', $term); 
    $this->db->or_like('WorkType', $term); 
    $this->db->or_like('Location', $term); 

    $this->default_order_by(); 
    //$this->db->limit(15); 
    $q = $this->db->get('wc_program'); 
     if ($q->num_rows() > 0) 
     { 
      foreach ($q->result_array() as $row) 
      { 
       $data[] = $row; 
      } 
     } 
    $q->free_result(); 
    return $data; 
} 

如何獲得分頁合作,開發基於這個代碼?由於搜索工作正常,我不想改變已有的代碼。我只需要它顯示每個頁面15條記錄,查找任何術語。

回答

0

通過你的per_page & NUM_LINKS到搜索()來計算偏移您查詢LIMIT &

你需要做一些簡單的數學計算偏移

+0

你爲什麼這麼說?不知道我明白 –

1

讓我們看看我能走你通過的問題:

  1. 您的搜索查詢需要一個LIMIT(你已經註釋掉...並且它缺少偏移...)。
  2. 您需要將您的POST頁面參數($ this-> input-> post('page'))傳遞給您的搜索模型,以便您知道您處於哪個頁面,以便計算LIMIT部分您的搜索模型的查詢。假設您在您的模型中將其稱爲$ current_page
  3. 爲什麼您的count_all_results查詢不符合您的搜索模型的查詢?它們應該與相同的WHERE條件匹配(除了計數查詢沒有LIMIT您要添加到搜索模型的查詢)。
  4. 計算的LIMIT(極限和偏移量):
    1. $限制= 15;
    2. $ offset = $ limit * $ current_page - $ limit;
    3. 如果($偏移< 0){$偏移= 0;}
  5. 你現在的限制是:$這 - > DB->極限($抵消,$限制);用於搜索模型的查詢。

希望有所幫助!

+0

嗨大衛謝謝你,我會看看如果我可以得到這個功能,也許我會再次重寫代碼,然後,可能會更容易! –

0

正如David Graham所說,你錯過了LIMIT和OFFSET。 CodeIgniter分頁是相當基本的,因爲底層的「ActiveRecord」本身就非常基本(實質上是一個查詢生成器,而不是一個ORM)。

因此,您需要考慮SQL級別,如何獲得所需結果的「頁面」。

下面我包含了來自我的一個項目的示例代碼。

控制器:

// set up pagination 

    $itemsPerPage = 20; 
    $totalItems = $this->Location_model->count_locations($locationName, $locationType, $locationParent); 

    // get itemStartIndex from URL if specified, otherwise default to 0 
    if ($this->uri->segment(3)) 
    { 
     $itemStartIndex = $this->uri->segment(3); 
    } 
    else 
    { 
     $itemStartIndex = '0'; 
    } 

    $this->load->library('pagination'); 

    $config['base_url'] = site_url('admin/locations'); 
    $config['total_rows'] = $totalItems; 
    $config['per_page'] = $itemsPerPage; 
    $config['uri_segment'] = 3; 

    // store offset in case user triggers a function and we want to come back to same page 
    $this->session->set_flashdata('pagination_offset', $itemStartIndex); 

    $this->pagination->initialize($config); 

    $data['pagination'] = $this->pagination->create_links(); 

    // get current locations from database 
    $records = $this->Location_model->get_locations($locationName, $locationType, $locationParent, $itemStartIndex, $itemsPerPage); 

    ... 

    // now $records gets passed to view for display 

MODEL:

function count_locations($locationName = '', $locationType = '', $locationParent = '') 
{ 
    $this->db->select('id'); 
    if ($locationName != '') 
    { 
     $this->db->like('name', $locationName); 
    } 
    if ($locationType != '') 
    { 
     $this->db->where('location_type', $locationType); 
    } 
    if ($locationParent != '') 
    { 
     $this->db->where('parent_id', $locationParent); 
    } 

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

    return $query->num_rows(); 
} 

function get_locations($locationName = '', $locationType = '', $locationParent = '', $startIndex = '0', $limit = '') 
{ 
    $this->db->select('*'); 
    if ($locationName != '') 
    { 
     $this->db->like('name', $locationName); 
    } 
    if ($locationType != '') 
    { 
     $this->db->where('location_type', $locationType); 
    } 
    if ($locationParent != '') 
    { 
     $this->db->where('parent_id', $locationParent); 
    } 

    $this->db->order_by('name', 'asc'); 
    $query = $this->db->get('locations', $limit, $startIndex); 

    if ($query->num_rows() > 0) 
    { 
     return $query; 
    } 
    else 
    { 
     return FALSE; 
    } 
} 

請注意,我的方法做查詢具有可選參數$ startIndex和$限制。這些是強制分頁工作。 URI段(在我的情況下,段3)將直接告訴您的控制器使用什麼OFFSET,並且您指定的per_page轉換爲LIMIT(在我的情況下,我使用$ itemsPerPage存儲,因爲它被多次引用 - 實際上我在我的情況下使用全局值,但爲了便於參考,我在此將其硬編碼)。

請注意,您還需要一個計數方法。你可以使用相同的查詢,加載所有結果,並將其計入控制器中,但我喜歡使用單獨的計數方法,它只使用我的WHERE限制生成最小查詢,並選擇COUNT('id'),它相當大。 (當然缺點是它是一個反模式晾乾,因爲相同的查詢代碼必須對您的計數方法對數據查詢方法來定義兩次,一次和一次)

注意您的代碼

我不會在控制器中指定那些or_where語句,而是會使用描述搜索的方法將它們放入模型中。這種搜索邏輯肯定應該在模型中 - 控制器應該只接受路由,將輸入傳遞給模型,然後設置分頁和查看結果。