晴栀博客 / zh-CN 晴栀的小博客!写通俗易懂的技术文章! Thu, 31 Dec 2020 12:50:24 +0800 Thu, 31 Dec 2020 12:50:24 +0800 PHP获取服务器基本信息 /index.php/archives/372/ /index.php/archives/372/ Thu, 31 Dec 2020 12:50:24 +0800 晴栀 今天给大家分享一下我自用的PHP获取服务器信息类的代码。


<?php
namespace ServerInfo;
/**
+------------------------------------------------------------------------------
 * 获取服务器信息类

+------------------------------------------------------------------------------
 */
class ServerInfo {
//类定义开始

    /**
    +----------------------------------------------------------
     * 获取服务器时间
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetServerTime() {
        return date('Y-m-d H:i:s');
    }

    /**
    +----------------------------------------------------------
     * 获取服务器解译引擎
     * 例如:Apache/2.2.8 (Win32) PHP/5.2.6
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetServerSoftwares() {
        return $_SERVER['SERVER_SOFTWARE'];
    }

    /**
    +----------------------------------------------------------
     * 获取php版本号
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetPhpVersion() {
        return PHP_VERSION;
    }

    /**
    +----------------------------------------------------------
     * 获取Http版本号
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetHttpVersion() {
        return $_SERVER['SERVER_PROTOCOL'];
    }

    /**
    +----------------------------------------------------------
     * 获取网站根目录
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetDocumentRoot() {
        return $_SERVER['DOCUMENT_ROOT'];
    }

    /**
    +----------------------------------------------------------
     * 获取PHP脚本最大执行时间
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetMaxExecutionTime() {
        return ini_get('max_execution_time') . ' Seconds';
    }

    /**
    +----------------------------------------------------------
     * 获取服务器允许文件上传的大小
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetServerFileUpload() {
        if (@ini_get('file_uploads')) {
            return '允许 ' . ini_get('upload_max_filesize');
        } else {
            return '禁止';
        }
    }

    /**
    +----------------------------------------------------------
     * 获取全局变量 register_globals的设置信息 On/Off
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetRegisterGlobals() {
        return $this->GetPhpCfg('register_globals');
    }

    /**
    +----------------------------------------------------------
     * 获取安全模式 safe_mode的设置信息 On/Off
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetSafeMode() {
        return $this->GetPhpCfg('safe_mode');
    }

    /**
    +----------------------------------------------------------
     * 获取Gd库的版本号
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetGdVersion() {
        if (function_exists('gd_info')) {
            $GDArray = gd_info();
            $gd_version_number = $GDArray['GD Version'] ? '版本:' . $GDArray['GD Version'] : '不支持';
        } else {
            $gd_version_number = '不支持';
        }
        return $gd_version_number;
    }

    /**
    +----------------------------------------------------------
     * 获取内存占用率
    +----------------------------------------------------------
     * @access public
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    public function GetMemoryUsage() {
        return $this->ConversionDataUnit(memory_get_usage());
    }
    //服务器IP
    public function ServerIp() {
        return GetHostByName($_SERVER['SERVER_NAME']);
    }
    //服务器系统
    public function Serveros() {
        return php_uname('s');
    }

    /**
    +----------------------------------------------------------
     * 对数据单位 (字节)进行换算
    +----------------------------------------------------------
     * @access private
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    private function ConversionDataUnit($size) {
        $kb = 1024; // Kilobyte
        $mb = 1024 * $kb; // Megabyte
        $gb = 1024 * $mb; // Gigabyte
        $tb = 1024 * $gb; // Terabyte
        //round() 对浮点数进行四舍五入
        if ($size < $kb) {
            return $size . ' Byte';
        } else if ($size < $mb) {
            return round($size / $kb, 2) . ' KB';
        } else if ($size < $gb) {
            return round($size / $mb, 2) . ' MB';
        } else if ($size < $tb) {
            return round($size / $gb, 2) . ' GB';
        } else {
            return round($size / $tb, 2) . ' TB';
        }
    }

    /**
    +----------------------------------------------------------
     * 获取PHP配置文件 (php.ini)的值
    +----------------------------------------------------------
     * @param string $val 值
     * @access private
    +----------------------------------------------------------
     * @return string
    +----------------------------------------------------------
     */
    private function GetPhpCfg($val) {
        switch ($result = get_cfg_var($val)) {
        case 0:
            return '关闭';
            break;
        case 1:
            return '打开';
            break;
        default:
            return $result;
            break;
        }
    }

}

]]>
2 /index.php/archives/372/#comments /index.php/feed/archives/372/
PHP公历农历的互相转换 /index.php/archives/369/ /index.php/archives/369/ Thu, 31 Dec 2020 00:38:00 +0800 晴栀 直接上代码!


<?php
/**
 * Created by PhpStorm.
 * User: Qingzhi
 * Blog: 
 * Date: 2020/12/31
 * Time: 0:40
 */

namespace app\currency\controller;


class Lunar
{


    var $MIN_YEAR = 1891;

    var $MAX_YEAR = 2100;

