关于Yii2基础controller和model的封装

如题,在实战项目中我们我们经常会要使用相同的逻辑,比如post/get获取参数,接口返回、参数校验等,因此可以将其封装起来调用。
这里分为根目录下的控制器controllers和处理数据库的models两个文件,其他业务逻辑放在modules模块中

一、根目录下controllers

// BaseController.php
<?php
namespace app\controllers;
use yii\web\{Controlle, IdentityInterface, Response};
use Yii;// 继承 yii\web\controller, 其他controller则继承BaseController
class BaseController extends Controller
{/*** 错误码*/protected $code = '';/*** 错误消息*/protected $msg = 'success';/*** 响应报文*/protected $rspData = [];/*** 模型*/protected $model = null;/*** 路由*/protected $route;public function __construct($id, $module, $config = []){$this->route = Yii::$app->requestedRoute;Yii::info(json_encode($this->request(), JSON_UNESCAPED_SLASHES), "[ERQUEST BODY] $this->route");parent::__construct($id, $module, $config);}/*** 设置拦截器*/public function behaviors(): array{return [];}public function init(){parent::init();}/*** 获取get参数*/protected function get($key = ''){$get = $key ? Yii::$app->request->get($key) : Yii::$app->request->get();return $get;}/*** 获取 post 参数*/protected function post($key = ''){$post = $key ? Yii::$app->request->post($key) : Yii::$app->request->post();return $post;}/*** 获取 get、post 参数*/protected function request($key = ''){$get = $this->get($key);$post = $this->post($key);if (is_array($get) && is_array($post)) {return array_merge($get, $post);}return $post ? $post : ($get ?: null);}/*** 返回当前用户*/public function getUserIdentity(): ?IdentityInterface{return Yii::$app->getUser()->identity;}/*** 前置操作*/public function beforeAction($action): bool{$params = $this->post();/*** 分页、排序、参数处理*/if ($this->model && !empty($params['page'])) {$page = intval($params['page']);if ($page < 1) {$page = 1;}$this->model->page = $page;}if ($this->model && !empty($params['pageSize'])) {$pageSize = Intval($params['pageSize']);$this->model->pageSize = $pageSize;}if ($this->model && !empty($params['_sorting'])) {$sorting = [];if (!is_array($params['_sorting'])) {$params['_sorting'] = json_decode($params['_sorting'], true);}foreach ($params['_sorting'] as $item) {$sorting[] = $item['field'] . ' ' . $item['type'];}$this->model->$sorting = implode(',', $sorting);}return parent::beforeAction($action);}/*** 判断是否是get方法*/protected function isGet(){return Yii::$app->request->isGet;}/*** 判断是否是post方法*/protected function isPost(){return Yii::$app->request->isPost;}/*** 组装JSON格式响应** @param array $data* @return Response*/public function asJson($data = []): Response{return parent::asJson(['code' => $this->code, 'msg' => $this->msg, 'data' => $data]);}protected function isAjax(){return Yii::$app->request->isAjax;}protected function littleToHump($word): string{$separator = '_';$word = $separator . str_replace($separator, '', $word);return ltrim(str_replace(' ', '', ucwords($word)), $separator);}/*** 响应数据*/protected function response($data = []): array{Yii::$app->response->format = Response::FORMAT_JSON;if ($this->code) {$rsp = ['code' => $this->code,'msg' => $this->msg,'data' => $this->rspData ?: $data];} else {$rsp = ['code' => '00000','msg' => $this->msg ?: 'success','data' => $this->rspData ?: $data];}return $rsp;}/*** 后置操作*/public function afterAction($action, $result){return parent::afterAction($action, $result);}/*** 验参*/public function paramsValidate(array $params, array $fieldRules, string $translator = 'default', string $tag = ''): bool{// field_validator 来自web/index.php中全局注册的components/helper/function.php$res = field_validator($params, $fieldRules, $translator, $tag);if (!empty($res)) {// 将校验参数的结果赋值给code, msg[$this->code, $this->msg] = $res;return false;}return true;}
}?>

二、根目录下models

// BaseModel.php
// 继承yii\db\ActiveRecord, 增删改查,操作数据库
<?php
namespace app\models;use yii\db\{ActiveRecord, ActiveQuery, Connection, Exception};
use Yii;abstract class BaseModel extends ActiveRecord
{public $page = 1; // 查询limit页码public $pageSize = 20;protected static $insertId = 0; // 插入数据的的ID/*** 调用父依赖构造函数** @param array $config*/public function __construct($config = []){parent::__construct($config);}/*** 数据库实例* @return Connection interface*/public function dbInstance(): Connection{$db = static::getDb(); // ActiveRecord方法,连接dbif ($db) {return $db;}return Yii::$app->db; // 默认全局db}/*** 查询对象* @return ActiveQuery interface*/public function query(): ActiveQuery{return self::find(); // ActiveRecord方法,查询}/*** 组装查询对象* * @param array $conditions 条件集合数组* @param array $fields 查询字段* @param array $expression 条件连接符* @param array $table 指定数据表* * @return ActiveQuery interface*/public function queryDbAll(array $conditions = [], string $fields = '*', string $expression = 'and', string $table = ''): ActiveQuery{// 兼容一维数组if (empty(array_filter($conditions, function ($v, $k) {return is_array($v) && is_numeric($k);}, ARRAY_FILTER_USE_BOTH))) {$conditions = [$conditions];}if (empty($table)) {$query = self::find()->select($fields);} else {$query = self::find()->from($table)->select($fields);}// array_filter默认去除false元素foreach (array_filter($conditions) as $k => $v) {if ($k === 0) {$query->where($v);continue;}switch ($expression) {case 'or':$query->orWhere($v);case 'and':default:$query->andWhere($v);}}// echo $query -> createCommand() -> getRawSql();return $query;}/*** 获取单条记录*/public function getDbOne(array $conditions = [], string $fields = '*', string $expression = 'and'): ?array{// 兼容一维数组if (empty(array_filter($conditions, function ($v, $k) {return is_array($v) && is_numeric($k);}, ARRAY_FILTER_USE_BOTH))) {$conditions = [$conditions];}$query = self::find()->select($fields);foreach (array_filter($conditions) as $k => $v) {if ($k === 0) {$query->where($v);continue;}switch ($expression) {case 'or':$query->orWhere($v);break;case 'and':default:$query->andWhere($v);break;}}if (in_array('id', static::primaryKey())) {$query->orderBy(['id' => SORT_DESC]);}$res = $query->asArray()->one();if (!empty($res)) {camel_snake($res);}return $res;}/*** 获取全部记录* @param array $conditions 表示查询条件,默认无条件查询* @param string $fields 表示返回的字段,默认全部返回,消耗接口流量宽带* @param array $order 表示排序,默认id降序* @param boolean $limit 表示数据条数,默认取全部* @param array $groupBy 表示列中同值分组,默认不分组* @param string $expression 表示条件关系,默认and*/public function getDbAll(array $conditions = [], string $fields = '*', array $order = ['id' => SORT_ASC], bool $limit = false, array $groupBy = [], string $expression = 'and'): array{/*** 兼容一维数组,最终转出二维数组* array_filter() ARRAY_FILTER_USE_BOTH表示回调可以接收两个参数 $v, $k* 当前array_filter表示过滤获取二维数组,如果得到空数组,则表示非二维数组,一维数组需要转出二维数组*/if (empty(array_filter($conditions, function ($v, $k) {return is_array($v) && is_numeric($k);}, ARRAY_FILTER_USE_BOTH))) {$conditions = [$conditions];}$query = self::find()->select($fields);foreach (array_filter($conditions) as $k => $v) {if ($k === 0) {$query->where($v);continue;}switch ($expression) {case 'or':$query->orWhere($v);break;case 'and':default:$query->andWhere($v);}}// dd(11, $conditions, $fields, $query);if (!empty($groupBy)) {$query->groupBy($groupBy);}if (!empty($order)) {$query->orderBy($order);}if ($limit) {$query->limit($this->pageSize)->offset(bcmul($this->pageSize, bcsub($this->page, 1)));}$res = $query->asArray()->all();array_walk($res, function (&$v) {if (!empty($v)) {camel_snake($v);}});return $res;}/*** 获取记录行*/public function getCount(array $conditions = [], string $expression = 'and'): int{// 兼容一维数组if (empty(array_filter($conditions, function ($v, $k) {return is_array($v) && is_numeric($k);}, ARRAY_FILTER_USE_BOTH))) {$conditions = [$conditions];}$query = self::find();foreach (array_filter($conditions) as $k => $v) {if ($k === 0) {$query->where($v);continue;}switch ($expression) {case 'or':$query->orWhere($v);break;case 'and':default:$query->addWhere($v);}}return $query->count();}/*** 添加记录*/public function create(array $data): int{$rows = $this->dbInstance()->createCommand()->insert(static::tableName(), $data)->execute();// 记录自增IDself::$insertId = $this->dbInstance()->getLastInsertID();return $rows;}/*** 批量添加*/public function batchCreate(array $fields, array $data): int{if (empty($fields) || empty($data)) {throw new Exception('Missing batch fields or data');}$rows = $this->dbInstance()->createCommand()->batchInsert(static::tableName(),$fields,$data)->execute();self::$insertId = $this->dbInstance()->getLastInsertID();return $rows;}/*** 获取插入的自增ID*/public function getInsertId(): int{return self::$insertId;}/*** 更改记录,*  $data 新的数据*  $conditions 查询条件的集合,如['id' => 'id', 'sex' => 'man']*/public function updateByCondition(array $data, array $conditions): int{if (empty($data) || empty($conditions)) {throw new Exception('Missing data or conditions');}return $this->dbInstance()->createCommand()->update(static::tableName(),$data,$conditions)->execute();}/*** 指定主键删除记录*/public function deleteById(int $id): void{if (empty($id)) {throw new Exception('Missing primary key');}self::findOne($id)->delete();}/*** 指定删除记录*/public function deleteData(array $params): void{if (empty($params)) {throw new Exception('Missing primary key');}self::findOne($params)->delete();}/*** 判断数据表是否存在*/public function tableExist(string $tableName): bool{return !empty($this->dbInstance()->getTableSchema($tableName));}
}?>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MapReduce\Shuffle

MapReduce\Shuffle MapReduce 是一种编程模型&#xff0c;用于处理和生成大数据集。这个模型由两个主要步骤组成&#xff1a;Map步骤和Reduce步骤。 Map步骤&#xff1a;在这个步骤中&#xff0c;输入数据集被分割成多个独立的数据块&#xff0c;然后每个数据块被分配给一个M…

云桌面和桌面云是什么?中国桌面云市场谁在领跑?

当我们谈论云桌面和桌面云时&#xff0c;确实很容易产生混淆。它们都涉及到云计算技术在个人计算环境中的应用&#xff0c;但具体的应用场景和侧重点有所不同。 云桌面&#xff1a;虚拟化的桌面环境 云桌面是一种基于云计算的虚拟化技术&#xff0c;它允许用户通过互联网访问一…

Visual Studio开发环境的搭建

1.引言 Visual Studio是微软公司开发的一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员进行各种编程任务&#xff0c;包括设计、开发、测试、调试和部署应用程序。典型功能包括&#xff1a; 代码编辑器。提供高效、智能的代码编辑器&#x…

Docker的私有仓库Harbor

Harbor概述 1.Harbor定义 私有&#xff0c;自定义用户的形式登陆仓库&#xff0c;拉取或者上传镜像。(内部管理的用户) Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的 Docker Registry 服务。 2.Docker Harbor…

【数学建模】《实战数学建模:例题与讲解》第十讲-时间序列预测(含Matlab代码)

【数学建模】《实战数学建模&#xff1a;例题与讲解》第十讲-时间序列预测&#xff08;含Matlab代码&#xff09; 基本概念移动平均&#xff08;Moving Average, MA&#xff09;:指数平滑法&#xff08;Exponential Smoothing&#xff09;:季节性调整&#xff08;Seasonal Adju…

SpringCloud系列(六)| 聊聊负载均衡

一、负载均衡概述 上一篇文章中&#xff0c;我们在集成OpenFeign的过程中提示我们需要加入了一个依赖就是&#xff1a; spring-cloud-starter-loadbalancer。 顾名思义&#xff0c;这个包的作用就是用来做负载均衡的。 简单解释一下什么是负载均衡&#xff0c;就是当我们的服…

Java8新特性:Lambda表达式

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

图像识别的精度与效率优化研究

基于深度学习的图像识别算法研究 摘要&#xff1a;随着深度学习技术的快速发展&#xff0c;基于深度学习的图像识别算法已经成为计算机视觉领域的研究热点。本文将介绍基于深度学习的图像识别算法的基本原理、研究进展和应用领域&#xff0c;并探讨其未来的发展趋势。 一、引言…

AI 搜索将如何影响 SEO

用户可以与之交互的 AI 搜索结果是肯定的。搜索营销人员要么对此感到生气&#xff0c;什么都不做&#xff0c;要么他们可以调查即将发生的事情并做好准备。 Google SGE 和 Bing 提供了相当相似的 AI 方法&#xff0c;是传统搜索和聊天机器人的混合体。 但这并不一定是当今 AI…

HarmonyOS--基础组件Text

Text组件 可以包含Span子组件。 接口 Text(content? : string | Resource) string: Text(我是ttttt) Resource: Text($r(app.string.aaaaaa)) 先找限定词目录&#xff0c;找不到内容 找base目录 属性 除支持通用属性外&#xff0c;还支持以下属性&#xff1a; 名称 参数…

全国合作商标服大赛决赛完整规则流程

本文是全国合作商标服大赛决赛完整规则流程&#xff0c;有需要的朋友可以参考下。 一、抢答比拼 1、政策管理考核题 系统评分。抢答题共15题/条线&#xff1a;单选10题&#xff0c;多选5题&#xff0c;基础分100分 单选答对10分/答错-5分&#xff0c;多选答对20分/答错-10分…

Mozilla 推出 Solo:借助 AI 帮助零编程用户创建网站

Mozilla 近日推出名为 Solo 的全新项目&#xff0c;面向没有任何编程经验的用户&#xff0c;通过融入 AI 能力&#xff0c;所创建的网站可以媲美专业开发者的开发效果。 Mozilla 表示该项目主要针对中小型企业、个体户&#xff0c;在官方演示中&#xff0c;用户只需要输入文本、…

SAP ABAP 使用cl_md_bp_maintain=>maintain更新BP税号CN0的数据,更新结果都会变成CN5类型问题处理

SAP ABAP 使用cl_md_bp_maintain>maintain更新BP税号CN0的数据&#xff0c;更新结果都会变成CN5类型&#xff0c;CN1类型一切正常。 1、BP税号 2、跟踪方法中代码 查看底层逻辑&#xff0c;发现CN0都被强制替换成CN5了&#xff0c;BP GUI界面还能正常使用CN0. 查询NOTES&a…

QT -CloudViewer工具

QT -CloudViewer工具 一、演示效果二、关键程序三、程序下载 一、演示效果 二、关键程序 void CloudViewer::doOpen(const QStringList& filePathList) {// Open point cloud file one by onefor (int i 0; i ! filePathList.size(); i) {timeStart(); // time startmycl…

快速排序(为什么不叫二分排序呢)

干完工作的时候突然想起来快速排序我一直没学&#xff0c;就去看了一下别人写的博客&#xff0c;用的就是二分查找的思想&#xff0c;而且感觉挺像插入排序的。 插入排序是寻找最大&#xff0c;小值&#xff0c;而快排是确定一个数的左右区域。 package com.qx;import java.u…

个人封装的 Controller 的返回值封装类

虽然结构都是 code、msg、data 三个参数。 但友好且可控的封装&#xff0c;能更好的约束后续研发人员的扩展。 package com.example.demo.utils;import lombok.Data;import java.io.Serializable;/*** author Rain* date 2023/11/30*/Data public class Result<T> impl…

【INTEL(ALTERA)】 quartus F-Tile HDMI 英特尔 FPGA IP设计示例无法正常工作怎么办

项目场景&#xff1a; quartus F-Tile HDMI 英特尔 FPGA IP设计示例无法正常工作。 原因分析&#xff1a; 由于英特尔 Quartus Prime Pro Edition 软件版本 22.4 中存在一个问题&#xff0c;对 SystemPLL IP 的更改导致 rx_tmds_clk 无法切换/保持在较低水平。 如果此时钟无…

Java 创建事件(Event)、事件监听器(EventListener)、事件发布(publishEvent)详解

在Java中&#xff0c;创建事件&#xff08;Event&#xff09;、事件监听器&#xff08;EventListener&#xff09;和事件发布&#xff08;publishEvent&#xff09;的工作原理涉及到观察者设计模式。这种设计模式用于实现对象之间的松耦合通信。事件&#xff08;Event&#xff…

Layui继续学习

1、简单评论区代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>社区评论区</title> <link rel"stylesheet" href"https://cdn.staticfile.org/layui/2.6.8/css/…

1+X大数据平台运维职业技能等级证书中级

hadoop&#xff1a; 由于我的功能限制&#xff0c;我无法直接为您执行这些操作或提供实际的截图。但我可以为您提供一步步的指导&#xff0c;帮助您完成这些任务。 1. 解压JDK安装包到“/usr/local/src”路径&#xff0c;并配置环境变量。 - 解压JDK&#xff1a;tar -zxf jd…