微信支付签名函数-简单方便

在php使用微信支付的时候,你会发现微信支付自带的API 十分复杂,其实是一个很简单的东西,程序员却装装13,弄得这么复杂,经过本人看代码,把微信支付相关过程简化出来,希望给有需要用的人用上。www.yiyou.org

<?php
/*
 * 生成微信支付签名
 * $input 输入参数格式 array('appid'=>'2323232','mch_id'=>'2222')
 * $secret  支付密钥,这个是自己设的,具体看微信api
 */
function weixin_sign($input,$secret){
    $para_filter=  wx_paraFilter($input);
    $para_sort = wx_argSort($para_filter); //参数排序
    $prestr = wx_createLinkstring($para_sort); ////把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
    $mysign = strtoupper(md5($prestr.'&key='.$secret));  //签名
    return $mysign;
}
/**
 * 除去数组中的空值和签名参数
 * @param $para 签名参数组
 * return 去掉空值与签名参数后的新签名参数组
 */
function wx_paraFilter($para) {
	$para_filter = array();
	while (list ($key, $val) = each ($para)) {
		if($key == "sign" || $key == "sign_type" || $val == "")continue;
		else	$para_filter[$key] = $para[$key];
	}
	return $para_filter;
}
/**
 * 对数组排序
 * @param $para 排序前的数组
 * return 排序后的数组
 */
function wx_argSort($para) {
	ksort($para);
	reset($para);
	return $para;
}
function wx_createLinkstring($para) {
	$arg  = "";
	while (list ($key, $val) = each ($para)) {
		$arg.=$key."=".$val."&";
	}
	//去掉最后一个&字符
	$arg = substr($arg,0,count($arg)-2);
	
	//如果存在转义字符,那么去掉转义
	if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
	
	return $arg;
}
function to_xml($arr_data){
    $xml = "<xml>";
    foreach ($arr_data as $key=>$val)
    {
            if (is_numeric($val)){
                    $xml.="<".$key.">".$val."</".$key.">";
            }else{
                    $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
    }
    $xml.="</xml>";
    return $xml;
}
function xml2array($xml){
    libxml_disable_entity_loader(true);
    $data=json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $data;
}
function nonce_str(){
    return md5(md5(time()).mt_rand(0, 100));
}
function http_request_xml($url, $postdata = null,$useCert=false){
    #$data = http_build_query($postdata);
    //echo ROOT_PATH.'/Libs/weixinapi/cert/apiclient_cert.pem';
    if(function_exists('curl_exec')){
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            if($postdata){
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

            }else{
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
                curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            }
            if($useCert == true){
			//设置证书
			//使用证书:cert 与 key 分别属于两个.pem文件
			curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
			curl_setopt($ch,CURLOPT_SSLCERT, ROOT_PATH.'/Libs/weixinapi/cert/apiclient_cert.pem');
			curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
			curl_setopt($ch,CURLOPT_SSLKEY,ROOT_PATH.'/Libs/weixinapi/cert/apiclient_key.pem');  
            }
            $data = curl_exec($ch);
            if( curl_errno ( $ch )){
                echo  'Curl error: '  .  curl_error ( $ch );
            }
            curl_close($ch);
    }else{
            if($postdata){
                    $url = $url.'?'.$postdata;
                    $opts = array(
                            'http' => array(
                                    'method' => 'POST',
                                    'header'=> "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
                                    'content' => $data
                                    )
                        );
                    $context = stream_context_create($opts);
                    $data = file_get_contents($url, false, $context);
            }else{
                $ctx = stream_context_create(array( 
                        'http' => array( 
                        'timeout' => 5 //设置一个超时时间,单位为秒 
                        ))); 
                $data=file_get_contents($url, 0, $ctx); 
            }
    }
    return $data;
}

因为我的微信是在框架内使用的,其中有一些变量要注意一下,ROOT_PATH是一个绝对路径,这个地方可以改改。调用办法

function wxpay($order){
        /*
         * 微信支付统一下单接口
         * https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
         */
        $body='付款';
        if($order['type']==2){
            $body='打赏楼主';
        }
        $parames=array(
            'appid'=> $this->APPID,
            'mch_id'=>  $this->MCHID,
            'nonce_str'=>  nonce_str(),
            'body'=>$body,
            'out_trade_no'=>$order['orderid'],
            'total_fee'=>$order['total_money']*100,  //单位分
            'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
            'notify_url'=>  get_siteurl().'/jrmmpay/notify',
        );
        if(is_weixin()){  //在微信内部
            $parames['trade_type']='JSAPI';
            $parames['openid']=  $this->get_openid();
        }else{
            $parames['trade_type']='NATIVE';
             $parames['product_id']=$order['id'];
        }
        
        $parames['sign'] = weixin_sign($parames, $this->PAYKEY);   //加入排序
        
        $xml = to_xml($parames);
        //print_r($xml);exit;
        $respon=http_request_xml('https://api.mch.weixin.qq.com/pay/unifiedorder',$xml);

        $data=  xml2array($respon);
        //print_r($data);
        if($data['result_code']=='FAIL'){
            //查成功
            header('Content-Type: text/html; charset=UTF-8');
            echo $data['err_code_des'];exit;
        }
        
        if(is_weixin()){
            $param=array(
              'appId'=> $this->APPID,
               'timeStamp'=>  '"'.time().'"',
               'nonceStr'=>  nonce_str(),
               'package'=>'prepay_id='.$data['prepay_id'],
               'signType'=>"MD5",

           );

            $param['paySign'] = weixin_sign($param, $this->PAYKEY);   
           $this->tpl->assign('param',  json_encode($param));
           $this->tpl->assign('order',$order);
            $this->tpl->draw('payment/weixinjsapi');
        }else{
            echo "<img width=\"400\" height=\"400\" src=\"?app=payment&act=qrcode&data=".  urlencode($data['code_url'])."\">";
        }

        
    }
 /*
 * 生成二维码图片
 */
 function qrcode(){
 require_once ROOT_PATH.'Libs/weixinapi/phpqrcode/phpqrcode.php';
 $url = urldecode($_GET["data"]);
 QRcode::png($url,FALSE,QR_ECLEVEL_L,11);
 }

上面的函数已经装扫码支付和普通支付集成在一起了。

下面是js API调用

<!DOCTYPE html>
<html>
    <head>
        <title>正在进行支付</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script type="text/javascript">
        function onBridgeReady(){
           WeixinJSBridge.invoke(
               'getBrandWCPayRequest', {$param},
               function(res){     
                   //alert('{$param}');
                   if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                       //window.location.href='/jinrimaoming.php?app=index&act=view2&id={$order.articleid}';
                       alert('ok');
                   }else{
                      // window.location.href='/jinrimaoming.php?app=index&act=view2&id={$order.articleid}';
                      alert('fail');
                   }
               }
           );
        }
        window.onload = function(){
            if (typeof WeixinJSBridge == "undefined"){
               if( document.addEventListener ){
                   document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
               }else if (document.attachEvent){
                   document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
                   document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
               }
            }else{
               onBridgeReady();
            }            
    }    
    </script>
    </head>
    <body>
        <div>支付正在进行中...</div>
    </body>
