2019年3月

功能:根据圆周率和地球半径系数与两点坐标的经纬度,计算两点之间的球面距离。

<?php
/**
 * 计算两点地理坐标之间的距离
 * @param  Decimal $longitude1 起点经度
 * @param  Decimal $latitude1  起点纬度
 * @param  Decimal $longitude2 终点经度 
 * @param  Decimal $latitude2  终点纬度
 * @param  Int     $unit       单位 1:米 2:公里
 * @param  Int     $decimal    精度 保留小数位数
 * @return Decimal
 */
function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){

    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI = 3.1415926;

    $radLat1 = $latitude1 * $PI / 180.0;
    $radLat2 = $latitude2 * $PI / 180.0;

    $radLng1 = $longitude1 * $PI / 180.0;
    $radLng2 = $longitude2 * $PI /180.0;

    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;

    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
    $distance = $distance * $EARTH_RADIUS * 1000;

    if($unit==2){
        $distance = $distance / 1000;
    }

    return round($distance, $decimal);

}

// 起点坐标
$longitude1 = 113.330405;
$latitude1 = 23.147255;

// 终点坐标
$longitude2 = 113.314271;
$latitude2 = 23.1323;

$distance = getDistance($longitude1, $latitude1, $longitude2, $latitude2, 1);
echo $distance.'m'; // 2342.38m

$distance = getDistance($longitude1, $latitude1, $longitude2, $latitude2, 2);
echo $distance.'km'; // 2.34km

?>

效果图:
11111.png

功能:

  1. 可限制开始、结束日期
  2. 可在日期上附加信息
  3. 可指定某些日期不可用
