Thinkphp使用postgresql新库报错解决

DROP FUNCTION IF EXISTS public.table_msg(varchar) CASCADE;
DROP FUNCTION IF EXISTS public.table_msg(varchar, varchar) CASCADE;
DROP FUNCTION IF EXISTS public.pgsql_type(varchar) CASCADE;
DROP TYPE IF EXISTS public.tablestruct CASCADE;

CREATE OR REPLACE FUNCTION public.pgsql_type(a_type character varying) RETURNS character varying AS
$BODY$
DECLARE
     v_type character varying;
BEGIN
     CASE a_type
         WHEN 'int8' THEN
              v_type := 'bigint';
         WHEN 'int4' THEN
              v_type := 'integer';
         WHEN 'int2' THEN
              v_type := 'smallint';
         WHEN 'bpchar' THEN
              v_type := 'char';
         ELSE
              v_type := a_type;
     END CASE;
     RETURN v_type;
END;
$BODY$
LANGUAGE plpgsql;

-- 2. tablestruct 类型
CREATE TYPE public.tablestruct AS (
  fields_key_name varchar(100),
  fields_name varchar(200),
  fields_type varchar(20),
  fields_length bigint,
  fields_not_null varchar(10),
  fields_default varchar(500),
  fields_comment varchar(1000)
);

-- 3. table_msg 函数(带 schema 参数)
CREATE OR REPLACE FUNCTION public.table_msg(a_schema_name varchar, a_table_name varchar)
RETURNS SETOF public.tablestruct AS
$body$
DECLARE
     v_ret tablestruct;
     v_oid oid;
     v_sql varchar;
     v_rec record;
     v_key varchar;
