微信开发笔记之接收消息,自动判断回复相应消息
山猫的博客,发送1,2,3,7测试相应的消息。菜单模式需要升级为服务号,或者订阅人数超过500以上。
1.用户发送的消息都是通过你提交的开发者 URL来接收。这里订阅号就可以搞定。
发送过来的都是xml格式数据,需要解析:
代码如下 | 复制代码 |
$data = $GLOBALS["HTTP_RAW_POST_DATA"]; |
回复也是需要返回XML的数据格式。
2.主动发送给用户消息,查询用户信息,创建自定义菜单(现在订阅号也可以用),以及一些高级功能,都是需要获取appid 和 AppSecret 以便得到 access_token
access_token 这东西,除接收信息,每个接口都要用到。access_token 的时间为 7200毫秒
过期需要重新获取。
更多请参考:http://mp.weixin.qq.com/wiki/index.php?title=%E9%A6%96%E9%A1%B5 额
目前我已经实现了,接收消息,自动判断回复相应消息(新闻),创建自定义菜单,点击自定义菜单后执行相应操作。用户列表之类。感觉目前开发模式和订阅模式没什么区别。。。
这里有一个测试回复的测试例子
代码如下 | 复制代码 |
<?php //define your token class wechatCallbackapiTest //valid signature , option public function responseMsg() //extract post data }else { ?> |
近日用PHP处理约7k条网络数据,现有网络情况下,耗时通常一秒一条,跑完整个程序大约近两个小时。
由于跑一次数据的时间太长,因此计划通过多个线程实现并行处理,我们可以通过pthreads扩展来实现真正的多线程,而不是常见的fsockopen来“模拟”。pthreads的官网介绍在这里:http://pthreads.org/
需要注意的是,如果尝试用数组在线程间交换数据,你会失望的,因为php的数组本身不是线程安全的,正确的做法是继承Stackable类。一个简单的demo如下所示:
代码如下 | 复制代码 |
<?php class my extends Thread { public function run(){ $this->synchronized(function($thread){ $storage = new storage(); $my->synchronized(function($thread){ var_dump($storage); |
上例如果$storage是array,那么dump出来的将是null。
启用多线程后,跑一次数据的时间可以压缩到1000秒内,不到二十分钟,已经在我的接受范围内了
最后发现一个自动加载BUG
线程的run方法可以继承主线程的常量,函数定义。ini_set()和自动加载不能继承。
具体什么能继承什么不能继承没找到相关文档,只能自己摸索。
继承过来的函数中只能进行一些基本操作,如果试图new一个对象(比如PDO)然后返回这个对象就会导致进程意外终止。
就目前来说基本不能用于生产环境。
只在php5.3以后的版本才真正的可以使用多线程序了,以前都是假的curl实现的多线程工作,下面我来给各位介绍几个多线程抓取信息测试例子,希望对各位会有帮助。
PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环任务,能够大大缩短程序执行时间。
PHP扩展下载:https://github.com/krakjoe/pthreads
PHP手册文档:http://php.net/manual/zh/book.pthreads.php
1、扩展的编译安装(Linux),编辑参数 --enable-maintainer-zts 是必选项:
cd /Data/tgz/php-5.3.8
./configure --prefix=/Data/apps/php --with-config-file-path=/Data/apps/php/etc --with-mysql=/Data/apps/mysql --with-mysqli=/Data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/Data/apps/libs --with-jpeg-dir=/Data/apps/libs --with-png-dir=/Data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/Data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts
make clean
make
make install
unzip pthreads-master.zip
cd pthreads-master
/Data/apps/php/bin/phpize
./configure --with-php-config=/Data/apps/php/bin/php-config
make
make install
添加扩展:
vi /Data/apps/php/etc/php.ini
extension = "pthreads.so"
一段PHP多线程、与For循环,抓取百度搜索页面的PHP代码示例:
代码如下 | 复制代码 |
<?php class test_thread_run extends Thread { public $url; public $data; public function __construct($url) { $this->url = $url; } public function run() { if(($url = $this->url)) { $this->data = model_http_curl_get($url); } } } function model_thread_result_get($urls_array) { foreach ($urls_array as $key => $value) { $thread_array[$key] = new test_thread_run($value["url"]); $thread_array[$key]->start(); } foreach ($thread_array as $thread_array_key => $thread_array_value) { while($thread_array[$thread_array_key]->isRunning()) { usleep(10); } if($thread_array[$thread_array_key]->join()) { $variable_data[$thread_array_key] = $thread_array[$thread_array_key]->data; } } return $variable_data; } function model_http_curl_get($url,$userAgent="") { $userAgent = $userAgent ? $userAgent : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, 5); curl_setopt($curl, CURLOPT_USERAGENT, $userAgent); $result = curl_exec($curl); curl_close($curl); return $result; } for ($i=0; $i < 100; $i++) { $urls_array[] = array("name" => "baidu", "url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000)); } $t = microtime(true); $result = model_thread_result_get($urls_array); $e = microtime(true); echo "多线程:".($e-$t)."n"; $t = microtime(true); foreach ($urls_array as $key => $value) { $result_new[$key] = model_http_curl_get($value["url"]); } $e = microtime(true); echo "For循环:".($e-$t)."n"; ?> |
例子,采集数据
代码如下 | 复制代码 |
<?php $save_to='/test.txt'; // 把抓取的代码写入该文件 $mh = curl_multi_init(); do { foreach ($urls as $i => $url) { foreach ($urls as $i => $url) { curl_multi_close($mh); |
例子, 模拟登陆
代码如下 | 复制代码 |
/** * 模拟登陆 * $url 请求地址 * $post 需要POST的数据 * $cookie 登陆时取的的COOKIE * $cookiejar cookie要存到的位置 例如/tmp/test.cookie * $referer 上页地址 * **/ function vcurl($url, $post = '', $cookie = '', $cookiejar = '', $referer = ''){ $tmpInfo = ''; //用来存放cookie的文件 //初始化curl $curl = curl_init(); //设定目标网址 curl_setopt($curl, CURLOPT_URL, $url); //使用目前所用的浏览器代理 curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); //如果有Ref参数,则设置Referer头,否则自动设置Referer头 if($referer) { curl_setopt($curl, CURLOPT_REFERER, $referer); } else { curl_setopt($curl, CURLOPT_AUTOREFERER, 1); } //如果有post数据参数,则方法为POST,并且设置数据,否则为GET if($post) { //发送一个常规的POST请求,默认类型为:application/x-www-form-urlencoded,www.111cn.net表单提交 curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $post); } //如果有cookie参数,则设置 if($cookie) { curl_setopt($curl, CURLOPT_COOKIE, $cookie); } //如果有cookie文件参数,则设置存取Cookie文件名 if($cookiejar) { curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiejar); curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiejar); } //如果是302转移,则返回转移后的网址及内容 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); //设置执行的最大秒数 curl_setopt($curl, CURLOPT_TIMEOUT, 100); //返回内容中是否包含头信息 curl_setopt($curl, CURLOPT_HEADER, 0); //把返回的结果存在文件或者变量中,而不是直接显示在浏览器 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //执行函数后的返回结果 $tmpInfo = curl_exec($curl); //如果出错,显示错误信息 if (curl_errno($curl)) { $tmpInfo = '<pre><b>错误:</b><br />'.curl_error($curl); } //关闭curl对象 curl_close($curl); //返回结果 return $tmpInfo; } |
例子、soap
代码如下 | 复制代码 |
function vcurlsoap($url, $SoapRequest, $SoapAction) { $ch = curl_init (); //initiate the curl session curl_setopt ( $ch, CURLOPT_URL, $url ); //set to url to post to curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); // return data in a variable curl_setopt ( $ch, CURLOPT_HEADER, 0 ); curl_setopt ( $ch, CURLOPT_POST, 1 ); curl_setopt ( $ch, CURLOPT_POSTFIELDS, $SoapRequest ); // post the xml curl_setopt ( $ch, CURLOPT_TIMEOUT, 60 ); // set timeout in seconds curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); $header = array ("Content-Type: text/xml" ); $header [] = "Content-Length: ".strlen($SoapRequest); if (! is_null ( $SoapAction )) $header [] = 'SOAPAction: "' . $SoapAction . '"'; curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header ); $xmlResponse = curl_exec ( $ch ); curl_close ( $ch ); return $xmlResponse; } |
出于对算法对于系统的影响的好奇,决定实验性的在实际生产环境中研究一下算法对系统效率的影响。二分法最重要的是对有序数据的查询定位,例如手机号码就是一个很贴切的有序排列的数据例子。
如果数据量很小,例如只有10条有序数据,要查询其中的第9条数据,轮询查询需要查询9次确定结果,二分法查询次数为3次(分别是匹配第5、8、9条记录)即可确定结果。数据量越大,二分法所带来的效率就是程2的阶乘递增,可以大大提升服务器的运行效率、提升用户等待时间、节省服务器资源。
实验环境:LAMP
实验数据:国内手机号码归属地。手机号码前7位代表一个号段,生成从1300000到1590000之间的所有号段按从小到大排列,大约30万条数据。
传统查询:对于任意手机号码,截取前7位,从数据库中第一条记录开始循环向下匹配,如果对照,则返回查询结果。
代码如下 | 复制代码 |
flock($fp,LOCK_SH); $note = fread($fp,filesize('./data.php')); //读取数据 fclose($fp); $note = explode("n",$note); array_pop($note); array_shift($note); $num = count($note); $_data = ''; //循环查询开始 for($i=1;$i<$num;$i++){ $row = explode(" ",$note[$i]); if($m == $row[0]){ $_data = $row; break; } } |
实测结果:最快0.03512秒、最慢0.63043秒、平均查询用时约为0.4秒。
二分法查询:对于任意手机号码,截取前7位。首先匹配数据库中最中间的第100000条数据,根据二分法原则,若匹配结果比中间值大,重新选择第二次匹配第100000到200000的中间值----第150000条数据。以此类推,直到查询到最后一位正确的值返回结果。那么每次的查询次数小于或等于17次。
代码如下 | 复制代码 |
flock($fp,LOCK_SH); |
实测结果:每次查询都在0.034—0.035之间。
结论:本试验可以看出,二分法数据查询效率比传统效率快10倍以上。本实验数据只有30万条,在普通的应用性数据查询时,数据量越大,越能显示出二分法的优越性(理论上讲,上千万的数据查询次数不超过30次便可准确定位),在更大量的数据的时候,查询效率或许能真的给人直观的反应。
相关文章
- 本篇文章主要分享了通过window.navigator来判断浏览器及其版本信息的实例代码。具有一定的参考价值,下面跟着小编一起来看下吧...2017-01-23
- 使用 conditional comment 来判断 IE 的版本。嗯,是早早有人提出,但没有认真看代码。昨天刚好在看 CSS3 PIE 的时候看到,觉得是不是不靠谱。今天看到 Paul Irish 也提起,那么,推荐一下吧。这是作者博客上写的:复制代码 代码...2014-05-31
- 这篇文章主要为大家详细介绍了C#微信开发之发送模板消息的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 下面小编就为大家分享一篇c# 判断是否为空然后赋值的4种实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了iOS新版微信底部返回横条问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 具体详情请看下文小编给大家带来的知识点。同编写程序类似,存储过程中也有对应的条件判断,功能类似于if、switch。在MySql里面对应的是IF和CASE1、IF判断IF判断的格式是这样的:IF expression THEN commands [ELSEIF ex...2015-10-21
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
废话不多说了,直接给大家贴代码了。<?php class test{} $a1 = null; $a2 = ""; //$a3 = $a4 = 0; $a5 = '0'; $a6 = false; $a7 = array(); //var $a8; $a9 = new test(); for ($i=1; $i <=9 ; $i++) {...2015-11-24- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
- 为公司系统业务需要,这几天了解了一下微信和支付宝扫码支付的接口,并用c#实现了微信和支付宝扫码支付的功能。需要的朋友跟随小编一起看看吧...2020-06-25
- 这篇文章主要介绍了C#判断一个字符串是否是数字或者含有某个数字的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了Python爬取微信小程序通用方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-29
- 这篇文章主要介绍了C#实现的微信网页授权操作逻辑封装,分析了微信网页授权操作的原理、步骤并给出了C#实现的网页授权操作逻辑封装类,需要的朋友可以参考下...2020-06-25
- 今天小编大家分享一篇C#获得程序的根目录以及判断文件是否存在的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-25
- 有很多人在做微信的扫一扫下载。但是在微信更新之后微信将该功能给禁止掉了,也不能说是全面禁止吧,因为腾讯、微信是一家嘛,通过应用宝审核的应用好像还是可以通过扫一扫直接下载的,下面通过本篇文章给大家介绍微信扫一扫下载app的代码片段,感兴趣的朋友一起看看吧...2016-01-02
- 这篇文章主要介绍了iOS新版微信底部工具栏遮挡问题完美解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
从PHP $_SERVER相关参数判断是否支持Rewrite模块
如果是http://www.jb51.net/p1141.html形式的URL,可通过$_SERVER['REQUEST_URI']和$_SERVER['QUERY_STRING']值的区别来分析,最主要是如果页面是通过重定向会产生$_SERVER['REDIRECT_QUERY_STRING']和$_SERVER['REDIREC...2013-10-04- 整体思路是这样的:判断div内部是否为空,如果为空,给出无数据提示;否则显示正常页面,下面给大家分享js判断div内容是否为空的方法,对判断div内容是否为空的相关知识感兴趣的朋友一起学习吧...2016-02-01
- 这篇文章主要为大家详细介绍了C#图像识别,微信跳一跳机器人,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-02
- 在微信公众号平台开发者那里,在“账号管理”那里,有一项功能是“生成带参数的二维码”,通过这儿生成的二维码,只要通过微信扫一扫之后,会把事件自动推送到微...2016-05-19