为啥要编写命令行程序?

命令行程序通常是一个脚本,但是PHP Yii 是web开发语言,如何能开发脚本程序?

所以,首先我们要明白使用PHP Yii 编写脚本语言的目的和原理。

目的

设想这么一个场景,你开发了一个电子商务网站,在测试阶段,你希望模拟用户的下单操作。或者你开发了一个类股票网站,在测试阶段,你需要模拟用户的委托买入、卖出操作,并撮合用户的买入和卖出。毕竟,如果想模拟大量用户的操作,而通过手动在数据库中添加测试数据,这工作量有点大。

所以,编写Yii 脚本的目的是,通过运行脚本,自动生成用户的下单操作。这个类似于一个服务器端的程序,可以用JAVA写,但是我们是PHP程序员啊,当然用PHP实现了。

原理和流程

使用PHP Yii 编写脚本的程序的基本原理是这样的:

(1)编写一个Command类,类名和文件名以Command为后缀,同时继承父类CConsoleCommand,文件存放在工程下的protected/commands/目录下,例如:

class TestCommand extends CConsoleCommand

(2)编写Command类的动作,类似控制器的动作,动作名需要以action为前缀,例如:

public function actionTest(){

echo "command test successfully.";

}

echo的内容会打印在Windows DOS或Linux的命令行程序页面上。完整的命令类如下:

<?php

class FarmProduceMatchCommand extends CConsoleCommand

{

/**

* Execute the action.

* @param array command line parameters specific for this command

*/

/*

public function run($args)

{

if(!isset($args[0]))

$this->usageError('please input params.');

echo('you input :\n');

var_dump($args);

}

*/

public function actionTest(){

echo "command test successfully.";

}

}

(3)如何运行自定义的Command类和动作呢,很简单,不需要配置PHP和Yii的环境和变量。打开Dos(windows系统)或Terminal(Linux系统),在命令行,将目录定位到你的yii工程的protected目录,该目录下有yiic命令程序。比如,我的工程目录在“C:\xampp\htdocs\syjjq2”,“syjjq2”就是我的yii工程。在命令行将目录定位到syjjq2工程下的protected目录,工程目录结构如下:

为什么要调用你工程下的protected目录的yiic.bat,而不直接调用Yii框架目录下的yiic.bat,主要原因是你的工程下的protected下的yiic.bat能自动识别该工程中的命令类和动作。而yii框架目录下的则找不到你自定义的命令。

下面我们操作一下在命令行调用自定义的动作,命令格式是:【yiic 自定义命令类名称 动作名称】。需要注意的是,这里的命令类名称和动作名称,与控制器名称和动作名称一样,可以把命令类想象成一个控制器,所以,命令名就是命令类的类名去掉command后缀,然后第一个字母小写,动作名称就是动作函数的名称去掉action前缀,然后第一个字母小写即可。比如,我想看看我自定义的FarmProduceMatchCommand命令类有几个动作,可以使用【yiic 自定义命令类名称】:

其实这种命令写法,没有指定要执行该命令类的哪一个动作,默认会执行名称为index的动作,但是,我们这个类没有名为index 的动作,所以它报了一个错,同时,会把该命令类下所有的动作都罗列出来。

好了,那我们正式执行我们自定义的FarmProduceMatchCommand命令类的test动作:

到此,我们自定义的命令类和动作就执行成功了!

进阶

(1)run函数。

Command类的起始函数为run,该函数继承自CConsoleCommand类,当你自定义的Command类重载run函数的时候,其他的自定义动作对于命令行来说都会失去效果,即当run函数存在的时候,无法在命令行调用其他的自定义动作,因为run函数会拦截其他动作的调用,把调用的动作认为是run函数的传入参数。比如,我们把上面的FarmProduceMatchCommand类中的run函数部分的注释去掉,你再在命令行运行刚才的【yiic farmProduceMatch test】命令试试,执行结果如下:

看到没,你希望执行的是farmProduceMatch的test动作,结果执行的是run函数,并且,你输入的动作名test被认为是run函数的一个传入参数。

run函数接收一个参数数组,你可以在命令行输入多个参数,以空格隔开即可,如:

yiic farmProduceMatch param1  param2  param3  param4……

也就是说,如果你的命令类中只有一件事情要处理,可以直接在run函数中编写。但通常来说,业务比较复杂的情况下,就需要在一个命令类中执行多个动作了,比如:生成委托买入订单动作,生成委托卖出订单动作,生成撮合委托订单动作……当你需要编写多个动作,并且分别需要在命令行中调用某个动作的时候,就需要把这个run函数给注释掉了。

(2)动作函数如何在命令行传入参数。

我们把上面的test动作稍微改一下:

public function actionTest($param1, $param2){

echo "command test successfully. you have input:$param1, $param2";

}

我给test函数添加了两个参数,并在屏幕上打印出来用户输入的两个参数:

