龚哥哥 - 山里男儿 爱生活、做自己!
使用百度API翻译接口将网页翻译成英文
发表于 2020-8-31 | 浏览(21644) | PHP

将网页内容翻译成英文,或者更多语言

HTML代码

<!doctype html>
<head>
    <meta charset="utf-8" />
    <title>网页翻译测试</title>
</head>
<body>
    <div>测试
        <div>橘子</div>
    </div>
    <div>梨</div>
    <div>测试</div>
    <div>零食</div>
    <div>水果</div>
    <div>上班</div>
    <div>ShopXO 免费开源系统,可商用,可二次开发。</div>

    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.17.0/js/md5.js"></script>
    <script type="text/javascript">
        function transformLanguage(newLanguage) {
            // 获取所有dom元素中文
            var transformStr = '';
            var temp_index = 0;
            // 获取所有dom元素
            function getChildDom(dom, type, data = {}) {
                if(type == 'read') {
                    [...dom.children].forEach(v => {
                        // 判断中文
                        // /^[\u0391-\uFFE5]+$/
                        var re= /[\u4e00-\u9fa5]/g;
                        // 防止某些标签有内容并且有标签 ,或者有空格 
                        var vHtml = $(v).contents().filter(function (index, content) {return content.nodeType === 3}).text().trim();
                        // 跳过script标签
                        if (re.test(vHtml) && v.tagName != 'SCRIPT') {
                            // 使用\n换行拼接、接口将返回数组
                            transformStr += `${vHtml}\n`
                        }
                        // 递归获取元素
                        getChildDom(v, type, data);
                    })
                }else {
                    [...dom.children].forEach(v => {
                        // 判断中文
                        // /^[\u0391-\uFFE5]+$/
                        var re= /[\u4e00-\u9fa5]/g;
                        var vHtml = $(v).contents().filter(function (index, content) {return content.nodeType === 3}).text().trim();
                        // 跳过script标签
                        if (re.test(vHtml) && v.tagName != 'SCRIPT') {
                            if((data[temp_index] || null) != null)
                            {
                                var transOld = data[temp_index]['src'];
                                var transNew = data[temp_index]['dst'];
                                // 防止标签里面还有标签,所以只替换里面的html,使用replace
                                $(v).html(
                                    $(v).html().replace( transOld, transNew)
                                )
                                temp_index++;
                            }
                        }
                        // 递归获取元素
                        getChildDom(v, type, data);
                    })
                }
            }
            getChildDom(document,'read');

            if((transformStr || null) != null)
            {
                getTranslateData();
                // 获取翻译
                // 接口申请地址 https://api.fanyi.baidu.com/
                function getTranslateData() {
                    var appid = '...';   // 百度翻译API的appid
                    var key = '...';   // 百度翻译API的key
                    var salt = (new Date).getTime();
                    var query = transformStr;
                    var from = 'zh';
                    var to = newLanguage;
                    var str1 = appid + query + salt + key;
                    var sign = md5(str1);
                    $.ajax({
                        url: 'baidu.php',
                        type: 'post',
                        dataType: 'json',
                        data: {
                            q: query,
                            appid: appid,
                            salt: salt,
                            from: from,
                            to: to,
                            sign: sign
                        },
                        success: function(data) {
                            data.trans_result && getChildDom(document,'write',data.trans_result);
                        }
                    });
                }
            }
        }

        // 页面加载完成再执行
        window.onload = function () {
            transformLanguage('en');
        };
    </script>
</body>

PHP代码

<?php

/**
 * curl
 * @author  Devil
 * @blog    http://gong.gg/
 * @version 1.0.0
 * @date    2020-08-31
 * @desc    description
 * @param   [type]          $url     [description]
 * @param   [type]          $post    [description]
 * @param   boolean         $is_json [description]
 */
function CurlPost($url, $post, $is_json = false)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    curl_setopt($ch, CURLOPT_URL, $url);

    // 是否 json
    if($is_json)
    {
        $data_string = json_encode($post);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                "Content-Type: application/json; charset=utf-8",
                "Content-Length: " . strlen($data_string)
            )
        );
    } else {
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                "Content-Type: application/x-www-form-urlencoded",
                "cache-control: no-cache"
            )
        );
    }

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

echo CurlPost('http://api.fanyi.baidu.com/api/trans/vip/translate', $_POST);

阅读全文

PHP采用Swoole扩展开发高性能WebSocket
发表于 2016-9-17 | 浏览(16965) | PHP

需要安装PHP Swoole扩展,官网地址:http://www.swoole.com/

安装教程可查看本博客中swoole安装

1、index.html 内容如下

<!DOCTYPE html>
<head>
<title>socket demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="./jquery-2.1.3.min.js"></script>
</head>
<body>
<input type="text" id="msg" />
<button id="send">发送</button>
</body>
</html>
<script>
$(function()
{
    // 创建socket对象
    var socket = new WebSocket('ws://'+document.domain+':9501');

    // 打开Socket 
    socket.onopen = function(event)
    {

        $('#send').on('click', function()
        {
            var msg = $('#msg').val();
            socket.send(msg);
            console.log(msg);
        });
        // 发送一个初始化消息
        socket.send("客户端初始化!"); 

        // 监听消息
        socket.onmessage = function(event) { 
            console.log("客户端监听到的消息:", event); 
        }; 

        // 监听Socket的关闭
        socket.onclose = function(event) { 
        console.log("Socket关闭了", event); 
        }; 

      // 关闭Socket.... 
      //socket.close() 
    };
});
</script>

