W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在上一個(gè)章節(jié)里,我們寫了一個(gè)用于展示靜態(tài)頁面的類文件,通過這個(gè)簡(jiǎn)單的例子我們把CI4框架里的一些基本的概念講解了一下。 我們還簡(jiǎn)單的使用了CI4里面的路由功能,通過自定義路由規(guī)則實(shí)現(xiàn)了頁面的鏈接地址凈化,使頁面的訪問地址看起來更整潔和搜索引擎友好。 現(xiàn)在,我們要開始進(jìn)行一些基于數(shù)據(jù)庫(kù)的動(dòng)態(tài)內(nèi)容的開發(fā)了。
我們假設(shè)你已經(jīng)安裝和 配置 好了用于 CodeIgniter4 運(yùn)行所需的數(shù)據(jù)庫(kù)軟件。 我們也假設(shè)你會(huì)使用數(shù)據(jù)庫(kù)管理的客戶端工具(mysql,MySQL Workbench或者phpMyAdmin等)來運(yùn)行稍后教程里提供的創(chuàng)建數(shù)據(jù)庫(kù)表和插入測(cè)試數(shù)據(jù)所需的SQL代碼。
下面我們就來教你如何為本教程創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),并且正確配置CodeIgniter來使用這個(gè)數(shù)據(jù)庫(kù)。
用你安裝好的數(shù)據(jù)庫(kù)客戶端工具打開數(shù)據(jù)庫(kù),然后運(yùn)行下面的兩段SQL代碼(MySQL適用)來創(chuàng)建一個(gè)數(shù)據(jù)表和插入一些測(cè)試數(shù)據(jù)。 隨著你對(duì) CodeIgniter 的熟悉程度越來越高,這些數(shù)據(jù)庫(kù)相關(guān)的操作也可以通過程序代碼在CodeIgniter框架下完成,你可以閱讀W3Cschool SQL 教程來了解相關(guān)內(nèi)容,以便掌握用程序代碼操作數(shù)據(jù)庫(kù)的相關(guān)技能。
CREATE TABLE news (
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(128) NOT NULL,
slug varchar(128) NOT NULL,
body text NOT NULL,
PRIMARY KEY (id),
KEY slug (slug)
);
Note: 數(shù)據(jù)表里的 slug 字段在基于互聯(lián)網(wǎng)訪問的網(wǎng)站上是個(gè)非常有用的字段。 一般在這個(gè)字段里存放簡(jiǎn)短的詞語來概括性描述數(shù)據(jù)內(nèi)容,這將提升用戶打開網(wǎng)址時(shí)候的訪問體驗(yàn),并且這種網(wǎng)址也是搜索引擎友好的網(wǎng)址,有利于網(wǎng)站內(nèi)容的SEO優(yōu)化。
然后我們?cè)跀?shù)據(jù)表里插入如下測(cè)試數(shù)據(jù):
INSERT INTO news VALUES
(1,'Elvis sighted','elvis-sighted','Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.'),
(2,'Say it isn\'t so!','say-it-isnt-so','Scientists conclude that some programmers have a sense of humor.'),
(3,'Caffeination, Yes!','caffeination-yes','World\'s largest coffee shop open onsite nested coffee shop for staff only.');
CodeIgniter安裝時(shí)會(huì)自動(dòng)生成一個(gè) .env
文件,確保里面的配置信息沒有被注釋掉,并且和你本地的數(shù)據(jù)庫(kù)實(shí)際情況相吻合:
database.default.hostname = localhost
database.default.database = ci4tutorial
database.default.username = root
database.default.password = root
database.default.DBDriver = MySQLi
我們要求你將數(shù)據(jù)庫(kù)的操作代碼寫在模型(Model)文件里面,以便以后代碼重用,不要將這些代碼寫在控制器(Controller)里。 你的模型文件們應(yīng)該成為你處理數(shù)據(jù)庫(kù)相關(guān)的增、刪、改、查操作的默認(rèn)地方。交由模型文件來操作數(shù)據(jù)庫(kù)或者其他格數(shù)的數(shù)據(jù)文件。
打開 app/Models/ 目錄,在這個(gè)目錄下面創(chuàng)建一個(gè)名字為 NewsModel.php 的文件,并在文件里加入如下代碼。 為了保證代碼運(yùn)行順利,你需要確認(rèn)一下已經(jīng)正確的完成了數(shù)據(jù)庫(kù)的相關(guān)配置 。
<?php
namespace App\Models;
class NewsModel extends \CodeIgniter\Model
{
protected $table = 'news';
}
這段代碼和我們上一個(gè)章節(jié)里創(chuàng)建的控制器里的代碼類似。 我們通過繼承CodeIgniterModel
創(chuàng)建了一個(gè)新的模型文件,并加載了CI4內(nèi)置的數(shù)據(jù)庫(kù)操作類庫(kù)。 后面我們可以在代碼里通過$this->db
來調(diào)用數(shù)據(jù)庫(kù)的相關(guān)操作類庫(kù)。
現(xiàn)在我們的數(shù)據(jù)庫(kù)和數(shù)據(jù)模型文件已經(jīng)建立好了。 我們首先寫一個(gè)方法從數(shù)據(jù)庫(kù)中獲取所有的新聞文章。 為實(shí)現(xiàn)這點(diǎn),我們將使用 CodeIgniter 的數(shù)據(jù)庫(kù)抽象層工具 查詢構(gòu)建器,通過它你可以編寫你的查詢代碼,并在所有支持的數(shù)據(jù)庫(kù)平臺(tái)上運(yùn)行。 數(shù)據(jù)模型文件可以方便的和 查詢構(gòu)建器 一起工作,并且提供了一些方法讓你操作數(shù)據(jù)的時(shí)候更加簡(jiǎn)單?,F(xiàn)在向你的模型中添加如下代碼。
public function getNews($slug = false)
{
if ($slug === false)
{
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
通過這段代碼,你可以執(zhí)行兩種不同的查詢,一種是獲取所有的新聞條目,另一種是根據(jù)特定的 slug 來獲取指定的新聞條目。 你可能注意到了,我們直接的進(jìn)行了基于$slug
變量的數(shù)據(jù)對(duì)比命令,并不需要預(yù)先執(zhí)行相應(yīng)字段的查詢操作,因?yàn)椴樵儤?gòu)建器自動(dòng)幫我們完成了這個(gè)工作。
我們?cè)谶@里用到的 findAll()
和 first()
都是 CodeIgniter4 的數(shù)據(jù)模型(Model)基礎(chǔ)類里面內(nèi)置的方法。 他們根據(jù)我們?cè)跀?shù)據(jù)模型文件里(本例中是 NewsModel 文件)聲明的$table
變量而知道該對(duì)哪個(gè)數(shù)據(jù)表進(jìn)行操作。 這些方法通過 查詢構(gòu)建器 運(yùn)行指令操作當(dāng)前數(shù)據(jù)表,并且會(huì)以數(shù)組的形式返回?cái)?shù)據(jù)查詢結(jié)果。在這個(gè)例子里面,findAll()
的返回值是包含了指定數(shù)據(jù)表中的所有數(shù)據(jù)對(duì)象的一個(gè)數(shù)組。
現(xiàn)在,查詢已經(jīng)在數(shù)據(jù)模型文件里寫好了,接下來我們需要將數(shù)據(jù)模型綁定到視圖上,向用戶顯示新聞條目了。 這可以在之前寫的 Pages
控制器里來做,但為了更清楚的闡述,我們定義了一個(gè)新的 News
控制器,創(chuàng)建在 app/controllers/News.php 文件中。
<?php namespace App\Controllers;
use App\Models\NewsModel;
class News extends \CodeIgniter\Controller
{
public function index()
{
$model = new NewsModel();
$data['news'] = $model->getNews();
}
public function view($slug = null)
{
$model = new NewsModel();
$data['news'] = $model->getNews($slug);
}
}
閱讀上面的代碼你會(huì)發(fā)現(xiàn),這和之前寫的代碼有些相似之處。 首先,它繼承了CodeIgniter的一個(gè)核心類,Controller
,這個(gè)核心類提供了很多非常有用的方法,它確保你可以操作當(dāng)前的 Request
和 Response
對(duì)象,也可以操作Logger
類, 方便你把日志文件寫到磁盤里。
其次,有兩個(gè)方法用來顯示新聞條目,一個(gè)顯示所有的,另一個(gè)顯示特定的。 你可以看到第二個(gè)方法中調(diào)用模型方法時(shí)傳入了 $slug
參數(shù),模型根據(jù)這個(gè) slug 返回特定的新聞條目。
現(xiàn)在,通過模型,控制器已經(jīng)獲取到數(shù)據(jù)了,但還沒有顯示出來。 下一步要做的就是將數(shù)據(jù)傳遞給視圖。 我們修改 index()
方法成下面的樣子::
public function index()
{
$model = new NewsModel();
$data = [
'news' => $model->getNews(),
'title' => 'News archive',
];
echo view('templates/header', $data);
echo view('news/index', $data);
echo view('templates/footer');
}
上面的代碼從模型中獲取所有的新聞條目,并賦值給一個(gè)變量(news)。 另外頁面的標(biāo)題賦值給了 $data['title']
元素,然后所有的數(shù)據(jù)被傳遞給視圖。 現(xiàn)在你需要?jiǎng)?chuàng)建一個(gè)視圖文件來顯示新聞條目了,新建 app/Views/news/index.php 文件并添加如下代碼。
<h2><?= $title ?></h2>
<?php if (! empty($news) && is_array($news)) : ?>
<?php foreach ($news as $news_item): ?>
<h3><?= $news_item['title'] ?></h3>
<div class="main">
<?= $news_item['text'] ?>
</div>
<p><a href="<?= '/news/'.$news_item['slug'] ?>">View article</a></p>
<?php endforeach; ?>
<?php else : ?>
<h3>No News</h3>
<p>Unable to find any news for you.</p>
<?php endif ?>
這里,我們通過一個(gè)循環(huán)將所有的新聞條目顯示給用戶,你可以看到我們直接采用了 HTML 和 PHP 混用的寫法創(chuàng)建了一個(gè)視圖頁面。 如果你希望使用一種模板語言,你可以使用 CodeIgniter 的 視圖模版解析類 <../outgoing/view_parser> ,或其他的第三方解析器。
新聞的列表頁就做好了,但是我們還缺少一個(gè)顯示特定新聞條目的頁面。 我們可以調(diào)用之前創(chuàng)建的模型里的數(shù)據(jù)來實(shí)現(xiàn)這個(gè)功能,你只需要向控制器中添加一些代碼,然后再新建一個(gè)視圖就可以了。 回到 News
控制器,使用下面的代碼替換掉 view()
方法:
public function view($slug = NULL)
{
$model = new NewsModel();
$data['news'] = $model->getNews($slug);
if (empty($data['news']))
{
throw new \CodeIgniter\PageNotFoundException('Cannot find the page: '. $slug);
}
$data['title'] = $data['news']['title'];
echo view('templates/header', $data);
echo view('news/view', $data);
echo view('templates/footer');
}
我們并沒有直接調(diào)用 getNews()
方法,而是傳入了一個(gè) $slug
參數(shù),所以它會(huì)返回相應(yīng)的新聞條目。 最后剩下的事是創(chuàng)建視圖文件 app/Views/news/view.php
并添加如下代碼 。
<?php echo ‘<h2>’.$news[‘title’].’</h2>’; echo $news[‘body’];
由于之前我們創(chuàng)建了基于通配符的路由規(guī)則,所以現(xiàn)在需要新增一條路由以便能訪問到你剛剛創(chuàng)建的控制器。 修改路由配置文件(app/config/routes.php)添加類似下面的代碼。 該規(guī)則可以讓地址中帶news的請(qǐng)求訪問 News
控制器而不是去訪問之前默認(rèn)的 Pages
控制器。 第一行代碼可以讓訪問 news/slug 地址的 URI 重定向到 News 控制器的 view() 方法。
$routes->get('news/(:segment)', 'News::view/$1');
$routes->get('news', 'News::index');
$routes->get('(:any)', 'Pages::view/$1');
在地址欄里輸入 localhost:8080/news 來訪問你創(chuàng)建好的新聞列表頁面吧。 你將會(huì)看到如下圖一樣的一個(gè)展示新聞列表的網(wǎng)頁,列表里的每個(gè)文章都帶一個(gè)可以打開該條新聞詳情頁面的超級(jí)鏈接。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: