KindEditor异步图片上传实现

1、引入KindeEditor编辑器,这里可以参考官方文档

2、上传文件的php

Select Code
1
2
3
4
5
6
7
8
<script>
  KindEditor.ready(function(K) {
    window.editor = K.create('#editor_singcms',{
      uploadJson : '{:U("Image/kindupload")}',
      afterBlur : function(){this.sync();}, //
    });
  });
</script>

2、返回格式(JSON)

Select Code
1
2
3
4
5
6
7
8
9
10
//成功时
{
 "error" : 0,
 "url" : "http://www.example.com/path/to/file.ext"
}
//失败时
{
 "error" : 1,
 "message" : "错误信息"
}

封装一个函数:

Select Code
1
2
3
4
5
6
7
8
9
10
function showKind($status, $data)
{
	header('Content-type:application/json;charset=UTF-8');
	if ($status==0) {
		// 成功时
		exit(json_encode(array('error'=>0, 'url'=>$data)));
	}
	// 失败时
	exit(json_encode(array('error'=>1, '上传失败')));
}

文档:http://kindeditor.net/docs/upload.html

3、上传图片部分,见上一篇文章:
异步上传图片

kindeditor图片异步上传效果

Uploadify异步上传图片效果

1、上传插件Uploadify出现Http Error 302错误

http 302是请求被重定向的意思,这就很容易理解了,如果你的uploadify处理上传脚本有session验证,就会出现此错误。

2、Uploadify异步上传图片(TP框架下的源码)

效果:
uploadify

控制器源码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class ImageController extends Controller
{
	public function ajaxuploadimage()
	{
		$res = D("UploadImage")->imageUpload();

		if ($res===false) {
			return show(0, '上传失败', '');
		} else{
			return show(1, '上传成功', $res);
		}
	}
}

image.js部分

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
/**
 * 图片上传功能
 */
$(function() {
    $('#file_upload').uploadify({
        'swf'      : SCOPE.ajax_upload_swf,
        'uploader' : SCOPE.ajax_upload_image_url,
        'buttonText': '上传图片',
        'fileTypeDesc': 'Image Files',
        'fileObjName' : 'file',
        //允许上传的文件后缀
        'fileTypeExts': '*.gif; *.jpg; *.png',
        'onUploadSuccess' : function(file,data,response) {
            // response true ,false
            if(response) {
                var obj = JSON.parse(data); //由JSON字符串转换为JSON对象
                
                $('#' + file.id).find('.data').html(' 上传完毕');

                $("#upload_org_code_img").attr("src",obj.data);
                $("#file_upload_image").attr('value',obj.data);
                $("#upload_org_code_img").show();
            }else{
                alert('上传失败');
            }
        },
    });
});

上传图片Model类:

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
/**
 * 上传图片类
 * @author  singwa
 */
class UploadImageModel extends Model {
    private $_uploadObj = '';
    private $_uploadImageData = '';

    const UPLOAD = 'upload';

    public function __construct() {
        $this->_uploadObj = new \Think\Upload();

        $this->_uploadObj->rootPath = './'.self::UPLOAD.'/';
        $this->_uploadObj->subName = date(Y) . '/' . date(m) .'/' . date(d);
    }

    public function imageUpload() {
        $res = $this->_uploadObj->upload();
        // print_r($res);die;

        if($res) {
            return '/02/' .self::UPLOAD . '/' . $res['file']['savepath'] . $res['file']['savename'];
        }else{
            return false;
        }
    }
}

微信开发第五篇:点击菜单自动回复文本消息

一、用户点击事件,微信会发送XML格式的数据给我们的服务器,如下:
// 点击菜单拉取消息时的事件推送 推送XML数据包示例:

Select Code
1
2
3
4
5
6
7
8
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[EVENTKEY]]></EventKey>
</xml>

更多事件类型见文档:http://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html

前面我们在index控制器的responseMsg方法中,接收到了微信服务器发送给我们服务器的信息,并且保存到服务器中。

数据如下:
接收信息

具体的格式如下:
接收信息XML

二、我们的服务器接收到XML信息后,获取事件Event和EventKey就可以写程序被动回复信息:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 获取事件类型
$event = $postObj->Event;