2、web_socket.php 内容如下

<?php

// 本机的ip
// 通过命令行运行 cli
$server = new swoole_websocket_server("192.168.0.110", 9501);

// 握手成功回调
$server->on('open', function(swoole_websocket_server $server, $request)
{
    echo "server: handshake success with fd{$request->fd}\n";
});

// 消息监听
$server->on('message', function(swoole_websocket_server $server, $frame)
{
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    $server->push($frame->fd, "this is server {$frame->data}");
});

// 关闭监听
$server->on('close', function($ser, $fd)
{
    echo "client {$fd} closed\n";
});

// http请求监听, 如果监听了Request则可以通过http访问
// 通过 http://192.168.0.110:9501 访问
$server->on('Request', function($req, $respone)
{
    // $req->get, $req->post
    if(!empty($req->get))
    {
        // 使用全局变量
        global $server;

        // 服务器推送消息给客户端
        // 参数1 socketID, 参数2 推送内容
        $server->push(1, "this is server hello request {$req->get['msg']}");

        // 响应完成
        $respone->end("success");
    }
});

// 开始
$server->start();

?>

3、在命令行运行web_socket.php

php web_socket

4、客户端在浏览器上访问,可发送消息到服务器并且响应服务器推送的消息

http://192.168.0.110/index.html

5、服务器端推送消息给客户端,在客户端页面可看见推送的消息

http://192.168.0.110:9501?msg=hello

6、测试结果,这里输入什么就给返回什么,在项目中根据自己项目做fid与用户的关联即可。

阅读全文

Elasticsearch入门 搜索引擎
发表于 2016-8-11 | 浏览(9727) | PHP

Elasticsearch最高效开源的搜索引擎框架,我们下面添加几条员工数据进行演示,详情可以在线文档查看,这里用PHP操作Elasticsearch的一些例子,在使用例子的情况下需要先安装Elasticsearch搜索引擎,安装方法可以查看官网,地址:https://www.elastic.co/downloads/elasticsearch

Elasticsearch依赖java,地址:http://www.java.com/

中文文档地址:http://es.xiaoleilu.com/

公共方法,用于操作Elasticsearch

/**
 * [PostCurl post请求]
 * @param  [string]  $url    [请求地址]
 * @param  [string]  $option [参数]
 * @param  [integer] $header [http头部信息]
 * @param  [string]  $type   [请求类型]
 * @return [array]           [返回的数据]
 */
function PostCurl($url, $option = '', $header = '', $type = 'POST')
{
    if(empty($header)) $header = array();
    $curl = curl_init (); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'); // 模拟用户使用的浏览器
    if (! empty($option)) {
        if($type == 'PUT')
        {
            $options = json_encode($option);
        } else {
            $options = json_encode($option, JSON_FORCE_OBJECT);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $options); // Post提交的数据包
    }
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // 设置HTTP头
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type);
    $result = curl_exec($curl); // 执行操作
    curl_close($curl); // 关闭CURL会话
    return json_decode($result, true);
}

定义url地址

$url = 'http://localhost:9200/';

1、添加员工数据

关系数据库     ⇒ 数据库 ⇒ 表     ⇒ 行     ⇒ 列(Columns)

Elasticsearch   ⇒ 索引   ⇒ 类型   ⇒ 文档   ⇒ 字段(Fields)

索引 megacorp

类型 employee

文档 1 ~ 3

字段

// 定义员工数据
$param = array(
    1   =>   array(
            'first_name'    =>   'John',
            'last_name'     =>   'Smith',
            'age'           =>   25,
            'about'         =>   'I love to go rock climbing',
            'interests'     =>   array('sports', 'music')
        ),
    2   =>   array(
            'first_name'    =>   'Jane',
            'last_name'     =>   'Smith',
            'age'           =>   32,
            'about'         =>   'I like to collect rock albums',
            'interests'     =>   array('music')
        ),
    3   =>   array(
            'first_name'    =>   'Douglas',
            'last_name'     =>   'Fir',
            'age'           =>   35,
            'about'         =>   'I like to build cabinets',
            'interests'     =>   array('forestry')
        ),
    );

// 循环将员工数据加入 Elasticsearch 搜索引擎中
$success = 0;
foreach($param as $k=>$v)
{
    $result = PostCurl($url.'megacorp/employee/'.$k, $v, '', 'PUT');
    if(isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) $success++;
}
echo $success.'<br />';

输出 3

2、获取id为1的员工数据

$result = PostCurl($url.'megacorp/employee/1', '', '', 'GET');
print_r($result);

返回数据
Array
(
    [_index] => megacorp
    [_type] => employee
    [_id] => 1
    [_version] => 28
    [found] => 1
    [_source] => Array
        (
            [first_name] => John
            [last_name] => Smith
            [age] => 25
            [about] => I love to go rock climbing
            [interests] => Array
                (
                    [0] => sports
                    [1] => music
                )

        )

)

3、搜索全部员工

$result = PostCurl($url.'megacorp/employee/_search', '', '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 4
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 3
            [max_score] => 1
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 3
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Douglas
                                    [last_name] => Fir
                                    [age] => 35
                                    [about] => I like to build cabinets
                                    [interests] => Array
                                        (
                                            [0] => forestry
                                        )

                                )

                        )

                )

        )

)

