龚哥哥 - 山里男儿 爱生活、做自己!
Nginx支持htpasswd 访问需要用户和密码认证
发表于 2016-5-26 | 浏览(5730) | 服务器

准备、创建脚本目录

/data/server/nginx/conf/htpasswd

一、创建文件 htpasswd.sh  内容如下

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "========================================"
echo "# A tool like htpasswd for Nginx       #"
echo "#--------------------------------------#"
echo "# Author:Devil http://gongfuxiang.com  #"
echo "========================================"

# file path
dir=$(pwd);
user="user.conf";
userfile="${dir}/${user}"

#set username
    username=""
    read -p "Please input username:" username
    if [ "$username" = "" ]; then
            echo "Error:username can't be NULL!"
            exit 1
    fi
    echo "==========================="
    echo "username was: $username"
    echo "==========================="

#set password
    unpassword=""
    read -p "Please input the Password:" unpassword
    if [ "$unpassword" = "" ]; then
            echo "Error:Password can't be NULL!"
            exit 1
    fi
    echo "==========================="
    echo "Password was: $unpassword"
    echo "==========================="
    password=$(perl -e 'print crypt($ARGV[0], "pwdsalt")' $unpassword)

# create file
if [ ! -f ${userfile} ]; then
  touch ${userfile} 

  echo "Create Auth file......"
fi

# delete original user
for file in $userfile;
do         
    sed -i "/^$MON[\t ]*$username/d" $file  
done

# add user
echo $username:$password >> $userfile
if [ $? == 0 ]; then
    echo $username:$password;
    echo "user add success, Auth file  path:${userfile}."
else
        echo "error"
        exit 1
fi

二、修改虚拟机配置文件 server 中添加以下配置信息

auth_basic "Authorized users only";
auth_basic_user_file /data/server/nginx/conf/htpasswd/user.conf;

三、添加授权用户(根据提示输入用户名和密码)

sh htpasswd.sh

阅读全文

PHP图片上传(简约版)
发表于 2016-5-5 | 浏览(7916) | 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;
    }
}
?>

阅读全文

mac下Apache环境配置
发表于 2016-5-5 | 浏览(5840) | 服务器

Host配置、添加域名

vim etc/hosts
  127.0.0.1    default.com

开启PHP

1、vim /etc/apache2/httpd.conf 查找 php5_module
  LoadModule php5_module libexec/apache2/libphp5.so
  把前面的#号去掉

2、按esc键输入 查找 DocumentRoot
  DocumentRoot 和 Directory 的值改成 /data/www