    var $lunarInfo = array(

        array(0, 2, 9, 21936), array(6, 1, 30, 9656), array(0, 2, 17, 9584), array(0, 2, 6, 21168), array(5, 1, 26, 43344), array(0, 2, 13, 59728),

        array(0, 2, 2, 27296), array(3, 1, 22, 44368), array(0, 2, 10, 43856), array(8, 1, 30, 19304), array(0, 2, 19, 19168), array(0, 2, 8, 42352),

        array(5, 1, 29, 21096), array(0, 2, 16, 53856), array(0, 2, 4, 55632), array(4, 1, 25, 27304), array(0, 2, 13, 22176), array(0, 2, 2, 39632),

        array(2, 1, 22, 19176), array(0, 2, 10, 19168), array(6, 1, 30, 42200), array(0, 2, 18, 42192), array(0, 2, 6, 53840), array(5, 1, 26, 54568),

        array(0, 2, 14, 46400), array(0, 2, 3, 54944), array(2, 1, 23, 38608), array(0, 2, 11, 38320), array(7, 2, 1, 18872), array(0, 2, 20, 18800),

        array(0, 2, 8, 42160), array(5, 1, 28, 45656), array(0, 2, 16, 27216), array(0, 2, 5, 27968), array(4, 1, 24, 44456), array(0, 2, 13, 11104),

        array(0, 2, 2, 38256), array(2, 1, 23, 18808), array(0, 2, 10, 18800), array(6, 1, 30, 25776), array(0, 2, 17, 54432), array(0, 2, 6, 59984),

        array(5, 1, 26, 27976), array(0, 2, 14, 23248), array(0, 2, 4, 11104), array(3, 1, 24, 37744), array(0, 2, 11, 37600), array(7, 1, 31, 51560),

        array(0, 2, 19, 51536), array(0, 2, 8, 54432), array(6, 1, 27, 55888), array(0, 2, 15, 46416), array(0, 2, 5, 22176), array(4, 1, 25, 43736),

        array(0, 2, 13, 9680), array(0, 2, 2, 37584), array(2, 1, 22, 51544), array(0, 2, 10, 43344), array(7, 1, 29, 46248), array(0, 2, 17, 27808),

        array(0, 2, 6, 46416), array(5, 1, 27, 21928), array(0, 2, 14, 19872), array(0, 2, 3, 42416), array(3, 1, 24, 21176), array(0, 2, 12, 21168),

        array(8, 1, 31, 43344), array(0, 2, 18, 59728), array(0, 2, 8, 27296), array(6, 1, 28, 44368), array(0, 2, 15, 43856), array(0, 2, 5, 19296),

        array(4, 1, 25, 42352), array(0, 2, 13, 42352), array(0, 2, 2, 21088), array(3, 1, 21, 59696), array(0, 2, 9, 55632), array(7, 1, 30, 23208),

        array(0, 2, 17, 22176), array(0, 2, 6, 38608), array(5, 1, 27, 19176), array(0, 2, 15, 19152), array(0, 2, 3, 42192), array(4, 1, 23, 53864),

        array(0, 2, 11, 53840), array(8, 1, 31, 54568), array(0, 2, 18, 46400), array(0, 2, 7, 46752), array(6, 1, 28, 38608), array(0, 2, 16, 38320),

        array(0, 2, 5, 18864), array(4, 1, 25, 42168), array(0, 2, 13, 42160), array(10, 2, 2, 45656), array(0, 2, 20, 27216), array(0, 2, 9, 27968),

        array(6, 1, 29, 44448), array(0, 2, 17, 43872), array(0, 2, 6, 38256), array(5, 1, 27, 18808), array(0, 2, 15, 18800), array(0, 2, 4, 25776),

        array(3, 1, 23, 27216), array(0, 2, 10, 59984), array(8, 1, 31, 27432), array(0, 2, 19, 23232), array(0, 2, 7, 43872), array(5, 1, 28, 37736),

        array(0, 2, 16, 37600), array(0, 2, 5, 51552), array(4, 1, 24, 54440), array(0, 2, 12, 54432), array(0, 2, 1, 55888), array(2, 1, 22, 23208),

        array(0, 2, 9, 22176), array(7, 1, 29, 43736), array(0, 2, 18, 9680), array(0, 2, 7, 37584), array(5, 1, 26, 51544), array(0, 2, 14, 43344),

        array(0, 2, 3, 46240), array(4, 1, 23, 46416), array(0, 2, 10, 44368), array(9, 1, 31, 21928), array(0, 2, 19, 19360), array(0, 2, 8, 42416),

        array(6, 1, 28, 21176), array(0, 2, 16, 21168), array(0, 2, 5, 43312), array(4, 1, 25, 29864), array(0, 2, 12, 27296), array(0, 2, 1, 44368),

        array(2, 1, 22, 19880), array(0, 2, 10, 19296), array(6, 1, 29, 42352), array(0, 2, 17, 42208), array(0, 2, 6, 53856), array(5, 1, 26, 59696),

        array(0, 2, 13, 54576), array(0, 2, 3, 23200), array(3, 1, 23, 27472), array(0, 2, 11, 38608), array(11, 1, 31, 19176), array(0, 2, 19, 19152),

        array(0, 2, 8, 42192), array(6, 1, 28, 53848), array(0, 2, 15, 53840), array(0, 2, 4, 54560), array(5, 1, 24, 55968), array(0, 2, 12, 46496),

        array(0, 2, 1, 22224), array(2, 1, 22, 19160), array(0, 2, 10, 18864), array(7, 1, 30, 42168), array(0, 2, 17, 42160), array(0, 2, 6, 43600),

        array(5, 1, 26, 46376), array(0, 2, 14, 27936), array(0, 2, 2, 44448), array(3, 1, 23, 21936), array(0, 2, 11, 37744), array(8, 2, 1, 18808),

        array(0, 2, 19, 18800), array(0, 2, 8, 25776), array(6, 1, 28, 27216), array(0, 2, 15, 59984), array(0, 2, 4, 27424), array(4, 1, 24, 43872),

        array(0, 2, 12, 43744), array(0, 2, 2, 37600), array(3, 1, 21, 51568), array(0, 2, 9, 51552), array(7, 1, 29, 54440), array(0, 2, 17, 54432),

        array(0, 2, 5, 55888), array(5, 1, 26, 23208), array(0, 2, 14, 22176), array(0, 2, 3, 42704), array(4, 1, 23, 21224), array(0, 2, 11, 21200),

        array(8, 1, 31, 43352), array(0, 2, 19, 43344), array(0, 2, 7, 46240), array(6, 1, 27, 46416), array(0, 2, 15, 44368), array(0, 2, 5, 21920),

        array(4, 1, 24, 42448), array(0, 2, 12, 42416), array(0, 2, 2, 21168), array(3, 1, 22, 43320), array(0, 2, 9, 26928), array(7, 1, 29, 29336),

        array(0, 2, 17, 27296), array(0, 2, 6, 44368), array(5, 1, 26, 19880), array(0, 2, 14, 19296), array(0, 2, 3, 42352), array(4, 1, 24, 21104),

        array(0, 2, 10, 53856), array(8, 1, 30, 59696), array(0, 2, 18, 54560), array(0, 2, 7, 55968), array(6, 1, 27, 27472), array(0, 2, 15, 22224),

        array(0, 2, 5, 19168), array(4, 1, 25, 42216), array(0, 2, 12, 42192), array(0, 2, 1, 53584), array(2, 1, 21, 55592), array(0, 2, 9, 54560)

    );


    /**
     * 将阳历转换为阴历
     * @param year 公历-年
     * @param month 公历-月
     * @param date 公历-日
     */

    public function convertSolarToLunar($year, $month, $date): array
    {//debugger;

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) {

            return array(1891, '正月', '初一', '辛卯', 1, 1, '兔');

        }

        return $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $date, $yearData[1], $yearData[2]));

    }

    /**
     * 根据距离正月初一的天数计算阴历日期
     * @param year 阳历年
     * @param between 天数
     */

    public function getLunarByBetween($year, $between): array
    {

        $lunarArray = array();

        $yearMonth = array();

        $t = 0;

        $e = 0;

        $leapMonth = 0;

        $m = '';

        if ($between == 0) {

            array_push($lunarArray, $year, '正月', '初一');

            $t = 1;

            $e = 1;

        } else {

            $year = $between > 0 ? $year : ($year - 1);

            $yearMonth = $this->getLunarYearMonths($year);

            $leapMonth = $this->getLeapMonth($year);

            $between = $between > 0 ? $between : ($this->getLunarYearDays($year) + $between);

            for ($i = 0; $i < 13; $i++) {

                if ($between == $yearMonth[$i]) {

                    $t = $i + 2;

                    $e = 1;

                    break;

                } else if ($between < $yearMonth[$i]) {

                    $t = $i + 1;

                    $e = $between - (empty($yearMonth[$i - 1]) ? 0 : $yearMonth[$i - 1]) + 1;

                    break;

                }

            }

            $m = ($leapMonth != 0 && $t == $leapMonth + 1) ? ('闰' . $this->getCapitalNum($t - 1, true)) : $this->getCapitalNum(($leapMonth != 0 && $leapMonth + 1 < $t ? ($t - 1) : $t), true);

            array_push($lunarArray, $year, $m, $this->getCapitalNum($e, false));

        }

        array_push($lunarArray, $this->getLunarYearName($year));// 天干地支

        array_push($lunarArray, $t, $e);

        array_push($lunarArray, $this->getYearZodiac($year));// 12生肖

        array_push($lunarArray, $leapMonth);// 闰几月

        return $lunarArray;

    }

    public function getLunarYearMonths($year): array
    {
        $monthData = $this->getLunarMonths($year);

        $res = array();

        $temp = 0;

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        $len = ($yearData[0] == 0 ? 12 : 13);

        for ($i = 0; $i < $len; $i++) {

            $temp = 0;

            for ($j = 0; $j <= $i; $j++) {

                $temp += $monthData[$j];

            }

            array_push($res, $temp);

        }

        return $res;

    }

    /**
     * 获取阴历每月的天数的数组
     * @param year
     */

    public function getLunarMonths($year): array
    {

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        $leapMonth = $yearData[0];

        $bit = decbin($yearData[3]);

        for ($i = 0, $iMax = strlen($bit); $i < $iMax; $i++) {

            $bitArray[$i] = substr($bit, $i, 1);

        }

        for ($k = 0, $keen = 16 - count($bitArray); $k < $keen; $k++) {

            array_unshift($bitArray, '0');

        }

        $bitArray = array_slice($bitArray, 0, ($leapMonth === 0 ? 12 : 13));

        for ($i = 0, $iMax = count($bitArray); $i < $iMax; $i++) {

            $bitArray[$i] += 29;

        }

        return $bitArray;

    }

    /**
     * 获取闰月
     * @param year 阴历年份
     */

    public function getLeapMonth($year): int
    {

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        return $yearData[0];

    }

    /**
     * 获取农历每年的天数
     * @param year 农历年份
     */

    public function getLunarYearDays($year): int
    {

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        $monthArray = $this->getLunarYearMonths($year);

        $len = count($monthArray);

        return ($monthArray[$len - 1] === 0 ? $monthArray[$len - 2] : $monthArray[$len - 1]);

    }


    /**
     * 获取数字的阴历叫法
     * @param $num int 数字
     * @param $isMonth bool 是否是月份的数字
     * @return string
     */
    public function getCapitalNum(int $num, bool $isMonth = false): string
    {


        $dateHash = array('', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');

        $monthHash = array('', '正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月');

        $res = '';

        if ($isMonth) {

            $res = $monthHash[$num];

        } else if ($num <= 10) {

            $res = '初' . $dateHash[$num];

        } else if ($num > 10 && $num < 20) {

            $res = '十' . $dateHash[$num - 10];

        } else if ($num === 20) {

            $res = "二十";

        } else if ($num > 20 && $num < 30) {

            $res = "廿" . $dateHash[$num - 20];

        } else if ($num === 30) {

            $res = "三十";

        }
        return $res;
    }

    /**
     * 获取干支纪年
     * @param year
     */

    /**
     * 获取干支纪年
     * @param $year int 年份
     * @return string
     */
    public function getLunarYearName(int $year): string
    {

        $sky = array('庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己');

        $earth = array('申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未');

        $year .= '';

        return $sky[$year{3}] . $earth[$year % 12];

    }

    /**
     * 根据阴历年获取生肖
     * @param year 阴历年
     */
    public function getYearZodiac($year): string
    {

        $zodiac = array('猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊');

        return $zodiac[$year % 12];

    }

    /**
     * 计算2个阳历日期之间的天数
     * @param year 阳历年
     * @param cmonth
     * @param cdate
     * @param dmonth 阴历正月对应的阳历月份
     * @param ddate 阴历初一对应的阳历天数
     */

    public function getDaysBetweenSolar($year, $cmonth, $cdate, $dmonth, $ddate)
    {

        $a = mktime(0, 0, 0, $cmonth, $cdate, $year);

        $b = mktime(0, 0, 0, $dmonth, $ddate, $year);

        return ceil(($a - $b) / 24 / 3600);

    }

    public function convertSolarMonthToLunar($year, $month, $date): array
    {

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];


        if ($year == $this->MIN_YEAR && $month <= 2 && $date <= 9) {

            return array(1891, '正月', '初一', '辛卯', 1, 1, '兔');

        }

        $month_days_ary = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

        $dd = $month_days_ary[$month];

        if ($this->isLeapYear($year) && $month == 2) $dd++;

        $lunar_ary = array();

        for ($i = 1; $i < $dd; $i++) {

            $array = $this->getLunarByBetween($year, $this->getDaysBetweenSolar($year, $month, $i, $yearData[1], $yearData[2]));

            $array[] = $year . '-' . $month . '-' . $i;

            $lunar_ary[$i] = $array;

        }

        return $lunar_ary;

    }

    /**
     * 判断是否是闰年
     * @param year
     */

    public function isLeapYear($year): bool
    {

        return (($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0));

    }

    /**
     * 将阴历转换为阳历
     * @param year 阴历-年
     * @param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月,只是有的时候第13个月的天数为0
     * @param date 阴历-日
     */

    public function convertLunarToSolar($year, $month, $date): array
    {

        $yearData = $this->lunarInfo[$year - $this->MIN_YEAR];

        $between = $this->getDaysBetweenLunar($year, $month, $date);

        $res = mktime(0, 0, 0, $yearData[1], $yearData[2], $year);

        $res = date('Y-m-d', $res + $between * 24 * 60 * 60);

        $day = explode('-', $res);

        $year = $day[0];

        $month = $day[1];

        $day = $day[2];

        return array($year, $month, $day);

    }

    /**
     * 计算阴历日期与正月初一相隔的天数
     * @param year
     * @param month
     * @param date
     */

    public function getDaysBetweenLunar($year, $month, $date): int
    {

        $yearMonth = $this->getLunarMonths($year);

        $res = 0;

        for ($i = 1; $i < $month; $i++) {

            $res += $yearMonth[$i - 1];

        }

        $res += $date - 1;

        return $res;

    }

    /**
     * 获取阳历月份的天数
     * @param year 阳历-年
     * @param month 阳历-月
     */

    public function getSolarMonthDays($year, $month): int
    {

        $monthHash = array('1' => 31, '2' => $this->isLeapYear($year) ? 29 : 28, '3' => 31, '4' => 30, '5' => 31, '6' => 30, '7' => 31, '8' => 31, '9' => 30, '10' => 31, '11' => 30, '12' => 31);

        return $monthHash["$month"];

    }

    /**
     * 获取阴历月份的天数
     * @param year 阴历-年
     * @param month 阴历-月,从一月开始
     */

    public function getLunarMonthDays($year, $month)
    {

        $monthData = $this->getLunarMonths($year);

        return $monthData[$month - 1];

    }


    /*class end*/

}


header("Content-Type:text/html;charset=utf-8");

$lunar = new Lunar();

$month = $lunar->convertSolarToLunar('2017', '03', '09');//将阳历转换为阴历

echo '<pre>';

print_r($month);



]]>
0 /index.php/archives/369/#comments /index.php/feed/archives/369/
PHP7中 &quot; ?? &quot; 和 &quot; ?: &quot; 的区别 /index.php/archives/365/ /index.php/archives/365/ Wed, 30 Dec 2020 23:56:00 +0800 晴栀 $a ?? 0 等同于 isset($a) ? $a : 0

$a ?: 0 等同于 $a ? $a : 0

empty:判断一个变量是否为空(null、false、00、0、'0'0'、都会返回true)

isset:判断一个变量是否设置(值为false、00、0、'0′、也会返回true) 注意:如果$a为php常量中的null则isset($a)为 false

代码示例:


$array = [
'a' => 1,
'b' => 2,
'c' => 0,
'd'=>[],
];

$a = $array['b'] ?? 0;
//结果为$a=2  相当于 $a = isset($array['b']) ? $array['b'] : 0;

$b = $array['a'] ?: 0;
//结果为$b=1

$c = $array['e'] ?? 3;
//结果为$c=3

$d = $array['e'] ?: 3;
//系统报错 因为 $array['e'] 未声明  //未定义数组索引: e

$e = $array['c'] ? 5 : 6;
//结果为$e=6

$f = isset($array['c']) ? 1 : 2;
//结果为$f=1

$g = $array['e'] ? 3 : 4;
//系统报错 因为 $array['e'] 未声明  //未定义数组索引: e

$h = isset($array['d']['e']) ? 5 : 6;
//结果为$h=6

$i = !empty($array['d']) ? 7 : 8;
//结果为$i=8

$j = !empty($array['e']) ? 9 : 10;
//结果为$j=10

]]>
0 /index.php/archives/365/#comments /index.php/feed/archives/365/
PHP 自定义方法 JSON数据格式美化 /index.php/archives/358/ /index.php/archives/358/ Sun, 27 Dec 2020 23:29:00 +0800 晴栀 美化json格式数据:

代码:

function json($data) {
    header('content-type:application/json;charset=utf-8');
    return stripslashes(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}

用到直接拿去即可。

文章来源:https://www.fyovo.com/6221.html

]]>
0 /index.php/archives/358/#comments /index.php/feed/archives/358/
PHP对接微信支付 /index.php/archives/356/ /index.php/archives/356/ Sat, 26 Dec 2020 18:37:00 +0800 晴栀 近期正好对接微信支付功能,写了一个微信支付类,方便以后使用,这里分享给大家,配置一下直接调用就能用!

食用说明:

  • 设置为自己的$appid,$mchid,$mch_key。详情看代码。
  • 根据自己情况设置文件的命名空间,也就是namespace
  • 整个类为整体,不要只复制其中一部分。
  • 调用里面支付类方法时需要设置回调地址,根据自己实际情况修改。

<?php
/**
 * Created by PhpStorm.
 * User: Qingzhi
 * Blog: 
 * Date: 2020/12/22
 * Time: 15:06
 */

namespace app\currency\controller;


class WechatPayCurrency
{

    protected static $appid = 'wxea7bb0eb62dsada54';//直连商户申请的公众号或移动应用appid。
    protected static $mchid = '1571256472';//直连商户的商户号,由微信支付生成并下发。
    protected static $mch_key = 'zhifumiyaozhifumiyao44244244';//支付密钥

    /**
     * 微信app支付接口
     * @param $order 商户订单编号
     * @param $price 金额(分)
     * @param string $body 商品描述
     * @return array
     */
    public static function wechatPaymentApp($order, $price, $body = '')
    {
        $gatewayUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        /** 商品描述 $body */
        $body = $body ?: '微信支付费用';
        /** 回调路径 $NotifyUrl */
        $NotifyUrl = \request()->domain() . '/wechat/pay_notify_url';
        // 获取统一下单参数 xml
        $post = [
            'appid'            => self::$appid, // 必填--服务商商户的APPID
            'body'             => $body, // 必填--商品描述
            'mch_id'           => self::$mchid, // 必填--微信支付分配的商户号
            'nonce_str'        => self::randNbumer(32, 3), // 必填--随机字符串,不长于32位。推荐随机数生成算法
            'notify_url'       => $NotifyUrl, //支付完成回调地址url,不能带参数
            'out_trade_no'     => $order, // 商户订单号
            'spbill_create_ip' => self::contrast_ip(), //必填--终端IP。调用微信支付API的机器IP  contrast_ip   $_SERVER['SERVER_ADDR']
            'total_fee'        => intval($price), // 订单价格
            'trade_type'       => 'APP'//交易类型 默认JSAPI   APP
        ];
        // 生成签名
        $KEY          = self::$mch_key;
        $sign         = self::MakeSign($post, $KEY);
        $post['sign'] = $sign;
        // 数组转xml
        $post_xml = self::arrayToXml($post);
        //POST方式请求http
        $xdXml = self::http_request($gatewayUrl, $post_xml);
        //微信返回 xml  转为数组
        $xdArray = self::xmlToArray($xdXml);
        if ($xdArray['return_code'] == 'SUCCESS' && $xdArray['result_code'] == 'SUCCESS') {
            return self::return_result($xdArray, 20000, '订单创建成功');
        } else {
            $msg = $xdArray['err_code_des'] ?? ($xdArray['return_msg'] ?? '订单创建失败,请重试');
            return self::return_result([], 50000, $msg);
        }
    }

    /**
     * 随机生成字符串
     * @param int $len 字符串长度
     * @param int $type 字符串类型
     * @return bool|string
     */
    private static function randNbumer($len = 32, $type = 3)
    {
        switch ($type) {
            case 1:
                $codeSet = '123456789';
                break;
            case 2:
                $codeSet = 'abcdefhijkmnpqrstuvwxyz';
                break;
            case 3:
                $codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
                break;
            case 4:
                $codeSet = 'abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY';
                break;
            default:
                $codeSet = '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY';
                break;
        }
        return substr(str_shuffle(str_repeat($codeSet, $len)), 0, $len);
    }

    /**
     * 传入ip则验证是否一致,不传入则返回当前ip
     * @param null $contrast 想要对比的IP地址
     * @return array|bool|false|string
     */
    private static function contrast_ip($contrast = null)
    {
        if (isset($_SERVER)) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $realip = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                $realip = $_SERVER['REMOTE_ADDR'];
            }
        } else {
            //不允许就使用getenv获取
            if (getenv("HTTP_X_FORWARDED_FOR")) {
                $realip = getenv("HTTP_X_FORWARDED_FOR");
            } elseif (getenv("HTTP_CLIENT_IP")) {
                $realip = getenv("HTTP_CLIENT_IP");
            } else {
                $realip = getenv("REMOTE_ADDR");
            }
        }
        if (!$contrast) return $realip;
        if ($contrast == $realip) return true;
        return false;
    }

    /**
     * @param $params
     * @param $KEY 支付key
     * @param string $type
     * @return string 签名
     */
    private static function MakeSign($params, $KEY, $type = "MD5")
    {
        //签名步骤一:按字典序排序数组参数
        ksort($params);
        $string = self::ToUrlParams($params);  //参数进行拼接 1
        $string = $string . "&key=" . $KEY;
        //签名步骤二:加密
        if ($type == 'MD5') {
            $string = md5($string);
        } else {
            $string = hash_hmac('sha256', $string, $KEY);
        }
        //签名步骤三:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * 将参数拼接为url(key=value&key=value)
     * @param $params
     * @return string
     */
    private static function ToUrlParams($params)
    {
        $string = '';
        if (!empty($params)) {
            $array = array();
            foreach ($params as $key => $value) {
                $array[] = $key . '=' . $value;
            }
            $string = implode("&", $array);
        }
        return $string;
    }

    /**
     * array转xml
     * @param $arr
     * @return string
     */
    private static function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            // 将字符转为大写
            //$key = strtoupper($key);
            // 进遍历
            if (is_array($val)) {
                $xml .= "<" . $key . ">" . self::arrayToXml($val) . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 微信传输调用接口
     * @param $url 接口链接
     * @param null $data 数组
     * @param array $cert 证书路径信息
     * @param array $headers 头信息
     * @return bool|string
     */
    private static function http_request($url, $data = null, $cert = array(), $headers = array())
    {
        $curl = curl_init();
        if (count($headers) >= 1) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        // 判断是使用证书
        if ($cert) {
            curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM'); // 证书的类型。支持的格式有"PEM" (默认值), "DER"和"ENG"。
            curl_setopt($curl, CURLOPT_SSLCERT, getcwd() . $cert['cert_url']); // 证书,用于双向认证
            curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM'); // 客户端私钥类型,支持的私钥类型为"PEM"(默认值)、"DER"和"ENG"
            curl_setopt($curl, CURLOPT_SSLKEY, getcwd() . $cert['cert_key_url']); // 私钥的文件路径
            //curl_setopt($curl,CURLOPT_CAINFO,getcwd()."/customerkey/rootca.pem");// 公共pem
            //curl_setopt($curl, CURLOPT_KEYPASSWD,'');// 私钥密码,私钥在创建时可以选择加密。
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        //$meta = curl_getinfo($curl);// 发送信息
        //dump($meta);
        curl_close($curl);
        return $output;
    }

    /**
     * xml转array
     * @param unknown $xml
     * @return Ambigous <string, unknown>
     */
    private static function xmlToArray($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $val       = json_decode(json_encode($xmlstring), true);
        return $val;
        //         方法一
        //        $result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        //        return $result;

        //         方法二 建名全大写不适应
        //        $p = xml_parser_create();
        //        xml_parse_into_struct($p, $xml, $vals, $index);
        //        xml_parser_free($p);
        //        $data = "";
        //        foreach ($index as $key => $value) {
        //            if ($key == 'xml' || $key == 'XML') continue;
        //            $tag        = $vals[$value[0]]['tag'];
        //            $value      = $vals[$value[0]]['value'];
        //            $data[$tag] = $value;
        //        }
        //        return $data;

        //         方法三  键值对不对
        //        $data = simplexml_load_string($xml); //xml转object
        //        $data = json_encode($data);  //objecct转json
        //        $data = json_decode($data, true); //json转array
        //        return $data;
    }

    /**
     * 自己封装的返回方法
     * @param array $data
     * @param int $code
     * @param string $msg
     * @return array
     */
    private static function return_result($data = [], $code = 20000, $msg = '')
    {
        if (is_string($data)) {
            $msg  = $data;
            $data = [];
        }
        return ['data' => $data, 'code' => $code, 'msg' => $msg, 'time' => time()];
    }

    /**
     * 小程序支付接口
     * @param $open_id 用户的openid
     * @param $order 订单编号
     * @param $price 金额(分)
     * @param string $body 商品描述
     * @return array
     */
    public static function wechatPaymentApple($open_id, $order, $price, $body = '')
    {
        $gatewayUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//微信统一下单接口
        $notify_url = \request()->domain() . '/wechat/pay_notify_url';//异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
        // 获取统一下单参数 xml
        $post = [
            'appid'            => self::$appid, // 必填--服务商商户的APPID
            'body'             => $body ?? '商品名称', // 必填--商品描述
            'mch_id'           => self::$mchid, // 必填--微信支付分配的商户号
            'nonce_str'        => self::randNbumer(32, 3), // 必填--随机字符串,不长于32位。推荐随机数生成算法
            'notify_url'       => $notify_url, //支付完成回调地址url,不能带参数
            'openid'           => $open_id,
            'out_trade_no'     => $order, // 商户订单号
            'spbill_create_ip' => self::contrast_ip(), //必填--终端IP。调用微信支付API的机器IP
            'total_fee'        => intval($price), // 订单价格
            'trade_type'       => 'JSAPI'//交易类型 默认JSAPI
        ];
        // 生成签名
        $KEY          = self::$mch_key;
        $sign         = self::MakeSign($post, $KEY);
        $post['sign'] = $sign;

        // 数组转xml
        $post_xml = self::arrayToXml($post);
        //        dump($post_xml);exit;
        //POST方式请求http
        $xdXml = self::http_request($gatewayUrl, $post_xml);
        //微信返回 xml  转为数组
        $xdArray = self::xmlToArray($xdXml);
        // 当生成订单成功后进行二次签名
        if ($xdArray['return_code'] == 'SUCCESS' && $xdArray['result_code'] == 'SUCCESS') {
            //二次签名  小程序调起支付数据签名字段列表:
            $res  = self::getSign($xdArray);
            $data = [
                'res'    => $xdArray,
                'result' => $res,
            ];
            return self::return_result($data, 20000, $xdArray['return_msg'] ?? '');
        } else {
            $data = [
                'res'    => $xdArray,
                'result' => $xdArray,
            ];
            return self::return_result($data, 50000, $xdArray['return_msg'] ?? '');
        }
    }

    /**
     * 二次验签
     * @param $xdArray
     * @return mixed
     */
    private static function getSign($xdArray)
    {
        $getPost['appId']     = self::$appid;
        $getPost['timeStamp'] = (string)time();
        $getPost['nonceStr']  = self::randNbumer(32, 3);
        $getPost['package']   = 'prepay_id=' . $xdArray['prepay_id'];
        $getPost['signType']  = "MD5";
        $KEY                  = self::$mch_key;
        $sign                 = self::MakeSign($getPost, $KEY);
        $getPost['paySign']   = $sign;
        return $getPost;
    }

    /**
     * 微信web支付
     * @param $order 订单编号
     * @param $price 订单金额
     * @param string $body 商品描述
     * @return array
     */
    public static function wechatPaymentWeb($order, $price, $body = '')
    {
        $gatewayUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//微信统一下单接口
        $notify_url = \request()->domain() . '/wechat/pay_notify_url';//异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
        //统一下单参数 xml
        $post = [
            'appid'            => self::$appid, // 必填--服务商商户的APPID
            'body'             => $body ?? '商品名称', // 必填--商品描述
            'mch_id'           => self::$mchid, // 必填--微信支付分配的商户号
            'nonce_str'        => self::randNbumer(32, 3), // 必填--随机字符串,不长于32位。推荐随机数生成算法
            'notify_url'       => $notify_url, //支付完成回调地址url,不能带参数
            'out_trade_no'     => $order, // 商户订单号
            'spbill_create_ip' => self::contrast_ip(), //必填--终端IP。调用微信支付API的机器IP  contrast_ip   $_SERVER['SERVER_ADDR']
            'total_fee'        => intval($price), // 订单价格
            'trade_type'       => 'NATIVE'//交易类型 默认JSAPI
        ];
        // 生成签名
        $KEY          = self::$mch_key;
        $sign         = self::MakeSign($post, $KEY);
        $post['sign'] = $sign;
        // 数组转xml
        $post_xml = self::arrayToXml($post);
        //POST方式请求http
        $xdXml = self::http_request($gatewayUrl, $post_xml);
        //微信返回 xml  转为数组
        $xdArray = self::xmlToArray($xdXml);
        if ($xdArray['return_code'] == 'SUCCESS' && $xdArray['result_code'] == 'SUCCESS') return self::return_result($xdArray, 20000, '订单创建成功');
        $msg = $xdArray['err_code_des'] ?? ($xdArray['return_msg'] ?? '订单创建失败,请重试');
        return self::return_result([], 50000, $msg);
    }

    /**
     * 微信退款查询
     * @param $out_trade_no
     * @return Ambigous|bool
     */
    public static function wechatRefundInquiry($out_trade_no)
    {
        $queryRefundUrl = "https://api.mch.weixin.qq.com/pay/refundquery";//微信退款查询接口
        if (empty($out_trade_no)) return self::return_result([], 50000, '订单号不能为空');
        $query = self::wechatpayQuery($out_trade_no);
        //POST方式请求http
        $xdXml = self::http_request($queryRefundUrl, $query);
        //微信返回 xml  转为数组
        $xdArray = self::xmlToArray($xdXml);
        if (!empty($xdArray['return_code']) && $xdArray['return_code'] == 'SUCCESS') return self::return_result($xdArray, 20000, '订单查询成功');
        $msg = $xdArray['err_code_des'] ?? ($xdArray['return_msg'] ?? '订单查询失败,请重试');
        return self::return_result([], 50000, $msg);
    }

    /**
     * 获取商户平台配置
     * @param $out_trade_no 订单号
     * @return string
     */
    private static function wechatPayQuery($out_trade_no)
    {
        $post = [
            'appid'        => self::$appid, // 必填--服务商商户的APPID
            'mch_id'       => self::$mchid, // 必填--微信支付分配的商户号
            'nonce_str'    => self::randNbumer(32, 3), // 必填--随机字符串,不长于32位。推荐随机数生成算法
            'out_trade_no' => $out_trade_no, // 商户订单号
        ];
        // 生成签名
        $KEY          = self::$mch_key;
        $sign         = self::MakeSign($post, $KEY);
        $post['sign'] = $sign;

        // 数组转xml
        $post_xml = self::arrayToXml($post);
        return $post_xml;
    }

    /**
     * 微信支付订单查询
     * @param bool $out_trade_no
     * @return Ambigous|bool
     */
    public static function wechatPaymentQuery($out_trade_no)
    {
        $querywayUrl = "https://api.mch.weixin.qq.com/pay/orderquery";//微信订单查询接口

        if (empty($out_trade_no)) return self::return_result([], 50000, '订单号不能为空');
        $query = self::wechatPayQuery($out_trade_no);
        //POST方式请求http
        $xdXml = self::http_request($querywayUrl, $query);
        //微信返回 xml  转为数组
        $xdArray = self::xmlToArray($xdXml);
        if (empty($xdArray['return_code'])) return self::return_result($xdArray, 50000, '查询失败');
        if ($xdArray['return_code'] == 'SUCCESS') return self::return_result($xdArray, 20000, '查询成功');
        $msg = $xdArray['err_code_des'] ?? ($xdArray['return_msg'] ?? '订单查询失败');
        return self::return_result($xdArray, 50000, $msg);
    }


}
]]>
2 /index.php/archives/356/#comments /index.php/feed/archives/356/
Git中系新增忽略文件或文件夹 /index.php/archives/326/ /index.php/archives/326/ Fri, 25 Dec 2020 11:49:00 +0800 晴栀 1. 在需要创建 .gitignore 文件的文件夹, 右键选择 Git Bash 进入命令行,进入项目所在目录。

