Codeigniter3 與 Codeigniter4 的差別
在2020/02/24時,Codeigniter4已經釋出了。由於我從之前的案子就用Codeigniter2開始一直用到Codeigniter3
所以自然也想知道Codeigniter4與之前的版本有什麼樣的差異。
PHP版本支援
首先,現來看一下PHP的版本支援
| 版本 | Codeigniter3 | Codeigniter4 | 
|---|---|---|
| 建議版本 | PHP5.6以上 | PHP7.2以上 | 
所以要將現有案子直接升級到4的人,可能要注意一下原本的寫法是否有被支援了。
資料夾結構
接著來看一下資料夾的結構。
可以看得出來資料夾的結構有以下的改變
| 版本 | Codeigniter3 | Codeigniter4 | 
|---|---|---|
| 資料夾名 | 開頭小寫 | 開頭大寫 | 
| 存取用資料夾 | 自訂 | 預設為writable | 
| index.php | 專案底下 | public內 | 
Coding Style
推薦的CodingStyle也有著完全不同的變化
| 版本 | Codeigniter3 | Codeigniter4 | 
|---|---|---|
| 類別命名 | snake case | camel case | 
| 方法命名 | snake case | camel case | 
| 方法命名建議 | getX -> 返回null或值 isX -> 返回布林代數 hasX -> 返回布林代數 etc..  | 
這次的改版也支援了 namespace 的類別命名,在命名上可以有更多的空間
此外除了以上幾點有興趣的可以直接看 這裡
Filter 功能
在這次的改版當中有個很重要的一點,就是追加了 Filter 。
從Codeigniter.php裡面可以看到在 Filter 被加在 Controller 的前後,分別有 beforFilter 與 afterFilter
這可以方便我們在進入 Controller 前進行一些方法與值的驗證。
Controller 的改變
接著,我們利用官方給的範例來看看 Controller 在執行上有什麼樣的改變。
首先是 CI3
<?php
class News extends CI_Controller {
        public function __construct()
        {
                parent::__construct();
                $this->load->model('news_model');
                $this->load->helper('url_helper');
        }
        public function index()
        {
                $data['news'] = $this->news_model->get_news();
        }
        public function view($slug = NULL)
        {
                $data['news_item'] = $this->news_model->get_news($slug);
        }
}
再來是 CI4
<?php namespace App\Controllers;
use App\Models\NewsModel;
use CodeIgniter\Controller;
class News extends Controller
{
    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
            parent::initController($request, $response, $logger);
    }
    public function index()
    {
        $model = new NewsModel();
        $data['news'] = $model->getNews();
    }
    public function view($slug = null)
    {
        $model = new NewsModel();
        $data['news'] = $model->getNews($slug);
    }
}
很明顯的,在 model 的引入有了截然不同的改變。在3中的load方法在4中已經沒有被使用,取而代之的是直接實體化class來進行調用。
建構子也從 __construct() 改為 initController() 。
Routing 寫法改變
在寫 Route 的時候,有著巨大的改變,變得比較簡潔易用了!
| 版本 | Codeigniter3 | Codeigniter4 | 
|---|---|---|
| 寫法 | $route[‘news/(:any)’] = ‘news/view/$1’; | $routes->get(‘news/(:any)’, ‘News::view/$1’); | 
方便的共通方法 service
在這次的共通方法中,我們可以透過service方法來呼叫已經引入的套件,例如常用的 validation 或是 csrf 驗證等等
<?=service('validation')->listErrors()?>
<form action="<?=base_url() . '/try'?>" method="POST">
  <label>testInput:</label><input type="text" name="testInput" />
  <input type="submit" value="submit" />
  <input type="hidden" name="<?=service('security')->getCSRFTokenName()?>" value="<?=service('security')->getCSRFHash()?>"/>
</form>
支援 .env 設定
我現在在Codeigniter3上都利用環境變數讓讀取config時到不同資料夾去。
在Codeigniter4就不用這麼麻煩了,建立一個.env就能搞定一切!
總結
其實整個概括的流程上其實並沒有太大的變動,但是在整個寫法上我認為有很大的改變。
比起2升到3還要改變的多很多,要熟悉可能還需要一點時間,現在在 Laravel 強勢的時候,Codeigniter 是否能夠挽回一點頹勢呢
讓我們拭目以待。我將這次練習的程式碼放到 github 上了,有興趣的人可以看看:P