PHP建站技术分享-从入门到精通PHP建站技术分享-从入门到精通PHP建站技术分享-从入门到精通

QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > CMS教程 > Fastadmin

【教程】无需重写Backend类的add和edit方法即可处理后台传过来的表单数据

管理员 2024-12-14
Fastadmin
21

fastadmin的一键生成控制器和一键生成菜单很方便,并且生成的控制器中继承了Backend类,不需要我们编写冗余的代码

但是当我们想对前端传过来的数据进行修改时,则需要把父类的对应方法复制过来再改写,但是一个add方法竟然有35行代码,如果在多几个控制器中分别复制几次,那岂不是会产生很多的冗余代码

目标

在控制器中不重写增改的方法来实现修改前端传的参数

需求

我有一个视频表,其中有个字段记录视频的时长,所以需要在添加记录的时候就把视频的时长计算出来写进表里

结果

通过该方法,只需在对应控制器中新建对应方法,即可修改后台传过来的参数内容

比如我要修改后台新增记录时传过来的表单数据,只需要在对应控制器使用addHook方法来处理

原理

在Backend控制器中判断子类的控制器中是否有对应处理后台表单传过来的参数的方法,如果有则交由处理

比如在add方法中,判断子类是否有addHook方法,如果有,就把自己接收到的$params传递过去任其修改

在addHook方法中就可以读取到视频文件的路径,然后计算出视频文件的时长,并把计算出的时长添加到$params['duration']上面,最后会写入数据库

环境

fastadmin版本:1.3.4.20220530

php版本:7.3

实现

准备工作

数据表:fa_video(视频管理)

类型长度不是null注释
idint255
namevarchar255
filevarchar252 文件路径
durationint255 视频时长

使用fastadmin的在线命令生成CRUD和菜单后,会在代码中出现如下文件

  • CRUD对应的控制器

    • application/admin/controller/Video.php
  • 视频管理对应的布局文件

    • /www/wwwroot/fastadmin/application/admin/view/video/add.html
    • /www/wwwroot/fastadmin/application/admin/view/video/edit.html
    • 可以删除两个文件中的duration表单字段,因为这个时长字段不是用户填的,是用户添加或修改记录时后台计算后添加的

修改application/admin/library/traits/Backend.php 文件

  1. 添加一个hookModifyParam方法(传参及代码内容参考下方完整代码)
  2. 在add方法中调用完preExcludeFields方法后面写上$this->hookModifyParam($params, 'addHook');
  3. 在edit方法中调用完preExcludeFields方法后面写上$this->hookModifyParam($params, 'editHook');

修改Video控制器

  1. 在控制器添加一个addHook方法(传参及代码内容参考下方完整代码,editHook方法也与此雷同)

实现目的

接下来再后台添加记录时,输入必要参数后点击确定,后端就会自动计算出选择的视频文件的时长,并随其它参数一起写进数据库

具体代码(可以直接复制使用)

Backend.php文件的完整代码