3、查找 hosts
  Include的值修改成 /private/etc/apache2/vhost/*.conf

4、按esc键输入 /Options
  修改两个参数
    AllowOverride All       会去找.htacess文件
    Options Indexes         目录可见指定
  保存退出

5、配置虚拟机和项目路径
  创建虚拟机路径:mkdir vhost
  在vhost目录下创建default.conf ,内容:
    <VirtualHost *:80>
      ServerAdmin email@email.com
      DocumentRoot "/data/www"
      ServerName default.com
      ErrorLog "/data/log/default.com-error_log"
      CustomLog "/data/log/default.com-access_log"   common
    </VirtualHost>
    保存退出

  创建日志路径:mkdir –p /data/log
  创建项目路径:mkdir –p /data/www

  在 /data/www 目录下创建 phpinfo.php 文件,内容:
  <?php
    echo phpinfo();
  ?>

6、重启apache,在终端输入 apachectl restart

7、浏览器访问 default.com 可以看见php的的配置信息就OK了。

PHP安装扩展

下载扩展包:https://yunpan.cn/cdp5SALnsiZK8 (提取码:d68c)

解压后的文件放到 /usr/lib/php/extensions/no-debug-non-zts-20121212 目录中

创建php.ini文件
  cd /etc
  cp php.ini.default php.ini
  vim php.ini 按esc键搜索 extension

添加以下扩展记录后保存退出
  extension=redis.so
  extension=mongo.so
  extension=memcache.so
  extension=memcached.so
  extension=mcrypt.so

重启apache,在终端输入 apachectl restar

环境安装完成~

阅读全文

PHP图片验证码生成
发表于 2016-5-5 | 浏览(6579) | 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;
    }

}
?>

阅读全文

mac PhotoshopCS6破解版
发表于 2016-4-29 | 浏览(5146) | 资源

360云盘下载

https://yunpan.cn/cPPSLkE4Hv8dt (提取码:3a28)

阅读全文

mac 画流程图软件 XMind破解版 Omnigraffle破解版 ProcessOn
发表于 2016-4-29 | 浏览(8567) | 资源

360云盘下载

Omnigraffle

    https://yunpan.cn/cPLqy8yxmVA7z (提取码:0e84)

XMind
    https://yunpan.cn/cPPrvPJBAAYpp (提取码:e15d)


当然,喜欢web版的可以移步这里

ProcessOn https://www.processon.com/

阅读全文

mac 虚拟机软件 VMware破解版
发表于 2016-4-29 | 浏览(5051) | 资源

360云盘下载

https://yunpan.cn/cLd37zwZWmRS8 (提取码:9cb1)

阅读全文

Shell使用教程
发表于 2016-4-12 | 浏览(5586) | 服务器
#!/bin/sh

# # 用户输入数据获取
# echo "What is your name?"
# read PERSON
# echo "Hello, $PERSON"

# # 定义变量,在变量名前面不需要加¥符号,使用的时候才需要加
# # 定义变量
# ret="value"
# echo $ret

# # 重新定义变量
# ret="value-ssss"
# echo $ret

# # 数字型变量
# number=100
# echo $number # line 22: unset: `value-ssss': not a valid identifier

# # 删除变量
# unset $ret
# echo $ret

# # 字符串循环,变量与字符串混合使用的使用加{}花括号
# # 推荐使用变量的时候,加花括号
# str="Ada Coffa Action Java"
# for v in $str
# do
#   echo "I am good at ${v}Script"
# done

# 字符串可以是单引号或者双引号,单引号中变量当做字符串输出,双引号中支持变量
# ret="ret string"
# # 单引号中不能带单引号,就是加了反斜杠转义也不可以
# # str='hello world \' $ret'
# str='hello world $ret ${ret}'
# echo $str
# str="Hello World Is \"$ret\""
# echo $str

# # 字符串拼接
# xing='Fu'
# strs="Gong "$xing" Xiang"
# name="Gong ${xing} Xiang"

# echo $strs
# echo $name

# # 获取字符串长度
# echo ${#name}

# # 提取子字符串
# echo ${name:4} # Fu Xiang
# echo ${name:1:5} # ong F

# # 查找子字符串,有问题
# # echo `expr index "$name" Fu`

# # 数组
# # 数组名=(值1 值2 值3 ... 值n)
# # 如:arr=(1 2 3 4 5 6)
# arr=(11 2222 3 44 5 6)
# echo $arr # 默认第一个下标元素 11
# echo ${arr[0]} # 第一个元素 11
# echo ${arr[1]} # 第二个元素 2222
# echo ${arr[*]} # 所有元素 11 2222 3 44 5 6
# echo ${arr[@]} # 所有元素 11 2222 3 44 5 6
# echo ${#arr[*]} # 数组的长度(下标1开始) 6
# echo ${#arr[@]} # 数组的长度(下标1开始) 6
# echo ${#arr[1]} # 元素1的长度 4(下标0开始)
# arr[1]="new values heihei"
# echo ${arr[1]}

# # 传递参数,没有参数则空
# # sh testshell.sh 11 22 你好世界
# echo "第一个参数:${1}"  # 11
# echo "第二个参数:${2}"  # 22
# echo "第三个参数:${3}"  # 你好世界
# echo "参数个数:${#}"  # 3
# echo "以一个但字符串显示所有脚本传递的参数:${*}"  # 11 22 你好世界
# echo "脚本运行的当前进程ID号:${$}"  # 当前进程ID号
# echo "后台运行的最后一个进程的ID号:${!}"
# echo "与$*相同,但是使用时加引号,并在引号中返回每个参数:${@}"  # 11 22 你好世界
# echo "显示Shell使用的当前选项,与set命令功能相同:${-}"  # hB
# echo "显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误:${?}"  # 0或错误

# 基本运算符
# 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
# expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
# 完整的表达式需要被 ` 符号包含(不是单引号)
# 乘法 * 必须加反斜杠
# val=`expr 2 + 2` # 2+2是不对的,中间必须空格分开
# echo "两数之和为:${val}"
# num1=1
# num2=2
# num3=3
# echo "num1+num2:`expr ${num1} + ${num2}`"   # 3
# echo "num3-num1:`expr ${num3} - ${num1}`"   # 2
# echo "num2*num3:`expr ${num2} \* ${num3}`"  # 6
# echo "num3/num2:`expr ${num3} / ${num2}`"   # 1
# echo "num3%num2:`expr ${num3} % ${num2}`"   # 1

# # if判断语句
# if [ $num1 == $num2 ]
# then
#   echo "num1等于num2"
# fi
# if [ $num1 != $num2 ]
# then
#   echo "num1不等于num2"
# fi

# # 关系运算符、不支持字符串、只支持数字
# # -eq 等于、-ne 不等于、-gt 大于、-lt 小于、-ge 大于等于、-le 小于等于
# if [ $num1 -eq $num2 ]
# then
#   echo "num1等于num2"
# fi
# if [ $num1 -ne $num2 ]
# then
#   echo "num1不等于num2"
# fi
# if [ $num2 -gt $num1 ]
# then
#   echo "num2大于num1"
# fi
# if [ $num1 -lt $num2 ]
# then
#   echo "num1小于num1"
# fi

# # 布尔运算符
# # ! 非运算(取反)、-o 或运算(一个符合就true)、-a 与运算(需要都符合就true)
# if [ ! $num1 == $num2 ]
# then
#   echo "num1不等于num2"
# fi
# if [ $num1 -ne $num2 -a $num2 -lt $num3 ]
# then
#   echo "条件成立"
# fi

# # 字符串运算符
# str1="abc"
# str2="efg"
# str3="abc"
# if [ $str1 = $str3 ]
# then
#   echo "str1等于str3"
# fi
# if [ $str1 != $str2 ]
# then
#   echo "str1不等于str2"
# fi
# if [ -z $str1 ]
# then
#   echo "str1长度为0"
# fi
# if [ -n $str1 ]
# then
#   echo "str1长度不为0"
# fi
# if [ $str1 ]
# then
#   echo "str1不为空"
# fi

# # 文件运算符
# dir="/data/"
# file="hello.txt"
# if [ -e ${dir}${file} ]
# then
#   echo "${file}文件存在"
# else
#   echo "${file}文件不存在"
# fi
# if [ -s ${dir}${file} ]
# then
#   echo "${file}文件大小大于0"
# else
#   echo "${file}文件大小等于0"
# fi
# if [ -x ${dir}${file} ]
# then
#   echo "${file}文件可执行"
# else
#   echo "${file}文件不可执行权限(755后几可执行了)"
# fi
# if [ -w ${dir}${file} ]
# then
#   echo "${file}文件可写"
# else
#   echo "${file}文件不可写"
# fi
# if [ -f ${dir}${file} ]
# then
#   echo "${file}文件是普通文件"
# else
#   echo "${file}文件不是普通文件"
# fi
# if [ -f "${dir}testshell.sh" ]
# then
#   echo "testshell.sh文件是普通文件"
# else
#   echo "testshell.sh文件不是普通文件"
# fi

# # echo 命令
# echo "it is s test"
# echo "\"id is a ' test\""
# read name # 接收键盘录入数据
# # > 覆盖文件中的内容、>>尾部追加内容
# echo "${name} it is a test `date`" >> ${dir}${file} # 讲内容写入文件
# cat ${dir}${file} # 查看文件中的内容

# # printf 命令
# echo "Hello World"
# printf "Hello World\n"

# printf "%-10s %-10s %-10s\n" 姓名 性别 体重kg
# printf "%-12s %-10s %-10.2f\n" 龚福祥 男 52.25453
# printf "%-12s %-10s %-10.2f\n" 潘玉龙 男 48.34566
# printf "%-11s %-10s %-10.2f\n" 杨过 男 60

# printf "%d %s\n" 100 "abc"
# printf '%d %s\n' 200 "efg"
# printf '%d %s %s %s\n' 300 "Hello" "World" "!"
# printf %s abc efg
# printf "\n\n"
# printf "%s\n" abcc efgg
# printf "www.gongfuxiang.com \n"

# # 控制流程
# num1=100
# num2=100
# if [ $num1 -eq $num2 ]
# then
#   echo "num1等于num2"
# else
#   echo "num1不等于num2"
# fi

# arr=(11 22 33 44 55)
# str="1 2 3 4 5"
# for index in ${arr[*]}
# #for index in $str
# do
#   echo "index the is: ${index}"
# done
# for tmp in 'Hello World'
# do
#   echo $tmp
# done

# int=0
# while(($int <= 5))
# do
#   let "int++"

#   # case 语句
#   case $int in
#       2 | 5)
#           echo "case int is ${int}"
#       ;;
#       4)
#           echo "case int is ${int}"
#       ;;
#   esac

#   # int等于2的时候跳出当前循环
#   if [ $int -eq 2 ]
#   then
#       continue
#   fi

#   # int等于4的时候结束循环
#   if [ $int -eq 5 ]
#   then
#       break
#   fi

#   echo "int is ${int}"
# done

# # function 方法
# # 函数调用必须在调用之前
# function DemoFun()
# {
#   echo "demofun()"
# }
# # 函数调用
# echo "函数执行开始"
# DemoFun
# echo "函数执行完毕"

# # 用户输入的值进行相加返回
# function WitchReturn()
# {
#   echo "输入第一个数字:"
#   read num

#   echo "输入第二个数字:"
#   read another
#   return $(($num+$another))
# }
# # 函数返回值使用 $? 来获取
# WitchReturn
# echo $?

# # 函数参数传递获取
# function FunParam()
# {
#   echo "第一个参数:${1}"
#   echo "第二个参数:${2}"
#   echo "第三个参数:${5}"
#   echo "所有参数:${*}"
#   echo "参数个数:${#}"
# }
# FunParam 11 22 33 "aa" "bb"

# # 输入/输出重定向
# file="hello.txt"

# # 尾部追加内容
# echo "gongfuxiang.com 龚福祥" > $file

# # 覆盖文件中的内容
# echo "gongfuxiang.org" >> $file

# # 文件中的内容行数
# #wc -l $file # 会输出文件名
# wc -l < $file # 不会输出文件名

# cat $file

# # 结果
# #     Devil
# # www.gongfuxiang.com
# cat << EOF
#   Devil
#   www.gongfuxiang.com
# EOF

# # 结果 2
# wc -l  << EOF
#   Devil
#   www.gongfuxiang.com
# EOF

# # 命令执行的内容不显示在终端上
# ls > /dev/null

# # 文件引入 source关键字或 .
# # testshell.sh testshell2.sh
# #. ./testshell2.sh
# source ./testshell2.sh

# # 使用变量
# echo $url

# # 使用方法
# ShellTestFun

# # (()) 双小括号的使用
# a=1
# b=2
# as=$((a+=1)) # 2
# echo $as
# echo $((a+=2)) # 4

# bs=$((b+1)) # 3
# echo $bs
# echo $((b+=2)) # 4

# # 表达式多个值
# c=1
# d=1
# e=1
# $((c++, d++, e--))
# # c,d,e 结果2,2,0
# echo $c
# echo $d
# echo $e

# # for循环
# for((i=0; i<=10; i++))
# do
#   echo $i
# done

# 创建测试目录
dir_name="shell_test"

mkdir $dir_name

read number
for((i=0; i<=$number; i++))
do
    # 在目录下循环创建多个文件
    touch "${dir_name}/test_file_${i}.txt"
done

阅读全文

微信支付接口,服务器端处理(新版)
发表于 2016-4-12 | 浏览(11313) | 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 '';
    }
}
?>

阅读全文

微信公众号支付
发表于 2016-1-25 | 浏览(6941) | PHP
<?php

/**
 * 微信支付驱动
 * @author  Devil
 * @version V_1.0.0
 */
class WechatPayLibrary
{
    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 [array] $param['total_fee']       [订单总金额]
     * @param [array] $param['notify_url']      [异步通知地址]
     * @param [array] $param['trade_type']      [交易JSAPI类型]
     * @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>
                <sign>'.$data['sign'].'</sign>
            </xml>';

        $result = $this->Xml_Array($this->Curl_Post('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml));
        if(!empty($result))
        {
            // 返回数据
            $pay_data = array(
                    'appId'         =>  $this->appid,
                    'timeStamp'     =>  time(),
                    'signType'      =>  'MD5',
                    'nonceStr'      =>  md5(time().rand()),
                    'package'       =>  'prepay_id='.$result['prepay_id'],
                );
            $pay_data['paySign'] = $this->GetParamSing($pay_data);

            return $pay_data;
        }
        return '';
    }

    /**
     * [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'] = 'JSAPI';
        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数据]
     */
    private function Curl_Post($url, $post)
    {
        $options = array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER         => false,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $post,
        );

        $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