2022 年 9 月 20 日

[教學] CodeIgniter 4 快速上手 (四) 建立簡易最新消息-更新與刪除篇

本篇目錄

我們已經教了CodeIgniter 4 的新增讀取,這一篇我們要來完成CRUD裡的最後兩步驟,也就是U的Update 更新與D的Delete 刪除,這兩個都屬於單篇內容控制的部分,我們先從比較複雜的更新來講起吧!

Step1. 取得單篇消息內容並放到view裡

還記得我們在讀取篇改view的時候有特別提到update的連結是要寫 /news/edit/id 嗎?連結中的 edit 就是function名稱的意思,也就是說我們要建立一個edit function 在 controller 裡!所以打開app > Controllers > News.php 在裡面新增 function 名為 edit,並且得帶上變數 $id :

public function edit($id){
    $model = new NewsModel();
    return view('form');
}

在function 名稱後面的括號了設定變數 $id,就會自動把網址列上的id 帶到function裡,不需要自己在$_Get 變數。接著我們要呼叫 Model 的來幫我們撈出我們要的那一篇內容,所以打開 app > Model > NewsModel.php ,我們已經有getNews ,但它現在只會撈全部,我們要它但有 id 時取 id 那一篇,沒 id 時取全部,所以跟 controller 的 function edit 一樣,我們要帶 $id 進去 model function 裡, 然後因為沒有 $id 時要撈全部,所 $id 要有一個預設值,因為我們要用 if 來判斷,所以乾脆 $id 預設值就給它 fasle 吧!

// read
public function getNews($id = false){
    if($id===false){
        return $this->orderBy('id', 'desc')->findAll();
    }else{
        return $this->getWhere(['id' => $id]);
    } 
}

這裡的判斷我們用完全等於 (===) ,所以一旦 $id 肯定 100% 是 false 時,我們就撈全部,不是 false 我們就撈單篇。設定好我們的 model 之後,我們在回去改我們的 controller

public function edit($id){
   $model = new NewsModel();
   $data['news'] = $model->getNews($id)->getRow();
   return view('form',$data);
}

透過 getNews($id) 將 $id 傳到model 然後取回一行的資料。

這時我們可以跟讀取的教學一樣,到測試站,找一篇按下Update,使用 CodeIgniter的Debug tool ,切換到Vars 分頁:

$news 變數裡的資料

你就會看到在Vars 分頁裡有一個 $news 變數,展開後會發現裡面有五筆資料,剛好對應資料表的5個欄位,到這裡我們就可以處理view的資料顯示問題。

打開 Views 裡的 form.php 做以下調整:

<form action="" method="post">
    <label for="title">title:</label>
    <input type="text" name="title" value="<?= $news->title;?>">
    <label for="content">content:</label>
    <textarea name="content" id="" cols="30" rows="10"><?= $news->content;?></textarea>
    <input type="submit" value="submit">
</form>

你可以發現這次將資料寫入畫面與之前的 $list['title'] 不太一樣,那是因為上次的 $list 是陣列屬性,而這次則是 stdClass 的物件屬性,在取物件內的值時,我們是用 -> 的方式來指定我們所需要的資料名稱,這兩者的差別就在這裡,如果你對這兩種的概念還是很模糊,那你只要記得在Vars 分頁裡看到 array 就是 $list['title'] 這樣的用法,如果是stdClass 就是用 $list->title 這樣的用法。

現在我們把資料撈出來了,然後也顯示在畫面上了,下一步我們就是要取得修改後的資料,然後存回資料庫!

Step2. 更新資料到資料庫中並回到列表確定顯示結果

還記得我們在新增時寫過一個 if 判斷嗎? 如果有 POST 資料則新增到資料庫,其他則顯示 form 畫面,在這裡我們要用一樣的 if 邏輯判斷, 如果有 post資料我們就更新資料庫,如果沒有折顯示 form 的畫面帶上資料,所以我們的 contorller eidt function 就會變成一下模樣:

public function edit($id){
        if($_POST){
            $model = new NewsModel();
            $data=[
                'title' => $this->request->getVar('title'),
                'content'  => $this->request->getVar('content'),
                'updateTime' => date('Y-m-d H:i:s')
            ];
            $model->update($id,$data);
            return redirect()->to(base_url('news')); 
        }else{
            $model = new NewsModel();
            $data['news'] = $model->getNews($id)->getRow();
            return view('form',$data);
        }
    }

如果有post 資料,那我們建立一個新的$model 變數是採用 NewsModel,然後創立一個$data陣列,把我們要更新的title 、 content 與 updateTime 3個欄位的資料放到 $data 陣列裡,然後我們在透過model 內見的update function 將這 3欄資料更新進去,這樣就可以完成資料更新的部分了!

Step3. 等等!我的 view怎麼壞了?

如果你到測試站按下 Add News ,你會發現Views 裡的 form.php 居然壞掉了!怎麼辦!該如何處理!!請你莫急莫慌莫害怕,這完全是正常的,原因是前面我們在處理更新的時候我們有用了 $news 這個物件,但是當你在新增時,這個物件並不存在啊,既然知道問題點在哪裡,那我們就很好解決了,打開Views 裡的 form.php ,我們做一下修改:

<form action="" method="post">
    <label for="title">title:</label>
    <input type="text" name="title" value="<?=isset($news) ? $news->title:'';?>">
    <label for="content">content:</label>
    <textarea name="content" id="" cols="30" rows="10"><?=isset($news) ? $news->content:''?></textarea>
    <input type="submit" value="submit">
</form>

在裡我們先用isset 判斷這個 $news 存不存在,如果存在我們就輸出 $news->title 或 $news->content,如果不存在我們就輸出空白,如此一來我們就解決了剛剛遇到的問題了!到這裡我麼就完成新增、讀取與更新了。

Step4. 最後一步的刪除千萬不能直接delete啊!

刪除這個功能對工程師來說是很單純的,一旦按下資料就會消失,可是使用者就會問「有沒有辦法救回來?」,如果你回答沒有辦法救回來,使用者失去的內容如果自己沒有備份,那他們的下一步就會說「那我要怎麼辦?」或是「怎麼可能救不回來?wordpress 都可以!」,那你真的欲哭無淚,最簡單的作法是你一開始就告知刪除會無法救回這件事,然後讓使用者有被中斷思考的時間,即使只有一秒,你也可以回答「刪除前已經有提示過了,所以真的沒辦法」,說起來簡單,但真的有效,而且你只需要寫上一段 onclick就好:

<h1>News List</h1>
<a href="<?= base_url();?>/news/create">Add News</a>
<ul>
    <?php foreach($list as $row):?>
        <li>
            <h3><?=$row['title'];?></h3>
            <p><?=$row['content'];?></p>
            <hr/>
            <p>
                <span>inset:<?=$row['insertTime'];?></span>
                <span>update:<?=$row['updateTime'];?></span>
                <a href="<?= base_url();?>/news/edit/<?=$row['id'];?>">Update</a> / 
                <a href="<?= base_url();?>/news/delete/<?=$row['id'];?>" onclick="return confirm('刪除後無法復原,你確定要刪除?')">Delete</a>
            </p>
        </li>
    <?php endforeach;?>
</ul>

我們透過 onclick可以寫一些javascript的特性,用 confirem來做取消或確認的動作,前面的 returen可以讓使用者決定取消時還停留在同一個頁面上。

處理完 view的部分,我們要來處理 contorller, 新增一個 delete function 並帶入 $id ,刪除回到新聞列表頁面:

public function delete($id){
    $model = new NewsModel();
    $model->delete($id);
    return redirect()->to(base_url('news')); 
}

現在你可以在前台按刪除試試看,你會發現你按下刪除的那一篇真的不見了!如果你想要刪除後會出現刪除成功的提示,那我會建議你 ruturn redirect 這個部分也改用 javascript 處理,不然你的alert 會沒有執行到就 return 回新聞列表頁了。

public function delete($id){
        $model = new NewsModel();
        $model->delete($id);
        //return redirect()->to(base_url('news')); 
        echo "<script type='text/javascript'>";
        echo "alert('刪除成功');";
        echo "window.location.href='".base_url('news')."'";
        echo "</script>";
    }
}

恭喜你!你已經學會了 CodeIgniter 4 的 新增、讀取、更新、刪除功能了!如果你還想要往上提升程式品質,我會建議你把資料庫操作的部分都移到 model 裡去,讓資料庫的部分都在model, Controller 處理其他邏輯會比較符合MVC的架構喔!如果你想下載本系列的完整範例程式碼,請由下方下載:

文章分類:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

相關推薦文章

希望您會喜歡
2008 年 5 月 4 日
[新聞]2008年新一代設計展

「新一代設計展」自1982年開辦至今,逐漸發展為全球獨一無二的設計新秀聯展,展現新生代設計創意,不只是台灣設計 […]

Read More
2008 年 11 月 15 日
[思考]關於網頁設計的學習之路

上禮拜遇到一個初學者拿著三本書(分別是html.CSS.JavaScript入門),他問我為什麼html只是J […]

Read More
2010 年 10 月 20 日
[網站]k.celine store凱思林 寢具家氛

負責內容:設計+動畫 k.celine store凱思林是個販賣高級寢具展售店,她們的客戶大部份都是知名飯店, […]

Read More
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram