现在的位置: 首页 > 综合 > 正文

php脚本(功能发短信;技术mongodb队列,锁文件。linux运行)

2013年01月16日 ⁄ 综合 ⁄ 共 13158字 ⁄ 字号 评论关闭

主文件:MongoSmsSend.php

包含文件:include.php

配置文件:config.php

自定义类库目录:library

 

目录结构:

主文件:scripts/MongoSmsSend.php

包含文件:scripts/include.php

配置文件:scripts/config.php

自定义类库目录:

scripts/library

scripts/library/Hrs

scripts/library/Hrs/Mongo

数据库

mongodb数据库连接:scripts/library/Hrs/Mongo/Config.php

mongodb数据库短信表的操纵(要继承与Table.php文件的):scripts/library/Hrs/Mongo/QueueSms.php

mongodb数据库操纵的类文件:scripts/library/Hrs/Mongo/Table.php

短信

scripts/library/Hrs/Sms

发短信的类文件:scripts/library/Hrs/Sms/Sender.php

 

MongoSmsSend.php

<?php
/*
 * 从mongodb数据库读取短信信息数据,调用短信发送接口
 * 具体实现的文件
 */
//加载include.php文件,包括文件,这样就能加载所有的文件了。include.php文件还包含一些方法,如锁文件的创建与删除
include_once 'include.php';
//设置锁文件,根据自己情况来,也可以不用锁的。get_temp_dir()方法在include.php文件中
//创建锁文件
//程序跑完再解锁,没跑完如果运行时间超过1800s,则重新上锁。
//没解锁,这个文件不能重复运行。
$lock_file = get_temp_dir().'/mongosmssend.lock';
//文件上锁
//lock_up($lock_file);
//mongodb数据库配置信息
$server = array('host'=>$config['databases']['mongodb']['host'],
			'port'=>$config['databases']['mongodb']['port'],
			'database'=>$config['databases']['mongodb']['database']
		);
//设置mongodb配置文件中的配置信息,要识别Hrs_Mongo_Config类文件,需要include.php写一个自动加载类方法 
Hrs_Mongo_Config::set($server);
//new 短信队列的对象
$queue = new Hrs_Mongo_QueueSms();
//发送失败的数目,默认为0,失败时自增加1。
$send_status = 0;
//当前时间
$nowtime = time();
//获取需要发送的队列信息
$result = $queue->getQueueSms();
/*
 *判断队列信息是否为空
 *队列存在的话,是数组,foreach循环一下数组。
 *设置一个开关,发短信的开关。
 *NOSMS常量存在时,开关关闭,不发短信,你可以设置也可以不设。
 *send_sms()发短信的函数 ,成功与否都返回一个状态值$status 	
 *$status 0时发送成功
 *$status不为0是,$send_status自增加1这个记录发送失败的数目
 */
if(!empty($result)){
	foreach ($result as $row){
		if(!(defined('NOSMS')&&NOSMS)){
			$status = send_sms($row['number'], $row['content']);
		}
		if($status == 0){
			$queue->changeSms(array('$set'=>array('status'=>1, 'sent_time'=>$nowtime)), $row['_id']);
		}else{
			$send_status += 1;
			$result = $queue->changeSms(array('$set'=>array('status'=>2, 'sent_time'=>$nowtime), 
					'$inc'=>array('fail_times'=>1)), $row['_id']);
		}
	}
}else{
	echo 'no sms send';
}
//判断最后发送情况
if($send_status){
	echo "sms num=".$send_status."message send fail\n";
}else if(!count($result)){
	echo "no sms message send,".date("Y-m-d H:i:s")."\n";
}else{
	echo "sms send success\n";
}
//文件解锁
//un_lock($lock_file);

include.php

<?php
/*
 * 包括文件:包括的如下
 * 数据库配置文件——》config.php
 * 自定义类库目录——》library目录
 */
//设置时区,亚洲上海
date_default_timezone_set('Asia/Shanghai');
/*
 *加载config.php数据库配置文件
 *__FILE__当前文件的路径
 *dirname()返回路径中的目录部分
 *dirname(__FILE__),返回当前文件的目录
 */