在命令行传入参数的时候要遵循格式【yiic 自定义命令类名称 动作名称 --参数1=参数值 --参数2=参数值 --参数3=参数值……】。

即要在你的动作参数名钱加两个‘-’,后面跟上赋值即可。多个参数赋值使用逗号隔开即可。

(3)执行yiic时报错。

执行yiic命令时,如果报错的话,例如php不是内部或外部命令之类的,你需要修改一下protected/yiic.bat文件,原始内容如下:

@echo off

rem -------------------------------------------------------------

rem Yii command line script for Windows.

rem This is the bootstrap script for running yiic on Windows.

rem -------------------------------------------------------------

@setlocal

set BIN_PATH=%~dp0

if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe

"%PHP_COMMAND%" "%BIN_PATH%yiic.php" %*

@endlocal

你要把“PHP_COMMAND=php.exe”改成你实际的PHP路径。比如我用的是集成PHP环境xampp,放在C:目录下的,那么php目录在“C:\xampp\php”。改成“PHP_COMMAND=C:\xampp\php\php.exe”即可。

(4)使用yiic命令,找不到自定义的命令类和动作。

其实这个很简单,前面我已经提到过了。自定义的command类,要放在/protected/commands/目录下;运行的yiic命令为/protected/yiic.bat文件,不要运行Yii framework下的yiic;检查自定义command类的文件名称和类名称命名是否规范,以及动作的命名是否规范。

(5)如何配置command类的相关配置项

Yii框架分为两个部分,一个是web,一个是cli,即命令行程序。cli模式有单独的配置文件:“/protected/config/console.php”。比如,你的自定义command类中,需要调用数据库,模型类,或者其他模块的文件,就需要在console.php中配置了。配置方法和main.php中一样。

高级

上面的例子我们已经讲了,如何编写命令类和动作,如何运行,等等。到此,我们也大概了解了yii的命令行运行机制,其实就是通过yiic命令调用某个命令类和动作。

下面,我们设想如下情景,我们需要模拟不同的用户在不同的时间进行下单操作。如果只是产生一条测试数据的话,我们直接在命令行中执行一下该动作即可,但是模拟不同时间不同用户的情况的话,我们就需要定时执行某个动作了。

定时执行某个动作,我们可以不用cli,直接写个控制器,然后写个动作,动作中有个死循环,每隔多长时间执行一次某个函数来生成一条测试数据。

但这种方法我觉得太过于笨重了,毕竟php属于web语言,让他执行一个服务端程序的事情确实有些不妥。

如果了解windows脚本或linux shell的同学应该可以想到这种方法,把命令行执行自定义命令类和动作的指令写入一个文本文件,然后将文件名的后缀改成*.bat(Windows系统),这样我们就创建了一个脚本,双击执行这个脚本,就会自动执行生成一条模拟用户下单的测试数据,就不用我们在命令行输入命令了。

比如,我创建一个test.bat文件,使用记事本打开,输入以下内容:

C:\xampp\htdocs\syjjq2\protected\yiic farmProduceMatchtest --param1=hello --param2=world

输入好后保存,我们就创建好了这个脚本。

如何自动执行这个脚本呢?我们可以创建一个系统计划任务,定时执行这个脚本。以下以Win7为例,讲解如何创建定时计划任务来定时执行我们的脚本。

首先,右键“计算机”,选择“管理”菜单,进入“计算机管理”页面:

在左栏,选择“计划任务程序”,然后在右栏选择“创建任务…”,打开创建任务对话框。

(1)创建任务-常规

任务的名称和描述可以随意写。安全选项和配置根据自己的需求写。其中,安全选项如果选择“只在用户登录时运行”,如果你的电脑又没设置密码,不需要登录,你的定时任务就永远无法执行了,所以,我选择第二个。

(2)创建任务-触发器

打开“触发器”选项卡,点击“新建…”按钮,我们新建一个触发器。触发器的内容可以根据你的需求填写,上图中,我创建了一个从当前时间开始每隔5分钟执行一次脚本的触发器。“启用”一定要勾上啊。

(3)创建任务-操作

打开“操作”选项卡,点击“新建…”按钮,新建一个操作。操作类型为“启动程序”,然后选择要执行的脚本文件的位置。如果要添加起始参数的话,可以在该页面进行配置。

(4)创建任务-条件

打开“条件”选项卡,根据自己的需求选择。

(4)创建任务-设置

打开“设置”选项卡,根据个人需求进行配置。

然后就可以点击“确定”按钮保存该任务计划了。

到此,任务计划已经创建完成,但是还没有结束。点击确定按钮创建任务计划成功后,在任务计划页面我们会看到我们创建的任务:

