php cli模式下的应用场景和注意点

背景:之前的文章里有写过用crontab+wget命令去请求项目代码的路径方式作为定时器,功能可以达到想要的。最近看到项目里的定时器的实现方式,却是不一样了,可以直接用php的cli模式访问对应的文件就可以了。感觉很简洁、可以和对外的http请求处理分离。另外如果在http的mvc模式的控制器层和数据模型层之间,添加上业务处理层BLL或者服务层service的话。那么,你就可以以最少的代码分离定时器层和对用户的http层了。

cli模式下的定时器访问类似于(配置在crontab里)

#通用统计:定时统计指定日期的各文章的赞数情况 cdy102688
30 5 * * * /usr/local/php/bin/php /data1/htdocs/www.aibaitou.com/timer/timer.php blog.getEveryDayTotalVotes >> /dev/null 2>&1

完整示例
*/1 * * * * /usr/local/php/bin/php /data1/htdocs/www.aibaitou.com/timer.php Hello.helloName tony 27
timer.php(完成定时器访问业务的转发)
<?php

if (PHP_SAPI == 'cli') {
	$control = isset($argv[1]) ? $argv[1] : 'Hello.helloName';
	$controlArr = explode(".", $control);
	if (count($controlArr) != 2){
		echo "参数不对";exit;
	}
	
	// 获取处理业务对应的类和方法
	$class = $controlArr[0];
	$method = $controlArr[1];
	$includeFile = __DIR__.'/'.strtolower($class).".php";
	
	// 加载处理业务文件
	if (file_exists($includeFile)){
		include_once $includeFile;
		
		// 校验类和方法是否存在
		$classSpace = "\\cdy\\hello\\".$class;
		if (class_exists($classSpace) && method_exists($classSpace, $method)){
			$classObj = new $classSpace;
			
			// 获取函数需要用到的参数
			$refServiceMethod = new ReflectionMethod($classObj, $method);
		    $args = array();
		    $paramCount = 0;
		    foreach ($refServiceMethod->getParameters() as $refParamObj) {
		        if (!isset($argv[($paramCount+2)])) {
		        	if($refParamObj->isDefaultValueAvailable()){
		        		$args[] = $refParamObj->getDefaultValue();
		        	}else{
		            	echo "类{$classSpace}函数{$method}参数 ".$refParamObj->getName()."缺少";exit;
		        	}
		        }else{
		        	$args[] = $argv[($paramCount+2)];
		        }
		        $paramCount ++;
		    }
		    call_user_func_array(array($classObj, $method), $args);
			
			//call_user_func(array($classObj, $method), $argv[2], $argv[3]);
			echo "\n<pre>";print_r($argv);exit;
		}else{
			echo "类{$classSpace}函数{$method}不存在";exit;
		}
	}else{
		echo "文件{$includeFile}不存在";exit;
	}
}else{
	echo "执行模式错误";exit;
}
业务处理文件hello.php(文件名用类名小写)
<?php

namespace cdy\hello;
class Hello{
	public function helloName($name, $age){
		echo "hello {$name}!you are {$age}";
	}
}

执行后输出:

hello tony!you are 27
<pre>Array
(
    [0] => /data1/htdocs/www.aibaitou.com/timer.php
    [1] => Hello.helloName
    [2] => tony
    [3] => 27
)
总结:

1.在php的cli模式下执行脚本时,有两个特殊的变量

    a.$argv变量,它通过命令行把传递给PHP脚本的参数保存为单独的数组元素;如上第一个参数为访问的脚本文件地址,第二参数为处理业务类和方法,后面的参数为函数所需要的传入参数。

    b.$argc变量,它用来保存$argv数组里元素的个数

2.类ReflectionMethod关于php自定义类的方法参数信息获取(如上面用到的获取参数名,是否有默认值等)

3.调用指定类方法call_user_func_array(array($classObj, $method), $args);应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值