服务器配置概要
【安装宝塔】yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
【编译安装】lnmp(nginx1.18 mysql5.7 php7.4 phpmyadmin5.0)
【安装宝塔】yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
【编译安装】lnmp(nginx1.18 mysql5.7 php7.4 phpmyadmin5.0)
whereOr与where同时使用时,需使用闭包模式,避免sql语句错误。
$user = Db::name('user')->where('uuid', $where['uuid'])->find();
if($user['phone'] && $user['card_id']){
$map1 = [['phone', '=', $user['phone']]];
$map2 = [['card_id', '=', $user['card_id']]];
$model = $model->where(function ($query) use ($map1, $map2) {
$query->whereOr([$map1, $map2]);
});
}elseif($user['card_id']){
$model = $model->where('card_id', $user['card_id']);
}elseif($user['phone']){
$model = $model->where('phone', $user['phone']);
}else{
$model = $model->where('id', 0);
}
ThinkPHP6操作oracle数据库 常见问题:
ORA-28547:connection to server failed, probable Oracle Net admin error
php_pdo_oci.dll
php_oci8.dll
同oracle版本对应及对应线程类型。windows版下载地址:https://pecl.php.net/package/oci8/2.2.0/windows 或使用https://windows.php.net/downloads/pecl/releases/oci8/2.2.0/如图,需查询A列同E列中的重复项。
在需展示的列单元格中输入:=IF(COUNTIF(E:E,A1),A1,""),意思是用A1单元格的数值在E列中查重,如果有重复值就在单元格中显示重复的数值。
按住ctrl向下填充即可获得两列中的重复项,再进行排序等操作即可。
项目中常用到生日提醒,且生日通常为农历生日。
本接口使用有限,推荐自定义转化类,链接:PHP阳历转阴历(农历)类,支持生肖、时辰等老黄历
基础方法:
//获取农历生日
function getNongLi($day='')
{
$day = $day?:date('Y-m-d');
$nongli = \sensen\services\HttpService::getRequest('https://api.xlongwei.com/service/datetime/convert.json?day='.$day);
$nongli = json_decode($nongli, true);
$end = $nongli['lunarYear'].'-'.$nongli['lunarMonth'].'-'.$nongli['lunarDay'];
$end = date('m-d', strtotime("{$end}"));
return $end;
}
//获取阳历生日
function getYangLi($day='')
{
if(!$day) return '';
$arr = explode('-', $day);
$nongli = \sensen\services\HttpService::getRequest("https://api.xlongwei.com/service/datetime/yangli.json?lunarYear={$arr[0]}&lunarMonth={$arr[1]}&lunarDay={$arr[2]}");
$nongli = json_decode($nongli, true);
if(isset($nongli['status'])) return '';
return $nongli['day'];
}
项目日志列表中需对报错数据详细信息进行查阅,需对json格式进行美化,如图:
样式代码:
<style>
.key{
color: red;
}
.string{
color: green;
}
.layui-layer-content{
padding: 10px;
}
</style>
layer弹窗展示数据:
table.on('tool(table-toolbar)', function(obj){
var data = obj.data;
var str = prettyFormat(data.data);
if(obj.event === 'detail'){
layer.open({
type: 1,
title: '数据详情',
skin: 'layui-layer-rim', //加上边框
area: ['600px', '500px'], //宽高
content: str
});
}
});
//json格式美化
function prettyFormat(json) {
try {
// 设置缩进为2个空格
//str = JSON.stringify(JSON.parse(str), null, 2);
str = JSON.stringify(json, null, 2);
str = str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
str = str.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
return "<pre>"+str+"</pre>"
} catch (e) {
alert("异常信息:" + e);
}
}
快速获取RSA密钥对:http://www.metools.info/code/c80.html
示例代码:
<?php
class App extends BaseController
{
private $syncUrl = 'https://www.xxx.com/api/event/sync';
private $privateKey; //私钥
private $publicKey; //其他系统公钥
private $keyLen = 2048;
private $appId = 1;
private $identity = 'hello';
public function __construct()
{
$this->privateKey = file_get_contents((app()->getRootPath() . 'private_key.pam'));
$this->publicKey = file_get_contents((app()->getRootPath() . 'cert_public.pam'));
}
//新版接口
public function test($uid='', $token='')
{
//请求tokenIsValidSync判断请求是否合法
$data = [
'app_id'=>$this->appId,
'app_identity'=>$this->identity,
'timestamp'=>time(),
'rnd_str'=>uniqid(),
'event'=>'tokenIsValidSync',
'uid'=>$uid,
'token'=>$token,
'profile'=>1
];
$enData = $this->privateEncrypt($data);
$postData = [
'app_id'=>$this->appId,
'data'=>$enData
];
$ret = HttpService::postRequest($this->syncUrl, $postData);
$info = json_decode($ret, true);
$decryptData = $this->publicDecrypt($info['data']);
$userInfo = json_decode($decryptData, true);
}
/**
* 私钥加密
*
* @param string|array $data 待加密数据
* @return string 已加密的内容
*/
public function privateEncrypt($data)
{
//如果是数组,则转换为JSON字符串
if (is_array($data)) $data = json_encode($data);
if (!is_string($data)) {
return null;
}
$encrypted = '';
//采用默认的 OPENSSL_PKCS1_PADDING 填充格式,数据长度必须小于密钥长度 - 11
$part_len = $this->keyLen / 8 - 11;
$parts = str_split($data, $part_len);
foreach ($parts as $part) {
$encrypted_temp = '';
openssl_private_encrypt($part, $encrypted_temp, $this->privateKey);
$encrypted .= $encrypted_temp;
}
return base64_encode($encrypted);
}
/**
* 公钥解密
*
* @param string $encrypted 待解密内容
* @return string 已解密内容
*/
public function publicDecrypt($encrypted = '')
{
if (!is_string($encrypted)) {
return null;
}
$decrypted = '';
$part_len = $this->keyLen / 8;
$base64_decoded = base64_decode($encrypted);
$parts = str_split($base64_decoded, $part_len);
foreach ($parts as $part) {
$decrypted_temp = '';
openssl_public_decrypt($part, $decrypted_temp, $this->publicKey);
$decrypted .= $decrypted_temp;
}
return $decrypted;
}
}
<?php
/**
* Desc: AES加密解密
* User: SenSen Wechat:1050575278
* Date: 2021/4/27
* Time: 14:14
*/
namespace sensen\services;
class AesService
{
protected static $method = "AES-128-CBC";
const KEY = 'fei1zui2you3jie!';
const IV = 'hello202105world';
/**
* 加密
* @param string|array $data 待加密
* @param string $key 秘钥
* @param string $iv 偏移量
* @return string|string[]|array
*/
public static function encrypt($data, $key=self::KEY, $iv=self::IV)
{
if(is_array($data)){
$res = [];
foreach ($data as $v){
$text = openssl_encrypt($v, static::$method, $key, OPENSSL_RAW_DATA, $iv);
$res[] = self::safetyBase64Encode($iv . $text);
}
}else{
$text = openssl_encrypt($data, static::$method, $key, OPENSSL_RAW_DATA, $iv);
$res = self::safetyBase64Encode($iv . $text);
}
return $res;
}
/**
* 解密
* @param string|array $text 待解密
* @param string $key 秘钥
* @param string $iv 偏移量
* @param false $login 是否为登录
* @return false|string|array
*/
public static function decrypt($text, $key=self::KEY, $iv=self::IV, $login=false) {
if(is_array($text)){
$data = [];
foreach ($text as $v){
$cipherText = self::safetyBase64Decode($v);
$cipherText = substr($cipherText, strlen($iv));
$data[] = openssl_decrypt($cipherText, static::$method, $key, OPENSSL_RAW_DATA, $iv);
}
}else{
$cipherText = self::safetyBase64Decode($text);
if($login){
//仅方便登录使用,登录时iv与key相同
$data = openssl_decrypt(base64_decode($text), static::$method, $key, OPENSSL_RAW_DATA, $iv);
}else{
$cipherText = substr($cipherText, strlen($iv));
$data = openssl_decrypt($cipherText, static::$method, $key, OPENSSL_RAW_DATA, $iv);
}
}
return $data;
}
/**
* base64安全编码
* @param string $text
* @return string|string[]
*/
public static function safetyBase64Encode($text)
{
$text = base64_encode($text);
$text = str_replace(['+','/'],['-','_'],$text);
return $text;
}
/**
* base64安全解码
* @param string $text
* @return false|string
*/
public static function safetyBase64Decode($text)
{
$text = str_replace(['-','_'],['+','/'],$text);
$text = base64_decode($text);
return $text;
}
}