孙立亚笔记 - 记录碰到的各种网站问题和解决方案

本地图片转base64

if (!function_exists('base64EncodeImage')) {

function base64EncodeImage ($image_file) {
    $base64_image = '';
    $image_info = getimagesize($image_file);
    $image_data = fread(fopen($image_file, 'r'), filesize($image_file));
    $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
    return $base64_image;
}

}

按经纬度距离搜索数据

在PHP中,要搜索一个特定经纬度100公里以内的地点,可以使用Haversine公式,该公式可以计算两点之间的大圆距离。以下是一个PHP函数,它使用Haversine公式来找出一个经纬度点周围100公里范围内的所有点。
function getPointsWithinRadius($lat, $lng, $radius = 100) {
// 地球半径,单位为公里
$earthRadius = 6371;
// 转换为弧度
$lat = deg2rad($lat);
$lng = deg2rad($lng);

// 计算经度差值的一半
$diffLongitude = deg2rad($radius / abs(cos(deg2rad($lat)) * 69));

// 计算纬度范围
$minLat = $lat - $diffLongitude;
$maxLat = $lat + $diffLongitude;

// 计算经度范围
$minLong = $lng - $diffLongitude;
$maxLong = $lng + $diffLongitude;

// 计算两点间距离
$sql = "SELECT id, (

6371 * acos(
    cos(radians(:lat)) *
    cos(radians(lat)) *
    cos(radians(lng) - radians(:lng)) +
    sin(radians(:lat)) *
    sin(radians(lat))
)

) AS distance
FROM your_table
HAVING distance < :radius
ORDER BY distance
LIMIT 0 , 20;";

// 替换实际的SQL查询,并传入实际的经纬度和半径
// 这里的:lat, :lng, :radius 应该被替换为实际的值
// 例如使用PDO:
// $sth = $pdo->prepare($sql);
// $sth->execute(array(':lat' => $lat, ':lng' => $lng, ':radius' => $radius));
// $points = $sth->fetchAll();

// 返回查询结果
return $points; // 这里应该是从数据库获取的点的数组
}
// 使用示例
$points = getPointsWithinRadius(34.0522, -118.2437, 100);

请注意,你需要将
your_table 替换为你的数据库中包含经纬度数据的表名,并且需要将
$pdo->prepare 和
$sth->execute 替换为实际的数据库查询代码。这个函数返回的是一个数组,其中包含了在指定的经纬度周围100公里范围内的点的数据。

以下是第二种方法,未测试
/**

  • Desc: 根据经纬度,半径范围获取附近
  • User: JamesLiu
  • Date: 2019/5/13
  • Time: 15:38
  • @param $longitude 经度
  • @param $latitude 纬度
  • @param $raidus 半径范围(单位:米)
  • @return array
    */

public function getAround($longitude, $latitude, $raidus)
{
$PI = 3.14159265;
$degree = (24901 * 1609) / 360.0;
$dpmLat = 1 / $degree;
$radiusLat = $dpmLat * $raidus;
$minLat = $latitude - $radiusLat;
$maxLat = $latitude + $radiusLat;
$mpdLng = $degree * cos($latitude * ($PI / 180));
$dpmLng = 1 / $mpdLng;
$radiusLng = $dpmLng * $raidus;
$minLng = $longitude - $radiusLng;
$maxLng = $longitude + $radiusLng;
return array('minLng' => $minLng, 'maxLng' => $maxLng, 'minLat' => $minLat, 'maxLat' => $maxLat);
}

经纬度距离组装成sql
1 $array = $this->getAround(115.826646, 28.718022, 2000);
2 $condition['longitude'] = array(array('EGT', $array['minLng']), array('ELT', $array['maxLng']), 'and');//(longitude >= minLng) AND (longitude <= maxLng)
3 $condition['latitude'] = array(array('EGT', $array['minLat']), array('ELT', $array['maxLat']), 'and');//(latitude >= minLat) AND (latitude <=maxLat)

