首 页   · 站长博客 · 用户注册 · 会员登陆  · 会员排行  ·最新主题  ·最近回复  精华区  版权声明  ·论坛管理
  当前登录身份:游客,请先登录。  笔名: 口令: 验证码:   
楼 主  index »  PHP原创源码发布区 » 站长原创:用PHP实现手机短信群发函数源码  


  作者:一起PHP
  注册时间:2004-02-27
  主题/回复:247/1521
  积分:4649
  等级:★★★★★☆(十一级)
  称号:论坛圣人

  nqp@nqp.me
  4304410
  www.nqp.me

 

 发表:2008-08-30 15:46:09 阅读 7309 次 回复 3 次 得分6  |   字号 字色
站长原创:用PHP实现手机短信群发函数源码
很久没有来论坛发教程了,论坛的人气降到了冰点。再这样下去我看马上就有关门大吉的必要拉

最近遇到一个手机短信群发问题。在网上搜了一下,大多是针对某种具体条件的群发,无法直接使用。于是尝试自行解决,现将解决经验分享:
关于短信群发,其实很容易想到所谓群发其实就是多次单发。即只要解决了单发问题,则可以循环执行单发来实现群发。

客户已经拥有了移动、联通两个短信发送接口。在短信发送时,只需要根据用户的手机号码来判断属于移动还是联通,然后将手机号码和发送内容作为参数传递给发送接口即可。

移动:移动的接口比较简单,在某台短信服务器上安装了相关软硬件,发送时只需要向该服务器的MSSQL数据库的指定表中插入一条记录,剩余的发送工作由发送接口完成。连接数据库并向表中插入记录的操作可以单次进行也可以循环进行,可以用ASP或PHP轻松实现,因此代码不再提供。

联通:联通的短信接口为一个带参数的URL。大体格式如下:
http://x.x.x.x/Sender?phone=手机号&content=短信内容&Service_code=服务号&pgId=3&connId=2000&mtTypeId=6&linkId=&username=用户名&password=密码&feephone=付费号码&reserve=

上面的格式中,我们一般只关心phone和content两个参数,其他参数均为固定值。其中reserve参数的值可以为空,但该参数不可省略。

在能否访问该URL的任意主机上键入这个URL并提供正确的参数,则可成功发送短信。短信发送后系统返回一个uft-8格式的XML文件。文件的大体格式如下:
代码如下:
<xml ....>
  <response>
    <responsecode>0</responsecode>
    <responsestr>正确</responsestr>
    <responseid>112233</responseid>
  </response>
</xml>
其中不难看出第一项为状态代码,第二项为描述,第三项为该发送任务的编号。
当发送成功时,responsecode为“0”,responsestr为“正确”。

这样,对于一次单发而言,只需要将手机号phone和短信内容content作为URL附加参数传递给接口程序,然后接收到返回结果并对结果进行分析,便可以知道发送成功与否。有许多方法可以完成这一功能。但是考虑到便于将来使用循环实现群发,本人采用了fopen()函数。
注意,fopen()函数在服务器端执,避免了其他一些URL引用方法中由客户断浏览器发送请求而带来的问题。而且fopen()函数支持带参数的URL,并且很容易循环执行。使用方法如下:
代码如下:
$url = "http://x.x.x.x/Sender?phone=13311111111&content=短信内容&....";
msg = @ fopen($url,"r");
if($msg){
    $str = @fread($msg,1024);
}else{
    echo "连接短信服务器失败。";
    exit;
}

这样$str中就已经包含了短信服务器的返回信息。这个信息是UFT-8格式的XML文档。要解析这个文档有很多方法。PHP中也有XML语法解析函数。但是如果此处需求并不是非常高,并不需要精确的分析返回结果,而只需要知道发送成功还是不成功,则可以不必去解析这个XML文档。直接根据其发送成功返回的responsecode为0就可以判断。如下面的代码:
代码如下:
if(strpos($str,"<responsecode>0</responsecode>") > 0){
    $back = "发送成功!";
}else{
    $back = "发送失败!(联通号码)";
}

当然还有其他字符串操作函数可以完成类似的判断,在此不再赘述。

