时空云博客 - php
type: channel
link: https://blog.skyw.cc/category/php.html
items: thinkphp8多应用缩短路由
items: 解决智简魔方虚拟主机&cdn自动开通失败
items: php操作redis大全
items: 宝塔网站异常自动化处理
items: \r,\n与\r\n区别
items: 智简魔方自动开通bug解决
items: 记录php防跨站
items: php给某文件夹下图片按照数字升序重命名
items: 谷歌api+Redis缓存实现php获取网站favicon图标api
items: php base64解码出现乱码

thinkphp8多应用缩短路由
type: item
date: 2023-08-03T11:26:44+08:00
description: 假设Index应用的index.php控制器如下<?php namespace app\index\controller; use app\index\BaseController; use think\facade\View; use think\facade\Db; //数据库 class Index extends BaseController { public function index($page = 1) { // 设置导航选择 $nav = ["index"=>1]; View::assign("nav", $nav); // 设置当前页数和分类ID View::assign("curr", $page); View::assign('cid', 0); // 从数据库读取配置项 $config = Db::name('config')->field('k, v')->select(); // 将配置项赋值给视图模板 foreach ($config as $item) { View::assign($item['k'], $item['v']); if ($item['k'] == "title") { View::assign('title', $item['v'] . '-首页'); } } // 获取文章分类列表 $class = Db::name("article_class")->where('parent_id', 0)->order('order')->select(); $class = $class->toArray(); // 处理分类数据 foreach ($class as $k => $v) { $item = $v; foreach ($item as $key => $value) { $item[$key] = $value ?? ''; } $item["children"] = Db::name("article_class")->where('parent_id', $item['id'])->order('order')->select()->toArray(); $class[$k] = $item; } // 将分类数据赋值给视图模板 View::assign('class', $class); // 获取文章总条数 $count = Db::name("article")->count(); View::assign('count', $count); // 获取分页后的文章列表 $article = Db::name("article")->order('order')->page($page, 10)->select(); array_walk($article, function (&$vo) { foreach ($vo as $key => $value) { $vo[$key] = $value ?? ''; } }); // 将文章列表赋值给视图模板 View::assign('article', $article); // 渲染视图模板并返回 return View::fetch(); } public function class($name, $page = 1) { // 设置当前页数 View::assign("curr", $page); // 获取这个名字的class信息 $crow = Db::name('article_class')->where('seo_name', $name)->find(); if (!$crow) { return 404; } View::assign('curClass', $crow); $cid = $crow['id']; $cname = $crow['name']; $pid = $crow['parent_id']; // 设置导航选择 if ($pid!=0) { $pname = Db::name("article_class")->where('id', $crow['parent_id'])->column("seo_name")[0]; $nav = [$pname=>1]; } else { $nav = [$crow['seo_name']=>1]; } View::assign("nav", $nav); // 从数据库读取配置项 $config = Db::name('config')->field('k, v')->select(); // 将配置项赋值给视图模板 foreach ($config as $item) { View::assign($item['k']…

解决智简魔方虚拟主机&cdn自动开通失败
type: item
date: 2023-05-26T21:32:03+08:00
description: 今天发现互联无法正常开通cdn和虚拟主机，抓包发现是cdn可能拦截或者超时导致url/后台/async_curl_multi返回了超时499解决方案：源站服务器指定host互联域名到127.0.0.1

