首先,当您接触yii框架时,您会发现,它已经精心设计好了一套命令行应用程序,那就是yiic
命令yiic原有的一些命令,我们可以创建web应用/控制器/模型/模块等等。
我们可以安yiic的风格,写出基于yii框架的命令行应用,这里的命令行应用基本上是配合Web应用来做的,什么时候会用到呢,最明显的例子是,crontab的应用,
例如:我们设计一个发送邮件系统,由于用户,或发送的信件很多,通过web方式发送非常站用http服务器资源,
估,我们准备通过数据表模拟发送队列,通过crontab定时执行这个命令,读取数据库表中的部分数据,发送邮件,
这个命令只占用系统中的一个进程,不会影响http的响应。当然,大型网站,会有专门的job服务器。
费话不多说了,先搭建环境
1.当你通过yiic创建一个webapp应用后,
会在webapp/protected/下生成yiic.php, 由于是命令行应用,所以这里的yiic.php其实就是与webapp下的index.php一样的,命令行入口文件。
2.打开yiic文件,添加一行设置,将commands目录的路径添加到yiic中,这样,yiic就能够找到commands目录下的命令文件了,修改后的代码如下,红色为新加入代码:
<?php
// change the following paths if necessary
$yiic=dirname(__FILE__).'/../../yii-read-only/framework/yiic.php';
$config=dirname(__FILE__).'/config/console.php';
@putenv('YII_CONSOLE_COMMANDS='. dirname(__FILE__).'/commands' );
require_once($yiic);
3.我们在commands目录下创建一个文件,由于我们要做一个发邮件的命令,所以命名为MailCommand.php
代码如下:
<?php
/**
* Description of MailCommand
*
* @author syang
*/
class MailCommand extends CConsoleCommand {
public $defaultAction='cron'; //这是一个缺省action名称,默认是index,这里我修改成了cron
/**
* cron action
* @param int $limit
*/
public function actionCron($limit=5) {
if (!$this->checkMon(__METHOD__)) {
$this->runError('The command is running. Please try again later.');
}
if ($limit >= 100 or $limit <= 0) {
$this->usageError('The limit parameter greater than 0 and less than 100');
}
MailQueue::model()->send($limit);
}
public function usageError($message)
{
echo("Error: $message\n\n".$this->getHelp()."\n");
exit(1);
}
public function runError($message)
{
echo("Error: $message\n\n");
exit(1);
}
protected function checkMon($action='', $process_num=1) {
if ($action=='') $action = $this->defaultAction;
$commandname = get_class($this);
$commandname = str_replace('command', '', strtolower($commandname));
if (strpos($action, "::")!== false) {
$action = substr(strtolower(end(explode("::", $action))), strlen('action'));
}
$cmd = "ps -ef | grep -v grep | grep yiic | grep \"{$commandname}\" ";
if ($action!=$this->defaultAction) {
$cmd .= "| grep \"{$action}\" ";
}
$cmd .= "| wc -l ";
$current_process_num = shell_exec($cmd);
if ( intval($current_process_num) > $process_num ) {
return false;
}
else {
return true;
}
}
}
ok,让我先讲解一下MailCommand类,这个扩展了CConsoleCommand,主要方法actionCron,与我们在Web应用中的控制器写方类似,actionCron方法有一个参数叫limit,它有一个缺省值,
注意:
如果actionXXX方法有参数,且没有缺省值,则在调用命令时,则必须指定参数(否则会报用法错误)。
如果actionXXX方法没有参数,则在调用命令时,不能指定参数 (否则会报用法错误)。
如果actionXXX有参数且有缺省值,则调用命令时,可以指定也可以不指定参数
usageError方法是继承自CConsoleCommand,由于CConsoleCommand类中定义的usageError仅仅只是die掉了,shell下返回的值还是0。所以,这里我修改了一下。
注意:通过在shell下执行一条命令后,可以通过$?获得刚才那条命令的执行情况。通常它与普通的程序语言的真假正好相反,即,$?为0表示上一条命令执行成功,如果$?非0则表示上条命令存在错误,执行不成功。
runError方法与usageError类似,只是不显示用法信息。
checkMon方法是我自己写的,主要是通过shell命令(仅限类nix系统)获得当前命令的进程数,举个例子,我们创建的mail命令,是通过crontab定义跑的,如果命令执行时间超过了下一次定时启动,则可能会出现2个或2个以上的进程。通过checkMon,我们基本上可以限制,这条命令可以启动几个进程,默认只有一个进程。通过checkMon方法,我们判断了如果有一个进程存在,就退出。不再运行。
4.ok,下面我们创建一个表mail_queue,sql如下:
CREATE TABLE IF NOT EXISTS `mail_queue` (
`queue_id` int(11) unsigned NOT NULL auto_increment,
`mail_to` varchar(150) NOT NULL default '',
`mail_encoding` varchar(50) NOT NULL default '',
`mail_subject` varchar(255) NOT NULL default '',
`mail_body` text NOT NULL,
`priority` tinyint(1) unsigned NOT NULL default '2',
`err_num` tinyint(1) unsigned NOT NULL default '0',
`add_time` int(11) NOT NULL default '0',
`lock_expiry` int(11) NOT NULL default '0',
PRIMARY KEY (`queue_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
注:为了演示,上面的表我直接使用了ecmall的邮件队列表,以下程序思路基本参考ecmall的程序
5.配置main/console.php,设置import路径,以及db连接,这部份与main.php类似。
并且在params部分添加了mailConfig的配置参数
'params'=>array(
// this is used in contact page
'mailConfig'=>array(
'sender'=> 'YiiBook Test Email',
'from'=> 'webmaster@yiibook.com',
'protocol' => '0', //1 is smtp
'host' => '',
'port' => '',
'username' => '',
'password' => '',
)
),
6.通过yiic或gii创建mail_queue表的模型类MailQueue.php
7. 在 MailQueue.php中添加以下两个方法
/**
* 清除发送N次错误和过期的邮件
*/
function clear()
{
$criteria=new CDbCriteria(array(
'condition'=>" err_num > 3 or add_time < :addtime",
'params'=>array(
'addtime'=> time() - 259200
)
));
//这里使用了CDbCriteria创建查询条件,并通过指定占位符,进行变量绑定。
return $this->deleteAll($criteria);
}
/**
* 发送邮件
*/
function send($limit = 5)
{
/* 清除不能发送的邮件 */
$this->clear();
$time = time();
/* 取出所有未锁定的 */
$mails = $this->findAll(array(
'condition' => "lock_expiry < ?",
'order' => 'add_time DESC, priority DESC, err_num ASC',
'limit' => $limit,
'params' => array($time)
));
//这里直接使用数据代替CDbCriteria类作为条件参数,并使用?作为占位符,
//条件中可以有多个?占位符,参数数组params中值的先后顺序会对应到条件中占位符的顺序。
if (!$mails)
{
/* 没有邮件,不需要发送 */
return 0;
}
/* 锁定待发送邮件 */
$queueIds = $this->getQueueIds($mails);
$lock_expiry = $time + 30; //锁定30秒
$this->updateAll(
array(
"err_num"=>new CDbExpression('err_num + 1'),
'lock_expiry' => $lock_expiry
),
"queue_id in ( {$queueIds} ) "
);
/* 获取邮件发送接口 */
$mailer = new Mailer(Yii::app()->params->mailConfig);
$mail_count = count($mails);
$error_count= 0;
$error = '';
/* 逐条发送 */
for ($i = 0; $i < $mail_count; $i++)
{
$mail = $mails[$i];
$result = $mailer->send($mail->mail_to, $mail->mail_subject, $mail->mail_body, $mail->mail_encoding, 1);
if ($result)
{
/* 发送成功,从队列中删除 */
$mail->delete();
}
else
{
$error_count++;
}
}
}
protected function getQueueIds($mails) {
$queueIds = array();
foreach($mails as $mail) {
$queueIds[]=$mail->queue_id;
}
return implode(",", $queueIds);
}
8.创建Mailer类
在components目录下,创建一个Mailer.php类,代码如下
<?php
/**
* Description of Mail
*
* @author syang
*/
//注意,这里我们要使用一个第三方类库phpmailer,所以我们先将class.phpmailer.php放到vendors下,
//并通过import将路径加入到include_path中,
Yii::import('application.vendors.*');
//引用class.phpmailer.php,由于第三方类库可能不符合yii的加载规则,把以需要手动加载。
require_once 'class.phpmailer.php';
define('MAIL_PROTOCOL_LOCAL', '1');
define('CHARSET', 'UTF-8');
class Mailer {
var $timeout = 30;
var $errors = array();
var $priority = 3; // 1 = High, 3 = Normal, 5 = low
var $debug = false;
var $mailer;
function __construct($config)
{
@extract($config);
$this->mailer = new phpmailer();
$this->mailer->From = $from;
$this->mailer->FromName = $this->_base64_encode($sender);
if ($protocol == MAIL_PROTOCOL_LOCAL)
{
/* mail */
$this->mailer->IsMail();
}
else
{
/* smtp */
$this->mailer->IsSMTP();
$this->mailer->Host = $host;
$this->mailer->Port = $port;
$this->mailer->SMTPAuth = !empty($pass);
$this->mailer->Username = $user;
$this->mailer->Password = $pass;
}
}
function send($mailto, $subject, $content, $charset, $is_html, $receipt = false)
{
$this->mailer->Priority = $this->priority;
$this->mailer->CharSet = $charset;
$this->mailer->IsHTML($is_html);
$this->mailer->Subject = $this->_base64_encode($subject);
$this->mailer->Body = $content;
$this->mailer->Timeout = $this->timeout;
$this->mailer->SMTPDebug = $this->debug;
$this->mailer->ClearAddresses();
$this->mailer->AddAddress($mailto);
$res = $this->mailer->Send();
if (!$res)
{
$this->errors[] = $this->mailer->ErrorInfo;
}
return $res;
}
function _base64_encode($str = '')
{
return '=?' . CHARSET . '?B?' . base64_encode($str) . '?=';
}
}
9.ok,基本完成了,
在命令行下,如我们当前在protected目录下,执行
./yiic mail
或
./yiic mail cron
或
./yiic mail cron --limit=10
总结,本篇仅通过一个具体的例子,演示了yii框架的命令行应用程序开发,仅做抛砖引玉。
涉及了shell的一些应用常识,yii框架的模型操作以及第三方类库的调用。
本人水平有限,欢迎拍砖。
- 浏览: 498499 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (335)
- VM (2)
- python 基础 (78)
- C (7)
- php (38)
- django (8)
- c++ (1)
- python 服务端编程 (21)
- ubuntu (1)
- linux (26)
- mysql (24)
- 缓存管理 (5)
- nginx (4)
- linux 命令行 (16)
- web (8)
- javascript (8)
- python 模块 (3)
- java (6)
- 面试题 (2)
- tornado (1)
- 运维 (10)
- 网络编程 (0)
- svn (5)
- css (1)
- mongodb (3)
- vim (8)
- infobright (1)
- shell (1)
- 算法 (2)
- redis (1)
最新评论
发表评论
-
修改 phpStorm 7.1.3 字体大小
2014-11-08 14:56 625原文地址: http://blog.csdn.net/wi ... -
UNIX时间戳换算问题
2014-02-20 09:35 939转:http://chenyudengyuqiong-163 ... -
php http_build_query
2014-02-12 09:45 844这函数方便,不用自己去拼接了 http_build_que ... -
stream_context_create作用
2014-02-12 09:42 825转 http://huangliangfeixu.blo ... -
php 的 private public protected
2014-01-09 20:14 1233public 表示全局,类内部外部子类都可以访问; pr ... -
CDbConnection failed to open the DB connection: could not find driver
2014-01-02 16:11 1102wamp5 看看是否安装了php_pdo_mysql扩展 ... -
【转】浅谈页面静态化、缓存技术与SEO
2013-12-25 11:17 1336原文地址: 浅谈页面静态化、缓存技术与SEO http ... -
php 路由机制
2013-12-02 17:52 810【转】 http://3haku.net/2012/07/04 ... -
php 跨域问题
2013-11-21 17:36 477header('P3P:CP="IDC DSP C ... -
Forbidden You don't have permission to access
2013-11-19 11:58 1192Forbidden You don't have permi ... -
【转】深入浅出之Smarty模板引擎工作机制(二)
2013-10-13 19:18 717http://www.cnblogs.com/hongfei/ ... -
【转】深入浅出之Smarty模板引擎工作机制 一
2013-10-13 19:12 749http://www.cnblogs.com/hongfei/ ... -
【转 php 优化】Squid是什么,Squid工作原理是什么
2013-11-06 17:43 818http://wuhaoshu.blog.51cto.co ... -
【转】PHP加速插件eAccelerator和Zend Optimizer是什
2013-12-18 09:02 942eaccelerator是一个开放源码的php应用程序加速 ... -
【转 php优化 】三款免费的PHP加速器:APC、eAccelerator、XCache比较
2013-10-12 17:08 829http://www.vpser.net/opt/apc- ... -
php中heredoc的使用方法
2013-10-12 16:31 663Heredoc技术,在正规的PH ... -
【转】php 安全 讨论magic_quotes_gpc、mysql_real_escape_string、addslashes的区别及用法
2013-10-11 18:01 824原文地址: http://blog.unvs.cn/archi ... -
PHP负载均衡指南
2013-10-11 17:55 779原文地址: http://www.yeeyan.org/art ... -
【转】PHP心得(收藏,慢慢看)
2013-09-08 18:39 828转:http://my.oschina.net/liu ... -
PHP配置指令作用域说明(PHP_INI_PERDIR、PHP_INI_SYSTEM、PHP_INI_USER、PHP_INI_ALL)
2013-08-27 10:15 853PHP总共有4个配置指令作用域:(PHP中的每个指令都有自己 ...
相关推荐
2. 组件化设计:Yii框架采用基于组件的设计模式,开发者可以通过复用组件快速组装出复杂的Web应用,大大提升开发效率。 3. 面向对象编程(OOP):Yii是一个纯OOP框架,要求开发者具备面向对象编程的知识和经验,...
一、Yii框架概述: 1. 高性能:Yii通过使用缓存机制、优化的查询构建器和预编译的模板引擎等技术,提供了比其他PHP框架更快的运行速度。 2. MVC设计模式:遵循MVC模式,使得模型、视图和控制器之间职责分明,有利于...
Yii 2.0 是一款基于组件的高性能 PHP 框架,用于开发 Web 2.0 应用程序。此框架提供了丰富的特性,包括 MVC(模型-视图-控制器)架构模式、活动记录(Active Record)、依赖注入(Dependency Injection)、单元测试...
本文档将详细介绍如何在本地环境中搭建并使用YII框架来创建一个简单的Web应用程序。 #### 二、安装与配置 ##### 2.1 环境检查 在开始安装YII之前,需要确保服务器环境满足YII的最低要求。根据文档提供的信息,...
1. **命令运行流程**:Yii框架中的控制台应用主要用于执行命令行任务。开发者可以通过创建命令行脚本来实现复杂的后台处理逻辑。 2. **自定义命令**:Yii框架允许开发者定义自己的控制台命令。这为执行定制任务提供...
在“yii-1.0.11.r1579”这个压缩包中,可能包含了Yii框架的1.0.11版本的源代码,包括核心库、示例应用、文档和可能的升级工具。对于初学者,可以通过阅读文档了解框架结构和用法,然后逐步学习如何创建模型、控制器...
它遵循MVC(模型-视图-控制器)设计模式,使得开发者能够构建可维护、高效的Web应用程序。 1. **Yii框架的基本概念**: - **MVC架构**:Yii中的MVC设计模式将业务逻辑、数据展示和用户交互分离开来,提高了代码的...
Yii PHP框架是一款高效、安全且易于使用的开源Web开发框架,专为快速开发大型Web应用程序而设计。该框架基于组件驱动的架构,强调性能优化,提供丰富的功能和强大的工具,使得开发者能够以最少的代码实现复杂的功能...
- **适用场景**:Yii框架特别适合用于开发高流量的应用程序,如门户、论坛、CMS(内容管理系统)、电子商务系统等。 - **技术要求**:运行基于Yii开发的Web应用需要支持PHP5.1.0或更高版本的Web服务器。此外,熟悉...
Yii2.0高级应用模板是基于Yii框架的二次开发模板,专为PHP开发者设计,用于构建复杂的、高性能的Web应用程序。Yii2.0是Yii框架的最新版本,它提供了许多改进和新特性,旨在提高开发效率和代码质量。如果你不想通过...
`YII框架应用.doc` 和 `YII框架应用.pdf` 可能是关于如何在实际项目中使用Yii的教程或指南。这些文档可能涵盖了从基本的环境设置、路由配置、模型-视图-控制器(MVC)架构的理解到数据库交互、表单处理、缓存管理、...
Yii 框架是一个高效的、基于组件的 PHP 框架,专为开发大型 Web 应用而设计。它的名称 "Yii" 在中文中意为 "易",寓意简单、高效且可扩展。Yii 提供了高度的可重用性,从而能够加快开发速度。为了运行基于 Yii 的 ...
- **灵活适应业务需求**:Yii框架因其高度可定制性和丰富的扩展性,能够快速响应不同业务场景的变化,适用于构建各种规模的应用。 - **统一编码习惯**:通过提供一系列最佳实践指南,帮助团队成员遵循一致的编程规范...
Yii2的高级应用程序模板是专为复杂Web应用设计的一个强大框架。这个模板,名为"yii-advanced-app-2.0.12.tgz",包含了用于构建多层架构的项目结构,适合大型企业级应用或者需要分离前端和后端代码的项目。在Yii2框架...
Yii框架是PHP开发领域中的一个高效且强大的框架,尤其适合构建大规模的Web应用程序。它的名字“Yii”在中文中意为...通过深入阅读和实践,开发者可以迅速提升在Yii框架上的技能,进而更有效地构建和维护Web应用程序。
Yii的设计理念是优化开发效率、性能和可维护性,它提供了丰富的特性来帮助开发者构建复杂的Web应用程序。 在描述中提到的“yii框架好用,升级版本后的更加好用”,这指的是Yii框架的进化历程。Yii有两个主要版本:...
YII2是YII框架的最新版本,基于组件设计,提供MVC(Model-View-Controller)架构模式,支持命令行接口,具有强大的缓存管理,以及优秀的性能优化机制。它采用了现代PHP最佳实践,如依赖注入、单元测试和自动化工作...
Yii2 Advanced框架是一款基于PHP构建的高性能Web应用开发框架,专为专业开发团队设计,用于构建复杂的前后端应用程序。Yii2.03-Advanced版本是该框架的一个更新迭代,提供了更多的特性和改进,以满足现代Web开发的...