前言:
PHP常用的应用框架有tp、Yii、laravel等都需要进行工具规划。
当下以tp框架为例,不管是thinkphp6还是thinkphp8或是thinkphp5,我们需要规划model层工具、需要规划validate层工具。为了长久考虑或是多环境考虑,我建议至少要规划model层工具。
拓展:
比如我前文中写到过MySQL多实例,后面会说到的MySQL主备,MySQL主从复制,MySQL高可用,MySQL双主,MySQL双主多从等。还有我在前文中写到过Redis的多实例,Redis的主备,Redis的主从及哨兵,Redis的集群等。就是通过规划model工具层来进行管理的。
现实中:
我把我常用的方法进行了总结:就是采用Redis与MySQL综合使用。下面贴出代码
<?php
/*** 本工具只针对单台服务器有用,可以配置多个数据库* 数据管理工具* Created by PhpStorm.* User: EDZ* Date: 2021/11/4* Time: 11:45*/
namespace app\model;
use app\BaseError;
use Predis\PredisException;
use Redis\Redis;
use think\facade\Db;
use think\service\ModelService;
class Tools extends ModelService{/*** 列表获取 -- 普通的* @ param $table 表名 必填项* @ param string $where 条件* @ param string $field 字段* @ param string $limit 分页及具体分页* @ param string $order 排序* @ param array $join 跨表联查* @ param string $connection 指定MySQL数据库配置文件* @ return array 返回二维数组*/protected static function dataLists($table, $where = [], $field = '*', $limit = [], $order = '', $join = [], $connection = ''){try {if (empty($table))throw new \ErrorException('表名必须填写');if (empty($connection)) {$model = Db::name($table);} else {$model = Db::connect($connection)->name($table);}if (!empty($field)) $model->field($field);if (is_array($join) && count($join) >= 1) {$model->alias('a');foreach ($join as $v) {$model->join($v[0],$v[1]);}}if (is_array($where) && count($where) >= 1) $model->where($where);if (!empty($order)) $model->order($order);$coun = [];if(is_array($limit)){if(count($limit) == 2){$coun['total'] = $model->count();$model->limit(($limit[0] - 1) * $limit[1], $limit[1]);}else if(count($limit) == 1){$model->limit($limit[0]);}else{throw new \ErrorException('limit参数错误');}}$res = $model->select()->toArray();return array('info' => $res, 'page' => $coun);} catch (\Exception $e) {//Log::write(sprintf('%s:系统错误: %s IN: %s LINE: %s', __METHOD__, $e->getMessage(), $e->getFile(), $e->getLine()), 'Error');throw new BaseError($e->getMessage(),50000,200);}}/*** 借助Redis查找列表数据(默认以主键倒序的,无法更改)* 缺点:如果数据量过大,需要手动更新Redis里面的数据后才能启动后台* @param $table 表名 必填项* @param array $where 条件* @param string $field 字段* @param array $limit 长度* @param string $connection 对应的数据库配置* @return array*/protected static function dataRedisLists($table, $where = [], $limit = [], $connection = ''){try {if(empty($table))throw new \ErrorException('表名必须填写');$key = config('database.connections.'.$connection.'.prefix').$table;$redis = Redis::select(config('cache.stores.redis.data_db_admin'));$number = $redis->llen($key.'_pk');if(empty($connection)) {$model = Db::name($table);}else{$model = Db::connect($connection)->name($table);}if($number == 0){$list = $model->field($model->getPk())->order($model->getPk().' DESC')->select()->toArray();if(count($list) > 0){foreach($list as $v){$redis->lpush($key.'_pk', $v[$model->getPk()]);}}}if(count($where) == 0){$start = ($limit[0]-1)*$limit[1];$stop = $limit[1]*1;$list = $redis->sort($key.'_pk', array('sort' => 'desc','limit' => array($start,$stop)));}else{$list = $model->field($model->getPk())->where($where)->select()->toArray();$list = array_column($list,$model->getPk());}$coun['total'] = $redis->llen($key.'_pk');return array('info' => $list, 'page' => $coun);} catch (\Exception $e) {//Log::write(sprintf('%s:系统错误: %s IN: %s LINE: %s', __METHOD__, $e->getMessage(), $e->getFile(), $e->getLine()), 'Error');throw new BaseError($e->getMessage(),50000,200);}}
}
下面既可以调用MySQL直接输出,也可以采用Redis队列读取数据唯一编号,后面程序循环读取数据库中具体值