4、搜索姓 last_name等于Smith的员工, 轻量的搜索方法

$result = PostCurl($url.'megacorp/employee/_search?q=last_name:Smith', '', '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 6
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 2
            [max_score] => 0.30685282
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                )

        )

)

5、使用Query DSL搜索。搜索姓 last_name等于Smith的员工, 轻量的搜索方法

$param = array(
    'query' =>   array(
            'match' =>   array('last_name'   =>   'Smith'),
        ),
    );
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 1
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 2
            [max_score] => 0.30685282
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                )

        )

)

6、更加复杂的搜索,搜索姓 last_name等于Smith的员工, 轻量的搜索方法。年龄大于30岁的限定条

$param = array(
    'query' =>   array(
        'filtered'  =>   array(
            'query'     =>   array(
                'match' =>   array('last_name'   =>   'Smith'),
            ),

            'filter'    =>   array(
                'range' =>   array(
                    'age'   =>   array('gt'  =>   30)
                ),
            ),
        ),
    ),
);
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 4
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 1
            [max_score] => 0.30685282
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                )

        )

)

7、更加复杂的全文搜索。一项在传统数据库很难实现的功能、我们将会搜索所有喜欢 rock climbing 的员工

$param = array(
    'query' =>   array(
            'match' =>   array('about'   =>   'rock climbing'),
        ),
    );
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 7
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 2
            [max_score] => 0.16273327
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.16273327
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 0.016878016
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                )

        )

)

8、段落搜索。我们只需要查询到 about 字段只包含 rock climbing 的短语的员工

$param = array(
    'query' =>   array(
            'match_phrase'  =>   array('about'   =>   'rock climbing'),
        ),
    );
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 2
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 1
            [max_score] => 0.23013961
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.23013961
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                )

        )

)

9、高亮我们的搜索。但是添加一个 highlight 参数

$param = array(
    'query' =>   array(
            'match_phrase'  =>   array('about'   =>   'rock climbing'),
        ),
    'highlight' =>   array(
            'fields'    =>   array(
                    'about' =>   array()
                )
        ),
    );
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 2
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 1
            [max_score] => 0.23013961
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.23013961
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                            [highlight] => Array
                                (
                                    [about] => Array
                                        (
                                            [0] => I love to go rock climbing
                                        )

                                )

                        )

                )

        )

)

10、统计。例如,找一下员工中最受欢迎的兴趣是什么

$param = array(
    'aggs'  =>   array(
        'all_interests' =>   array(
            'terms' =>   array('field'   =>   'interests'),
        ),
    ),
);
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 2
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 3
            [max_score] => 1
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 3
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Douglas
                                    [last_name] => Fir
                                    [age] => 35
                                    [about] => I like to build cabinets
                                    [interests] => Array
                                        (
                                            [0] => forestry
                                        )

                                )

                        )

                )

        )

    [aggregations] => Array
        (
            [all_interests] => Array
                (
                    [doc_count_error_upper_bound] => 0
                    [sum_other_doc_count] => 0
                    [buckets] => Array
                        (
                            [0] => Array
                                (
                                    [key] => music
                                    [doc_count] => 2
                                )

                            [1] => Array
                                (
                                    [key] => forestry
                                    [doc_count] => 1
                                )

                            [2] => Array
                                (
                                    [key] => sports
                                    [doc_count] => 1
                                )

                        )

                )

        )

)

11、如果只想要查询姓 smith 的员工的兴趣汇总情况

$param = array(
    'query' =>   array(
        'match' =>   array(
            'last_name' =>   'smith'
        ),
    ),
    'aggs'  =>   array(
        'all_interests' =>   array(
            'terms' =>   array('field'   =>   'interests'),
        ),
    ),
);
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 2
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 2
            [max_score] => 0.30685282
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 0.30685282
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                )

        )

    [aggregations] => Array
        (
            [all_interests] => Array
                (
                    [doc_count_error_upper_bound] => 0
                    [sum_other_doc_count] => 0
                    [buckets] => Array
                        (
                            [0] => Array
                                (
                                    [key] => music
                                    [doc_count] => 2
                                )

                            [1] => Array
                                (
                                    [key] => sports
                                    [doc_count] => 1
                                )

                        )

                )

        )

)

12、汇总还允许多个层面的统计。比如我们还可以统计每一个兴趣下的平均年龄

$param = array(
    'aggs'  =>   array(
        'all_interests' =>   array(
            'terms' =>   array('field'   =>   'interests'),
            'aggs'  =>   array(
                'avg_age' => array(
                    'avg'   =>   array(
                        'field' =>   'age'
                    ),
                ),
            ),
        ),
    ),
);
$result = PostCurl($url.'megacorp/employee/_search', $param, '', 'GET');
print_r($result);

