教程 ? 讀取新聞條目
在上一節(jié)中,我們通過如何寫出一個包含靜態(tài)頁面的類來了解了一些這個框架的基本概念。我們也根據(jù)自定義路由規(guī)則重新梳理了URI?,F(xiàn)在是時候向大家介紹動態(tài)內(nèi)容和如何使用數(shù)據(jù)庫了。
創(chuàng)建你的數(shù)據(jù)模型
數(shù)據(jù)庫的運算并不是在控制類中進行的,而是在數(shù)據(jù)模型中,這樣他們就可以在后面很容易地被反復使用。數(shù)據(jù)模型就是對你的數(shù)據(jù)庫或其他數(shù)據(jù)存儲方式進行取回、插入和更新的地方,它們的功能是展示你的數(shù)據(jù)(They represent your data)。
打開 application/models 文件夾新建一個文件 news_model.php ,代碼如下。確保你已經(jīng)按照 這里的說明配置了自己的數(shù)據(jù)庫。
<?php class News_model extends CI_Model { public function __construct() { $this->load->database(); } }
這段代碼和早前寫過的控制器的代碼類似。它創(chuàng)建了一個繼承 CI_Model 的數(shù)據(jù)模型,并用來載入數(shù)據(jù)庫。通過 $this->db 對象就可以使用數(shù)據(jù)庫類了。
在對數(shù)據(jù)庫進行查詢前,我們要先建一個數(shù)據(jù)表。連接你的數(shù)據(jù)庫并執(zhí)行下面的 SQL 命令,并在里面加些內(nèi)容。
CREATE TABLE news ( id int(11) NOT NULL AUTO_INCREMENT, title varchar(128) NOT NULL, slug varchar(128) NOT NULL, text text NOT NULL, PRIMARY KEY (id), KEY slug (slug) );
現(xiàn)在數(shù)據(jù)庫和數(shù)據(jù)模型都設(shè)置好了,我們需要一個方法來把我們的文章從數(shù)據(jù)庫中讀取出來。數(shù)據(jù)庫抽象層已經(jīng)包含在CodeIgniter的 Active Record模式 中了。這樣可以確保只寫一次查詢就可以應(yīng)用到 所有的數(shù)據(jù)庫系統(tǒng)上。在你的數(shù)據(jù)庫模型中添加如下代碼。
public function get_news($slug = FALSE) { if ($slug === FALSE) { $query = $this->db->get('news'); return $query->result_array(); } $query = $this->db->get_where('news', array('slug' => $slug)); return $query->row_array(); }
通過上面的代碼可以實現(xiàn)兩個不同的查詢,你可以得到所有的新聞紀錄,也可以通過 slug得到某一篇新聞。你可能注意到了 $slug 變量在查詢前并沒有被檢驗過(sanitized),因為Active Record類已經(jīng)把這個工作做完啦。
顯示新聞
既然查詢已經(jīng)寫完了,我們就要把這個數(shù)據(jù)模型和用來顯示新聞內(nèi)容的視圖聯(lián)系起來了。其實這個工作在我們之前寫的pages控制類中就可以實現(xiàn),但為了更清楚地向大家說明,我們來定義一個新的news控制類 application/controllers/news.php,代碼如下。
<?php class News extends CI_Controller { public function __construct() { parent::__construct(); $this->load->model('news_model'); } public function index() { $data['news'] = $this->news_model->get_news(); } public function view($slug) { $data['news'] = $this->news_model->get_news($slug); } }
看看上面的代碼就會發(fā)現(xiàn)和我們之前寫過的文件相似。首先,__construct方法是父級類 (CI_Controller) 的構(gòu)造函數(shù),并調(diào)用了數(shù)據(jù)模型,這樣這個控制器中的其他方法就能使用那個數(shù)據(jù)模型了。
其次,這里有兩個方法分別用來顯示所有的新聞和某一條。在第二個方法中可以看到 $slug 變量被傳遞給了數(shù)據(jù)模型中的方法。數(shù)據(jù)模型就是用這個slug來確定需要返回哪一篇文章的。
現(xiàn)在通過數(shù)據(jù)模型,數(shù)據(jù)已經(jīng)被控制器獲得了,但還無法顯示出來。下面我們就要把數(shù)據(jù)傳遞給視圖了。
public function index() { $data['news'] = $this->news_model->get_news(); $data['title'] = 'News archive'; $this->load->view('templates/header', $data); $this->load->view('news/index', $data); $this->load->view('templates/footer'); }
上面的代碼從數(shù)據(jù)模型中獲得了所有新聞的記錄,并把它們賦值給了一個變量。頁面的標題也賦給了 $data['title'] ,這些所有的數(shù)據(jù)都會傳遞給視圖?,F(xiàn)在你需要創(chuàng)建一個視圖來顯示這些新聞。新建 application/views/news/index.php 代碼如下。
<?php foreach ($news as $news_item): ?> <h2><?php echo $news_item['title'] ?></h2> <div id="main"> <?php echo $news_item['text'] ?> </div> <p><a href="news/<?php echo $news_item['slug'] ?>">View article</a></p> <?php endforeach ?>
在這里,每條新聞都被循環(huán)出來展示給讀者了。你可以看到我們的模板是用PHP和HTML混著寫的,如果你更喜歡用模板語言的話,你可以用CodeIgniter的 模板解析器類 或者第三方模板解析器(模板引擎)。
新聞概述頁面已經(jīng)做好了,現(xiàn)在還缺少每一篇文章的頁面。之前寫好的數(shù)據(jù)模型現(xiàn)在就可以非常簡單地用來實現(xiàn)這個功能啦。你只需要添加一些代碼到控制器并且創(chuàng)建一個視圖。把下面的代碼添加到news控制器中。
public function view($slug) { $data['news_item'] = $this->news_model->get_news($slug); if (empty($data['news_item'])) { show_404(); } $data['title'] = $data['news_item']['title']; $this->load->view('templates/header', $data); $this->load->view('news/view', $data); $this->load->view('templates/footer'); }
這里,$slug 變量作為參數(shù)傳遞給了 get_news() 方法,這樣就可以返回特定的某一篇文章了?,F(xiàn)在剩下的一件事就是創(chuàng)建視圖 application/views/news/view.php了,代碼如下。
<?php echo '<h2>'.$news_item['title'].'</h2>'; echo $news_item['text'];
設(shè)置路由
因為之前設(shè)置的通配符路由路由規(guī)則,現(xiàn)在你需要額外的路由來顯示剛剛寫的控制器。按照下面的代碼修改你的路由文件 (application/config/routes.php) ,這樣就確保了請求調(diào)用的是news控制器而不是之前設(shè)置的pages控制器。第一行代碼表示的是控制器中通過slug讀取的那條新聞。
$route['news/(:any)'] = 'news/view/$1'; $route['news'] = 'news'; $route['(:any)'] = 'pages/view/$1'; $route['default_controller'] = 'pages/view';
把瀏覽器的地址改回根目錄,在后面加上 index.php/news 來看看你的新聞頁面吧。
?