傳統 `
<?php include("../inc/inc.php"); islogin(); $Db = new Db(); // 自定義資料庫類 $id = (int)($_GET['aid'] ?? 0); if (!$id) exit; $query = $Db->query("SELECT upid, cntitle, orderid, id FROM cn_loupan_city WHERE upid = $id ORDER BY orderid ASC"); $rows = $Db->fetch($query); // 返回二維陣列 ?>
<table class="table_list"> <caption>{<?=htmlspecialchars($_GET['cname'])?>} 地區管理</caption> <tr> <th width="32%">地區名稱</th> <th width="43%">排序位置</th> <th width="25%">操作</th> </tr> <?php foreach ($rows as $v): ?> <tr> <td class="align_c"> <input id="c_<?=$v[3]?>" type="text" size="30" value="<?=htmlspecialchars($v[1])?>" /> </td> <td class="align_c"> <input id="s_<?=$v[3]?>" type="text" size="20" value="<?=htmlspecialchars($v[2])?>" /> </td> <td class="align_c"> <a href="javascript:sava('c_<?=$v[3]?>','s_<?=$v[3]?>',<?=$v[3]?>);">保存</a> | <a href="javascript:del(<?=$v[3]?>);">刪除</a> </td> </tr> <?php endforeach; ?> </table>
<script> function del(id) { if (confirm('確認刪除此條信息?')) { location.href = `public.php?action=deletes&id=${id}&aid=${=$id?>}&cname=${encodeURIComponent('=addslashes($_GET['cname'])?>')}`; } } function sava(titleId, orderId, id) { if (!confirm('確認你輸入數據無誤?')) return; const cntitle = document.getElementById(titleId).value.trim(); const orderid = document.getElementById(orderId).value.trim(); if (!cntitle || cntitle.length > 30) { alert('地區名稱不能為空且不超過 30 字元!'); return; } if (isNaN(orderid)) { alert('排序位置請輸入數字!'); return; } location.href = `public.php?action=edits&title=${encodeURIComponent(cntitle)}&orderid=${orderid}&id=${id}&aid=${=$id?>}&cname=${encodeURIComponent('=addslashes($_GET['cname'])?>')}`; } </script>
json_encode()
data-*
$id
GET /api/cities?parent_id=1 # 列表 POST /api/cities # 新增 PUT /api/cities/{id} # 更新 DELETE /api/cities/{id} # 刪除
<script setup> import { ref, onMounted } from 'vue'; const props = defineProps(['parentId', 'parentName']); const cities = ref([]); const loading = ref(false); async function load() { const res = await fetch(`/api/cities?parent_id=${props.parentId}`); const {data} = await res.json(); cities.value = data; } onMounted(load); async function save(city) { city.editing = false; const res = await fetch(`/api/cities/${city.id}`, { method: 'PUT', headers: {'Content-Type':'application/json', 'X-CSRF-TOKEN': csrfToken}, body: JSON.stringify({name: city.name, order: city.order}) }); if (!res.ok) { city.editing = true; alert('保存失敗'); } } async function remove(id) { if (!confirm('確認刪除?')) return; await fetch(`/api/cities/${id}`, {method:'DELETE', headers:{'X-CSRF-TOKEN': csrfToken}}); cities.value = cities.value.filter(c => c.id !== id); } </script> <template> <div class="card"> <h4>{{ parentName }} 地區管理</h4> <table> <thead><tr><th>名稱</th><th>排序</th><th>操作</th></tr></thead> <tbody> <tr v-for="city in cities" :key="city.id"> <td> <input v-if="city.editing" v-model="city.name" @blur="save(city)" @keyup.enter="save(city)" /> <span v-else @dblclick="city.editing=true">{{ city.name }}</span> </td> <td> <input v-if="city.editing" type="number" v-model.number="city.order" @blur="save(city)" /> <span v-else @dblclick="city.editing=true">{{ city.order }}</span> </td> <td> <button v-if="city.editing" @click="save(city)">保存</button> <button v-else @click="city.editing=true">編輯</button> <button @click="remove(city.id)" class="danger">刪除</button> </td> </tr> </tbody> </table> </div> </template>
「無表單提交」本質上是「前端收集數據 → 發送 HTTP 請求」的另一種寫法。原始範例雖實現了基本交互,但存在 XSS、CSRF、SQL 注入、REST 不合規等嚴重問題。現代化開發應採用:
核心邏輯:分層檢查,失敗即停 <?php $filen
Yii 1.x 框架安裝與第一個應用程式完整圖文教學 Yii
問題描述 使用 PHP 動態生成 JavaScript 陣列
一、安裝與環境驗證 安裝步驟 官網下載:yiiframew