2. 输入 touch .gitignore 命令就在文件夹就生成了一个.gitignore文件。 然后在.gitignore 文件里输入你要忽略的文件夹及其文件就可以了。

3. 用编辑器打开这个文件进行编辑。

4. 然后就写规则来操作要忽略的文件了。.gitignore文件过滤有两种模式,开放模式保守模式

4-1. 开放模式负责设置过滤哪些文件和文件夹

  • 过滤文件夹设置:

/mtk/ 表示过滤这个文件夹

  • 过滤文件设置:

    • 指定过滤某种类型的文件:

    *.zip 过滤所有类型为zip的文件

    *.rar 过滤所有类型为rar的文件

    *.via 过滤所有类型为via的文件

    *.tmp 过滤所有类型为tmp的文件

    *.err 过滤所有类型为err的文件

    • 指定过滤某个文件:

    /mtk/do.c

    /mtk/if.h


4-2. 保守模式负责设置哪些文件不被过滤,也就是哪些文件要被跟踪
  • 跟踪某个文件夹:

    !/plutommi/mmi

  • 跟踪某类文件:

    !*.c

    !*.h

  • 跟踪某个指定文件:

    • !/plutommi/mmi/mmi_features.h

5. 配置.gitignore 的简易原则:
  • 采用共享模式与保守模式结合配置的办法。
    一个文件夹下有很多文件夹和文件,而我只想跟踪其中的一个文件,这样设置就可以满足这种情况:
  • 先用共享模式把整个目录都设置为不跟踪。
  • 再用保守模式把这个文件夹中想要跟踪的文件设置为被跟踪。
    这样配置很简单,就可以跟踪想要跟踪的文件。
]]>
1 /index.php/archives/326/#comments /index.php/feed/archives/326/
根据身份证号获取性别 /index.php/archives/323/ /index.php/archives/323/ Thu, 10 Dec 2020 23:22:18 +0800 晴栀 根据身份证号获取性别

使用此之前最好先对证件号码进行格式验证,否则可能会获取错误。

相关文章:

[post cid="275" /]



/**
     * 根据身份证号获取性别
     * @param $idcard证件号码
     * @return bool|int 1男  2女  0外星人
     */
    function idcard_sex($idcard)
    {
        if (empty($idcard) || strlen($idcard) != 18 || !is_numeric($idcard[16])) return false;
        if ($idcard[16] & 1) return 1;
        if (!($idcard[16] & 1)) return 2;
        return 0;
    }

  • 如果返回false,则代表身份证格式错误!
]]>
0 /index.php/archives/323/#comments /index.php/feed/archives/323/
PHP报错The each() function is deprecated. This message will be suppressed on further calls /index.php/archives/351/ /index.php/archives/351/ Thu, 26 Nov 2020 17:38:00 +0800 晴栀 今天在使用支付宝sdk对接网页支付时,系统报了这个错误。

错误原因:

PHP7.2版本将each()方法移除了,项目中使用到each()地方就会报错!

支付宝支付SDK2.0中使用了each()方法。

错误截图:

each错误

解决办法1:

  • each()替换为foreach(),如下为示例:

each原写法为while (list ($key, $val) = each($para_temp)) { }
更改为:foreach ($para_temp as $key => $val) { }

示例代码:


     //while (list ($key, $val) = each($para_temp)) {   //旧写法已被废弃
     foreach ($para_temp as $key => $val) {    //替换方式
         if (false === $this->checkEmpty($val)) {
             //$val = $this->characet($val, $this->postCharset);
             $val = str_replace("'", "&apos;", $val);
             //$val = str_replace("\"","&quot;",$val);
             $sHtml .= "<input type='hidden' name='" . $key . "' value='" . $val . "'/>";
         }
     }


解决办法2:

  • 首先说明推荐第一种解决办法

办法2是自己修改each()方法代替:


function func_new_each(&$array){
    $res = array();
    $key = key($array);
    if($key !== null){
        next($array);
        $res[1] = $res['value'] = $array[$key];
        $res[0] = $res['key'] = $key;
    }else{
        $res = false;
    }
    return $res;
}

将上述方法放在公共文件中,然后将程序中将each修改为func_new_each即可。

ps:支付宝sdk中的需要替换的地方为alipay\AopClient.php中的375行,和412行。

]]>
0 /index.php/archives/351/#comments /index.php/feed/archives/351/
关于PHP代码优化24条建议 /index.php/archives/347/ /index.php/archives/347/ Fri, 06 Nov 2020 15:56:00 +0800 晴栀 1.echoprint快。

2.使用echo的多重参数代替字符串连接。

3.在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。

4.对global变量,应该用完就unset()掉。

5.用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会。

6.函数代替正则表达式完成相同功能。

7.当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。

8.使用选择分支语句switch case好于使用多个if,else if语句。

9.利用var_dump进行PHP代码调试。如果你在寻找php调试技术,我必须说var_dump应该是你要找的目标,在显示php信息方面这个命令可以满足你的所有需要,而调试代码的多数情况与得到PHP中的数值有关。

10.在包含文件时使用完整路径,解析操作系统路径所需的时间会更少。

11.动辄创建全局数值是一种糟糕的做法,不过有时候实际情况的确又需要这么做。对于数据库表数据库连接信息使用全局数值是一个不错的想法,但不要在你的PHP代码中频繁使用全局数值。另外,更好的一种做法是把你的全局变量存放在一个config.php文件中。

12.如果你想知道脚本开始执行的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()

13.打开apache的mod_deflate模块。

14.用@屏蔽错误消息的做法非常低效。

15.尽量采用大量的PHP内置函数

16.递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。

17.派生类中的方法运行起来要快于在基类中定义的同样的方法。

18.仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)

19.Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。

20.正如之前提到的,任何php网站中最重要的部分有99%的可能是数据库。因此,你需要非常熟悉如何正确的使用sql,学会关联表和更多高级的数据库技术。

21.调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。

22.当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回zval结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。

23.并不是所有情况都必须使用面向对象开发,面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。

24.除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。

]]>
0 /index.php/archives/347/#comments /index.php/feed/archives/347/
ThinkPHP5中Db类与Model类关系 /index.php/archives/309/ /index.php/archives/309/ Thu, 29 Oct 2020 11:38:00 +0800 晴栀 ThinkPHP5中Db类与Model类关系

在ThinkPHP中我们经常使用 Db 类操作和 Model 类继承,两者都能实现想要的数据库操作,那么一直有个问题困扰着我,他们两者差距到底是什么呢?实际使用起来,谁的理论操作速度更快呢?带着这两个问题,我去度娘找到了相对满意的答案,这里分享给大家!


这里先看一张TP源码的结构图:
TPModel结构图.png

可以看到图中Query查询对象地位特别重要,条条大路通Query!

  • Query 具备数据库操作的所有接口,是对 Connection 类的进一步封装和扩展,Query 支持链式操作,作为数据库中间传递对象,Db 和 Model 调用 Query 时,是通过 __call() 或者 __callStatic() 语法糖来自动触发调用的。
  • Query 从设计上来说,是遵从面向对象设计原则之一的里氏替换原则,除了输出的实体数据 Connection 外,其他的外部依赖都是依赖抽象类,这种通过继承的多态性可大大提高程序的可扩展性。
  • Query 在依赖外部类时,一般通过组合或直接调用来来建立依赖,而不是通过继承(也无法多重继承),可提高程序的灵活性,降低程序的臃肿度。

可以看到 Db 类是数据库操作的入口类,我们几乎没有直接操作过 Query 类。Db 类应用了对象关系映射(ORM)的设计方法,可以很方便的使用提供的接口,某种程度上因解析原因会稍微降低一些性能,不过你也可以用最原始的语句查询,并没有强制。

因为 Model 是一个抽象类,所以在使用时需要先继承一下。支持关系操作(Relation)。


最后总结:综上所述,Db类理论操作速度是要比Model要快滴!

参考链接:华子程序

]]>
0 /index.php/archives/309/#comments /index.php/feed/archives/309/