到此为止,我们已经可以完成短信的发送和返回结果的分析。可以说单发已经解决。下一步通过循环来实现群发。自然很容易相当编写一个函数,在使用时循环调用函数来实现群发。
另外,为了将移动和联通的号码放在同一个函数中判断/发送,我们可以为移动的短信服务器编写一个简单的接口,也通过类似联通的URL方式访问。这样在同一个函数中实现移动联通发送就不是问题了。而且这个接口可以用任意语言编写,使用时通过URL调用,非常方便。如使用以下格式:
http://x.x.x.x/yidong.asp?phone=13666666666&content=移动短信接口
在yidong.asp中,只需要接收phone和content两个参数,然后写入到上述的指定表中即可。写入成功后随便返回一个成功标志,如“<ok>”等。

现在我们已经可以写出一个通用的函数:
代码如下:
//首先是一个根据手机号返回服务商的简单函数
function phoneCheck($phone){
 $n = substr($phone,0,3);
 if(in_array($n,array(130,131,132,133,156))){
return "联通";
 }elseif(in_array($n,array(134,135,136,137,138,139,150,158,159))){
return "移动";
 }else{
return "未知号段"; 
 }
}

//短信发送的函数

function sendMessage($phone,$content){

$phonetype = phoneCheck($phone);
$liantong = 'http://x.x.x.x/sender?';
$yidong   = 'http://x.x.x.x/yidong.asp?';
$str = '';
$back = '';
if ($phonetype=="移动"){
$url = $yidong."phone=".$phone."&content=".$content;
$msg = @ fopen($url,'r');
if($msg){
   $str =@ fread($msg,1024);
   if(strpos($str,"<ok>")>0){
   $back = "发送成功!";
   }else{
   $back = "发送失败!(移动号码)".$str.$url;
   }
}else{
  $back = "发送失败(移动服务器无法连接)";
}
}elseif ($phonetype=="联通"){
$url= $liantong."phone=".$phone."&content=".$content."&......
$msg = @ fopen($url,"r");
if($msg){
  $str = @fread($msg,1024);
  if(strpos($str,"<responsecode>0</responsecode>") > 0){
   $back = "发送成功!";
  }else{
   $back = "发送失败!(联通号码)";
  }
}else{
     $back = "发送失败!(联通服务器无法连接)。";

}else{
$back = "未知的手机号码段,发送失败!";
}
return $back;
}


到此为止函数的构造已经完成。使用方法自然是十分简单。
单发:  echo sendMessage("13390000000","欢迎使用短信系统");

群发:
 for/while/do(){
  echo sendMessage($phone[$i],$content[$i]);
 }

使用echo是为了输出发送结果是成功还是失败。如不需要则可不输出。

用了一个多小时整理这篇文章,希望对遇到同类问题的朋友有所帮助。另外实现同类功能也许有更加简洁的方法,也请大家多多探讨,赐教!

一起PHP站长 08年8月30日
http://www.17php.com

(本帖被作者修改过2次,最后一次修改时间2008-08-30 15:47:25)

 
 1#楼  
 
  回复人:lc0633
  注册时间:2007-08-08
  主题/回复:1/8
  积分:427
  等级:★★☆(五级)
  称号:略有小成

   
 1#楼 发表于2008-10-27 10:24:46  评分:1 

回复给楼主(一起PHP)
 2#楼  
 
  回复人:小菜蛋
  注册时间:2008-01-03
  主题/回复:5/35
  积分:721
  等级:★★★(六级)
  称号:声名鹊起

   
 2#楼 发表于2009-05-18 17:45:40  评分:1 

回复给楼主(一起PHP)
学习了!
 3#楼  
 
  回复人:lixiuran1991
  注册时间:2012-05-05
  主题/回复:2/2
  积分:52
  等级:★(二级)
  称号:初出茅庐

   
 3#楼 发表于2012-05-06 23:03:24  评分:3 

回复给楼主(一起PHP)
good
  页数1/1首页 « 1 » 末页
  发表回复:您还没有登陆,无法发表回复。请先[登陆]

一起PHP技术联盟 主办:一起PHP 联系方式:站长QQ:4304410 QQ群:8423742 20159565 站长博客 E-mail: nqp@nqp.me 执行时间:0.014sec
SimsmaBBS 2008 (v6.0) Developed by 17php.com,Copyright(C)2003-2010 All rights reserved. 副本授权:一起PHP官方专用版