<style lang="less">
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
.clearfix:after {
  content: '';
  height: 0;
  line-height: 0;
  display: block;
  visibility: hidden;
  clear: both;
}
.calendar-wrapper {
  width: 100%;
  overflow: hidden;
  box-sizing: border-box;
  background-color: white;
  min-height: 772rpx;
}
.pick-view {
  margin: auto;
  width: 400rpx;
  height: 100rpx;
  position: relative;
  .pick-img {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    view{
      width: 60rpx; height: 60rpx;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}
picker {
  width: 130rpx;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.calendar-content {
  width: 100%;
  padding: 0rpx;
  background-color: white;
  box-sizing: border-box;
  font-size: 24rpx;
  .week {
    margin-bottom: 40rpx;
    > view {
      flex: 1;
      color: gray;
    }
  }
  .day {
    width: 100%;
    > view {
      position: relative;
      float: left;
      width: calc(100% / 7);
      height: 80rpx;
      box-sizing: border-box;
      margin-bottom: 20rpx;
    }
    .day-item {
      font-size: 32rpx;
      z-index: 200;
    }
    .not-view-month {
      color: #999;
    }
    .disabled{
      color: #ccc;
      background-color: #f7f7f7;
    }
    .more-text {font-size:20rpx; height: 1em; color: #ccc;}
    .round {
      position: absolute;
      background-color: black;
      width: 100%;
      height: 100%;
        top:0;
        left:0;
        border-radius: 0;
      z-index: 0;
    }
    .restime {
      color: white;
      .more-text {color: #fff;}
      .not-view-month {
        color: #e7e7e7;
      }
    }
  }
}
</style>

<template>
  <view class="calendar-wrapper">
    <view class="calendar-content">
      <view class="pick-view">
        <view class="pick-img">
          <view @tap="toPreMonth"><text  class="icon-back"></text></view>
          <view @tap="toNextMonth"><text class="icon-right"></text></view>
        </view>
        <picker @change="changePicker"  value="{{viewTime.year}}-{{viewTime.month}}" start="{{startDay?startDay.formatDay:''}}" end="{{endDay?endDay.formatDay:''}}" fields="month" mode="date">
          <view class="flex-center">
          {{viewTime.year}}年{{viewTime.month}}月
          </view>
        </picker>
      </view>
      <view class="week flex-center">
        <block wx:for="{{weeksCh}}" wx:key="{{item}}">
          <view class="flex-center">{{item}}</view>
        </block>
      </view>
      <view class="day clearfix">
        <block wx:for="{{viewDays}}" wx:key="{{item.key}}">
          <view @tap="changeResultTime({{item}})" :class="{'disabled':disableDaysIn[item.key] || (startDay && item.key<startDay.key) || (endDay && item.key>endDay.key),'not-view-month':!(item.month === viewTime.month && item.year === viewTime.year), 'restime': item.formatDay === current.formatDay}" class="flex-center">
            <view class="day-item">
              {{item.day}}
              <view class="more-text" wx:if="{{moreText}}">{{moreText[item.key]}}</view>
            </view>
            <view style="background-color: {{color}}" wx-if="{{(item.formatDay === current.formatDay)}}" class="round"> </view>
          </view>
        </block>
      </view>

    </view>
  </view>
</template>

<script>
import wepy from 'wepy'
import moment from 'moment'
export default class Calendar extends wepy.component {
    // use: <calendar :value.sync="date" :min.sync="minDay" :max.sync="maxDay" :moreText.sync="moreText" :disableDays.sync="disableDays" @hanleConfirm.user="hanleConfirm" color="#f00"></calendar>
    props = {
        visible : {
            type   : Boolean,
            default: false,
            twoWay : true
        },
        value   : {
            type   : String,
            default: moment().format('YYYY-MM-DD')
        },
        min: {
            //yyyy-MM-DD
            type   : String,
            default: ''
        },
        max: {
            //yyyy-MM-DD
            type   : String,
            default: ''
        },
        moreText: {
            type: Object,
            default: {}
        },
        disableDays: {
            type: Array,
            default: []
        },
        color   : {
            type   : String,
            default: 'black'
        }

    };
    data = {
        weeksCh : ['一', '二', '三', '四', '五', '六', '日'],
        // 数组最后导出的日期
        current : {
            year     : '',
            month    : '',
            day      : '',
            formatDay: '',
            weekCh   : ''
        },
        viewTime: {
            year     : '',
            month    : '',
            day      : '',
            formatDay: '',
            weekCh   : ''
        },
        // 当前视图的day数组
        viewDays: []

    };
    watch = {
        moreText(n,o){console.log(n,o)},
        current(n,o){
            this.$emit('hanleConfirm', n);
        },
        value(newValue, oldValue) {
            this._init(newValue)
        }
    };
    computed = {
        startDay(){
            this.minTime = '';
            if (this.min) {
                this.minTime = moment(this.min);
                return this._dealMoment(this.minTime);
            }
            return "";
        },
        endDay(){
            this.maxTime = '';
            if (this.max) {
                this.maxTime = moment(this.max);
                return this._dealMoment(this.maxTime);
            }
            return "";
        },
        disableDaysIn(){
            let o = {};
            this.disableDays.forEach(v=>{o[v]=true});
            return o;
        }
    };
    methods = {
        // pick选择器改变了
        changePicker(e) {
            // 改变当前视图日期数组
            this.viewDays = this._getData(moment(e.detail.value, 'YYYY-MM'))
        },
        // 点击上个月
        toPreMonth() {
            let time = moment(this.viewTime.formatDay).subtract(1, 'days');
            if (this.startDay) {
                //要显示的月小于最小允许的日期的月份
                let m =time.startOf('month');
                let m2 =this.minTime.startOf('month');
                if (m<m2) return false;
            }
            this.viewDays = this._getData(time)
        },
        // 点击下个月
        toNextMonth() {
            let time = moment(this.viewTime.formatDay).endOf('month').add(1, 'days');
            if (this.endDay) {
                //要显示的月大于最大允许的日期的月份
                let m =time.startOf('month');
                let m2 =this.maxTime.startOf('month');
                if (m>m2) return false;
            }
            this.viewDays = this._getData(time)
        },
        // 改变最后导出的时间
        changeResultTime(item) {
            const {disableDaysIn, startDay, endDay} = this;
            if (disableDaysIn[item.key] || (startDay && item.key<startDay.key) || (endDay && item.key>endDay.key)) return false;
            this._setTime(moment(item.formatDay));
        },
    };

    /**
     * _getData
     * 返回当前视图日期数组
     * @param time
     * @return [{day:31,month:3,year:2018},{day:1,month:4,year:2018},...]
     */
    _getData(time = moment()) {
        this._setViewTime(time)
        // 令时间变为当月1号的
        const firstDay = time.startOf('month')
        // 计算当月1号是星期几
        const firstDayOfWeek = firstDay.format('E')
        // 计算上个月多余时间
        const last = this._calDate(firstDay.subtract(firstDayOfWeek - 1, 'days'), firstDayOfWeek - 1)
        // 计算本月时间
        const current = this._calDate(firstDay, firstDay.daysInMonth())
        // 令时间变为本月末
        const endDay = time.subtract(1, 'days')
        // 当月与末是星期几
        const endDayOfWeek = endDay.format('E')
        // 计算下个月多余时间
        const next = this._calDate(endDay.add(1, 'days'), 7 - endDayOfWeek)
        return [...last, ...current, ...next]
    }

    /**
     * _setTime
     * 设定导出的时间
     * @param time moment对象
     */
    _setTime(time = moment()) {
        let cur = this._dealMoment(time);
        if (this.disableDaysIn[cur.key]) return {};
        this.current = cur;
    }

    /**
     * _setTime
     * 设定当前日历的时间
     * @param time moment对象
     */
    _setViewTime(time = moment()) {
        this.viewTime = this._dealMoment(time.startOf('month'))
    }

    /**
     * _calDate
     * 计算日期函数
     * @param time moment对象
     * @param length 返回数组的长度
     * @return 返回日期数组
     */
    _calDate(time, length) {
        let arr = []
        for (let i = 0; i < length; i++) {
            arr.push(this._dealMoment(time))
            time.add(1, 'days')
        }
        return arr
    }

    /**
     * _dealMoment
     * 处理moment对象
     * @param time moment对象
     * @return 返回一个Object{year, month, day, formatDay}
     */
    _dealMoment(time) {
        let formatDay = time.format('YYYY-MM-DD');
        let {years, months, date} = time.toObject();
        let key = formatDay.replace(/-/g, '');
        return {
            key,
            year     : years,
            month    : months + 1,
            day      : date,
            weekCh   : '周' + this.weeksCh[time.format('E') - 1],
            formatDay,
        }
    }

    /**
     * _init
     * 初始化
     * @param value '2018-02-02' YYYY-MM-DD
     */
    _init(value) {
        this.viewDays = this._getData(moment(value));
        this._setTime(moment(value));
        this.$apply();
    }

    onLoad() {
        this._init(this.value);
    }
}
</script>

关闭X-Powered-By 信息(隐藏PHP版本信息)

会暴露服务器运行的是php

修改 php.ini 文件 设置 expose_php = Off

官方给出的说明

Decides whether PHP may expose the fact that it is installed on the server
(e.g. by adding its signature to the Web server header). It is no security
threat in any way, but it makes it possible to determine whether you use PHP
on your server or not.

决定服务器上是否暴露安装有PHP,
(例如:把这些信息加到Web服务器头响应)。这是不安全的。
但能确定你的服务器时候运行着PHP。

意思就是打开的话可以告诉其他人这台服务器可以运行PHP,但不一定安全,可以关掉

隐藏或者混淆nginx返回的Server信息

1.隐藏版本号:

vi nginx.conf

在http 加上 server_tokens off;

如下:

http {
……省略配置
server_tokens off; ->即可隐藏版本号
…….省略配置
}

重启nginx后,我们返回的Server头格式为Server:nginx ,而且nginx自己的404页面也没有版本号的信息

2.返回自定义的server

混淆Server信息

我是不太愿意告诉别人我是使用什么Server的,但没有找到相关文献去隐藏它,所以我们可以混淆她,如把Server返回GFW之类的,吓唬吓唬那些脚本小子

大部分情况下,脚本的小子的扫描工具是扫描我们response返回的header中的server信息.我们可以采用编译源码的方法来改变返回的Server,笔者的版本是nginx1.7.0,我们修改src/http/ngx_http_header_filter_module.c 中的48行

static char ngx_http_server_string[] = "Server: nginx" CRLF;

把其中的nginx改为我们自己想要的文字即可,笔者就改为了GFW. 笔者输出的Server:GFW.(这个前提是你进行了第一个步句的操作,关闭了版本号)

如果你的版本号是开着的,你又想调戏下脚本小子.比如Server:billgate/1.9.0

我们修改src/core/nginx.h 定位到13-14行

#define NGINX_VERSION "1.7.0"

#define NGINX_VER "nginx/" NGINX_VERSION

Server返回的就是常量NGINX_VER, 我们把NGINX_VERSION大小定义为1.9.0,nginx改为billgate就能达到我们的目的了

阅读目录

一、&
二、ctrl + z
三、jobs
四、fg
五、bg
六、kill
七、nohup
fg、bg、jobs、&、nohup、ctrl+z、ctrl+c 命令

回到顶部
一、&
加在一个命令的最后,可以把这个命令放到后台执行,如

watch -n 10 sh test.sh & #每10s在后台执行一次test.sh脚本
回到顶部
二、ctrl + z
可以将一个正在前台执行的命令放到后台,并且处于暂停状态。

回到顶部
三、jobs
查看当前有多少在后台运行的命令

jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated。但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识。

回到顶部
四、fg
将后台中的命令调至前台继续运行。如果后台中有多个命令,可以用fg %jobnumber(是命令编号,不是进程号)将选中的命令调出。

回到顶部
五、bg
将一个在后台暂停的命令,变成在后台继续执行。如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出。

回到顶部
六、kill
法子1:通过jobs命令查看job号(假设为num),然后执行kill %num
法子2:通过ps命令查看job的进程号(PID,假设为pid),然后执行kill pid
前台进程的终止:Ctrl+c

回到顶部
七、nohup
如果让程序始终在后台执行,即使关闭当前的终端也执行(之前的&做不到),这时候需要nohup。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。关闭中断后,在另一个终端jobs已经无法看到后台跑得程序了,此时利用ps(进程查看命令)

ps -aux | grep "test.sh" #a:显示所有程序 u:以用户为主的格式来显示 x:显示所有程序,不以终端机来区分

进程的终止:

后台进程的终止: