perldancer 启动脚本-基于ubic

之前在网上找了几个启动脚本,都怪自己文档没有细看啊。其实dancer文档已经写得很详细了
https://metacpan.org/pod/Dancer2::Manual::Deployment

use qw(Ubic::Service::Plack);

# if your application is not installed in @INC path:
sub start {
    my $self = shift;
    $ENV{PERL5LIB} = '/home/perl_project/www.yiyou.org/lib/';
    $self->SUPER::start(@_);
}

__PACKAGE__->new(
    server_args=>{workers=>2,host=>'127.0.0.1' },
    server => 'Starman',
    app => '/home/perl_project/www.yiyou.org/bin/app.psgi',
    port => 8081,
    user => 'www-data',
);

 

perl-介绍一个好用的xml转hash包

最近一个项目里用到要将xml字符串转为perl-hash,在cpanm 试了很多软件包,发现xml::fast 这个是c写的,速度比较快,而且比较直观

使用方法

use XML::Fast;
 
my $hash = xml2hash $xml;
my $hash2 = xml2hash $xml, attr => '.', text => '~';

 

postfix 2.10+ 邮件转发问题

最近发邮件一直有这个错误

Apr 12 18:59:04 ZaphodBeeblebrox postfix/smtpd[10669]: NOQUEUE: reject: RCPT from mail.elmarotter.eu[83.161.154.53]: 554 5.7.1 : Relay access denied; from= to= proto=ESMTP helo=<[192.168.0.16]>

后来查看了不少文档, 发现是postfix 升级到 2.10.0的问题,

2.10的release中增加了

smtpd_relay_restrictions

* COMPATIBILITY: adding smtpd_relay_restrictions to main.cf
* to prevent inbound mail from unexpectedly bouncing.
* Specify an empty smtpd_relay_restrictions value to keep using
* smtpd_recipient_restrictions as before.

在/etc/postfix/main.cnf中加上

smtpd_relay_restrictions = permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination
就能解决这个问题。

yunpian云片网短信发送-perl示例

#!/usr/bin/perl
# Author fy@yiyou.org
# Date  2016-09-11
# 云片网短信-perl发送短信示例
# 使用时,务必将文件保存为utf8格式,否则发送的中文会出现乱码

use strict;
use Data::Dumper;
use HTTP::Tiny;
use JSON;
use utf8;

my $tel='13800138000'; #手机号码
my $msg='【验证码】内容'; #发送内容,需要审核通过

my $response = HTTP::Tiny->new->post_form('https://sms.yunpian.com/v2/sms/single_send.json',
                {apikey=>'_your_apikey_here_', #apikey
                mobile=>$tel,
                text=>$msg});
#print Dumper $response;exit;
my $json=decode_json ($response->{content});
print Dumper $json;

 

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

在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