Yii2控制台程序最佳实践
模板工程标准的控制台程序要素:
(1)完整明确文字提示用户(并且使用红,绿,黄三种颜色标识提示文字;红色为错误相关,绿色为成功相关,黄色为进行中提示)
(2)告知用户运行进度(完成任务的一部分即显示进度条)
(3)如果需要用户做出选择,应该出现文本选择组件(通常为让用户选择yes还是no,或者使用1,2,3让用户做出选择)
(4)支持空执行(即使用事务回滚的方法,做出模拟执行,以避免在真正执行时出现错误,真正执行前会发现错误)
(5)支持无限次运行(使用缓存记录ID号的方法,若已经执行过则不再执行)
(6)命令行可以支持加参数
(7)核心业务逻辑应该被封装
例如:
/** * 山西永济基地的成品均改为标准件 * 运行命令为./yii wms-handle/handle-piece-type-for-shanxi */ public function actionHandlePieceTypeForShanxi(){ //提示用户选择模拟更新还是真实更新 if(Console::confirm("请选择真实更新还是模拟更新;模拟更新不会真正更新数据;[yes]为真实更新[no]为模拟更新")){ $tip = Console::ansiFormat(PHP_EOL."正在轮询真实更新中",[Console::FG_GREEN]); Console::output("{$tip}"); unset($tip); $is_update=true; }else{ $tip = Console::ansiFormat(PHP_EOL."正在模拟更新中,不会真正更新",[Console::FG_RED]); Console::output("{$tip}"); unset($tip); $is_update=false; } $wmsProductInSheetModels = \core\models\WmsProductInSheet::find()->where(['common_producer_info_id'=>14, 'piece_type'=>2])->orderBy(['id'=>SORT_ASC])->all(); //设置进度条 Console::startProgress(0, count($wmsProductInSheetModels)); foreach ($wmsProductInSheetModels as $key => $wmsProductInSheetModel){ $transtion = \Yii::$app->db->beginTransaction(); try { //提示文字 $tip = Console::ansiFormat(PHP_EOL . "正在处理成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}", [Console::FG_YELLOW]); Console::output("{$tip}"); unset($tip); //已经处理过则无需再次处理 if (\Yii::$app->redis->sismember("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductInSheetModel->wms_product_in_sheet_number)) { throw new \yii\db\Exception(PHP_EOL . "成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}已经更新过,无需再次更新"); } //核心处理逻辑 $updateHandler = $wmsProductInSheetModel->updatePieceTypeFrom2To1(); if (!$updateHandler['status']){ throw new \yii\db\Exception($updateHandler['errmsg']); }else{ //提示文字 $tip = Console::ansiFormat(PHP_EOL . "正在处理成品入库单{$wmsProductInSheetModel->wms_product_in_sheet_number}成功", [Console::FG_GREEN]); Console::output("{$tip}"); unset($tip); } //更新进度条 Console::updateProgress($key + 1, count($wmsProductInSheetModels)); //如果是模拟更新则回滚 if (!$is_update) { throw new \yii\db\Exception(PHP_EOL . "此次是模拟更新,不会真正更新,正在回滚到初始状态!"); } $transtion->commit(); //将已更新的入库单号添加到已更新队列中 \Yii::$app->redis->sadd("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductInSheetModel->wms_product_in_sheet_number); } catch (\yii\base\Exception $e) { $transtion->rollBack(); $tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]); Console::output("{$tip}"); unset($tip); } catch (\yii\base\ErrorException $e) { $transtion->rollBack(); $tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]); Console::output("{$tip}"); unset($tip); } unset($wmsProductInSheetModel); } unset($wmsProductInSheetModels); //设置进度条 Console::endProgress(); //成品出库单 $wmsProductOutSheetModels = \core\models\WmsProductOutSheet::find()->where(['common_producer_info_id'=>14, 'piece_type'=>2])->orderBy(['id'=>SORT_ASC])->all(); //设置进度条 Console::startProgress(0, count($wmsProductOutSheetModels)); foreach ($wmsProductOutSheetModels as $key => $wmsProductOutSheetModel){ $transtion = \Yii::$app->db->beginTransaction(); try { //提示文字 $tip = Console::ansiFormat(PHP_EOL . "正在处理成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}", [Console::FG_YELLOW]); Console::output("{$tip}"); unset($tip); //已经处理过则无需再次处理 if (\Yii::$app->redis->sismember("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductOutSheetModel->wms_product_out_sheet_number)) { throw new \yii\db\Exception(PHP_EOL . "成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}已经更新过,无需再次更新"); } //核心处理逻辑 $updateHandler = $wmsProductOutSheetModel->updatePieceTypeFrom2To1(); if (!$updateHandler['status']){ throw new \yii\db\Exception($updateHandler['errmsg']); }else{ //提示文字 $tip = Console::ansiFormat(PHP_EOL . "正在处理成品出库单{$wmsProductOutSheetModel->wms_product_out_sheet_number}成功", [Console::FG_GREEN]); Console::output("{$tip}"); unset($tip); } //更新进度条 Console::updateProgress($key + 1, count($wmsProductOutSheetModels)); //如果是模拟更新则回滚 if (!$is_update) { throw new \yii\db\Exception(PHP_EOL . "此次是模拟更新,不会真正更新,正在回滚到初始状态!"); } $transtion->commit(); //将已更新的入库单号添加到已更新队列中 \Yii::$app->redis->sadd("in_sheet_number_updated_piece_type_for_shanxi", $wmsProductOutSheetModel->wms_product_out_sheet_number); } catch (\yii\base\Exception $e) { $transtion->rollBack(); $tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]); Console::output("{$tip}"); unset($tip); } catch (\yii\base\ErrorException $e) { $transtion->rollBack(); $tip = Console::ansiFormat(PHP_EOL . $e->getMessage(), [Console::FG_RED]); Console::output("{$tip}"); unset($tip); } unset($wmsProductOutSheetModel); } unset($wmsProductOutSheetModels); //设置进度条 Console::endProgress(); }
模拟执行的过程如下所示:
真实更新的过程如下:
Yii2控制台程序最佳实践的更多相关文章
- YII2 随笔 视图最佳实践
yii\base\Controller::render(): 渲染一个 视图名 并使用一个 布局 返回到渲染结果. yii\base\Controller::renderPartial(): 渲染一个 ...
- 【转】优化Web程序的最佳实践
自动排版有点乱,看着蛋疼,建议下载中文PDF版阅读或阅读英文原文. Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践.他们为此进行了 一系列的实验.开发了各 ...
- paip.java win程序迁移linux的最佳实践
paip.java win程序迁移linux的最佳实践 1.class load路径的问题... windows哈第一的从calsses目录加载,,而linux优先从jar加载.. 特别的是修理了ja ...
- Windows Azure 安全最佳实践 - 第 6 部分:Azure 服务如何扩展应用程序安全性
多种Windows Azure服务可以帮助您将应用程序安全性扩展到云. 有三种服务可提供多个提供程序之间的身份标识映射.内部部署数据中心间的连接和相互发送消息的应用程序功能(无论应用程序位于何处). ...
- Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二)
Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一) 接上一篇 3. Nginx配置反向代理 3.1 cnetos 安装nginx 首先,我们需要在服务器上安装N ...
- Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一)
环境 本地 win7 服务器:Virtual Box 上的Centos ssh工具: Xshell 文件传输: xftp 1.在本地创建asp.net core应用发布 1.1 使用Vs2017 新建 ...
- mpvue最佳实践 , 美团出的一个小程序框架
看手机微信,看到说美团出了1个小程序框架, mpvue 搜下来试试,看了网上的一个对比 ----------------- 以下为引用 我们对微信小程序.mpvue.WePY 这三个开发框架的主要能 ...
- Atitit. Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g
Atitit. Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g 两个方式::: 键盘式::先用热键呼叫出QS,然后开始输入程序中的部分字母,按En ...
- Javascript模块化编程(一)模块的写法最佳实践六、输入全局变量 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。 为了在模块内部调用全局变量,必须显式地将其他变量输入模块。
Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块但是,Javascript不是一种模块化编程语言,它不支持类clas ...
随机推荐
- Redis之过期时间
1.命令介绍 expire key seconds 设置key的有效时间,单位为秒expire命令返回1表示设置成功,返回0表示键不存在或设置失败. ttl keyttl命令返回值是键的剩余时间 ...
- 红米Note5进入全网通5.0时代,其实是高通已经落后了!
高通早在去年12月份就正式发布了新一代的骁龙845处理器,接下来就是人们对于搭载骁龙845处理器的手机充满期待,可是转眼到了2018年的3月份,目前已经发布的高端旗舰新机却只有三星S9和三星S9+,而 ...
- win7 64位操作系统 电脑桌面出现this computer is being attacked的窗口
本人为win7 64位操作系统,戴尔笔记本电脑. 昨天在教室写程序来着,突然桌面上出现this computer is being attacked的窗口,如下所示.每隔半分钟左右出现在电脑桌面上转两 ...
- 项目Alpha冲刺4
作业描述 课程: 软件工程1916|W(福州大学) 作业要求: 项目Alpha冲刺(团队) 团队名称: 火鸡堂 作业目标: 介绍第四天冲刺的项目进展.问题困难和心得体会 1.团队信息 队名:火鸡堂 队 ...
- mysql 索引原理
一.索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之 ...
- linux内存源码分析 - 内存压缩(同步关系)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 最近在看内存回收,内存回收在进行同步的一些情况非常复杂,然后就想,不会内存压缩的页面迁移过程中的同步关系也 ...
- SkylineGlobe 7.0版本 矢量数据查询示例代码
在Pro7.0.0和7.0.1环境下测试可用. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- CF741 D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
题目意思很清楚了吧,那么我们从重排回文串的性质入手. 很容易得出,只要所有字符出现的次数都为偶数,或者有且只有一个字符出现为奇数就满足要求了. 然后想到什么,Hash?大可不必,可以发现字符\(\in ...
- 《了不起的 nodejs》中 TwitterWeb 案例 bug 解决
了不起的nodejs算是一本不错的入门书,不过书中个别案例存在bug,按照书中源码无法做出和书中相同效果,原本兴奋的心情掺杂着些许失落. 现在我们看一下第七章HTTP,一个 Twitter Web 客 ...
- 性能调优9:根据WaitType诊断性能
SQL Server数据库接收到查询请求,从生成计划到执行计划的过程,等待次数和等待时间在一定程度上揭示了系统性能的压力,如果资源严重不足,就会成为性能的瓶颈.因此,对等待的监控非常有助于对系统性能进 ...