PHP知识记录
1.json_encode处理中文
json_encode( '中文', JSON_UNESCAPED_UNICODE);
json_encode( '中文', JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
最近在为移动端的项目提供接口,数据格式都为json,不过在过程中遇到一个小问题,代码如下:
情况一:
$tmp = array('a','b','c');
echo json_encode($tmp);
输出结果:['a','b','c']
情况二:
$tmp = array('a'=>'a','b'=>'b','c'=>'c');
echo json_encode($tmp);
输出结果:{'a':'a','b':'b','c':'c'}
问题出来了:
在二中,如果$tmp 可能为空的情况下,json_encode 后 输出的结果将是[]空数组
那么,这个接口在提供数据时就必须得分两种情况来考虑了:
数组为空时,接口输出的是空数组;
数组不为空时,接口输出的对象
解决方案:json_encode($tmp, JSON_FORCE_OBJECT) 不管在什么情况,接口永远输出对象,空数据及为{}
其实还有一个问题不知道原因:
在一,二两种情况中,为什么一种json_encode之后出来的是数组[],而二中出来的是对象{}
答案:
非连续的索引数组,在json_encode时都会被编码为object
这句话这么描述好像有些不妥
索引数组本来就是连贯的,应该是除了索引数组,其他数组(关联数组,多维数组)都会被编码为object
2..时间互换
var_dump(date('Y-m-d H:i:s',1556640000));
var_dump(strtotime('2019-3-31 23:59:59'));
TP时间戳操作
首先通过 composer 安装
composer require topthink/think-helper
在文件头部引入
use think\helper\Time;
比如需要获得今天的零点时间戳和23点59分59秒的时间戳
list($start, $end) = Time::today();
echo $start; // 零点时间戳
echo $end; // 23点59分59秒的时间戳
完整示例如下:
// 今日开始和结束的时间戳
Time::today();
// 昨日开始和结束的时间戳
Time::yesterday();
// 本周开始和结束的时间戳
Time::week();
// 上周开始和结束的时间戳
Time::lastWeek();
// 本月开始和结束的时间戳
Time::month();
// 上月开始和结束的时间戳
Time::lastMonth();
// 今年开始和结束的时间戳
Time::year();
// 去年开始和结束的时间戳
Time::lastYear();
// 获取7天前零点到现在的时间戳
Time::dayToNow(7)
// 获取7天前零点到昨日结束的时间戳
Time::dayToNow(7, true)
// 获取7天前的时间戳
Time::daysAgo(7)
// 获取7天后的时间戳
Time::daysAfter(7)
// 天数转换成秒数
Time::daysToSecond(5)
// 周数转换成秒数
Time::weekToSecond(5)
date_default_timezone_set('Asia/shanghai');
echo "今天:".date("Y-m-d")."<br>";
echo "昨天:".date("Y-m-d",strtotime("-1 day")), "<br>";
echo "明天:".date("Y-m-d",strtotime("+1 day")). "<br>";
echo "一周后:".date("Y-m-d",strtotime("+1 week")). "<br>";
echo "一周零两天四小时两秒后:".date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds")). "<br>";
echo "下个星期四:".date("Y-m-d",strtotime("next Thursday")). "<br>";
echo "上个周一:".date("Y-m-d",strtotime("last Monday"))."<br>";
echo "一个月前:".date("Y-m-d",strtotime("last month"))."<br>";
echo "一个月后:".date("Y-m-d",strtotime("+1 month"))."<br>";
echo "十年后:".date("Y-m-d",strtotime("+10 year"))."<br>";
a - "am" 或是 "pm"
A - "AM" 或是 "PM"
d - 几日,二位数字,若不足二位则前面补零; 如: "01" 至 "31"
D - 星期几,三个英文字母; 如: "Fri"
F - 月份,英文全名; 如: "January"
h - 12 小时制的小时; 如: "01" 至 "12"
H - 24 小时制的小时; 如: "00" 至 "23"
g - 12 小时制的小时,不足二位不补零; 如: "1" 至 12"
G - 24 小时制的小时,不足二位不补零; 如: "0" 至 "23"
i - 分钟; 如: "00" 至 "59"
j - 几日,二位数字,若不足二位不补零; 如: "1" 至 "31"
l - 星期几,英文全名; 如: "Friday"
m - 月份,二位数字,若不足二位则在前面补零; 如: "01" 至 "12"
n - 月份,二位数字,若不足二位则不补零; 如: "1" 至 "12"
M - 月份,三个英文字母; 如: "Jan"
s - 秒; 如: "00" 至 "59"
S - 字尾加英文序数,二个英文字母; 如: "th","nd"
t - 指定月份的天数; 如: "28" 至 "31"
U - 总秒数
w - 数字型的星期几,如: "0" (星期日) 至 "6" (星期六)
Y - 年,四位数字; 如: "1999"
y - 年,二位数字; 如: "99"
z - 一年中的第几天; 如: "0" 至 "365"
3.PHP正则
? 通配符匹配文件名中的 0 个或 1 个字符,而 * 通配符匹配零个或多个字符
正则表达式中常用的模式修正符有i、g、m、s、U、x、a、D、e 等。
它们之间可以组合搭配使用。
i 不区分(ignore)大小写;
例如: /abc/i 可以匹配 abc、aBC、Abc g 全局(global)匹配
如果不带g,正则过程中字符串从左到右匹配,找到第一个符合条件的即匹配成功,返回
如果带g,则字符串从左到右,找到每个符合条件的都记录下来,知道字符串结尾位置
例如:
var str = 'aaaaaaaa'
var reg1 = /a/; str.match(reg1) // 结果为:["a", index: 0, input: "aaaaaaaa"]
var reg2 = /a/g; str.match(reg2) // 结果为:["a", "a", "a", "a", "a", "a", "a", "a"]
m 多(more)行匹配
若存在换行\n并且有开始^或结束$符的情况下,和g一起使用实现全局匹配,
因为存在换行时默认会把换行符作为一个字符任务匹配字符串是个单行,
g只匹配第一行,添加m之后实现多行,每个换行符之后就是开始
var str = "abcggab\nabcoab";
var preg1 = /^abc/gm; str.match(preg1) // 结果为:["abc", "abc"]
var preg2 = /ab$/gm; str.match(preg2) // 结果为:["ab", "ab"]
s 特殊字符圆点 . 中包含换行符
默认的圆点 . 是 匹配除换行符 \n 之外的任何单字符,加上s之后, . 中包含换行符
$str = "abggab\nacbs";
$preg = "/b./s";
preg_match_all($preg, $str,$matchs);
print_r($matchs);//Array ( [0] => Array ( [0] => bg [1] => b [2] => bs ) )
U 只匹配最近的一个字符串;不重复匹配;
$mode="/a(.*?)c/";
$preg="/a.*c/U";//这两个正则返回相同的值
$str="abcabbbcabbbbbc" ;
preg_match($mode,$str,$content); echo $content[0];//abc
preg_match($preg,$str,$content); echo $content[0];//abc
//修正符:x 将模式中的空白忽略;
//修正符:A 强制从目标字符串开头匹配;
//修正符:D 如果使用$限制结尾字符,则不允许结尾有换行;
//修正符:e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;
4.三元运算符
$type = 2;
echo $type == 1 ? "1" : $type == 2 ? "2" : $type == 3 ? "3" : "4";
以上内容输出结果为3。
查看php运算符优先级表格,"=="的优先级别高于三元运算符。因此上面的代码等价于:
$res = $type == 1?"1":($type == 2);
//$res = true
$res = $res ?2:($type ==3);
//$res=2
$res = $res ? "3" :4;
//$res = 3
echo $res;
网上很多都以"PHP三元运算符的运算顺序是反的"为标题的文章,其实,执行顺序并不是反的,而是运算符优先级的问题
5.去掉BOM
ltrim($result ,"\XEF\XBB\XBF")
或者
$result = @iconv("UTF-8", "GBK//IGNORE", $result);
$result = @iconv("GBK", "UTF-8//IGNORE", $result);
允许跨域
header('Access-Control-Allow-Origin: http://192.168.1.129:8080');
// 也可以添加所有的请求为 允许,当然不推荐这样做了、
header('Access-Control-Allow-Origin: *');