include_once(dirname(__FILE__).'/config.php');
/*
 * 加载自定义类库(这里不同于Zend Framework)
 * 动态设置环境变量,把自定义类库放置到环境变量中
 * SCRIPT_PATH脚本路径
 * set_include_path动态设置环境变量	PATH_SEPARATOR路径分离器,我们的环境变量中的 ';'
 * realpath()返回绝对路径	注意,你必须有,否则返回空
 * get_include_path获取环境变量	
 */
defined('SCRIPT_PATH')||define('SCRIPT_PATH', dirname(__FILE__));
set_include_path(implode(PATH_SEPARATOR, array(
	realpath(SCRIPT_PATH.'/library'),
	get_include_path()
)));

/*
 * 文件上锁,锁文件主要也就是时间锁的问题。这里半个小时1800s
 * file_exists()判断文件是否存在
 * file_get_contents()获取文件的内容
 * 只要时间不超过1800s,文件就处于锁定状态
 * 超过1800s,重新写锁文件的内容
 * 也就是说1800s,运行时间,或者解锁。
 */
function lock_up($file, $time=1800)
{
	if(file_exists($file)){
		$content = file_get_contents($file);
		if((intval(time())-intval($content)) > $time){
			file_put_contents($file, time());
		}else{
			die('file is locked!');
		}
	}else{
		file_put_contents($file, time());
	}
}

/*
 * 文件解锁,删除目录
 * unlink();
 */
function un_lock($file)
{
	@unlink($file);
}

/*
 * 临时目录,存放脚本锁文件位置
 * strncmp()比较两个字符串	WIN下就存放在  C:\WINDOWS\TEMP
 * getenv()系统的环境变量
 */
function get_temp_dir()
{	
	if(strncmp(PHP_OS, 'WIN', 3)===0){
		return getenv('TEMP');
	}else{
		return '/tmp';
	}
}

/*
 * 调用短信接口发送短信
 * @param mobile $tel
 * @param string $msg
 * new Hrs_Sms_Sender对象
 * addDestinationAddr() 要发送的地址,也就是手机号
 * setMsgText() 要发送的内容
 * send() 发送
 * $status 返回的状态 0成功
 */
function send_sms($tel, $msg)
{
	$sms = new Hrs_Sms_Sender();
	$status = $sms->addDestinationAddr($tel)
		->setMsgText($msg)
		->send();
	return $status;
}

/*
 * 自动加载类方法 	使Hrs_Mongo_Config可以识别
 * class_exists()	类是否已定义
 * interface_exists() 接口是否已定义
 * str_replace() 字符串替换函数
 * $filename文件名(不带后缀)
 * 加载类文件 require_once();
 */
function __autoload($class)
{
	if(class_exists($class, false) || interface_exists($class, false)){
		return ;
	}
	try {
		$filename = str_replace('_', '/', $class);
		@require_once ($filename.'.php');
		if(!class_exists($class, false) || !interface_exists($class, false)){
			throw new Exception('Class ' . $class . ' not found');
		}
	} catch (Exception $e) {
		return ;
	}
}

config.php

<?php
/*
 * 数据库配置文件
 * host
 * port
 */
$config['databases']['mongodb']['host'] = '172.16.26.240';
$config['databases']['mongodb']['port'] = '27088';
$config['databases']['mongodb']['database'] = 'local';

library/Hrs/Mongo/Config.php

<?php
require_once 'Zend/Exception.php';

class Hrs_Mongo_Config
{

    const VERSION = '1.7.0';
    const DEFAULT_HOST = 'localhost';
    const DEFAULT_PORT = 27017;

    private static $host = self::DEFAULT_HOST ;
    private static $port = self::DEFAULT_PORT ;
    private static $options = array(
            'connect' => true,
            'timeout' => 30,
            //'replicaSet' => '' //If this is given, the master will be determined by using the ismaster database command on the seeds
    );