<?phpnamespace appadminlibrarytraits;use appadminlibraryAuth;use Exception;use PhpOfficePhpSpreadsheetCellCoordinate;use PhpOfficePhpSpreadsheetReaderXlsx;use PhpOfficePhpSpreadsheetReaderXls;use PhpOfficePhpSpreadsheetReaderCsv;use thinkDb;use thinkdbexceptionBindParamException;use thinkdbexceptionDataNotFoundException;use thinkdbexceptionModelNotFoundException;use thinkexceptionDbException;use thinkexceptionPDOException;use thinkexceptionValidateException;use thinkresponseJson;use thinkHook;trait Backend{    private $admin_controller_path = 'appadmincontroller';      /**     * 排除前台提交过来的字段     * @param $params     * @return array     */    protected function preExcludeFields($params)    {        if (is_array($this->excludeFields)) {            foreach ($this->excludeFields as $field) {                if (array_key_exists($field, $params)) {                    unset($params[$field]);                }            }        } else if (array_key_exists($this->excludeFields, $params)) {            unset($params[$this->excludeFields]);        }        return $params;    }    /**     * 查看     *     * @return string|Json     * @throws thinkException     * @throws DbException     */    public function index()    {        //设置过滤方法        $this->request->filter(['strip_tags', 'trim']);        if (false === $this->request->isAjax()) {            return $this->view->fetch();        }        //如果发送的来源是 Selectpage,则转发到 Selectpage        if ($this->request->request('keyField')) {            return $this->selectpage();        }        [$where, $sort, $order, $offset, $limit] = $this->buildparams();        $list = $this->model            ->where($where)            ->order($sort, $order)            ->paginate($limit);        $result = ['total' => $list->total(), 'rows' => $list->items()];        return json($result);    }    /**     * 回收站     *     * @return string|Json     * @throws thinkException     */    public function recyclebin()    {        //设置过滤方法        $this->request->filter(['strip_tags', 'trim']);        if (false === $this->request->isAjax()) {            return $this->view->fetch();        }        [$where, $sort, $order, $offset, $limit] = $this->buildparams();        $list = $this->model            ->onlyTrashed()            ->where($where)            ->order($sort, $order)            ->paginate($limit);        $result = ['total' => $list->total(), 'rows' => $list->items()];        return json($result);    }    /**     * 添加     *     * @return string     * @throws thinkException     */    public function add()    {        if (false === $this->request->isPost()) {            return $this->view->fetch();        }        $params = $this->request->post('row/a');        if (empty($params)) {            $this->error(__('Parameter %s can not be empty', ''));        }        $params = $this->preExcludeFields($params);        $this->hookModifyParam($params, 'addHook');        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {            $params[$this->dataLimitField] = $this->auth->id;        }        $result = false;        Db::startTrans();        try {            //是否采用模型验证            if ($this->modelValidate) {                $name = str_replace("\model\", "\validate\", get_class($this->model));                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;                $this->model->validateFailException()->validate($validate);            }            $result = $this->model->allowField(true)->save($params);            Db::commit();        } catch (ValidateException|PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if ($result === false) {            $this->error(__('No rows were inserted'));        }        $this->success();    }    /**     * 编辑     *     * @param $ids     * @return string     * @throws DbException     * @throws thinkException     */    public function edit($ids = null)    {        $row = $this->model->get($ids);        if (!$row) {            $this->error(__('No Results were found'));        }        $adminIds = $this->getDataLimitAdminIds();        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {            $this->error(__('You have no permission'));        }        if (false === $this->request->isPost()) {            $this->view->assign('row', $row);            return $this->view->fetch();        }        $params = $this->request->post('row/a');        if (empty($params)) {            $this->error(__('Parameter %s can not be empty', ''));        }        $params = $this->preExcludeFields($params);                $this->hookModifyParam($params, 'editHook');                $result = false;        Db::startTrans();        try {            //是否采用模型验证            if ($this->modelValidate) {                $name = str_replace("\model\", "\validate\", get_class($this->model));                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;                $row->validateFailException()->validate($validate);            }            $result = $row->allowField(true)->save($params);            Db::commit();        } catch (ValidateException|PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if (false === $result) {            $this->error(__('No rows were updated'));        }        $this->success();    }    /**     * 删除     *     * @param $ids     * @return void     * @throws DbException     * @throws DataNotFoundException     * @throws ModelNotFoundException     */    public function del($ids = null)    {        if (false === $this->request->isPost()) {            $this->error(__("Invalid parameters"));        }        $ids = $ids ?: $this->request->post("ids");        if (empty($ids)) {            $this->error(__('Parameter %s can not be empty', 'ids'));        }        $pk = $this->model->getPk();        $adminIds = $this->getDataLimitAdminIds();        if (is_array($adminIds)) {            $this->model->where($this->dataLimitField, 'in', $adminIds);        }        $list = $this->model->where($pk, 'in', $ids)->select();        $count = 0;        Db::startTrans();        try {            foreach ($list as $item) {                $count += $item->delete();            }            Db::commit();        } catch (PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if ($count) {            $this->success();        }        $this->error(__('No rows were deleted'));    }    /**     * 真实删除     *     * @param $ids     * @return void     */    public function destroy($ids = null)    {        if (false === $this->request->isPost()) {            $this->error(__("Invalid parameters"));        }        $ids = $ids ?: $this->request->post('ids');        if (empty($ids)) {            $this->error(__('Parameter %s can not be empty', 'ids'));        }        $pk = $this->model->getPk();        $adminIds = $this->getDataLimitAdminIds();        if (is_array($adminIds)) {            $this->model->where($this->dataLimitField, 'in', $adminIds);        }        $this->model->where($pk, 'in', $ids);        $count = 0;        Db::startTrans();        try {            $list = $this->model->onlyTrashed()->select();            foreach ($list as $item) {                $count += $item->delete(true);            }            Db::commit();        } catch (PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if ($count) {            $this->success();        }        $this->error(__('No rows were deleted'));    }    /**     * 还原     *     * @param $ids     * @return void     */    public function restore($ids = null)    {        if (false === $this->request->isPost()) {            $this->error(__('Invalid parameters'));        }        $ids = $ids ?: $this->request->post('ids');        $pk = $this->model->getPk();        $adminIds = $this->getDataLimitAdminIds();        if (is_array($adminIds)) {            $this->model->where($this->dataLimitField, 'in', $adminIds);        }        if ($ids) {            $this->model->where($pk, 'in', $ids);        }        $count = 0;        Db::startTrans();        try {            $list = $this->model->onlyTrashed()->select();            foreach ($list as $item) {                $count += $item->restore();            }            Db::commit();        } catch (PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if ($count) {            $this->success();        }        $this->error(__('No rows were updated'));    }    /**     * 批量更新     *     * @param $ids     * @return void     */    public function multi($ids = null)    {        if (false === $this->request->isPost()) {            $this->error(__('Invalid parameters'));        }        $ids = $ids ?: $this->request->post('ids');        if (empty($ids)) {            $this->error(__('Parameter %s can not be empty', 'ids'));        }        if (false === $this->request->has('params')) {            $this->error(__('No rows were updated'));        }        parse_str($this->request->post('params'), $values);        $values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));        if (empty($values)) {            $this->error(__('You have no permission'));        }        $adminIds = $this->getDataLimitAdminIds();        if (is_array($adminIds)) {            $this->model->where($this->dataLimitField, 'in', $adminIds);        }        $count = 0;        Db::startTrans();        try {            $list = $this->model->where($this->model->getPk(), 'in', $ids)->select();            foreach ($list as $item) {                $count += $item->allowField(true)->isUpdate(true)->save($values);            }            Db::commit();        } catch (PDOException|Exception $e) {            Db::rollback();            $this->error($e->getMessage());        }        if ($count) {            $this->success();        }        $this->error(__('No rows were updated'));    }    /**     * 导入     *     * @return void     * @throws PDOException     * @throws BindParamException     */    protected function import()    {        $file = $this->request->request('file');        if (!$file) {            $this->error(__('Parameter %s can not be empty', 'file'));        }        $filePath = ROOT_PATH . DS . 'public' . DS . $file;        if (!is_file($filePath)) {            $this->error(__('No results were found'));        }        //实例化reader        $ext = pathinfo($filePath, PATHINFO_EXTENSION);        if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {            $this->error(__('Unknown data format'));        }        if ($ext === 'csv') {            $file = fopen($filePath, 'r');            $filePath = tempnam(sys_get_temp_dir(), 'import_csv');            $fp = fopen($filePath, 'w');            $n = 0;            while ($line = fgets($file)) {                $line = rtrim($line, "nr");                $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);                if ($encoding !== 'utf-8') {                    $line = mb_convert_encoding($line, 'utf-8', $encoding);                }                if ($n == 0 || preg_match('/^".*"$/', $line)) {                    fwrite($fp, $line . "n");                } else {                    fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . ""n");                }                $n++;            }            fclose($file) || fclose($fp);            $reader = new Csv();        } elseif ($ext === 'xls') {            $reader = new Xls();        } else {            $reader = new Xlsx();        }        //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name        $importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';        $table = $this->model->getQuery()->getTable();        $database = thinkConfig::get('database.database');        $fieldArr = [];        $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);        foreach ($list as $k => $v) {            if ($importHeadType == 'comment') {                $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];            } else {                $fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];            }        }        //加载文件        $insert = [];        try {            if (!$PHPExcel = $reader->load($filePath)) {                $this->error(__('Unknown data format'));            }            $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表            $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号            $allRow = $currentSheet->getHighestRow(); //取得一共有多少行            $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);            $fields = [];            for ($currentRow = 1; $currentRow <= 1; $currentRow++) {                for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {                    $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();                    $fields[] = $val;                }            }            for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {                $values = [];                for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {                    $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();                    $values[] = is_null($val) ? '' : $val;                }                $row = [];                $temp = array_combine($fields, $values);                foreach ($temp as $k => $v) {                    if (isset($fieldArr[$k]) && $k !== '') {                        $row[$fieldArr[$k]] = $v;                    }                }                if ($row) {                    $insert[] = $row;                }            }        } catch (Exception $exception) {            $this->error($exception->getMessage());        }        if (!$insert) {            $this->error(__('No rows were updated'));        }        try {            //是否包含admin_id字段            $has_admin_id = false;            foreach ($fieldArr as $name => $key) {                if ($key == 'admin_id') {                    $has_admin_id = true;                    break;                }            }            if ($has_admin_id) {                $auth = Auth::instance();                foreach ($insert as &$val) {                    if (!isset($val['admin_id']) || empty($val['admin_id'])) {                        $val['admin_id'] = $auth->isLogin() ? $auth->id : 0;                    }                }            }            $this->model->saveAll($insert);        } catch (PDOException $exception) {            $msg = $exception->getMessage();            if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {                $msg = "导入失败,包含【{$matches[1]}】的记录已存在";            };            $this->error($msg);        } catch (Exception $e) {            $this->error($e->getMessage());        }        $this->success();    }  /**   * 通过HOOK让对应的控制器支持修改请求传过来的参数   * @param array $param 请求传过来的参数   * @param string $action 方法名(举例,如果是add方法,方法名可以是addHook,这样在继承此类的控制器中即可定义一个addHook方法来修改请求传过来的参数   */  private function hookModifyParam(array &$params, string $action) {    $controller = strtolower($this->request->controller());    $controller_arr = explode('.', $controller);    strpos($controller, '.') !== false && $controller_arr[count($controller_arr) - 1] = ucfirst($controller_arr[count($controller_arr) - 1]);    $controller = join('\', $controller_arr);    $controller_path = vsprintf('%s\%s', [$this->admin_controller_path, $controller]);    if (method_exists($controller_path, $action)) Hook::exec($controller_path, $action, $params);  }}

Video.php文件的完整代码

<?phpnamespace appadmincontroller;use appcommoncontrollerBackend;/** * 视频管理 * * @icon fa fa-circle-o */class Video extends Backend{    /**     * Video模型对象     * @var appadminmodelVideo     */    protected $model = null;    public function _initialize()    {        parent::_initialize();        $this->model = new appadminmodelVideo;    }        public function addHook(&$params) {        // 这里的$params就是前台提交的信息,可以对其修改,注意参数前有个&号        $params['duration'] = 10;   // 假设10就是我们计算出的这个视频的时长                // 这里不需要return,因为参数是使用的引用传递    }        public function editHook(&$params) {        // 这里的$params就是前台提交的信息,可以对其修改,注意参数前有个&号        $params['duration'] = 10;   // 假设10就是我们计算出的这个视频的时长                // 这里不需要return,因为参数是使用的引用传递    }    /**     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改     */}

需要注意的地方

  • 如果你对application/admin/controller/目录下不是控制器类,而是目录,或者目录套目录,那么这个目录的名字必须是全小写;如果出现了大写字母会识别不到控制器中的addHook和editHook方法;关于这一点目前我还没有想到好的解决办,此处的逻辑在hookModifyParam方法中,各位可自行修改

结语

上述代码并不是很优雅,我在这里属于是抛转引玉了


希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, Fastadmin, ClassCMS, LeCMS, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

相关推荐

扫码关注

qrcode

QQ交谈

回顶部