可以看到,我们创建的任务已经在任务列表中了,但是“状态”是“准备就绪”,也就是说任务还没开始运行。选择我们创建的任务,在右栏中选择“运行”,再看看我们创建的任务状态,变成“正在运行”就说明我们已经创建并运行任务计划成功了!

php 创建任务程序命令行,PHP Yii 命令行程序以及定时任务详解相关推荐

  1. 【转帖】windows命令行中java和javac、javap使用详解(java编译命令)

    windows命令行中java和javac.javap使用详解(java编译命令) 更新时间:2014年03月23日 11:53:15   作者:    我要评论 http://www.jb51.ne ...

  2. linux find文件,并复制,通过find命令寻找文件并拷贝到一个指定目录方法详解

    有这样的一个需求,需要将一部分符合条件的文件从一个目录拷贝到另一个目录中,可以通过使用find命令从源目录查找到符合条件的文件然后使用cp命令拷贝到目标目录 将通过find命令找到的文件拷贝到一个新的 ...

  3. 文本查找查找命令的grep 、egrep、fgrep用法的详解

    文本查找查找命令的grep .egrep.fgrep用法的详解 一.学习目标 了解并能熟悉运用grep.egrep.fgrep命令. 二.学习内容 1.grep.egrep.fgrep命令的意思和用法 ...

  4. python小游戏代码大全-20行python代码的入门级小游戏的详解

    背景: 作为一个python小白,今天从菜鸟教程上看了一些python的教程,看到了python的一些语法,对比起来(有其他语言功底),感觉还是非常有趣,就随手添了一点内容,改了一个小例程,当着练练手 ...

  5. 解决C#程序只允许运行一个实例的几种方法详解

    解决C#程序只允许运行一个实例的几种方法详解 参考文章: (1)解决C#程序只允许运行一个实例的几种方法详解 (2)https://www.cnblogs.com/randyzhuwei/p/5403 ...

  6. navicat创建MySql定时任务详解

    目录 navicat创建MySql 定时任务详解 一.开起定时任务 二.通过navicat创建定时任务 三.关闭.启动.别名.移动.删除event 四.查询Event信息 navicat创建MySql ...

  7. 小程序怎么处理轮训ajax,微信小程序中使用Promise进行异步流程处理的实例详解...

    微信小程序中使用Promise进行异步流程处理的实例详解 我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理.比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间( ...

  8. springboot 获取登录浏览器_java项目部署到linux服务器,微信小程序后台springboot项目部署到云服务器(图文详解)...

    前面给大家讲了一个点餐系统的开发,包括java点餐后台和微信点餐小程序.可是都是教大家如何在本地把项目跑起来.今天就来教大家如何把这个点餐系统部署到服务器,实现商用. 传送门 点餐系统的开发,java ...

  9. go语言之行--golang核武器goroutine调度原理、channel详解

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

  10. redis重启命令_请收下这份redis持久化详解

    前言 Redis支持RDB和AOF两种持久化机制, 持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的文件即可实现数据恢复. RDB介绍 按指定时间间隔把数据生成快照保存 ...

最新文章

  1. Paging Library使用及原理
  2. 2021-01-07 matlab数值分析  插值法 拉格朗日插值法 牛顿插值法
  3. Particle Filter Tutorial 粒子滤波:从推导到应用(三)
  4. Kettle环境搭建及使用(数据迁移)
  5. 测试面试题集-3.生活物品测试:杯子、伞、钢笔、桌子
  6. python standardscaler_定制便携python工具箱
  7. 生活的 tricks
  8. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_11-MongoDb入门-安装Mongodb数据库...
  9. php20行代码写小偷程序,PHP100教你20行代码写小偷程序
  10. 2022全新【趣盒】iapp源码带后台非常好看
  11. Android-MeasureSpec那些事 1
  12. 知乎提示浏览器版本过低怎么办
  13. 监控网页内容,发现需要的内容后弹框和声音提醒
  14. 行业陷入“围城”效应,新茶饮品牌凛冬将至
  15. google开放的一些接口
  16. us、ms、s 单位转换,不会的都是大傻子!!!
  17. 【ArcGIS风暴】气象台站气温(降水)矢量数据插值成栅格气温(降水)空间数据
  18. Qt实现QQ截图中的马赛克效果
  19. 【JavaSE】Java9Java10Java11新特性(687~717)
  20. Android 编译速度优化黑科技 - RocketX

热门文章

  1. 5.软件架构设计:大型网站技术架构与业务架构融合之道 --- 网络
  2. 30. Element parentNode 属性
  3. HTTP 1 1与HTTP 1 0的比较
  4. [原创]MOF提权下载者代码
  5. sqlsever 创建一个通用分页查询
  6. Python心得基础篇【7】面向对象进阶篇
  7. Allegro导出STP文件
  8. =、:=、?=、+=
  9. [BZOJ1007][HNOI2008]水平可见直线 计算几何
  10. Xcode模拟器simulators安装