返回数据
Array
(
    [took] => 16
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 3
            [max_score] => 1
            [hits] => Array
                (
                    [0] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 2
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Jane
                                    [last_name] => Smith
                                    [age] => 32
                                    [about] => I like to collect rock albums
                                    [interests] => Array
                                        (
                                            [0] => music
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 1
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => John
                                    [last_name] => Smith
                                    [age] => 25
                                    [about] => I love to go rock climbing
                                    [interests] => Array
                                        (
                                            [0] => sports
                                            [1] => music
                                        )

                                )

                        )

                    [2] => Array
                        (
                            [_index] => megacorp
                            [_type] => employee
                            [_id] => 3
                            [_score] => 1
                            [_source] => Array
                                (
                                    [first_name] => Douglas
                                    [last_name] => Fir
                                    [age] => 35
                                    [about] => I like to build cabinets
                                    [interests] => Array
                                        (
                                            [0] => forestry
                                        )

                                )

                        )

                )

        )

    [aggregations] => Array
        (
            [all_interests] => Array
                (
                    [doc_count_error_upper_bound] => 0
                    [sum_other_doc_count] => 0
                    [buckets] => Array
                        (
                            [0] => Array
                                (
                                    [key] => music
                                    [doc_count] => 2
                                    [avg_age] => Array
                                        (
                                            [value] => 28.5
                                        )

                                )

                            [1] => Array
                                (
                                    [key] => forestry
                                    [doc_count] => 1
                                    [avg_age] => Array
                                        (
                                            [value] => 35
                                        )

                                )

                            [2] => Array
                                (
                                    [key] => sports
                                    [doc_count] => 1
                                    [avg_age] => Array
                                        (
                                            [value] => 25
                                        )

                                )

                        )

                )

        )

)

删除指定日期之前的数据

curl -XDELETE 'http://localhost:9200/logstash-2017.02.25*'

上面这些已经可以基本掌握Elasticsearch的操作,后面更深入的、分布式集群,等...... 敬请关注~

阅读全文

PHP中4种排序算法
发表于 2016-7-6 | 浏览(7640) | PHP
<?php

/**
 * PHP排序算法Demo
 */

/**
 * [bubble_sort 冒泡排序]
 * @param  [array] $data [需要排序的数据(相邻的数据进行比较调换位置)]
 * @return [array]       [排序好的数据]
 */
function bubble_sort($data)
{
    if(!empty($data) && is_array($data))
    {
        $len = count($data);
        for($i=0; $i<$len; $i++)
        {
            for($k=0; $k<$len-1; $k++)
            {
                if($data[$k] > $data[$i])
                {
                    $data[$i] = $data[$i] ^ $data[$k];
                    $data[$k] = $data[$i] ^ $data[$k];
                    $data[$i] = $data[$i] ^ $data[$k];
                }
            }
        }
    }
    return $data;
}

/**
 * [select_sort 选择排序]
 * @param  [array] $data [需要排序的数据(选择最小的值与第一个调换位置)]
 * @return [array]       [排序好的数据]
 */
function select_sort($data)
{
    if(!empty($data) && is_array($data))
    {
        $len = count($data);
        for($i=0; $i<$len; $i++)
        {
            $t = $i;
            for($j=$i+1; $j<$len; $j++)
            {
                if($data[$t] > $data[$j])
                {
                    $t = $j;
                }
            }
            if($t != $i)
            {
                $data[$i] = $data[$i] ^ $data[$t];
                $data[$t] = $data[$i] ^ $data[$t];
                $data[$i] = $data[$i] ^ $data[$t];
            }
        }
    }
    return $data;
}

/**
 * [insert_sort 插入排序]
 * @param  [array] $data [需要排序的数据(把第n个数插到前面的有序数组中,以此反复循环直到排序好)]
 * @return [array]       [排序好的数据]
 */
function insert_sort($data)
{
    if(!empty($data) && is_array($data))
    {
        $len = count($data);
        for($i=1; $i<$len; $i++)
        {
            $tmp = $data[$i];
            for($j=$i-1; $j>=0; $j--)
            {
                if($data[$j] > $tmp)
                {
                    $data[$j+1] = $data[$j];
                    $data[$j]   = $tmp;
                } else {
                    break;
                }
            }
        }
    }
    return $data;
}

/**
 * [quick_sort 快速排序]
 * @param  [array] $data [需要排序的数据(选择一个基准元素,将待排序分成小和打两罐部分,以此类推递归的排序划分两罐部分)]
 * @return [array]       [排序好的数据]
 */
function quick_sort($data)
{
    if(!empty($data) && is_array($data))
    {
        $len = count($data);
        if($len <= 1) return $data;

        $base = $data[0];
        $left_array = array();
        $right_array = array();
        for($i=1; $i<$len; $i++)
        {
            if($base > $data[$i])
            {
                $left_array[] = $data[$i];
            } else {
                $right_array[] = $data[$i];
            }
        }
        if(!empty($left_array)) $left_array = quick_sort($left_array);
        if(!empty($right_array)) $right_array = quick_sort($right_array);

        return array_merge($left_array, array($base), $right_array);
    }
}

/**
 * 测试
 */
$data = array(10, 3, 6, 1, 24, 18, 7, 8);
echo '<pre>';

// 冒泡排序
print_r(bubble_sort($data));

// 选择排序
print_r(select_sort($data));

// 插入排序
print_r(insert_sort($data));

// 快速排序
print_r(quick_sort($data));

// 以下是结果
Array
(
    [0] => 1
    [1] => 3
    [2] => 6
    [3] => 7
    [4] => 8
    [5] => 10
    [6] => 18
    [7] => 24
)
Array
(
    [0] => 1
    [1] => 3
    [2] => 6
    [3] => 7
    [4] => 8
    [5] => 10
    [6] => 18
    [7] => 24
)
Array
(
    [0] => 1
    [1] => 3
    [2] => 6
    [3] => 7
    [4] => 8
    [5] => 10
    [6] => 18
    [7] => 24
)
Array
(
    [0] => 1
    [1] => 3
    [2] => 6
    [3] => 7
    [4] => 8
    [5] => 10
    [6] => 18
    [7] => 24
)

