2019/09/05
2024/12/11 (內容更新)
CodeIgniter跟很多框架一樣,也提供了資料庫相關的套件。
連結我們前面所用過的mysql資料表,建議使用.env來儲存設定,使用.env的好處是,我們可以將.env列在.gitignore裡,在程式碼上傳到github時,資料庫的帳號密碼就不會被其他人取得。
首先,將「env」複製一份,並將名稱設為「.env」。
database.default.hostname = localhost
database.default.database = practice
database.default.username = root
database.default.password = myPassword
database.default.DBDriver = MySQLi
# database.default.DBPrefix =
database.default.port = 3306
我們在前面介紹過Controller以及View,接下來,我們要介紹Model,將程式邏輯切為這三個部份就稱為MVC架構,現在很多web的框架都遵循MVC架構,CodeIgniter也是。
Model通常是包括資料庫及商業邏輯,跟web的操作(controller)與介面(view)是分離的,好處是如果以後前端不再流行web介面,只要改寫controller及view。甚至model可以被不同的controller及view使用。所以,現在的框架都會採用MVC架構。
另外,很多公司的分工不是依功能分工,而是將前端跟後端分開,精熟前端(尤其是javascript)的負責View,精熟後端(尤其是資料庫以及商業邏輯)的負責Model,中間再利用Controller串連起來,所以,會把系統依MVC切割。
CodeIgniter提供了一些比傳統php方便的一些library。例如,當我們要建立資料庫連結時,我們就可以利用: (詳參: 連接您的資料庫 / Connecting to your Database)
CodeIgniter提供了不同的查詢方式
我們先利用查詢,將讀取結果放到Associative Array裡,在CodeIgniter會自動關閉資料庫的連結,所以,不需要主動關閉。
<?php
$db = \Config\Database::connect();
$query = $db->query('select * from job');
$results = $query->getResultArray();
foreach ($results as $row) {
echo $row['company'];
echo $row['content'];
echo $row['pdate'];
}
這一行
$db = \Config\Database::connect();
也可以寫成
$db = db_connect();
再MVC的架構下,通常在Controller取得資料,再將資料傳到View。
app/Controllers/Jobs.php
<?php
namespace App\Controllers;
class Jobs extends BaseController
{
public function index()
{
// $db = \Config\Database::connect();
$db = db_connect();
$query = $db->query('select * from job');
$results = $query->getResultArray();
$data['title'] = '職缺列表';
$data['results'] = $results;
return view('templates/header', $data)
. view('pages/query', $data)
. view('templates/footer');
}
}
記得要在app/Config/Routes.php裡,加上:
$routes->get('jobs', 'Jobs::index');
我們先加一個
app/Views/pages/query.php
<?php
foreach ($results as $row) {
?>
<?= $row['company'] ?><br>
<?= $row['content'] ?><br>
<?= $row['pdate'] ?><br>
<?php
}
?>
這樣就可以取得資料庫裡的內容了。
使用大括號其實不容易閱讀,可以使用另一種寫法:
<?php
foreach ($results as $row):?>
<?= $row['company'] ?><br>
<?= $row['content'] ?><br>
<?= $row['pdate'] ?><br>
<?php endforeach ?>
如果點了「閱讀內容」去讀其中一筆資料,就呼叫view,並傳遞postid。跟很多框架一樣,可以不使用傳統的做法,直接利用"/"隔開,即可傳參數。
app/Views/pages/query.php
<div class="container">
<table class="table table-bordered table-striped">
<tr>
<th>求才廠商</th>
<th>求才內容</th>
<th>求才日期</th>
<th>功能</th>
</tr>
<?php foreach ($jobs as $job): ?>
<tr>
<td><?= $job->company ?></td>
<td><?= $job->content ?></td>
<td><?= $job->pdate ?></td>
<td><a href="jobs/<?= $job->postid ?>">閱讀內容</a></td>
</tr>
<?php endforeach ?>
</table>
</div>
要透過呼叫jobs並且傳postid,記得要在app/Config/Routes.php裡,加上:
$routes->get('jobs', 'Jobs::index');
$routes->get('jobs/(:segment)', [Jobs::class, 'view']);
app/Controllers/Jobs.php
<?php
namespace App\Controllers;
class Jobs extends BaseController
{
public function index()
{
// $db = \Config\Database::connect();
$db = db_connect();
$query = $db->query('select * from job');
$results = $query->getResultArray();
$data['title'] = '職缺列表';
$data['results'] = $results;
return view('templates/header', $data)
. view('pages/query', $data)
. view('templates/footer');
}
public function view(int $id)
{
// $db = \Config\Database::connect();
$db = db_connect();
$query = $db->query('select * from job where postid=' . $id);
$results = $query->getResultArray();
$data['title'] = '職缺列表';
$data['results'] = $results;
return view('templates/header', $data)
. view('pages/query', $data)
. view('templates/footer');
}
}
目前只用到了Controller及View,還沒用到Model,使用Model主要的原因是要把資料庫及商業邏輯從Controller裡分離出來。我們先看看要如何建構Model,在CodeIgniter裡,提供了一些功能讓Model的開發更容易。
首先,我們先建立一個Model。app/Models/JobModel.php,連接「job」資料表。
<?php
namespace App\Models;
use CodeIgniter\Model;
class JobModel extends Model
{
protected $table = 'job';
}
加上一個getJobs的方法,利用findAll()取得所有資料,利用where()設定條件,利用first()取得第一筆資料。CodeIgniter (事實上是Model類別)會去組合sql語法,並去執行sql語法,取得資料。
<?php
namespace App\Models;
use CodeIgniter\Model;
class JobModel extends Model
{
protected $table = 'job';
public function getJobs($postid = false)
{
if ($postid === false) {
return $this->findAll();
}
return $this->where(['postid' => $postid])->first();
}
}
Model設定好之後,可以利用Model取代原本在Controller裡資料庫的對應程式,先處理index():
app/Controllers/Jobs.php
public function index()
{
$model = model(JobModel::class);
$data['results'] = $model->getJobs();
$data['title'] = '職缺列表';
return view('templates/header', $data)
. view('pages/query', $data)
. view('templates/footer');
}
View完全不用改。
接下來我們來處理view()裡面的程式:
public function view($id=null)
{
$model = model(JobModel::class);
$data['job'] = $model->getJobs($id);
$data['title'] = '職缺列表';
return view('templates/header', $data)
. view('pages/queryOne', $data)
. view('templates/footer');
}
app/Controllers/Jobs.php
<?php
namespace App\Controllers;
use App\Models\JobModel;
class Jobs extends BaseController
{
public function index()
{
$model = model(JobModel::class);
$data['results'] = $model->getJobs();
$data['title'] = '職缺列表';
return view('templates/header', $data)
. view('pages/query', $data)
. view('templates/footer');
}
public function view($id=null)
{
$model = model(JobModel::class);
$data['job'] = $model->getJobs($id);
// log_message('debug', 'results: ' . print_r($data['results'], true));
$data['title'] = '職缺列表';
return view('templates/header', $data)
. view('pages/queryOne', $data)
. view('templates/footer');
}
}
我們增加一個app/Views/pages/queryOne.php
<div class="container">
<table class="table table-bordered table-striped">
<tr>
<th>求才廠商</th>
<th>求才內容</th>
<th>求才日期</th>
</tr>
<tr>
<td><?= $job['company'] ?></td>
<td><?= $job['content'] ?></td>
<td><?= $job['pdate'] ?></td>
</tr>
</table>
</div>
接下來,可以參考
完成新增及修改。