PHP生成二维码保存本地

使用如下
composer require bacon/bacon-qr-code
或者在composer.json里添加
"bacon/bacon-qr-code": "^2.0",

/**

 * 生成二维码
*/
public function myQrcode()
{
    $uid = $this->uid;
    $user = Db::name('member')->where('id', $uid)->find();
    if(!$user) {
        return self::returnMsg(201, '未找到当前会员信息');
    }
    if($user['status'] != 3) {
        return self::returnMsg(201, '你已被禁用');
    }

    $domain = get_sysconfig('xxl_imgdomain', 'base');
    $domain = rtrim($domain, '/');

    $qt_url = get_sysconfig('qt_url', 'base');
    $qt_url = rtrim($qt_url, '/');
    $url = $qt_url.'/#/pages/my/invitation-register/invitation-register?pid='.$uid;
    $md5_qturl = md5($qt_url);
    // 在短链系统上生成
    $dl_jkurl = get_sysconfig('dl_jkurl', 'base');
    $dl_jkurl = rtrim($dl_jkurl, '/');
    $cs = ['url' => $url];
    $res = curl($dl_jkurl.'/api/v1/shortlink/setLink', $cs, 'POST');
    $res = json_decode($res, true);

    if($res['code'] == 200 && isset($res['data']['info'])) {
        $url = $dl_jkurl.$res['data']['info'];
    }
    $name = root_path().'/public/qrcode/'.$md5_qturl.'_'.$uid.'.png';
    if(file_exists($name)) {
        // @unlink($name);
        $img = $domain.'/qrcode/qrcode_'.$uid.'.png';
        return self::returnMsg(200, 'success', $img);
    }

    $renderer = new \BaconQrCode\Renderer\ImageRenderer(
        new \BaconQrCode\Renderer\RendererStyle\RendererStyle(500),
        new \BaconQrCode\Renderer\Image\ImagickImageBackEnd()
    );
    $writer = new \BaconQrCode\Writer($renderer);

    $writer->writeFile($url, $name);
    $img = $domain.'/qrcode/'.$md5_qturl.'_'.$uid.'.png';

    // $img = file_get_contents($name); var_dump('<img src="'.$img.'">');die;
    // $img = base64_encode($img);
    // ob_end_clean();
    // ob_start();
    // echo  file_get_contents($name);
    // $img = ob_get_contents();

    // ob_end_clean();
    // $img = base64_encode($img);var_dump($img);die;
    return self::returnMsg(200, 'success', $img);
}

$renderer = new BaconQrCodeRendererImagePng();
$renderer->setHeight(256);
$renderer->setWidth(256);
$writer = new \BaconQrCode\Writer($renderer);
//输出到浏览器
header('content-type: image/png');
echo $writer->writeString('Hello World!');

添加搜索方法、多维数组排序

[

'name' => '试卷标题',
'field' => 'title',
'type' => 'input',
'value' => '',
'factor' => 'like',

],
[

'name' => '答题人手机号',
'field' => 'uid',
'type' => 'guanlian',
'value' => '',
'factor' => 'guanlian',
'guanlian_type' => 'like',
'guanlian_table' => 'member',
'guanlian_field' => 'phone',

],
[

'name' => '时间范围',
'field' => 'create_time',
'type' => 'date_adv',
'value' => '',
'factor' => 'daterand',

],
[

'name' => '状态',
'field' => 'status',
'type' => 'select',
'value' => ['1' => '已读', '0' => '未读'],
'factor' => 'eq',

],

JS数组常用方法

一、数组定义

 数组是引用数据类型的对象数据类型(特殊的对象)。
 创建一个数组,需要开辟一个堆内存,以键值对的形式存储数组内容。
 数组属性名默认是数字。数字从零开始递增,表示当前是第几项,把这个数字称为”索引“。
 **数组是以数字为索引,索引从零开始递增的结构。**
 默认存在一个length属性,代表数组的长度,是可以动态调整的。 
 数组中的每一项可以保存任何类型的数据。
