Database

CodeIgniter & Database

2019/09/05

簡介

CodeIgniter跟很多框架一樣,也提供了資料庫相關的套件。(詳參: 資料庫參考 / Database Reference)

設定

連結我們前面所用過的資料表,我們將設定設為:

application/config/database.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$active_group = 'default';
$query_builder = TRUE;

$db['default'] = array(
 'dsn' => '',
 'hostname' => 'localhost',
 'username' => 'root',
 'password' => '12345678',
 'database' => 'practice',
 'dbdriver' => 'mysqli',
 'dbprefix' => '',
 'pconnect' => TRUE,
 'db_debug' => TRUE,
 'cache_on' => FALSE,
 'cachedir' => '',
 'char_set' => 'utf8',
 'dbcollat' => 'utf8_general_ci',
 'swap_pre' => '',
 'encrypt' => FALSE,
 'compress' => FALSE,
 'stricton' => FALSE,
 'failover' => array(),
 'save_queries' => TRUE
);

MVC架構

我們在前面介紹過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)

$this->load->database('default');

當我們沒有給任何參數時,CodeIgniter會讀取前面的設定檔,因為我們已經在設定檔中指定沒有參數就使用'default'。所以,也可以寫:

$this->load->database();

application/models/Job_model.php

<?php
class Job_model extends CI_Model {

  public function __construct() {
    $this->load->database('default');
  }
}

Read

首先,先在Controller裡指定所需要的model

application/controllers/Job.php

<?php
class Job extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->model('job_model');
  }

}

application/models/Job_model.php

<?php
class Job_model extends CI_Model {

  public function __construct() {
    $this->load->database();
  }

}

Controller啟動index(),呼叫Model裡的get_job()。

application/controllers/Job.php

<?php
class Job extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->model('job_model');
  }

  public function index() {
    $data['jobs'] = $this->job_model->get_job();
    $data['title'] = 'Job posting';

    $this->load->view('templates/header', $data);
    $this->load->view('job/index', $data);
    $this->load->view('templates/footer');
  }

}

CodeIgniter跟很多web的框架一樣提供了get(),讓我們不必使用SQL語法也可以讀取資料表 (詳參: 查詢生成器類別 / Query Builder Class),也可以直接寫SQL (詳參: 執行查詢 / Running Queries)。

  public function get_job() {
      $query = $this->db->get('job');
      return $query->result();
  }

application/models/Job_model.php

<?php
class Job_model extends CI_Model {

  public function __construct() {
    $this->load->database();
  }

  public function get_job() {
    $query = $this->db->get('job');
    return $query->result();
  }
}

回到Controller,將回傳的內容放進$data['jobs'],再來就啟動view,將回傳的內容傳到view。

application/controllers/Job.php

<?php
class Job extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->model('job_model');
  }

  public function index() {
    $data['jobs'] = $this->job_model->get_job();
    $data['title'] = 'Job posting';

    $this->load->view('templates/header', $data);
    $this->load->view('job/index', $data);
    $this->load->view('templates/footer');
  }

}

view讀取時,就可以讀取到$jobs。

application/views/job/index.php

<div class="container">
   <table class="table table-bordered table-striped">
    <tr>
      <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>
    </tr>
    <?php endforeach ?>
  </table>
</div>

** 注意,CodeIgniter提供了替代 View 檔案的 PHP 的語法 / Alternate PHP Syntax for View Files。其實,用原本的php語法也可以。 也就是

    <?php foreach ($jobs as $job): ?>
    <tr>
      <td><?= $job->company ?></td>
      <td><?= $job->content ?></td> 
      <td><?= $job->pdate ?></td>
    </tr>
    <?php endforeach ?>

等同

    <?php foreach ($jobs as $job){ ?>
    <tr>
      <td><?= $job->company ?></td>
      <td><?= $job->content ?></td> 
      <td><?= $job->pdate ?></td>
    </tr>
    <?php } ?>

如果點了View job,要讀其中一筆資料,就呼叫view,並傳遞postid。跟很多框架一樣,可以不使用傳統的做法,直接利用"/"隔開,即可傳參數。

<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="view/<?= $job->postid ?>">閱讀內容</a></td>
    </tr>
    <?php endforeach ?>
  </table>
</div>

呼叫view並且傳postid

application/controllers/Job.php

<?php
class Job extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->model('job_model');
  }

  public function index() {
    $data['jobs'] = $this->job_model->get_job();
    $data['title'] = 'Job posting';

    $this->load->view('templates/header', $data);
    $this->load->view('job/index', $data);
    $this->load->view('templates/footer');
  }

  public function view($postid = NULL){
    $data['job'] = $this->job_model->get_job($postid);
  
    if (empty($data['job'])) {
      show_404();
    }
  
    $data['title'] = $data['job']->company;
  
    $this->load->view('templates/header', $data);
    $this->load->view('job/view', $data);
    $this->load->view('templates/footer');
  }

}

CodeIgniter提供get_where()及row()來簡化讀取資料表 (詳參: 查詢生成器類別 / Query Builder Class)。

    $query = $this->db->get_where('job', array('postid' => $postid));
    return $query->row();

application/models/Job_model.php

<?php
class Job_model extends CI_Model {

  public function __construct() {
    $this->load->database();
  }

  public function get_job($postid = FALSE) {
    if ($postid === FALSE) {
      $query = $this->db->get('job');
      return $query->result();
    }

    $query = $this->db->get_where('job', array('postid' => $postid));
    return $query->row();
  }

}

取得資料後回傳到controller,controller再把資料傳到view。

application/controllers/Job.php

<?php
class Job extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->model('job_model');
  }

  public function index() {
    $data['jobs'] = $this->job_model->get_job();
    $data['title'] = 'Job posting';

    $this->load->view('templates/header', $data);
    $this->load->view('job/index', $data);
    $this->load->view('templates/footer');
  }

  public function view($postid = NULL){
    $data['job'] = $this->job_model->get_job($postid);
  
    if (empty($data['job'])) {
      show_404();
    }
  
    $data['title'] = $data['job']->company;
  
    $this->load->view('templates/header', $data);
    $this->load->view('job/view', $data);
    $this->load->view('templates/footer');
  }

}

application/views/job/view.php

<?php
echo '<h2>'.$job->company.'</h2>';
echo $job->content.'<p>';
echo $job->pdate.'<p>';

** 作業 **