?>

阅读全文

PHP坐标圆周率计算
发表于 2016-6-15 | 浏览(7420) | PHP
/**
 * [GetSquarePoint 坐标圆周率计算]
 *  $lng = '116.655540';
 *  $lat = '39.910980';
 *  $squares = GetSquarePoint($lng, $lat);
 *       
 *  print_r($squares);
 *  $info_sql = "select id,locateinfo,lat,lng from `lbs_info` where lat<>0 and lat>{$squares['right-bottom']['lat']} and lat<{$squares['left-top']['lat']} and lng>{$squares['left-top']['lng']} and lng<{$squares['right-bottom']['lng']} ";
 *  计算某个经纬度的周围某段距离的正方形的四个点
 *
 *  param lng float 经度
 *  param lat float 纬度
 *  param distance float 该点所在圆的半径,该圆与此正方形内切,默认值为0.5千米
 *  return array 正方形的四个点的经纬度坐标
 */
function GetSquarePoint($lng, $lat, $distance = 0.5)
{
    if(empty($lng) || empty($lat)) return '';

    /* 地球半径,平均半径为6371km */
    $radius = 6371;

    $d_lng =  2 * asin(sin($distance / (2 * $radius)) / cos(deg2rad($lat)));
    $d_lng = rad2deg($d_lng);

    $d_lat = $distance/$radius;
    $d_lat = rad2deg($d_lat);

    return array(
        'left-top'=>array('lat'=>$lat + $d_lat,'lng'=>$lng-$d_lng),
        'right-top'=>array('lat'=>$lat + $d_lat, 'lng'=>$lng + $d_lng),
        'left-bottom'=>array('lat'=>$lat - $d_lat, 'lng'=>$lng - $d_lng),
        'right-bottom'=>array('lat'=>$lat - $d_lat, 'lng'=>$lng + $d_lng)
    );
}

阅读全文

PHP TCP通信
发表于 2016-6-15 | 浏览(7167) | PHP

创建文件 server.php 内容如下

<?php

$filename = '/data/www/devil/tcp/server.txt';
$myfile = fopen($filename, "a+");
set_time_limit( 0 );
ob_implicit_flush();
$socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
socket_bind( $socket, '192.168.1.94', 11109 );
socket_listen($socket);
$acpt=socket_accept($socket);
echo "Acpt!\n";
while ( $acpt ) {
    $words=fgets(STDIN);
    socket_write($acpt,$words);
    $hear=socket_read($acpt,1024);
    echo $hear;
    fwrite($myfile, $hear);
    if("bye\r\n"==$hear){
        socket_shutdown($acpt);
        break;
    }
    usleep( 5000 );
}
socket_close($socket);

fclose($myfile);
?>

创建文件 client.php 内容如下

<?php

$filename = '/data/www/devil/tcp/client.txt';
$myfile = fopen($filename, "a+");

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$con=socket_connect($socket,'192.168.1.94',11109);
if(!$con){socket_close($socket);exit;}
echo "Link\n";
while($con){
        $hear=socket_read($socket,1024);
        echo $hear;
        fwrite($myfile, $hear);
        $words=fgets(STDIN);
        socket_write($socket,$words);
        if($words=="bye\r\n"){break;}
        usleep( 5000 );
}
socket_shutdown($socket);
socket_close($sock);

fclose($myfile);
?>

文件创建好后,修改 $filename 变量相对应自己系统的地址,写测试数据

192.168.1.94 ip改成自己服务器的或者本机ip

php server.php
php client.php

在 server.php 窗口输入 hello
回到 client.php 窗口可以马上看见 hello
当然在 client.php 窗口输入的内容在 server.php 窗口也可以马上看见

阅读全文

PHP计算两个坐标之间的距离
发表于 2016-6-15 | 浏览(7287) | PHP
/**
 * [GetDistance 计算两个进纬度之间的距离]
 * @param [float] $lat1 [纬度1]
 * @param [float] $lng1 [经度1]
 * @param [float] $lat2 [纬度2]
 * @param [float] $lng2 [经度2]
 * @return[float]       [两个坐标距离值]
 */
function GetDistance($lat1, $lng1, $lat2, $lng2)
{
    $pi = 3.1415926535898;
    $earth_radius = 6378.137;

    $radLat1 = $lat1 * ($pi / 180);
    $radLat2 = $lat2 * ($pi / 180);

    $a = $radLat1 - $radLat2; 
    $b = ($lng1 * ($pi / 180)) - ($lng2 * ($pi / 180)); 

    $s = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1)*cos($radLat2)*pow(sin($b/2),2))); 
    $s = $s * $earth_radius; 
    $s = round($s * 10000) / 10000; 
    return $s; 
}

阅读全文

PHP图片上传(简约版)
发表于 2016-5-5 | 浏览(7830) | PHP
<?php

/**
 * 图片处理类
 * @author  Devil
 * @version v_0.0.1
 */
class Images
{
    private $path;
    private $zoom;