php操作redis大全
type: item
date: 2022-10-07T16:44:22+08:00
description: setex 带生存时间的写入值 $redis->setex('key', 3600, 'value'); setnx 判断是否重复的，写入值,如存在了不修改返回0,不存在就添加返回1 $redis->setnx('key', 'value'); 返回已经删除key $redis->delete('key1'); 成功返回1失败返回0 $redis->delete('key1','key2'); 删除两个键成功返回1失败返回0 查询生存时间 $redis->ttl('key1'); 持久化的返回-1，有生存时间的返回时间（单位秒） 同时给多个key赋值,同时设置key0和key1 $redis->mset(array('key0' => 'value0', 'key1' => 'value1')); key中的值进行自增1，如果填写了第二个参数，者自增第二个参数所填的值 $redis->incr('key1'); $redis->incrBy('key1', 10); 减法跟加法一样 $redis->decr("key1"); 减少1 $redis->decrBy("key1",5) 减少5 list相关操作，连表操作 lPush $redis->lPush("list", "888"); $id = $redis->lpush('list','HHHHHHH');echo $id;返回链表的元素个数 $redi->lrange('list',0,-1); 返回全部数据，数组形式 $redis->lrange('list',0,2); 返回连表0-2坐标的三个元素 lPushx/rPushx $redis->lPushx(key, value); 在名称为key的list左边(头)/右边（尾）添加一个值为value的元素,如果value已经存在，则不添加 $redis->lpop('list');输出链表最左边的ksy的值，输出后删除掉这个key $redis->rpop('list');输出链表最右边的ksy的值，输出后删除掉这个key $redis->lset('list',7,"update"); 修改坐标为7的值,成功返回1 集合：sadd，sadd是无序的集合,每次插入集合的时候都可能会弄乱里面集合的排序 sadd s1 zhangsan sadd s1 lisi sadd s1 wangwu sadd t1 yangxingyi sadd t1 lilei sadd t1 zhangsan smembers s1 s1的所有集合内容 sdiff s1 t1 s1有的，t1没有的,差集 $redis->sinter('s1','t1');返回s1和t1两个集合都有的,数组形式 scard s1 返回s1集合里面的个数，有多少个就返回多少个,没有从0开始的,坐标才从0开始的 spop抽奖场景，返回集合里面随机的数 spop s1 默认返回1个,返回后就删除这个数，中奖了就不能再中了 $i = $redis->spop('s1');var_dump($i); 返回一个数,返回后删除这个数 $i = $redis->spop('s1',2);var_dump($i);不能返回两个的,提示错误的 随机返回集合里面的一个元素，但不删除，重复中奖 $i = $redis->srandmember('s1');echo $i; sismember s1 zhangsan 查询张三在不在集合里面,在1，不在false $i = $redis->sismember('s1','zhangsan2');echo $i;在1，不在false zadd key 2 value 有序集合 zadd y1 1 zhangsan; zadd y1 3 lisi; zadd y1 2 wangwu; zrange y1 0 -1; 排序就是,根据插入的时候的排序从小到达zhangsan,wangwu,lisi $i = $redis->zrange('y1',0,-1);var_dump($i); 返回数组，键值不是插入时候给的键，是从0开始的新键 zrevrange y1 0 -1； 反转排序，插入的时候键值越高，排序越优先 zcard y1 ；获取有序集合里面的个数，有多少个就返回多少个,没有从0开始的,坐标才从0开始的 无序就scard,有序就zcard，有z没有s sInterStore 求交集并将交集保存到output的集合 $redis->sInterStore('output', 'key1', 'key2', 'key3') Hash操作 hSet $redis->hSet('h', 'key1', 'hello'); 向名称为h的h…

