搜尋結果頁面需支援即時刪除不想要的連結,要求前後端同步更新且無需整頁重整。採用 ThinkPHP + jQuery AJAX 實現。
<a href="javascript:void(0);"
id="<?php echo $val['id']; ?>"
class="delete">刪除</a>
javascript:void(0) 防止頁面跳轉id 儲存資料庫主鍵,供 AJAX 傳遞class="delete" 作為 jQuery 事件委派選擇器<script>
$(function() {
// 事件委派:效能優於逐個綁定,支援動態新增元素
$('.list').on('click', 'a.delete', function(e) {
e.preventDefault();
if (!confirm('確定要刪除嗎?')) return;
var $link = $(this);
var id = $link.attr('id');
$.ajax({
url: '/Search/index.php/Jason/delete',
type: 'GET', // 明確指定,原文未寫預設 GET
data: { id: id },
dataType: 'json',
success: function(res) {
if (res.del == '1') {
// 方案 A:直接移除(原文)
$link.parents('.list').remove();
// 方案 B:滑動淡出後移除(進階體驗)
// $link.parents('.list').slideUp('slow', function() {
// $(this).remove();
// });
} else {
alert('刪除失敗:' + (res.msg || '未知錯誤'));
}
},
error: function(xhr) {
alert('請求異常:' + xhr.status);
}
});
});
});
</script>
URL /Search/index.php/Jason/delete 對應:
Search(或項目名)JasonAction(ThinkPHP 3.x 命名慣例)delete()<?php
class JasonAction extends Action {
public function delete() {
// 僅接受 GET 請求(原文邏輯,建議改 POST/DELETE)
if (!$this->isGet()) {
$this->ajaxReturn(['del' => '0', 'msg' => '請求方式錯誤']);
}
// 登入驗證
$uid = session('uid');
if (empty($uid)) {
$this->ajaxReturn(['del' => '0', 'msg' => '未登入']);
}
// 參數獲取與驗證
$id = $this->_get('id', 'intval');
if (empty($id)) {
$this->ajaxReturn(['del' => '0', 'msg' => '參數無效']);
}
// 業務邏輯:刪除前建議檢查權限
$model = M('SearchResult'); // 實際表模型
$result = $model->where("id={$id} AND uid={$uid}")->delete();
if ($result !== false) {
$this->ajaxReturn(['del' => '1', 'msg' => '刪除成功']);
} else {
$this->ajaxReturn(['del' => '0', 'msg' => '資料不存在或無權限']);
}
}
}
| 層面 | 原文寫法 | 改進建議 |
|---|---|---|
| HTTP 方法 | GET | RESTful 應用 DELETE/POST,防 CSRF |
| 參數過濾 | 直接拼接 SQL | 使用 _get('id','intval') 或參數綁定 |
| 權限控制 | 僅判斷登入 | 加入資料擁有者驗證 AND uid={$uid} |
| 回應格式 | 手動 json_encode | 使用 $this->ajaxReturn() 統一格式 |
| 前端選擇器 | .list a.delete | 事件委派 .list.on('click','a.delete') |
| DOM 移除 | .remove() | .slideUp(fn) 提升體驗 |
deleted_at 欄位,避免物理刪除導致關聯資料斷裂id 陣列傳遞version 欄位防止併發刪除衝突uid, action, target_id, ip, time 供審計<?php
// 防 CSRF Token 驗證(ThinkPHP 3.2+ 內建)
if (!$this->isPost() || !checkToken()) {
$this->ajaxReturn(['del' => '0', 'msg' => 'Token 無效']);
}
// SQL 注入防護:模型自動過濾或參數綁定
$result = $model->where(['id' => $id, 'uid' => $uid])->delete();
// 或
$result = $model->where("id=%d AND uid=%d", [$id, $uid])->delete();
這個流程展示了經典 jQuery + ThinkPHP 異步交互模式。現代專案建議採用 RESTful API 設計、前後端分離架構,但理解傳統模式對維護舊專案、快速原型開發仍有價值。