[TOC]
## 【字段編輯·思路分析】
### 思路分析
> 1、更改字段編輯模板
2、控制器查詢該字段信息,并分配到模板
3、重點解決參數設置在模板中自動加載
4、修改處理方法(控制器負責邏輯判斷;模型負責業務處理)
如果字段名稱不修改,則修改models_field表,否則,還需修改對應附表的字段名稱
### 注意事項
1、字段類型是不能修改的,只能改屬性;
2、變量中嵌套變量是不能顯示的,要用php原生寫法;
~~~
<?php echo $setting['defaultvalue']; ?>
<?php if ($setting['ispassword']) echo 'checked'; ?>
<?php if (!$setting['ispassword']) echo 'checked'; ?>
~~~
### 優化代碼
> 1、完善無限極分類
2、添加和修改,判斷是否重名條件是不一樣的(字符串查詢,預處理機制,安全)
3、字段編輯條件判斷(字段名和字段別名是否重名)
4、字段刪除時,判斷附表中是否存在該字段,存在則刪除(通用函數field_exists)
## 模型(字符串查詢,預處理機制)
> 判斷模型是否存在,采用字段串條件查詢,配合預處理機制
### 局部代碼
~~~
use app\admin\model\ModelsField as ModelsFieldModel;
$models = new ModelsModel;
$models::where("id!=:id AND (tablename=:tablename OR name=:name)")
->bind([
'id'=>$id,
'tablename'=>$data['tablename'],
'name'=>$data['name']]
)->count();
~~~
### 模型編輯完整代碼
~~~
//編輯模型
public function edit($tab=1,$id=0){
if(request()->isPost()){
$data = input('post.');
if(trim($data['tablename'])==''){
return error('模型表名不能為空!');
exit;
}
$models = new ModelsModel;
//判斷模型是否存在,采用字段串條件查詢,配合預處理機制
if($models::where("id!=:id AND (tablename=:tablename OR name=:name)")
->bind(['id'=>$id,'tablename'=>$data['tablename'],'name'=>$data['name']])->count()){
return error('模型已經存在!');
exit;
}
//獲取原數據庫表名
$oldTableName = Db::name('models')->where('id',$id)->value('tablename');
//當前提前新表名
$newTableName = trim($data['tablename']);
if($models->allowField(true)->isUpdate()->save($data)){
//判斷數據庫表名是否做了修改
if($oldTableName!=$newTableName){
if($models->editTableName($oldTableName,$newTableName)){
return success('模型編輯成功!',url('index',['tab'=>1]));
}else{
return error('模型編輯失敗!');
}
}else{
return success('模型編輯成功!',url('index',['tab'=>1]));
}
}else{
return error('模型信息未變動或修改失敗!');
}
}
}
~~~
## 模板中自動加載模板,變量賦值
#### 列表模板中代碼:index.html
~~~
<div id="setting">
{$fieldinfo.setting}
</div>
~~~
其中,{$fieldinfo.setting}是序列化代碼,不是需要的內容
#### 編輯模板中代碼:field_edit.html
~~~
<div class="col-md-12">
<div class="form-group">
<label class="col-sm-1 control-label">默認值</label>
<div class="col-sm-11">
<input type="text" name="setting[defaultvalue]" class="form-control" value="<?php echo $setting['defaultvalue']; ?>">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">密碼框</label>
<div class="col-sm-11">
<input type="radio" name="setting[ispassword]" value="1" <?php if ($setting['ispassword']) echo 'checked'; ?>> 是
<input type="radio" name="setting[ispassword]" value="0" <?php if (!$setting['ispassword']) echo 'checked'; ?>> 否
</div>
</div>
</div>
~~~
#### 控制器中代碼
> 1、反序列化setting值
~~~
//獲取當前字段信息
$fieldinfo = Db::name('models_field')->where('id',$fid)->find();
$setting = unserialize($fieldinfo['setting']);//替換前參數值反序列化
$this->assign('setting',$setting);
~~~
> 讀取字段編輯模板(編輯模板與添加模板一一對應)
> 任務:A添加(讀取)模板;B替換模板中的變量(默認值)
~~~
//打開緩沖區
ob_start();
//引入字段編輯模板文件
include APP_PATH . 'admin/view/models_field/setting/' . $fieldinfo['formtype'] . '/field_edit.html';
$data_setting = ob_get_contents();
//清空緩沖區并關閉輸出緩沖
ob_end_clean();
$fieldinfo['setting'] = $data_setting; //替換后參數值
$this->assign('fieldinfo',$fieldinfo);
~~~
> 3、修改代碼
~~~
public function edit(){
//實例化字段模型
$modelsfield = new ModelsFieldModel;
if(request()->isPost()){
if($modelsfield->editField(input('post.'))){
return success('字段編輯成功!',url('index',array('id'=>input('post.modelid'),'tab'=>1)));
}else{
return error('字段修改失敗!');
}
}
}
~~~
#### 模型中代碼
~~~
/**
* [editField 編輯字段實現]
* @param [array] $data [提交的表單信息]
* @return [type] [成功返回true,失敗返回false]
*/
public function editField($data){
//對字段參數進行序列化
$setting = $data['setting'];
$data['setting'] = serialize($setting);
if(isset($setting[defaultvalue])){
$defaultvalue = $setting[defaultvalue];
}
//模型ID
$modelid = $data['modelid'];
//根據模型ID獲取模型名
$modelname = Db::name('models')->where('id',$modelid)->value('tablename');
//獲取數據表前綴
$dbPrefix = config('database.prefix');
//獲取副表名
$tablename = $dbPrefix.$modelname;
//字段名
$fieldname = $data['field'];
//獲取原字段名稱
$oldFieldname = Db::name('models_field')->where('id',$data['id'])->value('field');
$modelsfield = new ModelsField;
if($modelsfield->allowField(true)->isUpdate()->save($data)){
//判斷字段名有無修改,修改則需要改副表中相應字段名
if($oldFieldname!=$fieldname){
//修改副表字段名
switch($data['formtype']){
case "text":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '{$defaultvalue}' ";
Db::execute($sql);
break;
case "textarea":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "editor":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "box":
if($setting[fieldtype]=='varchar'){
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` VARCHAR(1) NOT NULL DEFAULT '{$defaultvalue}' ";
}elseif($setting[fieldtype]=='int'){
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` TINYINT(1) NOT NULL DEFAULT '{$defaultvalue}' ";
}
Db::execute($sql);
break;
case "image":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '' ";
Db::execute($sql);
break;
case "images":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "number":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` INT";
Db::execute($sql);
break;
case "box":
if($setting[fieldtype]=='date'){
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` DATE";
}elseif($setting[fieldtype]=='datetime'){
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` DATETIME";
}
Db::execute($sql);
break;
case "downfile":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '' ";
Db::execute($sql);
break;
case "downfiles":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldFieldname}` `{$fieldname}` TEXT";
Db::execute($sql);
break;
}
return true;
}
return true;
}else{
return false; //編輯失敗
}
}
~~~
## 相關知識
### 原生態更改數據表某字段值
~~~
UPDATE tp_models_field SET issystem=0 WHERE modelid=35;
~~~
### 原生態修改數據表字段名稱
~~~
ALTER TABLE `ps_test` DROP COLUMN `{$info['field']}` ;
~~~
### 原生態添加數據表字段名稱
~~~
ALTER TABLE `ps_test` ADD `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '{$defaultvalue}';
~~~
### 轉數組格式
~~~
方法一:$settings = array('setting'=>$data_setting);
方法二:$settings['setting'] = $data_setting;(推薦)
~~~
## 公共函數
### 判斷數據表是否存在
~~~
/**
* [table_exists 檢測數據表是否存在]
* @param string $tablename [表名,不含前綴]
* @return [bool] [存在返回true,不存在返回false]
*/
function table_exists($tablename='')
{
//獲取所有數據表名
$tables = [];
$data = Db::query('SHOW TABLES');
foreach ($data as $value) {
$tables[] = $value['Tables_in_'.config('database.database')];
}
//獲取表前綴
$dbPrefix = config('database.prefix');
//當前的表名
$tablename=$dbPrefix.$tablename;
if(in_array($tablename,$tables)){
return true; //存在
}else {
return false; //不存在
}
}
~~~
### 判斷字段是否存在
~~~
/**
* [field_exists 檢測數據表字段是否存在]
* @param string $tablename [表名,不含前綴]
* @param string $field [字段名]
* @return [bool] [存在返回true,不存在返回false]
*/
function field_exists($tablename='', $field='')
{
//獲取表前綴
$dbPrefix = config('database.prefix');
//先判斷數據表是否存在
if(table_exists($tablename)){
$fieldArray = Db::query("Describe `{$dbPrefix}{$tablename}` `{$field}` ;");
if(is_array($fieldArray[0])){
return true; //存在
}else {
return false; //不存在
}
}else {
return false; //不存在
}
}
~~~
## 添加字段模型處理代碼
~~~
//添加字段
public function addField($data){
//對字段參數進行序列化
$setting = $data['setting'];
$data['setting'] = serialize($setting);
if(isset($setting[defaultvalue])){
$defaultvalue = $setting[defaultvalue];
}
//模型ID
$modelid = $data['modelid'];
//根據模型ID獲取模型名
$modelname = Db::name('models')->where('id',$modelid)->value('tablename');
//獲取數據表前綴
$dbPrefix = config('database.prefix');
//獲取副表名
$tablename = $dbPrefix.$modelname;
//字段名
$fieldname = $data['field'];
//檢測當前模型下字段名是否重復
$count = Db::name('models_field')->where('field',$fieldname)->where('modelid',$modelid)->count();
if($count){
return -1;
}else{
//添加新字段
$modelsfield = new ModelsField;
if($modelsfield->allowField(true)->save($data)){
//添加副表字段
switch($data['formtype']){
case "text":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '{$defaultvalue}' ";
Db::execute($sql);
break;
case "textarea":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "editor":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "box":
if($setting[fieldtype]=='varchar'){
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR(1) NOT NULL DEFAULT '{$defaultvalue}' ";
}elseif($setting[fieldtype]=='int'){
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TINYINT(1) NOT NULL DEFAULT '{$defaultvalue}' ";
}
Db::execute($sql);
break;
case "image":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '' ";
Db::execute($sql);
break;
case "images":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
Db::execute($sql);
break;
case "number":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` INT";
Db::execute($sql);
break;
case "box":
if($setting[fieldtype]=='date'){
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATE";
}elseif($setting[fieldtype]=='datetime'){
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATETIME";
}
Db::execute($sql);
break;
case "downfile":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR(255) NOT NULL DEFAULT '' ";
Db::execute($sql);
break;
case "downfiles":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
Db::execute($sql);
break;
}
return 1;
}else{
return -2;
}
}
}
~~~
- Layer無刷新不跳轉彈框提示信息
- 整合ThinkPHP+實用代碼
- TP整合Layer插件實現無刷新
- 自定義助手函數
- 添加信息失敗后不跳轉
- 三種無限級分類
- TP常用代碼
- 自定義公共函數
- TP模型管理專題
- TP模型管理之添加模型
- sfox_newmodel.sql
- TP模型管理之刪除模型
- TP模型管理之編輯模型
- TP模型管理之字段添加
- sfox_newmodel.sql_edit
- layer_hplus.js_edit
- TP模型管理之字段刪除
- TP模型管理之字段編輯
- TP模型管理之預覽模型
- TP模型管理之公共函數
- layer_hplus.js_修訂一
- TP模型管理之預覽模型靜態頁
- 后臺內容管理系統
- 分類樹顯示
- 內容列表顯示
- 信息發布
- 編輯信息
- layer_hplus.js
- myJs第一版
- myJs第二版
- myJs第三版
- myJs第四版
- TP5插件用法
- Datatables
- WebUploader
- bootstrap-fileinput
- UEditor
- 簡單調用
- 路徑問題
- 跨域多圖上傳
- 跨域單圖上傳
- UEditor圖片跨域上傳解決方案
- 定制工具欄圖標
- ajaxFileUpload
- LayUI
- 圖片上傳
- layui分頁
- 搜索頁
- 搜索優化及刪除
- Uploadify
- TP5前端應用
- 靜態首頁
- 前臺首頁功能實現
- 自定義標簽庫
- 前臺模板繼承應用
- 首頁自定義標簽改進
- 文章內容頁
- 自定義標簽改進
- 自定義標簽修正
- 圖片等比例自動縮放
- 后臺權限管理
- 角色管理
- 規則管理
- 權限設置
- 會員管理
- 權限管理
- 前臺登錄注冊功能
- 注冊登錄
- 阿里大于手機注冊
- 阿里大于升級阿里云短信服務
- 自動登錄完成
- PHP異位或加密實現自動登陸
- 微信開發
- 分享接口
- 靜態頁面實現微信分享
- 動態頁微信分享
- 頁面靜態化
- 1-全站靜態化前期配置
- 2-鏈接地址靜態化
- TP5常用片段代碼
- 加載靜態資源路徑與常量
- thinkphp5預定義常量
- 刪除某文件夾的內容
- 解壓插件包
- 異步提交插件
- 其他功能
- 背景音樂
- 手機訪問PC網站自動跳轉到手機網站代碼
- 手機微信音樂MP3播放器
- 后盾之網頁背景音樂
- 播放器寬度自適應
- 前臺首頁數據調用
- 視頻列表
- 搜索分頁
- H5解決蘋果(IOS)不能自動播放音樂
- 清空緩存
- 文件處理常識
- 刪除路徑下的所有文件夾和文件
- 一鍵清空緩存
- 評論留言
- 格式化時間
- 替換微博內容的URL地址@用戶與表情
- PHP正則理解
- jQuery評論插件
- TP空操作
- TP路由
- 跨域訪問
- 設置請其頭允許跨域請求
- 模板前臺判斷手機訪問跳轉手機網址代碼
- PHP遍歷一個文件夾下所有文件和子文件夾
- PHP獲取視頻的第一幀與時長
- TP5數據庫
- 鏈式操作原理
- update替換字段部分內容
- 后臺開發
- 后臺登錄頁居中顯示
- TP5自帶驗證碼
- JS & JQuery專題
- 二級城市聯動菜單
- 模板引擎
- 混合模板編譯
- 黃永成TP微博開發
- 消息推送
- memcache安裝
- 插件開發
- 插件介紹
- 插件鉤子
- 淺談初步理解鉤子
- 插件鉤子(hooks)分析
- 插件鉤子簡單理解
- 控制器調用插件
- 鉤子通用處理函數
- 插件基類代碼
- 插件測試代碼
- 淺談鉤子與插件
- 技術綜合
- 常用代碼
- PHP
- 56個PHP開發常用代碼片段(上)
- 56個PHP 開發常用代碼片段(中)
- 56個PHP 開發常用代碼片段(下)
- sublime text安裝自動補全注釋的插件
- 影音視頻開發
- 視頻
- H5視頻直播掃盲
- 音樂
- 語音
- PHP實現語音播報功能
- MUI
- 窗體操作