    /**
     * [__construct 构造方法]
     * @param [string]  $path [图片存储路径]
     * @param [int]     $zoom [压缩程度]
     */
    public function __construct($path = '', $zoom = 60)
    {
        // 参数校验
        if(empty($path)) exit('param path no');

        // 属性赋值
        $this->path = $path;
        $this->zoom = $zoom;
    }

    /**
     * [ImagesReturn 数据返回]
     * @param [mixed]   $msg  [错误信息/数据]
     * @param [int]     $code [状态]
     * @return[array]         [返回数据]
     */
    private function ImagesReturn($msg = '', $code = 0)
    {
        return array('msg'=>$msg, 'code'=>$code);
    }

    /**
     * [FormSave form图片资源存储]
     * @param [string] $resources   [图片临时资源]
     * @param [string]  $name       [图片名称(可空)]
     * @param [string]  $path       [自定义图片路径(可空)]
     * @return[array]               [图片名称]
     */
    public function FormSave($resources, $name = '', $path = '')
    {
        // 参数校验
        if(empty($resources['tmp_name']) || empty($resources['type'])) return $this->ImagesReturn('参数错误', -1);

        // 文件名生成
        $file_name = empty($name) ? $this->FileNewName() : $name;

        // 图片后缀名
        $suffix = $this->GetSuffix($resources['type']);
        if(empty($suffix)) $this->ImagesReturn('图片后缀名有误', -2);

        // 图片存储
        $file_name = $file_name.'.'.$suffix;
        $path = empty($path) ? $this->path : $path;
        if(move_uploaded_file($resources['tmp_name'], $path.$file_name)) return $this->ImagesReturn($file_name);

        // 返回错误
        return $this->ImagesReturn('图片存储失败', -100);
    }

    /**
     * [GetSuffix 获取图片的后缀名]
     * @param [string] $type [图片资源类型]
     * @return[string]       [后缀名]
     */
    private function GetSuffix($type)
    {
        $img_all = array(
            'jpg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif');

        $key = array_search($type, $img_all);
        if($key === false) return '';
        return $key;
    }

    /**
     * [FileNewName 生成文件名]
     */
    private function FileNewName()
    {
        $name = date('YmdHis');
        for($i=0; $i<6; $i++) $name .= rand(0, 9);
        return $name;
    }

    /**
     * [Compression 图片缩放存储]
     * @param [string]  $images [图片资源]
     * @param [string]  $name   [图片名称(可空)]
     * @param [string]  $path   [自定义图片路径(可空)]
     * @param [int]     $w      [宽度(可空)]
     * @param [int]     $h      [高度(默认原始尺寸或以宽度自动计算)]
     * @param [int]     $zoom   [压缩值(默认60)]
     * @return[array]           [图片信息]
     */
    public function Compression($images, $name = '', $path = '', $w = 0, $h = 0, $zoom = 0)
    {
        // 参数校验
        if(empty($images)) return $this->ImagesReturn('参数错误', -1);

        // 获取图片信息
        $info = @getimagesize($images);
        if($info == false) return $this->ImagesReturn('图片有误', -2);

        // 文件名生成
        $file_name = empty($name) ? $this->FileNewName() : $name;

        // 图片后缀名
        //$suffix = $this->GetSuffix($info['mime']);
        $suffix = strrchr($images, '.'); 
        if(empty($suffix)) return $this->ImagesReturn('图片后缀名有误', -3);

        // 取得尺寸的比例值
        $proportion = empty($w) ? 0 : $w/$info[0];

        // 新的宽度
        $new_width = empty($w) ? $info[0] : $w;

        // 如果没有自定义高度则根据宽度计算高度
        $new_height = empty($h) ? (($w < $info[0] && !empty($proportion)) ? intval($proportion*$info[1]) : (($w > $info[0] && !empty($proportion)) ? intval($proportion*$info[1]) : $info[1])) : $h;

        // 新建一个彩色图像
        $new_img = imagecreatetruecolor($new_width, $new_height);

        // 图片资源
        $img = $this->ImageFrom($images, $new_img, $info['mime']);
        if(!$img) return $this->ImagesReturn('图片资源获取失败', -4);

        // 缩放图片
        imagecopyresampled($new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $info[0], $info[1]);

        // 缩放程度
        $zoom = empty($zoom) ? (empty($this->zoom) ? 100 : $this->zoom) : $zoom;

        // 存储图片
        $file_name = $file_name.$suffix;
        $path = empty($path) ? $this->path : $path;
        switch($info['mime'])
        {
            case 'image/png':
                $state = imagepng($new_img, $path.$file_name);
                break;

            case 'image/gif':
                $state = imagegif($new_img, $path.$file_name);
                break;

            default:
                $state = imagejpeg($new_img, $path.$file_name, $zoom);
        }

        // 释放内容
        imagedestroy($img);
        imagedestroy($new_img);

        // 返回
        if($state) return $this->ImagesReturn($file_name);
        return $this->ImagesReturn($file_name);
        $this->ImagesReturn('文件储存失败', -100);
    }