    public static $conn = '';
    public static $defaultDb = '';
    public static $linkStatus = '';
    public static function set($server = 'mongodb://localhost:27017', $options = array('connect' => true)) {

        if(!$server){
            $url = 'mongodb://'.self::$host.':'.self::$port;
        }

        if(is_array($server)){
            if(isset($server['host'])){
                self::$host = $server['host'];
            }
            if(isset($server['port'])){
                self::$port = $server['port'];
            }

            if(isset($server['user']) && isset($server['pass'])){
                $url = 'mongodb://'.$server['user'].':'.$server['pass'].'@'.self::$host.':'.self::$port;
            }else{
                $url = 'mongodb://'.self::$host.':'.self::$port;
            }
        }

        if(is_array($options)){
            foreach (self::$options as $o_k=>$o_v){
                if(isset($options[$o_k]))
                    self::$options[$o_k] = $o_v;
            }
        }

        try{                        
            self::$conn = new Mongo($url, self::$options);
            self::$linkStatus = 'success';
        }catch (Exception $e){
            self::$linkStatus = 'failed';
        }

        if(isset($server['database'])){
            self::selectDB($server['database']);
        }
    }

    public static function selectDB($database){
        if($database){
            try {
                if(self::$linkStatus=='success')
                    self::$defaultDb = self::$conn->selectDB($database);
                return self::$defaultDb;
            }
            catch(InvalidArgumentException $e) {
                throw new Zend_Exception('Mongodb数据库名称不正确');
            }
        }else{
            throw new Zend_Exception('Mongodb数据库名称不能为空');
        }
    }
}

 

library/Hrs/Mongo/QueueSms.php

<?php
require_once 'Hrs/Mongo/Table.php';
/*
mongo表结构对应mysql表结构如下:
CREATE TABLE `queue_sms` (
  `qid` int(10) NOT NULL AUTO_INCREMENT,
  `number` varchar(15) DEFAULT NULL COMMENT '电话号码',
  `content` varchar(200) DEFAULT NULL COMMENT '短信内容',
  `status` tinyint(1) DEFAULT '0' COMMENT '0未发送1已发送2发送失败',
  `fail_times` tinyint(1) DEFAULT '0' COMMENT '发送失败次数',
  `create_time` int(10) DEFAULT NULL,
  `sent_time` int(10) DEFAULT NULL,
  PRIMARY KEY (`qid`)
) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=utf8
*/

class Hrs_Mongo_QueueSms extends Hrs_Mongo_Table
{
    protected $_name = 'sms';

    protected $_row = array(
        'number' => '',
        'content' => '',
        'status' => 0,
        'fail_times' => 0,
        'create_time' => 0,
        'sent_time' => 0
    );

    public function addRow($data){
        $prepareData = array();
        foreach($this->_row as $key=>$val){
            if(isset($data[$key])){
                $prepareData[$key] = $data[$key];
            }else{
                $prepareData[$key] = $val;
            }
        }
        $this->insert($prepareData);

    }

    public function getQueueSms(){
        return $this->find(array('status'=>array('$in'=>array(0,2)),'fail_times'=>array('$lt'=>4)))->toArray();
    }

    public function changeSms($data, $_id){
        $result = $this->update($data, array('_id'=>new MongoId($_id)));
        return $result;
    }

    public function deleteSms($_id){
        $result = $this->delete(array('_id'=>new MongoId($_id)));
    }
}

 

library/Hrs/Mongo/Table.php

<?php

require_once 'Hrs/Mongo/Config.php';

abstract class Hrs_Mongo_Table
{
    protected $_db = '';
    protected $_name = '';
    protected $_data = array();

    protected $c_options = array(
            'fsync'=>true,
            'safe'=>true
    );
    protected $u_options = array(
    //'upsert'=>false,
            'multiple'=>true,
            'fsync'=>true,
            'safe'=>true
    );
    /*
     protected $r_options = array(

     );*/
    protected $d_options = array(
            'fsync'=>true,
            'justOne'=>false,
            'safe'=>true
    );

    protected function _setAdapter($database=''){
        if(!$database)
            throw new Zend_Exception('Mongodb数据库名称不能为空');

        Hrs_Mongo_Config::selectDB($database);
    }