switch ($event) {
    case 'CLICK':
        // 用户点击后触发该事件
        $eventKey = $postObj->EventKey;

        switch ($eventKey) {
            case 'V1001_TODAY_MUSIC':
                $this->sendMsg('帮助菜单:回复A查看更多图文信息!');
                break;
        }


        break;
    
    default:
        # code...
        break;
}

click_event

click_event_case

纯文本消息发送函数:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
// 发送纯文本消息
public function sendMsg($str)
{
  $textTpl = '<xml>
  <ToUserName><![CDATA['.$this->fromUsername.']]></ToUserName>
  <FromUserName><![CDATA['.$this->toUsername .']]></FromUserName>
  <CreateTime>'.time().'</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA['.$str.']]></Content>
  </xml>';

  echo $textTpl;exit;
}

三、用户订阅事件,发送纯文本信息

Select Code
1
2
3
case 'subscribe':
    $this->sendMsg('你开心就好!');
    break;

click_event_case2

微信开发第四篇:自定义菜单

官方文档:
https://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html

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
//通过浏览器访问这个方法,来生成菜单
public function makeMenu()
{  
    $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$this->getAccessToken();
    $data = '{
         "button":[
         {  
              "type":"click",
              "name":"今日歌曲",
              "key":"V1001_TODAY_MUSIC"
          },
          {
               "name":"菜单",
               "sub_button":[
               {    
                   "type":"view",
                   "name":"搜索",
                   "url":"http://www.soso.com/"
                },
                {
                   "type":"view",
                   "name":"博客",
                   "url":"http://www.webjust.org"
                },
                {
                   "type":"click",
                   "name":"赞一下我们",
                   "key":"V1001_GOOD"
                }]
           }]
     }';

    $res = $this->curlHttp($url, $data);
    dump($res);
}

最终效果:
微信自定菜单

curlHttp的函数封装见另外一篇文章:curlHttp

获取Token:微信开发第三篇:获取access token

源码:https://github.com/webjust/wechat_beiginner

微信开发第三篇:获取access token

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

说明:实现中,一般请求的access_token就保存在本地数据库一份,微信接口很多需要使用到token值,而官方的访问次数也是有限制的,每天2000次。

获取access token

官方文档出处:http://mp.weixin.qq.com/wiki/2/88b2bf1265a707c031e51f26ca5e6512.html

实现源码:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//获取access_token
public function getAccessToken()
{
//appid和secret记得要替换
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx542c11817c22d123&secret=8b2d7aac7d5dc87173bc62a429545e18';

$res = $this->curlHttp($url);

$accessToken = json_decode($res, true);

// 测试行
var_dump($accessToken);exit;

return $accessToken['access_token'];
}

实现结果:
access_token_02

CURL实现GET/POST请求的完整内容解析及函数封装

使用cURL完成简单的请求主要分为以下四步:
1.初始化,创建一个新cURL资源
2.设置URL和相应的选项
3.抓取URL并把它传递给浏览器
4.关闭cURL资源,并且释放系统资源

更多的选项参考官方的说明:
http://php.net/manual/zh/function.curl-setopt.php

一、默认模拟的是:GET请求

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
// 1、初始化一个cURL会话
$ch = curl_init();

// 2、设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, 'http://www.baidu.com');

// TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

// 3、抓取URL并将其返回给浏览器
$data = curl_exec($ch);

var_dump($data);

// 4、关闭cURL资源
curl_close($ch);
?>

显示结果:
CURL的GET请求示例

二、模拟CURL POST请求
实现过程同上,唯一的差别是设置选项:curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

源码如下:

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
<?php 
// 1、初始化一个cURL会话
$ch = curl_init();

// 2、设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, 'http://test.com/curl/ceshi.php');

// TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

// 准备提交的数据
$data = array('username'=>'zhangsan', 'age'=>18);

/**
 * POST请求,设置选项为CURLOPT_POSTFIELDS,传递一个数组
 */
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);


// 3、抓取URL并将其返回给浏览器
$res = curl_exec($ch);

echo $res;

// 4、关闭cURL资源
curl_close($ch);

?>

文件:http://test.com/curl/ceshi.php是本地的打印函数

Select Code
1
<?php var_dump($_POST);?>

最终效果:
CURL模拟POST请求

三、封装成函数

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function curlHttp($url, $data=null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        //无论是post还是get都不能直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //判断是不是post
        if( $data ){
            //告诉小弟需要带上的数据
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }