微信开发第二篇:被动回复文本消息和图文消息

官方文档详见:
http://mp.weixin.qq.com/wiki/1/6239b44c206cab9145b1d52c67e6c551.html

当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。

回复文本消息

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
if ($keyword=='1') {
// 纯文本消息回复
$textTpl = '<xml>
<ToUserName><![CDATA['.$this->fromUsername.']]></ToUserName>
<FromUserName><![CDATA['.$this->toUsername .']]></FromUserName>
<CreateTime>'.time().'</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[欢迎来到我的微信测试公众号]]></Content>
</xml>';

echo $textTpl;
exit;
}

效果如下:

ceshi_01

图文消息回复代码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
elseif ($keyword=='2') {
// 图文信息回复格式
$newTpl = '<xml>
<ToUserName><![CDATA['.$this->fromUsername.']]></ToUserName>
<FromUserName><![CDATA['.$this->toUsername.']]></FromUserName>
<CreateTime>'.time().'</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[苹果正式发布iPhone 7/7 Plus:国行价格5388元/6388元起]]></Title> 
<Description><![CDATA[苹果召开新品发布会,iPhone 7和iPhone 7 Plus正式登台亮相,国行版本的售价分别为5388元和6388元起,预售从9月9日下午3:01开始。]]></Description>
<PicUrl><![CDATA[http://upload.chinaz.com/2016/0908/6360891704559950162920888.jpeg]]></PicUrl>
<Url><![CDATA[http://www.chinaz.com/mobile/2016/0908/578020.shtml]]></Url>
</item>
</Articles>
</xml>';

echo $newTpl;
exit;
}

效果如下:

ceshi_02

微信开发第一篇:实现接入流程

一、申请公众号测试号地址
http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

官方接入文档:
http://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html

TOKEN_001

TOKEN_002

TOKEN_003

成功输出,就代表配置成功!

在接口配置信息信息处,提交url和Token值

TOKEN_0004

TOKEN_0005

TOKEN_0006

代码:仅供学习测试用途

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
namespace Home\Controller;
use Think\Controller;

define("TOKEN", "ceshi");

class IndexController extends Controller {

// 采用微信官方提供的验证方法
public function index(){
	$echoStr = $_GET["echostr"];

    // 验证通过以后,会走else区间
	if($this->checkSignature() && isset($echoStr)){
		echo $echoStr;
		exit;
	} else{
		$this->responseMsg();
	}
}

// 发送者的消息会传送到自己的服务器
public function responseMsg()
{
	//get post data, May be due to the different environments
	$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

	$str = json_encode($postStr);
	
	$data['xml'] = $str;

	D('tmp')->add($data);
	
}

// 官方提供的验证
private function checkSignature()
{
    // you must define TOKEN by yourself
    if (!defined("TOKEN")) {
        throw new Exception('TOKEN is not defined!');
    }
    
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];
    		
	$token = TOKEN;
	$tmpArr = array($token, $timestamp, $nonce);
    // use SORT_STRING rule
	sort($tmpArr, SORT_STRING);
	$tmpStr = implode( $tmpArr );
	$tmpStr = sha1( $tmpStr );
	
	if( $tmpStr == $signature ){
		return true;
	}else{
		return false;
	}
}
}

见官方文档说明:
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html

新手注册新浪云,安装应用

1、注册新浪云
http://www.sinacloud.com/

2、实名认证1-3天
sae_01

sae_02

3、创建新应用
sae_03

4、创建成功

5、这里使用git方式管理和上传代码,也可以选择SVN
sae_04

sae_05

06sae_04

sae_05


首先,创建一个新的Git仓库并且添加一个Git远程仓库sae,地址为:https://git.sinacloud.com/webjust1 。

$ mkdir webjust1 && cd webjust1
$ git init
$ git remote add sae https://git.sinacloud.com/webjust1

上传代码。如部署Git的主分支(master)的代码到新浪云服务器上的版本1中:

$ touch index.php
$ git add index.php
$ git commit -m”initial commit”
$ git push sae master:1

从新浪云服务器上删除版本1的代码。

$ git push sae :1

在新浪云上,应用版本对应于Git的远程分支。

代码更新命令:
git add .
git commit -m”1″
git push sae master:1

更多帮助:http://document.thinkphp.cn/manual_3_2/sae.html

6、数据库配置文件:

SAE空间提供数据库常量:

数据库主库(可以读可以写):SAE_MYSQL_HOST_M
数据库从库(不能写只能读):SAE_MYSQL_HOST_S
数据库端口(主库从库都是一个):SAE_MYSQL_PORT
数据库用户名:SAE_MYSQL_USER
数据库密码:SAE_MYSQL_PASS
数据库名称:SAE_MYSQL_DB

配置文件:

Select Code
1
2
3
4
5
6
7
8
9
10
11
<?php
return array(
// 数据库配置
'DB_TYPE'               =>  'mysql',     // 数据库类型
'DB_HOST'               =>  SAE_MYSQL_HOST_M, // 服务器地址
'DB_NAME'               =>  SAE_MYSQL_DB,          // 数据库名
'DB_USER'               =>  SAE_MYSQL_USER,      // 用户名
'DB_PWD'                =>  SAE_MYSQL_PASS,          // 密码
'DB_PORT'               =>  SAE_MYSQL_PORT,        // 端口
'DB_PREFIX'             =>  'cms_',    // 数据库表前缀
);

https://www.sinacloud.com/home/index/faq_detail/doc_id/82.html

7、注意模板文件路径的大小写

MySQL表锁、行锁的小实验

数据准备

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE DATABASE `test`;
use test;

CREATE TABLE `user1`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(30) NOT NULL DEFAULT '',
`age` INT NOT NULL DEFAULT 0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

-- 测试数据
INSERT INTO user1 (name, age) VALUES
('a', 1),
('b', 2),
('c', 3),
('d', 4),
('e', 5);

开启事务机制,锁定一行

Select Code
1
2
3
4
5
-- 开启事务
begin;

-- 锁定一行
SELECT * FROM user1 WHERE name='a' AND age=1 for update;

说明:for update是锁表的操作。

行锁的特点:InnoDB存储引擎是通过索引上的索引项加锁来实现的,这就意味着:只有通过索引条件检索数据,InnoDB才会使用行级锁。否则,InnoDB将使用表锁。

锁定同一个表中的另外一行数据

Select Code
1
2
3
-- 打开另一个窗口执行上面的步骤
begin;
SELECT * FROM user1 WHERE name='b' AND age=2 for update;

结果:表被锁定,此操作无效。

下一步:给name这个字段添加索引,这样InnoDB将被执行行锁而不是表锁。

操作命令:

Select Code
1
2
-- 添加索引
ALTER TABLE user1 ADD INDEX index_name(name)

查看表索引

结论:
没有索引的情况下,会出现表锁;
InnoDB支持行锁,但是行锁需要有索引的支持,如果没有索引则是表锁
MyISAM只支持表锁,这也是为什么MySQL新版是默认使用InnoDB存储引擎。
InnoDB支持行锁定

PHP MemCache缓存加速的完整入门教程内容及实战案例

一、MemCache的基本概念
MemCache系统是通过客户端发送的命令(set/get)管理“内存中缓存”的数据。客户端在于MemCached服务器建立连接以后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符key,存取操作均通过这个key进行,保存到memcached中的对象实际上是放置在内存中的,而并不是保存在缓存文件中的,这也是为什么MemCached能够如此告诉快速的原因。

memcached工作原理

MemCache在WEB中的应用:

1、使用MemCache作为中间缓冲层减少数据库的压力
2、MemCache分布式的应用

二、MemCache的安装及管理
1、Linux下安装MemCache软件
省略…

2、Window下安装MemCache软件
下载MemCache二进制数据包;
解压后放在某个磁盘的分区下面:如D:\

执行安装命令:

D:\>memcached.exe -d install

安装memcached

通过计算机管理的“服务”中查看刚安装的memcached软件。

计算机管理的服务查看memcached

启动memcached服务器:

D:\>memcached.exe -d start

启动memcached服务器

停止memcached服务器的运行:

D:\>memcached.exe -d stop

3、memcached服务器的管理

一些常用的管理选项:

例如:memcached.exe -d -m 2048 -l localhost -p 11211

-d 以守护程序方式运行memcached
-m 2048 2GB内存
-l localhost 监听本机
端口 11211

memcached服务器的管理

三、使用Telnet作为memcached的客户端管理
1、连接memcached服务器

telnet localhost 11211

连接memcached服务器

2、基本的memcached客户端命令

stats:当前所有memcached服务器运行的状态信息
add:添加一个数据到服务器
set:替换一个已经存在的数据。如果数据不存在,则和add命令相同。
get:从服务器端提取指定的数据。
delete:删除指定的单个数据。清除所有的数据,可以使用flush_all指令。

3、数据管理指令

添加(add)、修改(set)

<命令><键><标记><有效期><数据长度>

键:key
标记:一个16位的无符号整型数据,用来设置服务器端和客户端的一些交互操作
有效期:0表示无限制,单位是秒

memcached 数据管理指令

删除(delete)和获取(get)

<命令><键>

memcached 删除数据管理指令

四、PHP的memcached管理接口
1、安装PHP中的MemCache应用程序扩展接口
安装文件后,在配置文件中加入“extension=php_memcache.dll”

2、PHP程序使用MemCache应用程序接口的方法实例

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
<?php
    //实例化得到memcache对象
    $mem = new Memcache();

    //连接memcached服务器
    $mem->connect('127.0.0.1',11211);

    //赋值
    $mem->set('name','jack',2,1000);

    //取值
    echo $mem->get('name');

结果输出:jack

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
	//得到memcache对象
	$mem = new Memcache();

	//连接
	$mem->connect('127.0.0.1', 11211);

	$list = array('name'=>'jack', 'age'=>18);

	//赋值   存进去是什么样子,读取出来就是什么样
	$mem->set('list', $list);

	//取值
	$res = $mem->get('list');

	echo '<pre>';
	    print_r($res);
	echo '</pre>';

输出结果如下:

从memcached服务器中获取数据

分布式memcached服务器

Select Code
1
2
3
4
//添加多台服务器
$mem->addServer('192.168.12.6',11211);
$mem->addServer('192.168.12.251',11211);
$mem->addServer('192.168.12.25',11211);

五、MemCache的实例应用
1、从数据库读取用户表的PHP代码

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
$mem = new Memcache();
$mem->connect('127.0.0.1', 11211);

$sql = "select id, username, password, addtime from shop_user";

$fileName = md5($sql);

// 从memcached服务器获取值
$userlist = $mem->get($fileName);

if (empty($userlist)){

    $link = mysqli_connect('127.0.0.1','root', '', 'ishop');
    mysqli_set_charset($link,'utf8');

    sleep(3);
    $res = mysqli_query($link, $sql);

    if ($res) {
        while ($row = mysqli_fetch_assoc($res)) {
            $userlist[] = $row;
        }
    }

    // bool Memcache::set ( string $key , mixed $var [, int $flag [, int $expire ]] )
    // 向memcached中设置值,设置失效时间是10s
    $mem->set($fileName, $userlist, 2, 10);
}

/*
key 
要设置值的key。 
var 
要存储的值,字符串和数值直接存储,其他类型序列化后存储。 
flag 
使用 MEMCACHE_COMPRESSED 指定对值进行压缩(使用zlib)。 
expire 
当前写入缓存的数据的失效时间。
*/

?>

2、HTML的数据展示代码

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<table width="600" border="1" align="center">
<caption><h2>用户列表</h2></caption>
<tr>
    <th>ID</th>
    <th>UserName</th>
    <th>Password</th>
    <th>AddTime</th>
</tr>
<?php foreach($userlist as $v): ?>
<tr>
    <td><?php echo $v['id']; ?></td>
    <td><?php echo $v['username']; ?></td>
    <td><?php echo $v['password']; ?></td>
    <td><?php echo $v['addtime']; ?></td>
</tr>
<?php endforeach; ?>
</table>

六、代码解释:

1、第一次访问时,$userlist数据为空,因此会读取数据库操作,查询的结果会同时存储到memcached中,$mem->set($fileName, $userlist, 2, 10); 并且设置了失效的时间为10s。

2、$userlist只要没有失效,那么访问该页面,就会通过$userlist = $mem->get($fileName);来获取存储在memcached中的查询结果,而不直接访问数据库。这样读取的速度就会很快。

3、当缓存失效后,再读取数据库中的最新数据。

memcached_案例展示