    /**
     * [ImageFrom 图片资源获取]
     * @param [string] $images [原图片资源]
     * @param [string] $new_img[新的图片资源]
     * @param [string] $type   [图片类型]
     * @return[mixed]          [成功返回图象资源,失败返回 false]
     */
    private function ImageFrom($images, $new_img, $type)
    {
        // 参数校验
        if(empty($images) || empty($type)) return false;

        // 图片资源获取
        switch($type)
        {
            case 'image/png':
                $img = imagecreatefrompng($images);

                // png保留透明背景
                imagealphablending($new_img, false);
                imagesavealpha($new_img, true);
                imagesavealpha($img, true);
                break;

            case 'image/gif':
                $img = imagecreatefromgif($images);
                break;

            default:
                case 'image/jpeg':
                $img = imagecreatefromjpeg($images);
        }
        return $img;
    }
}
?>

阅读全文

PHP图片验证码生成
发表于 2016-5-5 | 浏览(6515) | PHP
<?php

/**
 * 验证码驱动
 * @author  Devil
 * @version v_1.0.0
 */
class VerifyLibrary
{
    private $rand_string;
    private $img;

    /**
     * [__construct 构造方法]
     */
    public function __construct()
    {
        /* 验证码生成 */
        $this->rand_string = $this->GetRandString();
    }

    /**
     * [GetVerify 获取当前验证码]
     */
    public function GetVerify()
    {
        return $this->rand_string;
    }

    /**
     * [GetVerifyImg 验证码生成]
     * @return [string] [验证码]
     */
    public function GetVerifyImg() {
        $this->img = imagecreatetruecolor(63, 22); //创建一个画布(真色彩)

        // 画背景
        $back_color = imagecolorallocate($this->img, 235, 236, 237); 
        imagefilledrectangle($this->img,0,0,63,22,$back_color);

        //加入干扰,画出多条线
        $this->InterferenceLine();

        //加入干扰,画出点    
        $this->InterferencePoint();

        //将生成好的字符串写入图像
        $fgcolor = imagecolorallocate($this->img, rand(0,200), rand(0,255), rand(0,255));
        imagestring($this->img, 5, 5, 5, strtoupper($this->rand_string), $fgcolor);

        //输出图像
        header('Content-Type: image/gif');
        imagegif($this->img);

        //销毁图像
        imagedestroy($this->img);
    }

    /**
     * [InterferencePoint 加入干扰,画点]
     */
    private function InterferencePoint()
    {
        for($i=0; $i<200; $i++){ 
            $bgcolor = imagecolorallocate($this->img, rand(0,255), rand(0,255), rand(0,255));  //产生随机的颜色
            imagesetpixel($this->img, rand()%90, rand()%30, $bgcolor); 
        }
    }

    /**
     * [InterferenceLine 加入干扰,画出多条线]
     */
    private function InterferenceLine()
    {
        for($i=0; $i<5; $i++)
        {
            $bgcolor=imagecolorallocate($this->img, rand(0,255), rand(0,255), rand(0,255));  //产生随机的颜色
            imageline($this->img, rand(10,90), 0, rand(10,90), 20, $bgcolor);
        }
    }

    /**
     * [GetRandString 生成随机数值]
     * @param [int]     $number [随机数位数]
     * @return[string]          [返回小写的随机数值]
     */
    private function GetRandString($number = 6)
    {
        $origstr = '3456789abxdefghijkmnprstuvwxy';
        $verifystring = '';
        $len = strlen($origstr);
        for($i=0; $i<$number; $i++) {
            $index = mt_rand(0, $len-1);
            $char = $origstr[$index];
            $verifystring .= $char;
        }
        return $verifystring;
    }

}
?>

阅读全文

微信支付接口,服务器端处理(新版)
发表于 2016-4-12 | 浏览(11196) | PHP
<?php

/**
 * 微信支付驱动
 * @author  Devil
 * @version V_1.0.0
 */
class WeiXinPay
{
    private $appid;
    private $secret;
    private $mch_id;
    private $key;

    /**
     * [__construct 构造方法]
     */
    private function __construct($config)
    {
        $this->appid = isset($config['appid']) ? $config['appid'] : '';
        $this->secret = isset($config['secret']) ? $config['secret'] : '';
        $this->mch_id = isset($config['mchid']) ? $config['mchid'] : '';
        $this->key = isset($config['key']) ? $config['key'] : '';
    }

    /**
     * [Instantiate 静态方法]
     * @param [array] $config   [微信配置信息]
     * @return[object]          [当前类对象]
     */
    public static function Instantiate($config)
    {
        $object = null;
        if(!is_object($object)) $object = new self($config);
        return $object;
    }

    /**
     * [WechatPay 微信支付]
     * @param [string]  $param['body']              [商品简要描述]
     * @param [string]  $param['out_trade_no']      [商户订单号]
     * @param [int]     $param['total_fee']         [订单总金额]
     * @param [string]  $param['notify_url']        [异步通知地址]
     * @param [string]  $param['trade_type']        [交易类型(默认JSAPI)JSAPI | APP]
     * @param [string]  $param['openid']            [openid]
     * @param [string]  $param['attach']            [原样返回的数据(可选)]
     * @return[array]                                  [微信支付数据]
     */
    public function WechatPay($param)
    {
        if(empty($param)) return '';

        $data = $this->GetPayParam($param);

        $xml = '<xml>
                <appid>'.$this->appid.'</appid>
                <body>'.$data['data']['body'].'</body>
                <mch_id>'.$this->mch_id.'</mch_id>
                <nonce_str>'.$data['data']['nonce_str'].'</nonce_str>
                <notify_url>'.$data['data']['notify_url'].'</notify_url>
                <openid>'.$data['data']['openid'].'</openid>
                <out_trade_no>'.$data['data']['out_trade_no'].'</out_trade_no>
                <spbill_create_ip>'.$data['data']['spbill_create_ip'].'</spbill_create_ip>
                <total_fee>'.$data['data']['total_fee'].'</total_fee>
                <trade_type>'.$data['data']['trade_type'].'</trade_type>
                <attach>'.$data['data']['attach'].'</attach>
                <sign>'.$data['sign'].'</sign>
            </xml>';

        $result = $this->Xml_Array($this->Curl_Post('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml));
        if(!empty($result['prepay_id']))
        {
            // 返回数据
            $pay_data = array(
                    'appid'         =>  $this->appid,
                    'partnerid'     =>  $this->mch_id,
                    'prepayid'      =>  $result['prepay_id'],
                    'package'       =>  'Sign=WXPay',
                    'noncestr'      =>  md5(time().rand()),
                    'timestamp'     =>  time(),
                );
            $pay_data['sign'] = $this->GetParamSing($pay_data);
            return $pay_data;
        }
        return '';
    }

    /**
     * [Refund 退款接口]
     * @param   [array] $param  [退款的参数]
     * @return  [boolean]       [成功true, 则false]
     */
    public function Refund($param)
    {
        if(empty($param)) return false;

        $data = array(
                'appid'         =>  $this->appid,
                'mch_id'        =>  $this->mch_id,
                'nonce_str'     =>  md5(time().rand()),
                'transaction_id'=>  $param['transaction_id'],
                'out_refund_no' =>  md5($param['transaction_id'].$param['total_fee']),
                'total_fee'     =>  $param['total_fee'],
                'refund_fee'    =>  $param['refund_fee'],
                'op_user_id'    =>  $this->mch_id,
            );
        $data['sign'] = $this->GetParamSing($data);

        $result = $this->Xml_Array($this->Curl_Post('https://api.mch.weixin.qq.com/secapi/pay/refund', $this->GetParamXml($data), true));
        return (!empty($result['result_code']) && $result['result_code'] == 'SUCCESS' && !empty($result['return_msg']) && $result['return_msg'] == 'OK');
    }

    /**
     * [GetParamXml xml键值对拼接]
     * @param [array] $param [需要拼接xml的数组]
     * @return[string]       [xml数据]
     */
    private function GetParamXml($param)
    {
        if(empty($param) || !is_array($param)) return '';

        $xml = '';
        foreach($param as $k=>$v)
        {
            $xml .= '<'.$k.'>'.$v.'</'.$k.'>';
        }
        return '<xml>'.$xml.'</xml>';
    }

    /**
     * [Xml_Array xml转数组]
     * @param [string] $xml [xml字符串]
     * @return[array]       [数组]
     */
    private function Xml_Array($xml)
    {
        if(!Xml_Parser($xml)) return '';

        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }

    /**
     * [GetPayParam 获取支付参数]
     * @param [array] $param [支付的数据]
     * @return[array] [支付的字符串和签名]
     */
    private function GetPayParam($param)
    {
        if(empty($param)) return '';

        $param['appid'] = $this->appid;
        $param['mch_id'] = $this->mch_id;
        $param['nonce_str'] = md5(time().rand().$param['out_trade_no']);
        $param['spbill_create_ip'] = get_client_ip();
        $param['trade_type'] = empty($param['trade_type']) ? 'JSAPI' : $param['trade_type'];
        $param['attach'] = empty($param['attach']) ? 'gongfuxiang' : $param['attach'];
        return array(
            'sign'  =>  $this->GetParamSing($param),
            'data'  =>  $param,
        );
    }

    /**
     * [GetParamSing 签名生成]
     * @param [array] $param    [需要参与签名的数据]
     * @return[string]          [签名]
     */
    private function GetParamSing($param)
    {
        if(empty($param)) return '';

        ksort($param);
        $sign  = '';
        foreach($param as $k=>$v)
        {
            if($k != 'sign') $sign .= "$k=$v&";
        }
        return strtoupper(md5($sign.'key='.$this->key));
    }

    /**
     * [Curl_Post curl模拟post]
     * @param  [string] $url        [请求地址]
     * @param  [array] $post        [发送的post数据]
     * @param  [boolean] $use_cert  [是否需要使用证书]
     */
    private function Curl_Post($url, $post, $use_cert = false)
    {
        $options = array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER         => false,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $post,
        );

        if($use_cert == true)
        {
            //设置证书
            //使用证书:cert 与 key 分别属于两个.pem文件
            $options[CURLOPT_SSLCERTTYPE] = 'PEM';
            $options[CURLOPT_SSLCERT] = WEB_ROOT.'cert/wechat_app_apiclient_cert.pem';
            $options[CURLOPT_SSLKEYTYPE] = 'PEM';
            $options[CURLOPT_SSLKEY] = WEB_ROOT.'cert/wechat_app_apiclient_key.pem';
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, $options);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    /**
     * [Notify 异步回调]
     * @return [array] [支付数据]
     */
    public function Notify()
    {
        $result = empty($GLOBALS['HTTP_RAW_POST_DATA']) ? '' : $this->Xml_Array($GLOBALS['HTTP_RAW_POST_DATA']);

        if(isset($result['sign']) && $result['sign'] == $this->GetParamSing($result)) return $result;
        return '';
    }
}
?>

阅读全文

TOP