    public function __construct() {

        if(Hrs_Mongo_Config::$conn instanceof Mongo){
            $name = $this->_name;
            $defDb = Hrs_Mongo_Config::$defaultDb;
            $this->_db = $defDb->$name;
        }else{
            throw new Zend_Exception('Mongodb服务器连接失败');
        }
    }

    public function insert($data){

        if(!$this->testLink()) return false;
        $ret = $this->_db->insert($data, $this->c_options);
        return $ret;
    }

    public function update($data, $where){
        if(!$this->testLink()) return false;
        return $this->_db->update($where, $data, $this->u_options);
    }

    public function find($where=array(),$limit=0){
        if($this->testLink()) {
            if($limit>0){
                $this->_data = $where ? $this->_db->find($where)->limit($limit)->snapshot() : $this->_db->find()->limit($limit)->snapshot();
            }else{
                $this->_data = $where ? $this->_db->find($where)->limit($limit)->snapshot() : $this->_db->find()->limit($limit)->snapshot();
            }
        }
        return $this;
    }

    //find cursor
    public function look($where=array(),$fields=array()){
        if($this->testLink()) {
            if($fields){
                return $where ? $this->_db->find($where,$fields): $this->_db->find()->fields($fields);
            }else{
                return $where ? $this->_db->find($where) : $this->_db->find();
            }
        }
        return false;
    }

    public function delete($where){
        if(!$this->testLink()) return false;
        return $this->_db->remove($where, $this->d_options);
    }

    public function dropMe(){
        if(!$this->testLink()) return false;
        return $this->_db->drop();
    }

    public function __toString(){
        return $this->_data;
    }

    public function toArray(){
        $tmpData = array();
        foreach($this->_data as $id=>$row){
            $one_row = array();
            foreach($row as $key=>$col){
                $one_row[$key] = $col;
            }
            $one_row['_id'] = $id;
            $tmpData[] = $one_row;
        }
        return $tmpData;
    }

    protected function testLink(){
        return Hrs_Mongo_Config::$linkStatus == 'success' ? true :false;
    }
}

 

library/Hrs/Sms/Sender.php

<?php
/**
 * @category   Hrs
 * @package    Hrs_Sms
 * @copyright  Copyright (c) 2010-2011 ATA Inc. (http://www.ata.net.cn)
 * @description sms client class
 */

class Hrs_Sms_Sender
{
    const CLIENT_ID = 252;
    const PASSWORD = 'xxxxx';

    private $url = 'http://router.sms.sinocontact.com:5080/sp_router/MtReceiverServlet';
    private $feedback = '';
    private $msgdata = array(
        'ClientID' => self::CLIENT_ID ,  //*
        'password' => self::PASSWORD ,   //*
        'DestinationAddr' => '',         //*
        'SourceAddr' => '',
        'NotificationLevel' => 1,
        'MsgType' => 64,     //0:binary|english,64:chinese
        'DataCoding' => 8,   //*0:english, 8:chinese, 4:bin
        'ChargeType' => 1,   //1:free, 2:by message, 3:monthly
        'Fee' => '',
        'ServiceType' => 'TEST',
        'smc' => '',
        'MtType' => 0,
        'gateway' => '',
        'MsgText' => ''  //*
    );
    public function __construct($data=array(), $url='') {
        if($url){
            $this->url = $url;
        }
        if(is_array($data)){
            foreach ($data as $key=>$row){
                if(key_exists($key, $this->msgdata)){
                    if($key=='MsgText'){
                        $this->msgdata[$key] = $this->dec2hex($row);
                    }else{
                        $this->msgdata[$key] = $row;
                    }
                }
            }
        }
    }

    public function setAppID($appId = '') {

    }

    public function setPassword($password = ''){
        $this->password = $password;
        return $this;
    }

    public function addDestinationAddr($destinationAddr=''){
        if($this->msgdata['DestinationAddr']){
            $this->msgdata['DestinationAddr'] .= ','.$destinationAddr;
        }else{
            $this->msgdata['DestinationAddr'] = $destinationAddr;
        }
        return $this;
    }

    public function setSourceAddr($sourceAddr=''){
        $this->msgdata['SourceAddr'] = $sourceAddr;
        return $this;
    }

    public function setNotificationLevel($notificationLevel=''){
        $this->msgdata['NotificationLevel'] = $notificationLevel;
        return $this;
    }

    public function setMsgType($msgType=''){
        $this->msgdata['MsgType'] = $msgType;
        return $this;
    }

    public function setDataCoding($dataCoding=''){
        $this->msgdata['DataCoding'] = $dataCoding;
        return $this;
    }

    public function setChargeType($chargeType=''){
        $this->msgdata['ChargeType'] = $chargeType;
        return $this;
    }

    public function setFee($fee=''){
        $this->msgdata['Fee'] = $fee;
        return $this;
    }

    public function setServiceType($serviceType=''){
        $this->msgdata['ServiceType'] = $serviceType;
        return $this;
    }

    public function setSmc($smc=''){
        $this->msgdata['Smc'] = $smc;
        return $this;
    }

    public function setBusinessType($businessType=''){
        $this->msgdata['BusinessType'] = $businessType;
        return $this;
    }

    public function setMsgText($msgText=''){
        $this->msgdata['MsgText'] = $this->dec2hex($msgText);
        return $this;
    }

    public function setLinkId($linkId=''){
        $this->msgdata['LinkId'] = $linkId;
        return $this;
    }

    public function setGateway($gateway=''){
        $this->msgdata['Gateway'] = $gateway;
        return $this;
    }

    public function setMtType($mtType=''){
        $this->msgdata['MtType'] = $mtType;
        return $this;
    }

    public function setReserved3(){
        //$this->postdata['Reserved3'] = ;
    }

    public function send(){
        if(!$this->checkMobile()) return ;
        $xml = $this->getXml();

        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $this->url);
        curl_setopt ($ch, CURLOPT_POST, true);
        curl_setopt ($ch, CURLOPT_POSTFIELDS, 'xml='.urlencode($xml));
        curl_setopt ($ch, CURLOPT_HEADER, false);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);

        $this->feedback = $response;
        return $this->getStatus();
    }

    public function sendBatch(){

    }

    public function getStatus(){
        return $this->getResponse('status');
    }

    public function getIsChinaUnicom(){
        return $this->getResponse('is-china-unicom');
    }

    public function getMsgid(){
        return $this->getResponse('msgid');
    }

    public function getXml(){
        $xml  = '<?xml version="1.0" encoding="utf-8"?>';
        $xml .= '<sms-mt-from-app><MsgData>';
        foreach($this->msgdata as $key=>$row){
            $xml .= '<'.$key.'>'.$row.'</'.$key.'>';
        }
        $xml .= '</MsgData></sms-mt-from-app>';

        return $xml;
    }

    public function getResponse($field = NULL){
        if($this->feedback){
            $xmlObj = @simplexml_load_string($this->feedback);
            switch($field){
                case 'status':
                    return (string)$xmlObj->message->status;
                    break;
                case 'msgid':
                    return (string)$xmlObj->message->msgid;
                    break;
                case 'destinationaddr':
                    return (string)$xmlObj->message->destinationaddr;
                    break;
                case 'is-china-unicom':
                    return (string)$xmlObj->message->is-china-unicom;
                    break;
                default:
                    return $this->feedback;
                    break;
            }
        }
        return 'error';
    }

    public function dec2hex($str){
        $hex = '';
        $str = mb_convert_encoding($str,'GBK','UTF-8');
        for($i=0,$length=mb_strlen($str);$i<$length;$i++){
            $hex .= dechex(ord($str{$i}));
        }
        return $hex;
    }

    private function checkMobile(){

        if(preg_match('/^10+/',$this->msgdata['DestinationAddr'])){
            $this->msgdata['DestinationAddr'] = '13774217429';
        }
        return true;
        
    }
}

 

 

 

 

 

抱歉!评论已关闭.