BEGIN
     -- 获取表 oid
     SELECT c.oid INTO v_oid
     FROM pg_class c
     INNER JOIN pg_namespace n ON c.relnamespace = n.oid AND lower(n.nspname) = lower(a_schema_name)
     WHERE c.relname = a_table_name;

     IF NOT FOUND THEN
         RETURN;
     END IF;

     -- 构造动态查询
     v_sql := '
     SELECT
           a.attname AS fields_name,
           a.attnum AS fields_index,
           pgsql_type(t.typname::varchar) AS fields_type,
           a.atttypmod - 4 AS fields_length,
           CASE WHEN a.attnotnull THEN ''not null'' ELSE '''' END AS fields_not_null,
           pg_get_expr(ad.adbin, ad.adrelid) AS fields_default,
           d.description AS fields_comment
     FROM pg_attribute a
     INNER JOIN pg_class c ON a.attrelid = c.oid
     INNER JOIN pg_type t ON a.atttypid = t.oid
     LEFT JOIN pg_attrdef ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
     LEFT JOIN pg_description d ON d.objoid = c.oid AND d.objsubid = a.attnum
     WHERE a.attnum > 0 AND a.attisdropped = false AND c.oid = ' || v_oid || '
     ORDER BY a.attnum;
     ';

     -- 遍历字段
     FOR v_rec IN EXECUTE v_sql LOOP
         v_ret.fields_name := v_rec.fields_name;
         v_ret.fields_type := v_rec.fields_type;
         IF v_rec.fields_length > 0 THEN
             v_ret.fields_length := v_rec.fields_length;
         ELSE
             v_ret.fields_length := NULL;
         END IF;
         v_ret.fields_not_null := v_rec.fields_not_null;
         v_ret.fields_default := v_rec.fields_default;
         v_ret.fields_comment := v_rec.fields_comment;

         SELECT constraint_name INTO v_key
         FROM information_schema.key_column_usage
         WHERE table_schema = a_schema_name
           AND table_name = a_table_name
           AND column_name = v_rec.fields_name;

         IF FOUND THEN
             v_ret.fields_key_name := v_key;
         ELSE
             v_ret.fields_key_name := '';
         END IF;

         RETURN NEXT v_ret;
     END LOOP;

     RETURN;
END;
$body$
LANGUAGE plpgsql VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION public.table_msg(a_schema_name varchar, a_table_name varchar) IS '获得表信息';

-- 4. table_msg 函数(简化版,只传 table_name)
CREATE OR REPLACE FUNCTION public.table_msg(a_table_name varchar)
RETURNS SETOF public.tablestruct AS
$body$
DECLARE
    v_ret tablestruct;
BEGIN
    FOR v_ret IN SELECT * FROM public.table_msg('public', a_table_name) LOOP
        RETURN NEXT v_ret;
    END LOOP;
    RETURN;
END;
$body$
LANGUAGE plpgsql VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION public.table_msg(a_table_name varchar) IS '获得表信息';

rhel系更新启动内核

dracut --force #强制更新initramfs
#dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
#grubby --set-default /boot/vmlinuz-5.19.0-ml.x86_64   #设置指定内核
grubby --set-default 0         #设置启动第一个内核
grubby --default-kernel       #查看启动内核

初学golang之用beego快速创建项目

现安装golang https://go.dev/dl/

go install github.com/beego/bee/v2@latest
export PATH=$PATH:$(go env GOPATH)/bin
bee new app
cd app
go mod tidy
bee run

苹果giftcard礼品卡链接备忘录

https://www.apple.com/shop/buy-giftcard/giftcard

关闭windows账户锁定策略

在 Windows 系统中,账户锁定策略(Account Lockout Policy) 用于在多次登录失败后锁定账户,以防止暴力破解。但在远程桌面(RDP)、自动化运维或测试环境中,这一机制可能导致正常账号被频繁锁定。

net accounts /lockoutthreshold:0

 

验证方式

net accounts

输出中显示:Lockout threshold: Never

几个常用的openresty配置文件

 location /testz {
default_type text/plain;

echo request_uri "$request_uri";
echo Server addr "$server_addr";
echo remote_addr "$remote_addr";
echo http_x_http_forwarded_for "$http_x_http_forwarded_for";
echo proxy_add_x_forwarded_for "$proxy_add_x_forwarded_for";
echo http_x_forwarded_for "$http_x_forwarded_for";
echo http_accept_language "$http_accept_language";
echo http_user_agent "$http_user_agent";
echo content_length "$content_length";
echo content_type "$content_type";
echo document_root "$document_root";
echo document_uri "$document_uri";
echo limit_rate "$limit_rate";
echo request_method "$request_method";
echo remote_port "$remote_port";
echo remote_user "$remote_user";
echo request_filename "$request_filename";
echo request_uri "$request_uri";
echo query_string "$query_string";
echo args "$args";
echo scheme "$scheme";
echo server_protocol "$server_protocol";
#echo server_addr "$server_addr";
echo server_name "$server_name";
echo server_port "$server_port";
echo URI "$uri";
echo http_referer $http_referer;
echo request $request;
echo connection $connection;
echo remote_user $remote_user;
echo request_time $request_time;
echo hostname $hostname;
echo realpath_root $realpath_root;
echo proxy_protocol_addr $proxy_protocol_addr;
echo http_via $http_via;
echo http_host $http_host;
echo time_local $time_local;
#echo SESSION $session;
echo http_cookie $http_cookie;


    echo "man man lai 2";
#echo $http_cookie ;
#echo $user_cookie;
#echo $cookie_PHPSESSID;
#echo $http_host;

set_sha1 $hash_ip $remote_addr;
echo hash_ip $hash_ip;

echo connection $connection;
echo connection_requests $connection_requests;
echo connections_active $connections_active;
echo connections_reading $connections_reading;
echo connections_waiting $connections_waiting;
echo connections_writing $connections_writing;
if ( $http_cookie = '') {echo "You cookie is null";}

#if {$connection_requests >= '100') {echo yes;}


set $testvar 233;

rewrite_by_lua 'ngx.var.testvar = 123';


echo $testvar;
}
 cat    googleapis.conf
sub_filter_once off;
sub_filter_types text/css text/xml text/javascript;
sub_filter "https://fonts.googleapis.com" "/assets/vendor/googleapis";
sub_filter "//fonts.googleapis.com" "/assets/vendor/googleapis";
sub_filter "https://ajax.googleapis.com" "/assets/vendor/ajax";
sub_filter "https://fonts.gstatic.com" "/assets/vendor/fonts_gstatic";

#sub_filter "https://www.google.com/jsapi" "/assets/vendor/gstatic/charts/loader.js";
proxy_hide_header Link;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;

location ~ /assets/vendor/googleapis/ {
  proxy_set_header Accept-Encoding "";
  rewrite ^/assets/vendor/googleapis/(.+)$ /$1 break;
  proxy_pass https://fonts.googleapis.com;
  proxy_set_header Host "fonts.googleapis.com";
  proxy_set_header User-Agent $http_user_agent;
  expires 1d;
  sub_filter "https://fonts.gstatic.com" "/assets/vendor/fonts_gstatic";
}

location ~ /assets/vendor/fonts_gstatic/ {
  rewrite ^/assets/vendor/fonts_gstatic/(.+)$ /$1 break;
  proxy_pass https://fonts.gstatic.com;
  proxy_set_header Host "fonts.gstatic.com";
  proxy_set_header User-Agent $http_user_agent;
  expires 1y;

}

location ~ /assets/vendor/gstatic/ {
  rewrite ^/assets/vendor/gstatic/(.+)$ /$1 break;
  proxy_pass https://www.gstatic.com;
  proxy_set_header Host "www.gstatic.com";
  expires 1y;
}

location ~ /assets/vendor/ajax/ {
  rewrite ^/assets/vendor/ajax/(.+)$ /$1 break;
  proxy_pass https://gajax.googleapis.com;
  proxy_set_header Host ajax.googleapis.com;
  expires 1y;
}
cat  gstatic.conf
sub_filter_once off;
sub_filter_types  text/css;

sub_filter https://fonts.gstatic.com/ /gstatic/;
sub_filter https://fonts.googleapis.com/ /googleapis/;
sub_filter http://fonts.gstatic.com/ /gstatic/;
sub_filter http://fonts.googleapis.com/ /googleapis/;
sub_filter //fonts.gstatic.com/ /gstatic/;
sub_filter //fonts.googleapis.com/ /googleapis/;

#proxy_bind $remote_addr transparent;
proxy_hide_header Link;


location /gstatic/ {
resolver 8.8.8.8;
    proxy_set_header Host fonts.gstatic.com;
    proxy_pass http://fonts.gstatic.com/;
}

location /googleapis/ {
resolver 8.8.8.8;
   proxy_set_header Host fonts.googleapis.com;
   proxy_pass http://fonts.googleapis.com/;
}
cat   error.conf
        error_page 404  @404page;
        error_page 502 503 504  @502page;
        location @502page {
                default_type text/plain;
                echo "Backend server time out";
                }
        location @404page {
                default_type text/plain;
                echo "Not Found";
                }
cat cc.conf
set $hash_ip HASHKEY2015$remote_addr;
set_sha1 $hash_var $hash_ip;
    if ($cookie_cfcuid != "$hash_var"){
        add_header Set-Cookie "cfcuid=$hash_var";
        rewrite .* "https://$http_host$uri" redirect;
      }

nginx动态编译njs

看网上没啥人玩,记录一下。

踩了2个坑,一是需要xslt,二是pcre2, 主要看之前编译nginx用的那个pcre版本

大致流程

apt install libxml2-dev libxslt1-dev git curl  libpcre2-dev
wget http://nginx.org/download/nginx-1.28.0.tar.gz
tar zxf nginx-1.28.0.tar.gz
cd nginx-1.28.0
git clone https://github.com/nginx/njs
./configure --with-compat --add-dynamic-module=./njs/nginx  
make modules
cp objs/ngx_http_js_module.so /usr/lib/nginx/modules/ngx_http_js_module.so
echo "load_module modules/ngx_http_js_module.so;" >  /etc/nginx/modules-enabled/50-mod-njs.conf
nginx -t

确定pcre版本

 ldd /usr/sbin/nginx | grep pcre

 

njs确定加载后在http字段引入

http {
js_import my_ua.js;
}

location再调用写好的js内容就可以玩耍了

    location / {
        js_content my_ua.checkRequest;
    }

直接官方仓库安装的就更简单了。

code-server初始化配置

官方项目地址:https://github.com/coder/code-server

现成编译安装包:https://github.com/coder/code-server/releases

docker/podman镜像https://github.com/coder/code-server/pkgs/container/code-server

docker hub地址 https://hub.docker.com/r/codercom/code-server

容器部署方式

podman run -d \
  --restart=always \
  --name=code-server \
  -p 8080:8080 \
  -v /opt/:/opt \
  -e PASSWORD="密码" \
  --user 0:0 \
  -e "DOCKER_USER=$USER" \
  ghcr.io/coder/code-server:4.106.3-39

Docker Hub

docker.io/codercom/code-server:latest

快速初始化code-server

podman exec -it code-server /bin/bash   #进入容器后运行初始化脚本
code-server --install-extension ms-ceintl.vscode-language-pack-zh-hans
code-server --install-extension lkrms.pretty-php
echo '{"locale":"zh-cn"}' > ~/.local/share/code-server/User/argv.json

Nginx反向代理配置

        location / {
            proxy_pass http://localhost:8080/;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Accept-Encoding gzip;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

 

中间配置nginx的时候出现websockt中断,好像是Accept-Encoding的问题, 折腾了几次后又正常了。

配置好后把root目录拷贝一份,做文件夹映射应该可以下次直接使用。

CloudPanel定时任务文件丢失恢复

不知道什么原因定时任务文件没了, 导致ssl没a自动续期,手动恢复下。

cat>/etc/cron.d/clp<<EOF
MAILTO=""
5 0 * * * clp /usr/bin/sudo /etc/init.d/rsyslog restart &> /dev/null
15 2 * * * clp /usr/bin/sudo /usr/bin/systemctl restart clp-agent &> /dev/null
10 3 * * * clp /usr/bin/bash -c "/usr/bin/clpctl monitoring:data:clean" &> /dev/null
15 3 * * * clp /usr/bin/bash -c "/usr/bin/clpctl db:backup --ignoreDatabases='db1,db2' --retentionPeriod=7" &> /dev/null
15 4 * * * clp /home/clp/scripts/create_backup.sh &> /dev/null
10 5 * * * clp /usr/bin/bash -c "/usr/bin/clpctl lets-encrypt:renew:custom-domain:certificate" &> /dev/null
15 5 * * * clp /usr/bin/bash -c "/usr/bin/clpctl lets-encrypt:renew:certificates" &> /dev/null
15 6 * * * clp /usr/bin/bash -c "/usr/bin/clpctl vhost-templates:import --delay=true" &> /dev/null
20 6 * * * clp /usr/bin/bash -c "/usr/bin/clpctl cloudflare:update:ips --delay=true" &> /dev/null
25 6 * * * clp /usr/bin/bash -c "/usr/bin/clpctl app:clean-up:sessions" &> /dev/null
0 */8 * * * clp /usr/bin/bash -c "/usr/bin/clpctl announcement:check" &> /dev/null
EOF

 

windows更改3389端口

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d 12345 /f
netsh advfirewall firewall add rule name="RDP Custom Port" dir=in action=allow protocol=TCP localport=12345

某宝上账号带有“工控” “自动化”的店最好别碰

共同特征是卖服务器配件网络设备等东西

价格标得非常低吸引流量,进去就是议价,甚至自己都没有货。。。。

Mysql FULLTEXT 索引

ALTER TABLE `sqltable` ADD FULLTEXT `name` (`name`), ADD FULLTEXT `full_tag` (`tag`);
ALTER TABLE `sqltable` ADD FULLTEXT(name, tag);

 

Thinkphp8查询写法

class Blog extends Model
{
    public static function matchSearch($keyword,$field)
    {
        return  self::whereRaw("MATCH($field) AGAINST(? IN NATURAL LANGUAGE MODE)", [$keyword])->select();
    }
}
// 调用
$data = Blog:matchSearch('小明','name');

 

对比redis-search插件方式,SQL可以额外免维护方式比较方便。

redis-server8.4编译安装

debian源的版本比较老,而且redis-redisearch更老。

安装新版本ReJSON和RediSearch啥都有, 就是启动服务的时候官方service加载search就会卡住。

cd /tmp
VER=$(curl -Ss   https://api.github.com/repos/redis/redis/releases/latest|grep tag_name|grep -Po '[0-9]+\.[0-9]+\.[0-9]+.*(?=")')
wget https://github.com/redis/redis/archive/refs/tags/${VER}.tar.gz  -O - | tar xz
cd redis-${VER}
export BUILD_TLS=yes
export BUILD_WITH_MODULES=yes
export INSTALL_RUST_TOOLCHAIN=yes
export DISABLE_WERRORS=yes
make -j "$(nproc)" all
make install
ln -s /usr/local/bin/redis-server  /usr/bin/

cat>>/etc/redis/redis.conf<<EOF
loadmodule /usr/local/lib/redis/modules/redisbloom.so
loadmodule /usr/local/lib/redis/modules/redisearch.so
loadmodule /usr/local/lib/redis/modules/rejson.so
loadmodule /usr/local/lib/redis/modules/redistimeseries.so
EOF

cat>/etc/systemd/system/redis.service<<EOF
[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
Type=simple
User=root
Group=root
LimitNOFILE=10032
TimeoutStartSec=300
TimeoutStopSec=60

[Install]
WantedBy=multi-user.target
EOF

systemctl enable redis --now

 

/usr/local/bin/    #二进制目录
/etc/redis/redis.conf  #配置文件目录

 

# Modules
module:name=search,ver=80402,api=1,filters=0,usedby=[],using=[ReJSON],options=[handle-io-errors]
module:name=vectorset,ver=1,api=1,filters=0,usedby=[],using=[],options=[handle-io-errors|handle-repl-async-load]
module:name=ReJSON,ver=80400,api=1,filters=0,usedby=[search],using=[],options=[handle-io-errors]
module:name=bf,ver=80400,api=1,filters=0,usedby=[],using=[],options=[handle-io-errors]
module:name=timeseries,ver=80400,api=1,filters=0,usedby=[],using=[],options=[handle-io-errors]

 

官方安装文档地址:

https://redis.io/docs/latest/operate/oss_and_stack/install/build-stack/almalinux-rocky-9/
https://redis.io/docs/latest/operate/oss_and_stack/install/build-stack/debian-bookworm/
https://redis.io/docs/latest/operate/oss_and_stack/install/build-stack/ubuntu-noble/

vscode 配置备忘录

VScode扩展插件安装pretty-php

apt install php-cli php-mbstring -y  
apt install tilix -y
#macos配置文件路径
/Users/用户名Library/Application\ Support/Code/User/settings.json

#Linux配置文件目录
/home/用户名/.config/Code/User/settings.json
{
    "workbench.colorTheme": "Default Light Modern",
    "editor.accessibilitySupport": "off",
    "editor.formatOnType": true,
    // ==== PHP ====
    "[php]": {
        "editor.defaultFormatter": "lkrms.pretty-php",
        "editor.formatOnSave": true
    },

    // ==== HTML ====
    "[html]": {
        "editor.defaultFormatter": "vscode.html-language-features",
        "editor.formatOnSave": true
    },
    // ==== TPL / 模板 ====
    "files.associations": {
        "*.tpl": "html",
        "*.tpl.php": "html"
    },
    "html.format.indentInnerHtml": true,
    "html.format.wrapLineLength": 600,
    "html.format.templating": true,
    "html.format.contentUnformatted": "script,style,pre,code,template,meta",

    // ==== 编辑器外观 ====
    "editor.fontFamily": "Menlo, Monaco, 'Courier New', JetBrains Mono, monospace",
    "editor.fontSize": 14,
    "continue.showInlineTip": false,
    "editor.tokenColorCustomizations": {},
    "editor.defaultFormatter": "lkrms.pretty-php",
    "editor.formatOnPaste": true,
    "css.format.braceStyle": "expand",
    "amazonQ.allowFeatureDevelopmentToRunCodeAndTests": {
        
    }
}

RediSearch和RedisJSON安装

sudo apt update
sudo apt install -y \
    build-essential \
    cmake \
    g++ \
    git \
    libssl-dev \
    libboost-all-dev \
    libjemalloc-dev \
    pkg-config
sudo apt install build-essential llvm cmake libclang1 libclang-dev cargo
git clone --recursive https://github.com/RediSearch/RediSearch.git
cd RediSearch
sudo make setup
make build
git clone https://github.com/RedisJSON/RedisJSON.git
cd RedisJSON
make

 

编译太麻烦了从docker镜像直接拉现成的

podman pull docker.io/redislabs/redisearch:latest
podman run -d   --name redisearch   -p 6379:6379  docker.io/redislabs/redisearch:latest