</html>

 

perl生成yyyy-mm-dd H::i::s日期总结

1、

use POSIX qw(strftime);
print strftime("%Y-%m-%d %H:%M:%S",localtime());

2、

use Time::localtime;
$tm=localtime;
my ($day,$month,$year)=($tm->mday,$tm->month,$tm->year);

3、

use Time::Piece;

my $date = localtime->strftime('%m/%d/%Y');
print $date;

4、

use DateTime qw();
DateTime->now->strftime('%m/%d/%Y')

5、

use strict;
use warnings;
use Date::Calc qw();
my ($y, $m, $d) = Date::Calc::Today();
my $ddmmyyyy = sprintf '%02d.%02d.%d', $d, $m, $y;
print $ddmmyyyy . "\n";

6、

# Capture date from shell
my $current_date = `date +"%m/%d/%Y"`;

# Remove newline character
$current_date = substr($current_date,0,-1);

print $current_date, "\n";

 

perl简单记录程序运行日志

use Log::Logger;
use POSIX qw(strftime);
sub my_logger{
    my $msg=shift;
    my $time_f=strftime("%Y-%m-%d %H:%M:%S",localtime(time));
    my $lh = new Log::Logger;
    $lh->open_append("/var/log/jrmmadm_comment_notify.log");
    $lh->log($time_f.' '.$msg);
    $lh->close;
}
#使用
my_logger('www.yiyou.org');

 

php跟据图像中心生成缩略图thumb

如果一张长方形的图像,不管是立像还是卧像,可以跟据图像裁剪成一个正方形,再生成一个缩略图。