宝塔网站异常自动化处理
type: item
date: 2022-08-21T10:21:00+08:00
description: 因为我昨天网站疑似碰到宝塔2点半ssl证书死循环bug导致服务器卡死，今天使用这篇文章监控php并做了个记录支持检测php，nginx，mysql，redisphp：<?php $act = $_REQUEST['act']; if ($act == "site") { //检测网站 echo "ok"; } elseif ($act == "mysql") { //检测数据库 $link = mysqli_connect('localhost', '账号', '密码'); if (!$link) { die('Could not connect to MySQL: ' . mysqli_error()); } else { echo 'ok'; mysqli_close($link); } } elseif ($act == "redis") { //检测数据库 $redis = new Redis(); if (!$redis->connect('127.0.0.1', 6379, 5)) { die('Could not connect to Redis'); } else { echo 'ok'; } }bash脚本：site=`curl -s http://地址/check_bt.php?act=site`; if $site == 'ok' ;then echo 'php is ok' else service php-fpm-56 restart /etc/init.d/nginx start fi mysql=`curl -s http://地址/check_bt.php?act=mysql`; if $mysql == 'ok' ;then echo 'mysql is ok' else /etc/init.d/mysqld start fi redis=`curl -s http://地址/check_bt.php?act=redis`; if $redis == 'ok' ;then echo 'redis is ok' else /etc/init.d/redis stop /etc/init.d/redis start fi食用说明：1、将PHP放到你的网站，修改mysqluser和mysqlpasswd分别为你网站的数据库账户和密码；2、将bash放到你的宝塔计划任务，3分钟执行一次，修改里面的https://vience.dift.cn/isok.php为你的PHP地址；本文基于以下文章修改原文地址：宝塔网站异常自动化处理 - KEKC博客-KEKC博客

\r,\n与\r\n区别
type: item
date: 2022-07-17T22:48:25+08:00
description: 写程序api时遇到的问题记录一下用户可以设置白名单ip，换行一个ip结果explode('\n',$ips)后检查ip in_array失败在我尝试json_encode后发现打散的数组元素含有\r，解决方法：打散前删除\r即可百度得到解释\n是换行，英文是New line\r是回车，英文是Carriage return机械打字机有回车和换行两个键作用分别是:换行就是把滚筒卷一格，不改变水平位置。回车就是把水平位置复位，不卷动滚筒。Enter = 回车+换行(\r\n) 注:\r\n连用时,不能调换顺序关于“回车”（carriage return）和“换行”（line feed）这两个概念的来历和区别。在计算机还没有出现之前，有一种叫做电传打字机（Teletype Model 33）的玩意，每秒钟可以打10个字符。但是它有一个问题，就是打完一行换行的时候，要用去0.2秒，正好可以打两个字符。要是在这0.2秒里面，又有新的字符传过来，那么这个字符将丢失。于是，研制人员想了个办法解决这个问题，就是在每行后面加两个表示结束的字符。一个叫做“回车”，告诉打字机把打印头定位在左边界；另一个叫做“换行”，告诉打字机把纸向下移一行。这就是“换行”和“回车”的来历，从它们的英语名字上也可以看出一二。后来，计算机发明了，这两个概念也就被般到了计算机上。那时，存储器很贵，一些科学家认为在每行结尾加两个字符太浪费了，加一个就可以。于是，就出现了分歧。Unix系统里，每行结尾只有“<换行>”，即“\n”；Windows系统里面，每行结尾是“<换行><回车>”，即“\n\r”；Mac系统里，每行结尾是“<回车>”。一个直接后果是，Unix/Mac系统下的文件在Windows里打开的话，所有文字会变成一行；而Windows里的文件在Unix/Mac下打开的话，在每行的结尾可能会多出一个^M符号。

智简魔方自动开通bug解决
type: item
date: 2022-07-07T17:41:00+08:00
description: 今天我发现我免费主机配置自动开通后仍然需要手动开通首先我想到可能我网上下载的ep对接插件有问题？然后我去官网买了份还是不能自动开通我甚至解密了插件改了部分逻辑仍然不行。。最终搜索发现去年论坛有人说是ssl问题，关闭ssl即可我关闭ssl发现真可以了。。发现是宝塔Let's Encrypt的证书不行的锅换用腾讯云免费证书成功

记录php防跨站
type: item
date: 2022-06-20T22:14:54+08:00
description: 最近安装一款websocket的客服系统时，使用了以下php.ini[PHP] ;;;;;;;;;;;;;;;;;;; ; About php.ini ; ;;;;;;;;;;;;;;;;;;; ; PHP's initialization file, generally called php.ini, is responsible for ; configuring many of the aspects of PHP's behavior. ; PHP attempts to find and load this configuration from a number of locations. ; The following is a summary of its search order: ; 1. SAPI module specific location. ; 2. The PHPRC environment variable. (As of PHP 5.2.0) ; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) ; 4. Current working directory (except CLI) ; 5. The web server's directory (for SAPI modules), or directory of PHP ; (otherwise in Windows) ; 6. The directory from the --with-config-file-path compile time option, or the ; Windows directory (C:\windows or C:\winnt) ; See the PHP docs for more specific information. ; http://php.net/configuration.file ; The syntax of the file is extremely simple. Whitespace and lines ; beginning with a semicolon are silently ignored (as you probably guessed). ; Section headers (e.g. [Foo]) are also silently ignored, even though ; they might mean something in the future. ; Directives following the section heading [PATH=/www/mysite] only ; apply to PHP files in the /www/mysite directory. Directives ; following the section heading [HOST=www.example.com] only apply to ; PHP files served from www.example.com. Directives set in these ; special sections cannot be overridden by user-defined INI files or ; at runtime. Currently, [PATH=] and [HOST=] sections only work under ; CGI/FastCGI. ; http://php.net/ini.sections ; Directives are specified using the following syntax: ; directive = value ; Directive names are *case sensitive* - foo=bar is different from FOO=bar. ; Directives are variables used to configure PHP or PHP extensions. ; There is no name validation. If PHP can't find an expected ; directive because it is not set or is mistyped, a default value will be used. ; The value can be a string, a number, a PHP constant (e.g. E_ALL or…

php给某文件夹下图片按照数字升序重命名
type: item
date: 2022-05-28T22:07:44+08:00
description: <?php $format = 'jpg'; $path = './'; $files = getfile($path, $format); $i = 1; foreach ($files as $v) { $tv = basename($v); list($name, $ext) = explode('.', $tv); $newname = $path . $i . '.' . $ext; if (rename($v, $newname)) { echo '成功将' . $v . '重命名' . $newname . ''; } $i++; } function getfile($path, $format) { $dirs = array(); foreach (glob("$path*") as $d) { $tmp = explode('.', $d); $k = end($tmp); if (is_file($d) && ($k == strtolower($format))) { $dirs[] = $d; } } return $dirs; }

谷歌api+Redis缓存实现php获取网站favicon图标api
type: item
date: 2022-02-06T19:29:00+08:00
description: 前言：我自己的导航站懒得添加站点时一个一个去复制粘贴他们的图标地址，网上找的接口和代码不是很好用，于是有了这个作品本代码需要有redis才可使用，需要搭建在海外服务器上（因为调用的谷歌api）使用方法：api.php?url=对方网页地址fav_function.php<?php $redis = new Redis(); if (!$redis->connect('127.0.0.1', 6379, 5)) die('Redis无法链接，请联系上级重启Redis'); $redis->select(1); //选择数据库 function redis_search($key) { global $redis; $json = $redis->get($key); if ($json == '') { return false; } elseif ($array = json_decode($json, true)) { return $array; } else { return $json; } } function redis_save($key, $data, $limit = 600) { global $redis; $json = is_array($data) ? json_encode($data) : $data; $redis->setex($key, $limit, $json); } function redis_del($key) { global $redis; $redis->del($key); } function pr($a) { print_r($a); die; } function restoreUrl($shortUrl) { //pr($shortUrl); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $shortUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0'); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_NOBODY, false); curl_setopt($curl, CURLOPT_TIMEOUT, 15); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); $data = curl_exec($curl); $curlInfo = curl_getinfo($curl); curl_close($curl); if ($curlInfo['http_code'] == 301 || $curlInfo['http_code'] == 302) { return $curlInfo['redirect_url']; } return $shortUrl; } function geticon($domain) { $key = 'icon:'.$domain; if ($data = redis_search($key)) return $data; $url = 'https://www.google.com/s2/favicons?domain='.$domain; $data = curl_get(restoreUrl($url)); redis_save($key, $data, 6000); echo $data; } function curl_get($url) { $ch = curl_init($url); $httpheader[] = "Accept: */*"; $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8"; $httpheader[] = "Connection: close"; curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch,…

php base64解码出现乱码
type: item
date: 2022-01-28T21:54:00+08:00
description: 今天帮小龙改写订单导出时，我写的ajax先输出base64，再由js提交ajax到php文件让php解码base64输出下载文件，结果输出的base64我网上解密正常，服务端解码乱码。于是一番百度发现是$_GET传输时+被替换成空格造成的，改回来即可$str = base64_decode(str_replace(" ","+",$_GET['str']));