let arr = [
    1,
    '2',
    {
        id:'aaa',
        name:'我的名'
    },
    [4],
    function (){},
    Symbol(1),
    false
];

(1)arr[索引] 获取某一项,或操作它
(2)arr.length-1 数组最后一项
(3)arr[arr.length-1]=true; 修改数组最后一项的值
(4)arr.length=10;增加数组的长度,新增的每一项都会取得undefined值。length不是只读的
(5)arr[arr.length-1]初始化未定义值,默认是undefined
(6)delete arr[arr.length-1] 把数组当做普通对象来操作,键值可以删掉,但是length的长度不会改变
(7)arr.length-- 删除数组最后一项

数组是一个有序的,可以存储任何数据类型值的对象数据类型值。

二、学习重点
1、检查类型

console.log(arr instanceof Array); //=>true
console.log(Array.isArray(arr)); //=>true

instanceof 它假定只有一个全局执行环境
isArray 不管在哪个全局执行环境中创建的数组,都可以检测
2、操作方法要注意以下几点

  a.方法的作用
  b.params 参数(执行方法时传递的值)
  c.return 返回值(执行完成后返回的结果)
  d.执行完原数组是否修改,数组是对象数据类型的值,存储在堆内存中,所以要清楚其是否会变化。

三、常用方法
1、增删改
push 向数组的末尾添加一个或更多元素,并返回新的长度。
语法: array.push(item1, item2, ..., itemX)

arr.push({id:1,name:'sly'});

pop 删除数组的最后一个元素并返回删除的元素。
语法: array.pop()

arr.pop()

unshift 向数组的开头添加一个或更多元素,并返回新的长度。
语法:array.unshift(item1,item2, ..., itemX)

arr.unshift(6,[7,8]);

shift 删除并返回数组的第一个元素
语法: array.shift()

arr.shift()

splice 从数组中添加或删除元素
语法: array.splice(index,howmany,item1,.....,itemX)
howmany参数是选填,整数可为0,作用是从index后删除的个数,如果不填,则从index到最后

arr.splice(3,0,'a','c','e');
arr.splice(2,3,'b','f','h');

2、查询和拼接
slice 选取数组的的一部分,并返回一个新数组
语法:array.slice(start, end) 负数表示从结尾开始算

arr.slice(-3, -1); // 取倒数第二 倒数第三 
arr.slice(4,10); // 从第5个,取到第10个元素

concat 连接两个或更多的数组,并返回结果
语法:array.concat(array2,array3,...,arrayX)

var hege = ["Cecilie", "Lone"];
var stale = ["Emil", "Tobias", "Linus"];
var kai = ["Robin"];
var children = hege.concat(stale,kai); // ["Cecilie", "Lone", "Emil", "Tobias", "Linus", "Robin"]

3、转换为字符串
toString  把数组转换为字符串,并返回结果
语法:array.toString()  数组中的元素之间用逗号分隔
arr.toString();
join  把数组的所有元素放入一个字符串
语法:array.join(separator) 选填separator,用指定分隔符分开,默认为逗号
arr.join('|'); 
4、验证是否包含某一项
indexOf  搜索数组中的元素,并返回它所在的位置,如果没有搜索到则返回 -1
语法:array.indexOf(item,start)
arr.indexOf("Apple",4); // 从第五个元素开始查找 Apple
lastIndexOf 搜索数组中的元素,并返回它最后出现的位置,如果没有搜索到则返回 -1
语法:array.lastIndexOf(item,start)
arr.lastIndexOf('apple', 2);
includes 判断一个数组是否包含一个指定的值,返回布尔值
语法:array.includes(searchElement, fromIndex) fromIndex可选, 
arr.includes('apple');

5、排序
reverse、sort

6、迭代
forEach、map、filter、some、every

7、归并
reduce、reduceRight