//from yiyou.org fy@yiyou.org
function cut2thumbnail($src_file,$dsc_file,$width,$height){
        if(!file_exists($src_file)){
            return false;
        }
        if($width <=0||$height <=0){
            return false;
        }
        $imagetype=  exif_imagetype($src_file);

        $src_img ='';
        switch ($imagetype){
            case IMAGETYPE_PNG:
                $src_img=imagecreatefrompng($src_file);
                break;
            case IMAGETYPE_JPEG:
                $src_img=  imagecreatefromjpeg($src_file); 
                break;
            case IMAGETYPE_BMP:
                $src_img=ImageCreateFromBMP($src_file);
                break;
            default:
                return false;
                break;
        }
        list($src_width,$src_height)=  getimagesize($src_file);
        //如果原图比请求的图像还要小
        if($src_width < $width || $src_height < $height){
            @copy($src_file, $dsc_file);
            return true;
        }
        
        
        $target_image  = imagecreatetruecolor($width,$height);//目标缩小后的图像
        
        $cropped_img=$src_img; //如果$cropped_image未改变,说明自身是正方型
        
        if($src_width > $src_height){ //宽大于高
            $diff=$src_width-$src_height; //差异
            $one_part =floor($diff/2); //取中间
            $cropped_img=  imagecreatetruecolor($src_height, $src_height);
            imagecopy($cropped_img,$src_img,0,0,$one_part,0,$src_height,$src_height);
        }
        if($src_width < $src_height){ //宽小于高
            $diff=$src_height-$src_width; //差异
            $one_part =floor($diff/2); //取中间
            $cropped_img=  imagecreatetruecolor($src_width, $src_width);
            imagecopy($cropped_img,$src_img,0,0,0,$one_part,$src_width,$src_width);
        }
        
        $cropped_width=imagesx($cropped_img);
        $cropped_height=imagesy ($cropped_img);
        
        imagecopyresampled($target_image, $cropped_img, 0, 0, 0, 0, $width, $height, $cropped_width, $cropped_height);

        switch ($imagetype){
            case IMAGETYPE_PNG:
                imagepng($target_image,$dsc_file);
                break;
            case IMAGETYPE_JPEG:
                imagejpeg($target_image, $dsc_file,90);
                break;
            case IMAGETYPE_BMP:
                imagejpeg($target_image,$dsc_file); 
                break;
        }
        return true;
        //imagedestroy($src_img);
        //imagedestroy($cropped_img);
        //imagedestroy($target_image);
}

 

php去掉html标记保留文字内容函数

项目需要,所以自己写了一个,感觉还不错www.yiyou.org

function ClearHtml($content) {
    $content = preg_replace("/<\w+>/i", "", $content);
    $content = preg_replace("/<\w+[^>]*>/i", "", $content); 
    $content = preg_replace("/<\/\w+>/i", "", $content);
    return $content;
}

 

perl过滤文件中标记区的行

perl群有一个网友提问,如何跳过文本文件中特定标记中,整块的行,想想这个问题有点意思,所以睡前思考了一下,把方法写了出来

use strict;


my $del_flag=0;

while(<DATA>){
	chomp;
	if($_=~/^\*block$/){
		#print "found \n";
		if($del_flag==0){
			$del_flag=1;
			next;
		}
		if($del_flag==1){
			$del_flag=0;
			next
		}
		
	}
	next if $del_flag==1;
	print $_,"\n";
}

__DATA__
aaa
aa33
dfsf
sfsf
----
*block
aaa
sfsf
*block
****
sfsfsfs
sfsfsfssfsf
sfsfsfssfsfsf
111111
*block
aaa
sfsf
*block
2222222

 

perl四舍五入

perl 里没有四舍五入函数,不过有个模块

https://metacpan.org/pod/Math::Round::Var

使用比较简单

use Math::Round::Var;
my $rnd = Math::Round::Var->new(0.01);
# rounds to two decimal places:
my $num = 399886.758673;
$num = $rnd->round($num);
print "$num\n"; # 399886.76

php匹配替换文本中的网址加上a-href链接标签

最近有一个项目,需要把用户提交的文本中有网址的内容加上 链接标签,差不多花了一天时间把这个正则写好,效果还不错。给大家分享一个

<?php
$regex='/((http:\/\/|www\.|https:\/\/)(\w+|\.|\?|\=|\/|\&|\:|\d+)+)/';
$str='今天准备来测试一个网址功能的问题,首先使用正常的网址格式是http://aaa.bbs.yiyou.org,有时候我们也可能使用这种方式www.yiyou.org>,如果你会带一个url的网址可能是这样的www.yiyou.org/index.php?aa=aaa&aaa&bb=bbb,但有时候可能是一个伪静态的页面,可能是这样的 http://www.yiyou.org/yiyou/,但很多时候都把http这个内容忘记了,结果是这样的www.yiyou.org/yiyou,至此,网址可以测试了一部分了。再测试一下https://www.yiyou.org/?aa=test,如果加入端口怎么办呢?http://www.yiyou.org:5000/?aaa=bb';
#echo preg_replace($regex,$rep,$str);
echo preg_replace_callback($regex,function($matches){
 #print_r($matches);exit;
 if(!empty($matches[0]) && (strstr($matches[0],'http://')||strstr($matches[0],'https://'))){
        return '<a href="'.$matches[0].'">'.$matches[0].'</a>';
}else{
        return '<a href="http://'.$matches[0].'">'.$matches[0].'</a>';
}

},$str);
echo "<br>";
echo '--------------------<br>';
echo $str;