<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>枫の屋</title><description>迷途的港湾</description><link>https://6wd.cn/</link><language>zh_CN</language><item><title>CentOS 7 内核升级脚本 (kernel-lt-5.4)</title><link>https://6wd.cn/posts/centos7-kernel-lt-5-4-upgrade/</link><guid isPermaLink="true">https://6wd.cn/posts/centos7-kernel-lt-5-4-upgrade/</guid><description>set -eo pipefail</description><pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;脚本内容，均无加密可放心使用，如果不想看可以拉到最后看使用脚本&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# =====================================================
# CentOS 7 内核一键安装脚本 - 源修复版
# 版本: 3.0
# 描述: 修复CentOS 7源问题，直接从网络下载并安装kernel-lt-5.4.278
# =====================================================

# 设置严格模式（兼容老旧系统）
set -eo pipefail
set +u  # 避免未定义变量报错

# 颜色定义
RED=&apos;\033[0;31m&apos;
GREEN=&apos;\033[0;32m&apos;
YELLOW=&apos;\033[1;33m&apos;
BLUE=&apos;\033[0;34m&apos;
PURPLE=&apos;\033[0;35m&apos;
CYAN=&apos;\033[0;36m&apos;
WHITE=&apos;\033[1;37m&apos;
NC=&apos;\033[0m&apos;

# 配置常量
readonly KERNEL_VERSION=&quot;5.4.278-1.el7.elrepo.x86_64&quot;
readonly KERNEL_PACKAGE=&quot;kernel-lt-${KERNEL_VERSION}.rpm&quot;
readonly DOWNLOAD_URL=&quot;http://linux.6wd.cn/${KERNEL_PACKAGE}&quot;
readonly LOG_FILE=&quot;/var/log/kernel-install-$(date +%Y%m%d-%H%M%S).log&quot;
readonly BACKUP_DIR=&quot;/root/kernel-backup-$(date +%Y%m%d-%H%M%S)&quot;

# 错误退出函数
error_exit() {
    echo -e &quot;\n${RED}╔════════════════════════════════════════════════════════════════╗${NC}&quot;
    echo -e &quot;${RED}║                         ❌ 安装失败 ❌                          ║${NC}&quot;
    echo -e &quot;${RED}╠════════════════════════════════════════════════════════════════╣${NC}&quot;
    echo -e &quot;${RED}║${WHITE} 错误: $1${NC}&quot;
    echo -e &quot;${RED}║${WHITE} 日志: $LOG_FILE${NC}&quot;
    echo -e &quot;${RED}╚════════════════════════════════════════════════════════════════╝${NC}&quot;
    exit 1
}

# 清理函数
cleanup() {
    if [[ -f &quot;$KERNEL_PACKAGE&quot; ]]; then
        rm -f &quot;$KERNEL_PACKAGE&quot; 2&amp;gt;/dev/null
        echo -e &quot;${BLUE}[清理] 已删除临时文件: $KERNEL_PACKAGE${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    fi
}

# 设置陷阱
trap cleanup EXIT
trap &apos;echo -e &quot;\n${RED}[中断] 脚本被用户终止${NC}&quot; | tee -a &quot;$LOG_FILE&quot;; exit 130&apos; INT TERM

# 打印横幅
print_banner() {
    clear 2&amp;gt;/dev/null || true
    echo -e &quot;${PURPLE}╔════════════════════════════════════════════════════════════════╗${NC}&quot;
    echo -e &quot;${PURPLE}║${WHITE}${BOLD}          CentOS 7 内核一键安装脚本 (源修复版)            ${PURPLE}║${NC}&quot;
    echo -e &quot;${PURPLE}╠════════════════════════════════════════════════════════════════╣${NC}&quot;
    printf &quot;${PURPLE}║${WHITE} 目标内核: ${GREEN}%-45s${PURPLE}║${NC}\n&quot; &quot;$KERNEL_VERSION&quot;
    printf &quot;${PURPLE}║${WHITE} 日志文件: ${BLUE}%-45s${PURPLE}║${NC}\n&quot; &quot;$LOG_FILE&quot;
    echo -e &quot;${PURPLE}╚════════════════════════════════════════════════════════════════╝${NC}&quot;
    echo &quot;&quot;
}

# 修复CentOS 7源
fix_centos_repo() {
    echo -e &quot;${BLUE}[1/7] 修复CentOS 7 yum源...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    # 备份原有源
    if [[ -d /etc/yum.repos.d ]]; then
        mkdir -p /etc/yum.repos.d/backup
        mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ 2&amp;gt;/dev/null || true
    fi
    
    # 使用阿里云镜像源（CentOS 7 vault）
    cat &amp;gt; /etc/yum.repos.d/CentOS7-Aliyun.repo &amp;lt;&amp;lt; &apos;EOF&apos;
[base]
name=CentOS-7 - Base - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/os/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[updates]
name=CentOS-7 - Updates - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/updates/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[extras]
name=CentOS-7 - Extras - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/extras/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[epel]
name=Extra Packages for Enterprise Linux 7 - \$basearch
baseurl=http://mirrors.aliyun.com/epel/7/\$basearch
gpgcheck=0
enabled=1
EOF

    # 添加elrepo源（用于内核）
    rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 2&amp;gt;/dev/null || true
    cat &amp;gt; /etc/yum.repos.d/elrepo.repo &amp;lt;&amp;lt; &apos;EOF&apos;
[elrepo]
name=ELRepo.org Community Enterprise Linux Repository - el7
baseurl=http://mirrors.aliyun.com/elrepo/elrepo/el7/\$basearch/
        http://elrepo.org/linux/elrepo/el7/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
protect=0

[elrepo-kernel]
name=ELRepo.org Community Enterprise Linux Kernel Repository - el7
baseurl=http://mirrors.aliyun.com/elrepo/kernel/el7/\$basearch/
        http://elrepo.org/linux/kernel/el7/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
protect=0
EOF

    # 清理缓存
    yum clean all &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1
    yum makecache &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1
    
    echo -e &quot;${GREEN}✓ yum源修复完成${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 检查root权限
check_root() {
    echo -e &quot;${BLUE}[2/7] 检查权限...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    if [[ $EUID -ne 0 ]]; then
        error_exit &quot;此脚本必须以root权限运行&quot;
    fi
    echo -e &quot;${GREEN}✓ root权限验证通过${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 检查系统
check_system() {
    echo -e &quot;${BLUE}[3/7] 检查系统版本...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    if [[ ! -f /etc/centos-release ]]; then
        error_exit &quot;此脚本仅支持CentOS系统&quot;
    fi
    
    local centos_version=$(cat /etc/centos-release | grep -oP &apos;[0-9]+&apos; | head -1)
    if [[ &quot;$centos_version&quot; != &quot;7&quot; ]]; then
        error_exit &quot;此脚本仅支持CentOS 7，当前版本: $(cat /etc/centos-release)&quot;
    fi
    
    local arch=$(uname -m)
    if [[ &quot;$arch&quot; != &quot;x86_64&quot; ]]; then
        error_exit &quot;此脚本仅支持x86_64架构，当前架构: $arch&quot;
    fi
    
    echo -e &quot;${GREEN}✓ 系统版本: $(cat /etc/centos-release) ($arch)${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 检查磁盘空间
check_disk_space() {
    echo -e &quot;${BLUE}[4/7] 检查磁盘空间...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    BOOT_FREE=$(df -m /boot | awk &apos;NR==2 {print $4}&apos;)
    if [[ &quot;$BOOT_FREE&quot; -lt 200 ]]; then
        error_exit &quot;/boot分区空间不足（可用: ${BOOT_FREE}MB），需要至少200MB&quot;
    fi
    echo -e &quot;${GREEN}✓ /boot分区可用: ${BOOT_FREE}MB${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 下载内核文件
download_kernel() {
    echo -e &quot;${BLUE}[5/7] 开始下载内核文件...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    echo &quot;下载地址: $DOWNLOAD_URL&quot; | tee -a &quot;$LOG_FILE&quot;
    
    # 选择下载工具
    if command -v wget &amp;amp;&amp;gt;/dev/null; then
        echo &quot;使用 wget 下载...&quot; | tee -a &quot;$LOG_FILE&quot;
        wget -O &quot;$KERNEL_PACKAGE&quot; &quot;$DOWNLOAD_URL&quot; --progress=bar:force 2&amp;gt;&amp;amp;1 | tee -a &quot;$LOG_FILE&quot;
    elif command -v curl &amp;amp;&amp;gt;/dev/null; then
        echo &quot;使用 curl 下载...&quot; | tee -a &quot;$LOG_FILE&quot;
        curl -L -o &quot;$KERNEL_PACKAGE&quot; &quot;$DOWNLOAD_URL&quot; --progress-bar 2&amp;gt;&amp;amp;1 | tee -a &quot;$LOG_FILE&quot;
    else
        error_exit &quot;未找到 wget 或 curl，无法下载&quot;
    fi
    
    # 验证下载
    if [[ ! -f &quot;$KERNEL_PACKAGE&quot; ]]; then
        error_exit &quot;下载失败：文件未找到&quot;
    fi
    
    # 兼容Linux/BSD的stat命令
    FILE_SIZE=$(stat -c%s &quot;$KERNEL_PACKAGE&quot; 2&amp;gt;/dev/null)
    if [[ -z &quot;$FILE_SIZE&quot; ]]; then
        FILE_SIZE=$(stat -f%z &quot;$KERNEL_PACKAGE&quot; 2&amp;gt;/dev/null)
    fi
    
    if [[ -z &quot;$FILE_SIZE&quot; || &quot;$FILE_SIZE&quot; -lt 10000000 ]]; then
        error_exit &quot;下载文件不完整（大小: ${FILE_SIZE:-0} 字节）&quot;
    fi
    echo -e &quot;${GREEN}✓ 下载成功，文件大小: $((FILE_SIZE/1024/1024))MB${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 安装依赖
install_dependencies() {
    echo -e &quot;${BLUE}[6/7] 安装依赖包...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    # 先安装epel-release
    yum install -y epel-release &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1 || true
    
    # 安装必要的工具
    local packages=(
        &quot;grub2-tools&quot;
        &quot;coreutils&quot;
        &quot;numfmt&quot;
        &quot;file&quot;
        &quot;which&quot;
    )
    
    local failed=0
    for pkg in &quot;${packages[@]}&quot;; do
        echo -n &quot;  安装 $pkg... &quot; | tee -a &quot;$LOG_FILE&quot;
        if yum install -y &quot;$pkg&quot; &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1; then
            echo -e &quot;${GREEN}成功${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
        else
            echo -e &quot;${YELLOW}跳过${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
        fi
    done
    
    echo -e &quot;${GREEN}✓ 依赖安装完成${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 安装内核
install_kernel() {
    echo -e &quot;${BLUE}[7/7] 安装内核...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    # 尝试yum安装
    echo &quot;尝试使用yum安装...&quot; | tee -a &quot;$LOG_FILE&quot;
    if yum localinstall -y &quot;$KERNEL_PACKAGE&quot; &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1; then
        echo -e &quot;${GREEN}✓ yum安装成功${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    else
        echo -e &quot;${YELLOW}⚠ yum安装失败，尝试rpm强制安装...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
        
        # 安装内核依赖
        yum install -y elfutils-libelf-devel &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1 || true
        
        # rpm强制安装
        rpm -ivh --replacepkgs &quot;$KERNEL_PACKAGE&quot; --nodeps &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1 || {
            error_exit &quot;内核安装失败，请检查日志: $LOG_FILE&quot;
        }
        echo -e &quot;${GREEN}✓ rpm安装成功${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    fi
    
    # 验证安装
    if rpm -q &quot;kernel-lt-${KERNEL_VERSION}&quot; &amp;amp;&amp;gt;/dev/null; then
        echo -e &quot;${GREEN}✓ 内核安装验证通过${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    else
        error_exit &quot;内核安装验证失败：rpm数据库中未找到&quot;
    fi
}

# 配置GRUB
configure_grub() {
    echo -e &quot;${BLUE}[8/8] 配置GRUB引导...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    
    GRUB_CFG=&quot;/boot/grub2/grub.cfg&quot;
    if [[ ! -f &quot;$GRUB_CFG&quot; ]]; then
        error_exit &quot;GRUB配置文件不存在: $GRUB_CFG&quot;
    fi
    
    # 获取GRUB菜单项
    GRUB_ENTRIES=$(awk -F\&apos; &apos;$1==&quot;menuentry &quot; {print i++ &quot; : &quot; $2}&apos; &quot;$GRUB_CFG&quot; 2&amp;gt;/dev/null)
    if [[ -z &quot;$GRUB_ENTRIES&quot; ]]; then
        error_exit &quot;无法读取GRUB菜单项&quot;
    fi
    
    # 查找新内核索引
    NEW_INDEX=$(echo &quot;$GRUB_ENTRIES&quot; | grep -n &quot;$KERNEL_VERSION&quot; | head -1 | cut -d: -f1)
    if [[ -z &quot;$NEW_INDEX&quot; ]]; then
        KERNEL_MAIN_VER=&quot;${KERNEL_VERSION%%-*}&quot;
        NEW_INDEX=$(echo &quot;$GRUB_ENTRIES&quot; | grep -n &quot;$KERNEL_MAIN_VER&quot; | head -1 | cut -d: -f1)
        echo -e &quot;${YELLOW}⚠ 使用模糊匹配找到内核索引${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    fi
    
    # 转换为0-based索引
    if [[ -n &quot;$NEW_INDEX&quot; ]]; then
        NEW_INDEX=$((NEW_INDEX - 1))
        echo -e &quot;${GREEN}✓ 找到新内核GRUB索引: $NEW_INDEX${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    else
        NEW_INDEX=0
        echo -e &quot;${YELLOW}⚠ 未找到新内核索引，使用默认索引0${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    fi
    
    # 设置默认启动项
    if grub2-set-default &quot;$NEW_INDEX&quot; &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1; then
        echo -e &quot;${GREEN}✓ 默认启动项设置成功${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    else
        echo -e &quot;${YELLOW}⚠ grub2-set-default失败，尝试手动设置...${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
        GRUBENV=&quot;/boot/grub2/grubenv&quot;
        if [[ -f &quot;$GRUBENV&quot; ]]; then
            cp -a &quot;$GRUBENV&quot; &quot;${GRUBENV}.backup&quot;
            if grep -q &apos;^saved_entry=&apos; &quot;$GRUBENV&quot;; then
                sed -i &quot;s/^saved_entry=.*/saved_entry=$NEW_INDEX/&quot; &quot;$GRUBENV&quot;
            else
                echo &quot;saved_entry=$NEW_INDEX&quot; &amp;gt;&amp;gt; &quot;$GRUBENV&quot;
            fi
            echo -e &quot;${GREEN}✓ 手动设置成功${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
        fi
    fi
    
    # 重新生成GRUB配置
    grub2-mkconfig -o &quot;$GRUB_CFG&quot; &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1
    echo -e &quot;${GREEN}✓ GRUB配置已更新${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
}

# 显示完成信息
show_completion() {
    echo -e &quot;\n${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}&quot;
    echo -e &quot;${GREEN}║${WHITE}${BOLD}                      ✅ 安装成功！                          ${GREEN}║${NC}&quot;
    echo -e &quot;${GREEN}╠════════════════════════════════════════════════════════════════╣${NC}&quot;
    echo -e &quot;${GREEN}║${WHITE}  当前内核: ${NC}$(uname -r)&quot; | tee -a &quot;$LOG_FILE&quot;
    echo -e &quot;${GREEN}║${WHITE}  新内核:   ${GREEN}$KERNEL_VERSION${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    echo -e &quot;${GREEN}║${WHITE}  日志文件: ${BLUE}$LOG_FILE${NC}&quot; | tee -a &quot;$LOG_FILE&quot;
    echo -e &quot;${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}&quot;
    echo &quot;&quot;
    
    # 询问重启
    echo -ne &quot;${YELLOW}是否立即重启系统？${NC} (y/n): &quot;
    read -r reboot_choice
    if [[ &quot;$reboot_choice&quot; =~ ^[Yy]$ ]]; then
        echo -e &quot;${BLUE}系统将在5秒后重启...${NC}&quot;
        echo -e &quot;${RED}按 Ctrl+C 取消重启${NC}&quot;
        sleep 5
        sync &amp;amp;&amp;amp; reboot
    else
        echo -e &quot;${BLUE}请手动执行 &apos;reboot&apos; 重启系统${NC}&quot;
        echo -e &quot;${BLUE}重启后执行 &apos;uname -r&apos; 验证内核版本${NC}&quot;
    fi
}

# ========== 主函数 ==========
main() {
    print_banner
    
    # 执行步骤
    check_root
    check_system
    check_disk_space
    fix_centos_repo      # 新增：修复yum源
    download_kernel
    install_dependencies
    install_kernel
    configure_grub
    
    # 完成
    show_completion
}

# ========== 执行主函数 ==========
main &quot;$@&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;✨ 主要修复内容&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;修复yum源问题&lt;/strong&gt; (新增 &lt;code&gt;fix_centos_repo&lt;/code&gt; 函数)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用阿里云镜像源替换失效的腾讯云源&lt;/li&gt;
&lt;li&gt;添加elrepo源用于内核支持&lt;/li&gt;
&lt;li&gt;自动备份原有源配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. &lt;strong&gt;增强依赖安装&lt;/strong&gt; (改进 &lt;code&gt;install_dependencies&lt;/code&gt; 函数)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;即使部分依赖安装失败也能继续&lt;/li&gt;
&lt;li&gt;添加必要工具如 &lt;code&gt;numfmt&lt;/code&gt;、&lt;code&gt;file&lt;/code&gt; 等&lt;/li&gt;
&lt;li&gt;更详细的安装状态显示&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. &lt;strong&gt;改进错误处理&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;更友好的错误提示界面&lt;/li&gt;
&lt;li&gt;详细的步骤显示&lt;/li&gt;
&lt;li&gt;添加8个步骤的完整流程&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. &lt;strong&gt;添加美化功能&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用Unicode边框&lt;/li&gt;
&lt;li&gt;彩色进度显示&lt;/li&gt;
&lt;li&gt;清晰的步骤分隔&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;📥 使用方法&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 直接运行（会自动修复源问题）
bash &amp;lt;(curl -s http://linux.6wd.cn/up.sh)

# 或者下载后运行
curl -o up.sh http://linux.6wd.cn/up.sh
chmod +x up.sh
./up.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个版本会&lt;strong&gt;自动修复yum源问题&lt;/strong&gt;，使用阿里云镜像，确保依赖包能正常下载！&lt;/p&gt;
</content:encoded></item><item><title>Alist S3 上传指定目录脚本文档</title><link>https://6wd.cn/posts/alist-s3-upload-script/</link><guid isPermaLink="true">https://6wd.cn/posts/alist-s3-upload-script/</guid><description>此文档将指导你如何使用修改后的 Python 脚本，其中包括以下功能：</description><pubDate>Tue, 29 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;自动生成子文件夹并上传至 Alist S3 脚本配置文档&lt;/h1&gt;
&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;p&gt;此文档将指导你如何使用修改后的 Python 脚本，其中包括以下功能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;手动设置主文件夹名称。&lt;/li&gt;
&lt;li&gt;在主文件夹下自动生成一个 &lt;code&gt;backup+时间&lt;/code&gt; 的子文件夹。&lt;/li&gt;
&lt;li&gt;上传本地文件至 Alist S3 存储，并保存在 &lt;code&gt;主文件夹/backup+时间&lt;/code&gt; 目录中。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;本教程使用Alist中的S3协议进行搭建对接的123云盘&lt;/h2&gt;
&lt;h3&gt;1，先进入Alist的官网安装并运行，由于网络上此教程太多，我这边不过多教学，官网的一键安装也十分方便（&lt;a href=&quot;https://alist.nn.ci/zh/guide/install/script.html&quot;&gt;Alist官网地址：alist.nn.ci&lt;/a&gt;）&lt;/h3&gt;
&lt;h3&gt;2，进入Alist后台-&amp;gt;存储-&amp;gt;添加  来添加存储，我们以123pan为例&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/29/20240829180949.png&quot; alt=&quot;image-20240829180949416&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3，成功添加&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/29/20240829181029.png&quot; alt=&quot;image-20240829181029527&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4，进入123盘，在根目录新建&lt;code&gt;desktop&lt;/code&gt;以及&lt;code&gt;mobile&lt;/code&gt;文件夹用于存储手机和电脑访问时候呈现出不同尺寸的图片，并且检查是否正常创建&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/29/20240829181236.png&quot; alt=&quot;image-20240829181235977&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5，进入Alist后台创建S3协议的密钥以及id&lt;/h3&gt;
&lt;p&gt;在设置-&amp;gt;对象存储中点击&lt;code&gt;S3 generate&lt;/code&gt;来创建Key，在下方添加桶以及位置&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/29/20240829181626.png&quot; alt=&quot;image-20240829181626581&quot; /&gt;&lt;/p&gt;
&lt;p&gt;配置完成后去Alist的配置文件位置修改配置文件让他启用S3服务&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/29/20240829182645.png&quot; alt=&quot;image-20240829182645804&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;脚本的配置&lt;/h2&gt;
&lt;h3&gt;完整代码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import os
import boto3
import schedule
import time
from datetime import datetime
from botocore.exceptions import NoCredentialsError, PartialCredentialsError

# ===================== 配置部分 =====================
DIRECTORY_TO_UPLOAD = &apos;/path/to/your/local_directory&apos;  # 本地需要上传的目录
S3_BUCKET_NAME = &apos;your-s3-bucket-name&apos;  # S3 桶名称
ALIST_S3_ENDPOINT = &apos;http://YOUR_IP:YOUR_PORT&apos;  # Alist S3 的 IP + 端口
AWS_ACCESS_KEY_ID = &apos;YOUR_AWS_ACCESS_KEY_ID&apos;  # Alist S3 的访问密钥
AWS_SECRET_ACCESS_KEY = &apos;YOUR_AWS_SECRET_ACCESS_KEY&apos;  # Alist S3 的密钥
UPLOAD_INTERVAL_MINUTES = 60  # 每隔 60 分钟上传一次
UPLOAD_NOW = True  # 设置为 True 表示立即上传, False 表示不立即上传
SCHEDULED_UPLOAD = True  # 设置为 True 表示定期上传，False 表示仅执行一次上传
CUSTOM_FOLDER_NAME = &apos;your-custom-folder&apos;  # 手动设置的主文件夹名称
# ===================== 配置部分结束 =====================

# 初始化 S3 客户端，使用 Alist 的 IP + 端口作为 endpoint_url
s3 = boto3.client(
    &apos;s3&apos;,
    aws_access_key_id=AWS_ACCESS_KEY_ID,  # 替换为 Alist 的访问密钥
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,  # 替换为 Alist 的密钥
    endpoint_url=ALIST_S3_ENDPOINT,  # Alist S3 的 IP + 端口
    region_name=&apos;us-east-1&apos;  # 区域随意设置一个
)

# 生成 backup+时间 文件夹名称的函数
def generate_backup_folder_name():
    # 使用当前日期时间生成文件夹名称，例如 &apos;backup-2024-10-04-14-30&apos;
    return f&quot;backup-{datetime.now().strftime(&apos;%Y-%m-%d-%H-%M&apos;)}&quot;

# 上传目录到 S3 的函数，带有自动生成的 backup+时间子文件夹名称
def upload_directory_to_s3(directory_path, bucket_name, custom_folder_name):
    try:
        # 生成 backup+时间 的子文件夹名称
        backup_folder_name = generate_backup_folder_name()
        # 在自定义的主文件夹下生成 backup+时间 的子文件夹
        full_folder_path = os.path.join(custom_folder_name, backup_folder_name)

        # 遍历指定目录中的所有文件和子目录
        for root, dirs, files in os.walk(directory_path):
            for file_name in files:
                full_file_path = os.path.join(root, file_name)  # 文件的完整路径
                # 定义 S3 中的文件路径，包含主文件夹和 backup+时间 文件夹
                s3_file_path = os.path.join(full_folder_path, os.path.relpath(full_file_path, directory_path))
                try:
                    # 上传文件到 S3
                    s3.upload_file(full_file_path, bucket_name, s3_file_path)
                    print(f&quot;Uploaded: {full_file_path} to {bucket_name}/{s3_file_path}&quot;)
                except FileNotFoundError:
                    print(f&quot;文件未找到: {full_file_path}&quot;)
                except NoCredentialsError:
                    print(&quot;无法找到 S3 凭证。&quot;)
                except PartialCredentialsError:
                    print(&quot;提供的 S3 凭证不完整。&quot;)
    except Exception as e:
        print(f&quot;错误: {e}&quot;)

# 调度上传任务的函数
def schedule_upload(directory_path, bucket_name, custom_folder_name, interval_minutes):
    # 定义调度任务的函数
    def job():
        print(f&quot;正在上传 {directory_path} 到 S3 桶 {bucket_name}...&quot;)
        upload_directory_to_s3(directory_path, bucket_name, custom_folder_name)

    # 安排任务按照指定的时间间隔运行
    schedule.every(interval_minutes).minutes.do(job)

    print(f&quot;已安排每 {interval_minutes} 分钟上传一次。&quot;)

    # 持续运行调度程序
    while True:
        schedule.run_pending()  # 运行待处理的任务
        time.sleep(1)  # 等待 1 秒后检查下一个任务

# 主函数入口
if __name__ == &quot;__main__&quot;:
    # 如果上传标志为 True，则立即上传一次
    if UPLOAD_NOW:
        print(f&quot;立即上传 {DIRECTORY_TO_UPLOAD} 到 S3 桶 {S3_BUCKET_NAME}...&quot;)
        upload_directory_to_s3(DIRECTORY_TO_UPLOAD, S3_BUCKET_NAME, CUSTOM_FOLDER_NAME)
    
    # 根据 SCHEDULED_UPLOAD 判断是否定期上传
    if SCHEDULED_UPLOAD:
        # 启动上传任务的调度
        schedule_upload(DIRECTORY_TO_UPLOAD, S3_BUCKET_NAME, CUSTOM_FOLDER_NAME, UPLOAD_INTERVAL_MINUTES)
    else:
        print(&quot;已设置为仅执行一次上传任务。&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. &lt;strong&gt;本地需要上传的目录&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;DIRECTORY_TO_UPLOAD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 指定本地需要上传的目录路径。此目录中的文件会被上传到 S3 中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;DIRECTORY_TO_UPLOAD = &apos;/path/to/your/local_directory&apos;
&lt;/code&gt;&lt;/pre&gt;
将 &lt;code&gt;&apos;/path/to/your/local_directory&apos;&lt;/code&gt; 替换为你实际想要上传的本地目录路径。例如：&lt;pre&gt;&lt;code&gt;DIRECTORY_TO_UPLOAD = &apos;/home/user/documents&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;2. &lt;strong&gt;S3 桶名称&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;S3_BUCKET_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 指定你在 Alist S3 服务中的存储桶（bucket）名称，所有文件将被上传至该桶中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;S3_BUCKET_NAME = &apos;your-s3-bucket-name&apos;
&lt;/code&gt;&lt;/pre&gt;
将 &lt;code&gt;&apos;your-s3-bucket-name&apos;&lt;/code&gt; 替换为你实际的 S3 桶名称，例如：&lt;pre&gt;&lt;code&gt;S3_BUCKET_NAME = &apos;my-backup-bucket&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;3. &lt;strong&gt;Alist S3 服务的 IP 和端口&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;ALIST_S3_ENDPOINT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 访问 Alist S3 服务的 IP 地址和端口。格式为 &lt;code&gt;http://IP:PORT&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;ALIST_S3_ENDPOINT = &apos;http://YOUR_IP:YOUR_PORT&apos;
&lt;/code&gt;&lt;/pre&gt;
将 &lt;code&gt;&apos;http://YOUR_IP:YOUR_PORT&apos;&lt;/code&gt; 替换为你的 Alist S3 服务的 IP 地址和端口。例如，如果服务在 &lt;code&gt;192.168.1.100&lt;/code&gt; 上运行，端口为 &lt;code&gt;9000&lt;/code&gt;：&lt;pre&gt;&lt;code&gt;ALIST_S3_ENDPOINT = &apos;http://192.168.1.100:9000&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;4. &lt;strong&gt;访问密钥 (AWS Access Key ID)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 用于 Alist S3 服务的访问密钥，用于身份验证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;AWS_ACCESS_KEY_ID = &apos;YOUR_AWS_ACCESS_KEY_ID&apos;
&lt;/code&gt;&lt;/pre&gt;
将 &lt;code&gt;&apos;YOUR_AWS_ACCESS_KEY_ID&apos;&lt;/code&gt; 替换为你的实际 Alist S3 访问密钥，例如：&lt;pre&gt;&lt;code&gt;AWS_ACCESS_KEY_ID = &apos;ABCD1234EXAMPLE&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;5. &lt;strong&gt;密钥 (AWS Secret Access Key)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 用于 Alist S3 服务的密钥，与访问密钥一起用于身份验证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY = &apos;YOUR_AWS_SECRET_ACCESS_KEY&apos;
&lt;/code&gt;&lt;/pre&gt;
将 &lt;code&gt;&apos;YOUR_AWS_SECRET_ACCESS_KEY&apos;&lt;/code&gt; 替换为你的实际密钥，例如：&lt;pre&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY = &apos;abcd1234secretEXAMPLE&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;6. &lt;strong&gt;手动设置的主文件夹名称&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;CUSTOM_FOLDER_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 这是你手动设置的主文件夹名称。所有文件将会上传到 S3 中此主文件夹下的 &lt;code&gt;backup+时间&lt;/code&gt; 子文件夹中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;CUSTOM_FOLDER_NAME = &apos;your-custom-folder&apos;
&lt;/code&gt;&lt;/pre&gt;
例如，将此设置为 &lt;code&gt;my-backups&lt;/code&gt;，脚本会将所有文件上传到 &lt;code&gt;my-backups/backup-时间&lt;/code&gt; 的路径中。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;7. &lt;strong&gt;上传时间间隔（分钟）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;UPLOAD_INTERVAL_MINUTES&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 控制脚本自动上传的时间间隔，单位为分钟。脚本会按照该时间间隔定期上传文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;UPLOAD_INTERVAL_MINUTES = 60
&lt;/code&gt;&lt;/pre&gt;
在此示例中，脚本会每隔 60 分钟上传一次文件。可以根据你的需求修改为不同的间隔时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;8. &lt;strong&gt;立即上传开关&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;UPLOAD_NOW&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 布尔值，控制脚本在启动时是否立即上传文件。如果设置为 &lt;code&gt;True&lt;/code&gt;，脚本会在启动时立即上传；如果为 &lt;code&gt;False&lt;/code&gt;，则只按照调度时间上传。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;UPLOAD_NOW = True
&lt;/code&gt;&lt;/pre&gt;
设置为 &lt;code&gt;True&lt;/code&gt; 时，脚本会立即执行上传任务。如果不希望立即上传，可以将其设置为 &lt;code&gt;False&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;9. &lt;strong&gt;定期上传开关&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;SCHEDULED_UPLOAD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 控制是否启用定期上传。如果设置为 &lt;code&gt;True&lt;/code&gt;，脚本会按设定的时间间隔定期执行上传。如果设置为 &lt;code&gt;False&lt;/code&gt;，脚本只会运行一次。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;示例&lt;/strong&gt;:&lt;pre&gt;&lt;code&gt;SCHEDULED_UPLOAD = True
&lt;/code&gt;&lt;/pre&gt;
如果设置为 &lt;code&gt;True&lt;/code&gt;，脚本会按 &lt;code&gt;UPLOAD_INTERVAL_MINUTES&lt;/code&gt; 定期上传文件。设置为 &lt;code&gt;False&lt;/code&gt; 时，脚本只会执行一次上传任务，然后退出。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;10. &lt;strong&gt;自动生成 &lt;code&gt;backup+时间&lt;/code&gt; 子文件夹&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;变量&lt;/strong&gt;: &lt;code&gt;generate_backup_folder_name()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;描述&lt;/strong&gt;: 这个函数会自动生成一个以 &lt;code&gt;backup+时间&lt;/code&gt; 格式命名的子文件夹，用于存储每次上传的文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成格式&lt;/strong&gt;: &lt;code&gt;backup-YYYY-MM-DD-HH-MM&lt;/code&gt;，例如：&lt;pre&gt;&lt;code&gt;backup-2024-10-04-14-30
&lt;/code&gt;&lt;/pre&gt;
每次运行脚本，都会在手动设置的主文件夹下生成一个新的 &lt;code&gt;backup+时间&lt;/code&gt; 子文件夹，并将本地文件上传到这个子文件夹中。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;运行方式：&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;将脚本保存为 &lt;code&gt;.py&lt;/code&gt; 文件（例如 &lt;code&gt;upload_to_s3.py&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;使用 Python 运行脚本：&lt;pre&gt;&lt;code&gt;python3 upload_to_s3.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;立即上传&lt;/strong&gt;：如果 &lt;code&gt;UPLOAD_NOW = True&lt;/code&gt;，脚本会立即执行上传任务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定期上传&lt;/strong&gt;：如果 &lt;code&gt;SCHEDULED_UPLOAD = True&lt;/code&gt;，脚本会按设定的时间间隔定期上传。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;示例配置：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;DIRECTORY_TO_UPLOAD = &apos;/home/user/documents&apos;  # 本地目录
S3_BUCKET_NAME = &apos;my-backup-bucket&apos;  # S3 桶名称
ALIST_S3_ENDPOINT = &apos;http://192.168.1.100:9000&apos;  # Alist S3 服务 IP 和端口
AWS_ACCESS_KEY_ID = &apos;ABCD1234EXAMPLE&apos;  # 访问密钥
AWS_SECRET_ACCESS_KEY = &apos;abcd1234secretEXAMPLE&apos;  # 密钥
UPLOAD_INTERVAL_MINUTES = 30  # 每 30 分钟上传一次
UPLOAD_NOW = True  # 立即上传
SCHEDULED_UPLOAD = True  # 定期上传
CUSTOM_FOLDER_NAME = &apos;my-backups&apos;  # 主文件夹名称
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;文件上传结构示例：&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/04/20241004133119.png&quot; alt=&quot;image-20241004133119193&quot; /&gt;&lt;/p&gt;
&lt;p&gt;假设 &lt;code&gt;CUSTOM_FOLDER_NAME = &apos;my-backups&apos;&lt;/code&gt;，上传后的文件路径将如下所示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;S3_BUCKET_NAME/my-backups/backup-2024-10-04-14-30/file1.txt
S3_BUCKET_NAME/my-backups/backup-2024-10-04-14-30/file2.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过该脚本配置，你可以灵活设置手动文件夹名称，同时利用自动生成的 &lt;code&gt;backup+时间&lt;/code&gt; 子文件夹来管理文件的上传，方便备份和归档管理。如果你有任何其他问题，欢迎继续咨询！&lt;/p&gt;
</content:encoded></item><item><title>批处理bat脚本自动配置java的jdk环境变量</title><link>https://6wd.cn/posts/bat-script-config-java-jdk-env/</link><guid isPermaLink="true">https://6wd.cn/posts/bat-script-config-java-jdk-env/</guid><description>每当更换电脑或者是重装系统之后，都需要重新配置java系统路径。但是又不想每次都去查配置方法，所以写了个脚本自动配置。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;每当更换电脑或者是重装系统之后，都需要重新配置java系统路径。但是又不想每次都去查配置方法，所以写了个脚本自动配置。&lt;/p&gt;
&lt;h3&gt;脚本内容&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;:: chcp 65001 代码表示更改为Unicode(utf-8)
chcp 65001
@echo off
@echo 第一步 输入要设置的JAVA_HOME路径:(As example: D:\Program Files\Java\jdk1.8.0_181)
set /p input=&quot;请输入JAVA_HOME路径：&quot;
@echo 第二步 设置JAVA_HOME路径
setx JAVA_HOME &quot;%input%&quot; /M
@echo 第三步 设置PATH
setx path &quot;%path%;%%JAVA_HOME%%\bin&quot; /M
@echo 第四步 设置classpath
setx classpath .;%%JAVA_HOME%%\lib\dt.jar;%%JAVA_HOME%%\lib\tools.jar /M
@echo “执行完成”
pause
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;步骤及意义&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;关闭回显&lt;code&gt;@echo off&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第一步是接收手动输入&lt;code&gt;java&lt;/code&gt;安装路径，例：&lt;code&gt;D:\Program Files\Java\jdk1.8.0_181&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/03/10/20240310234314.png&quot; alt=&quot;安装路径&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第二步是将输入的值设置给全局属性，并命名为&lt;code&gt;JAVA_HOME&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;其中：加&lt;code&gt;/M&lt;/code&gt;是代表设置system变量，可使所有用户可用，不加/M则只当前用户可用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第三步是设置&lt;code&gt;PATH&lt;/code&gt;,因为是覆盖更新，所以在之前要加上现有的&lt;code&gt;PATH&lt;/code&gt;变量即&lt;code&gt;%path%;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第四步是设置&lt;code&gt;classpath&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;使用方式&lt;/h3&gt;
&lt;p&gt;新建一个txt文本文件，然后将上述全部语句粘贴进去，保存后，将文件后缀修改为&lt;code&gt;.bat&lt;/code&gt;即可。&lt;/p&gt;
&lt;p&gt;右键，使用管理员权限运行。&lt;/p&gt;
&lt;h3&gt;echo 和@echo的区别&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;echo&lt;/code&gt;: 会在shell中显示echo这条命令和后面要输出的内容&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@echo&lt;/code&gt;: 不会显示echo这条命令，只会显示后面要输出的内容&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;例如:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;echo “hello” 输出为：echo “hello” hello&lt;/p&gt;
&lt;p&gt;@echo “hello” 输出为：hello&lt;/p&gt;
&lt;p&gt;在执行命令之前会把要执行的命令进行输出，称之为回显&lt;/p&gt;
&lt;p&gt;如果要执行的命令以字符@开始，则不会回显&lt;/p&gt;
&lt;h3&gt;set和setx的区别&lt;/h3&gt;
&lt;p&gt;1、SET命令：这种语法只能在Cmd Shell环境中有效，关闭运行环境&lt;a href=&quot;https://so.csdn.net/so/search?q=%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F&amp;amp;spm=1001.2101.3001.7020&quot;&gt;环境变量&lt;/a&gt;将不保存。&lt;/p&gt;
&lt;p&gt;2、SETX命令：Window XP 以上的系统都自带了该命令（如果没有，下载一个&lt;a href=&quot;https://download.csdn.net/download/jerrygaoling/12845436&quot;&gt;Setx.exe&lt;/a&gt;)，这种方式为永久设定环境变量。&lt;/p&gt;
</content:encoded></item><item><title>CentOS Linux 安装MySQL</title><link>https://6wd.cn/posts/centos-install-mysql/</link><guid isPermaLink="true">https://6wd.cn/posts/centos-install-mysql/</guid><description>首先，尝试一下直接使用 yum 安装 MySQL</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;首先，尝试一下直接使用 yum 安装 MySQL&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum install mysql-community-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果成功，表示不需要配置MySQL rpm 源信息，直接就安装完成了&lt;/p&gt;
&lt;p&gt;但是，如果出现以下错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Loading mirror speeds from cached hostfile
没有可用软件包 mysql-community-server。
错误：无须任何处理
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;表示我们没有添加安装包的源信息，需要安装 MySQL rpm 源信息&lt;/p&gt;
&lt;h3&gt;安装 MySQL rpm 源信息&lt;/h3&gt;
&lt;p&gt;打开 &lt;a href=&quot;https://link.zhihu.com/?target=http%3A//dev.mysql.com/downloads/repo/yum/&quot;&gt;http://dev.mysql.com/downloads/repo/yum/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/22/20240122213558.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;根据你的系统版本，选择对应的安装包，例如我的是CentOS 7.5，这个系统的Linux内核是 Linux 7，所以我选择了红框内的地址，大家依次类推。&lt;/p&gt;
&lt;p&gt;拼接下载地址头：&lt;a href=&quot;https://link.zhihu.com/?target=http%3A//dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm&quot;&gt;http://dev.mysql.com/get/&lt;/a&gt;，得到以下地址&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用 wget + 刚才拼接的地址，下载安装包源信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget  http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rpm 安装源信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -ivh mysql80-community-release-el7-7.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;再尝试使用 yum 安装MySQL&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum install mysql-community-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装过程中，会提示让我们确认，一律输入 &lt;code&gt;y&lt;/code&gt; 按回车即可&lt;/p&gt;
&lt;p&gt;安装完成后，yum会自动覆盖自带的mariaDB，所以不需要我们手动卸载它&lt;/p&gt;
&lt;h3&gt;检查安装是否成功&lt;/h3&gt;
&lt;p&gt;检查一下刚才的安装是否成功&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -qa | grep mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql-community-libs-compat-8.0.33-1.el7.x86_64
mysql-community-icu-data-files-8.0.33-1.el7.x86_64
mysql80-community-release-el7-7.noarch
mysql-community-common-8.0.33-1.el7.x86_64
mysql-community-libs-8.0.33-1.el7.x86_64
mysql-community-server-8.0.33-1.el7.x86_64
mysql-community-client-8.0.33-1.el7.x86_64
mysql-community-client-plugins-8.0.33-1.el7.x86_64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出类似以上内容，表示安装完成&lt;/p&gt;
&lt;p&gt;检查mariaDB是否被覆盖&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm -qa | grep mariadb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出空，表示 mariaDB 已经被成功覆盖。&lt;/p&gt;
&lt;h2&gt;MySQL 常用命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 启动
systemctl start mysqld

# 第一次启动后，可以查看mysql初始化密码
grep &apos;temporary password&apos; /var/log/mysqld.log

# 重启
systemctl restart mysqld

# 停止
systemctl stop mysqld

#查看状态
systemctl status mysqld

#开机启动
systemctl enable mysqld
systemctl daemon-reload

# 查看进程、版本信息
ps -ef | grep mysql
或
netstat -atp

# 登录
mysql -u root -p&apos;密码内容&apos;

# 查看所有表
show databases;

# 进入数据库
use 表名

# 查看所有表
show tables

# 查看某张表信息
desc 表名

# 查
select * from 表名
# 删
delete from 表名 where field=xx
# 改
update 表名 set field=&apos;xxx&apos; where field=&apos;xxx&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;登录和修改密码&lt;/h2&gt;
&lt;p&gt;我们安装的时候，并没有设置初始密码&lt;/p&gt;
&lt;p&gt;所以 mysql 在第一次启动的时候，会自动初始化一个密码&lt;/p&gt;
&lt;p&gt;通过以下这行代码，我们可以查看 mysql 自动初始化的密码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 第一次启动后，可以查看mysql初始化密码
grep &apos;temporary password&apos; /var/log/mysqld.log

输出（root@localhost: 后面的是密码）：
2023-04-21T06:03:27.071550Z 6 [Note] [MY-010454] [Server] A temporary password
is generated for root@localhost: r2to%yZ%a)%s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;登录&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 登录mysql，一定要注意：-p和&apos;密码&apos;之间是没有空格的
mysql -u root -p&apos;r2to%yZ%a)%s&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;修改 root 密码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;注意了，默认的密码策略，需要：大写英文 + 特殊字符 + 数字&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Root_123&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有些同学可能会觉得，老子密码想设置啥就设置啥，轮得到你这 mysql 在这里瞎BB？&lt;/p&gt;
&lt;p&gt;那也是可以修改密码校验策略的&lt;/p&gt;
&lt;p&gt;首先，安装密码验证插件&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但是有个前提，你还是需要先按它的要求修改第一次密码，才能安装密码验证策略插件，哈哈&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;1、先按照mysql的要求，修改一次密码
ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;Root_123&apos;;

2、退出mysql
exit

3、重新登录mysql
mysql -u root -p&apos;Root_123&apos;

4、安装密码验证插件
install plugin validate_password soname &apos;validate_password.so&apos;;

5、查看是否启用了插件
select plugin_name, plugin_status from information_schema.plugins where plugin_name like &apos;validate%&apos;;
+-------------------+---------------+
| plugin_name       | plugin_status |
+-------------------+---------------+
| validate_password | ACTIVE        |
+-------------------+---------------+
输出这样的内容，表示成功启用
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看验证策略的键、值信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHOW VARIABLES LIKE &apos;validate_password%&apos;;

对于高版本的mysql，例如mysql 8，验证策略的key，是 validate_password.xxx
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| validate_password.check_user_name    | ON    |
| validate_password.dictionary_file    |       |
| validate_password.length             | 8     |
| validate_password.mixed_case_count   | 1     |
| validate_password.number_count       | 1     |
| validate_password.policy             | MEDIUM|
| validate_password.special_char_count | 1     |
+--------------------------------------+-------+


对于低版本的mysql，例如mysql 5.7，验证策略的key，是 validate_password_xxx
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| validate_password.check_user_name    | ON    |
| validate_password.dictionary_file    |       |
| validate_password.length             | 8     |
| validate_password.mixed_case_count   | 1     |
| validate_password.number_count       | 1     |
| validate_password.policy             | MEDIUM|
| validate_password.special_char_count | 1     |
+--------------------------------------+-------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们修改密码策略和密码长度&lt;/p&gt;
&lt;p&gt;我的策略信息的 key ，是 &lt;code&gt;validate_password.xxx&lt;/code&gt;这个格式的，所以按照如下进行设置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;设置密码校验策略为：0（只验证密码长度）
set global validate.password_policy=0;

设置密码最低长度=N，例如设置密码最低长度=6，也就是密码最少要设置6个字符及以上
set global validate.password_length=6;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了，现在密码就可以按照你刚才配置的策略，来进行设置密码了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;123456&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;开放 root 账户远程登录&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 登录
mysql -u root -p&apos;密码&apos;

# 如果你的数据库是 mysql 8 及以上
# 1、进入数据库
use mysql
# 2、修改user表
update user set host=&apos;%&apos; where user=&apos;root&apos;;

# mysql 5.7 及之前，执行这行代码即可
GRANT ALL PRIVILEGES ON *.* TO &apos;root&apos;@&apos;%&apos; IDENTIFIED BY &apos;你的密码&apos; WITH GRANT OPTION;

# 重载授权表
FLUSH PRIVILEGES;

# 退出
exit

# 重启
systemctl restart mysqld
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;端口开放&lt;/h2&gt;
&lt;p&gt;经过实测，使用阿里云或者腾讯云，在服务器上，无需配置 &lt;code&gt;iptables&lt;/code&gt; 端口信息&lt;/p&gt;
&lt;p&gt;但必须在阿里云或者腾讯云控制台 - 服务器 - 安全组，开放 3306端口。&lt;/p&gt;
</content:encoded></item><item><title>CentOS更换阿里源</title><link>https://6wd.cn/posts/centos-switch-aliyun-source/</link><guid isPermaLink="true">https://6wd.cn/posts/centos-switch-aliyun-source/</guid><description>2022-05-19 11:51 猎手家园 阅读(6909) 评论(1) 编辑 收藏) 举报)</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;a href=&quot;https://www.cnblogs.com/hunttown/p/16287988.html&quot;&gt;CentOS8配置阿里云YUM源&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;2022-05-19 11:51 &lt;a href=&quot;https://www.cnblogs.com/hunttown/&quot;&gt;猎手家园&lt;/a&gt; 阅读(6909) 评论(1) &lt;a href=&quot;https://i.cnblogs.com/EditPosts.aspx?postid=16287988&quot;&gt;编辑&lt;/a&gt; [收藏](javascript:void(0)) [举报](javascript:void(0))&lt;/p&gt;
&lt;p&gt;1、进入配置目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /etc/yum.repos.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2、备份原yum源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mv CentOS-Linux-Base.repo CentOS-Linux-Base.repo.bak
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3、下载阿里云源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4、修改yum源&lt;/p&gt;
&lt;p&gt;输入命令 “vim CentOS-Base.repo” 后，按“冒号” 进入命令模式&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#首先输入：
%s/mirrors.cloud.aliyuncs.com/mirrors.aliyun.com/g

#回车后，再次按“冒号”后，输入：
%s/$releasever/$releasever-stream/g

#回车，然后再按“冒号”后输入保存命令：
wq
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;说明：在vim命令下，按下冒号键是命令模式，按回车键执行，最后输入 wq 是保存并退出命令&lt;/p&gt;
&lt;p&gt;5、还需要改两个地方，否则会出现以下错误：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;错误：为 repo ‘appstream‘ 下载元数据失败 : Cannot prepare internal mirrorlist: No URLs in mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用vim打开文件CentOS-Linux-AppStream.repo、CentOS-Linux-Extras.repo，将原来的mirrorlist给注释掉，然后新增一行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;baseurl=https://mirrors.aliyun.com/centos/$releasever-stream/extras/$basearch/os/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6、重新缓存&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#清理
yum clean all

#生成缓存
yum makecache
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Centos更新内核</title><link>https://6wd.cn/posts/centos-update-kernel/</link><guid isPermaLink="true">https://6wd.cn/posts/centos-update-kernel/</guid><description>不知道大家有没有遇到过这样的问题，在使用docker创建vlan网络时，会提示“Error response from daemon: kernel version failed to meet the minimum ipvlan ...</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;手动升级CentOS 7.9内核的正确方式&lt;/h1&gt;
&lt;h2&gt;&lt;strong&gt;1.背景&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;不知道大家有没有遇到过这样的问题，在使用docker创建vlan网络时，会提示“Error response from daemon: kernel version failed to meet the minimum ipvlan kernel requirement of 4.2, found 3.10.0”，需要的内核为4.2，但找到的内核为3.10.0。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pic4.zhimg.com/80/v2-eb8a06cce02afaad1c0c62cf31ab1aa7_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看一下系统的内核版本，使用以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uname -a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到当前的内核确实为3.10.0.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pic2.zhimg.com/80/v2-d6d5eb0bfaf2a687bd7fc108b060ef39_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;查看一下CentOS的版本，使用以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat /etc/redhat-release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到是最新的7.9版本。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pic3.zhimg.com/80/v2-e814e2df0bf66c49596d5b875ed226fa_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;2.错误尝试&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;按照一贯的思路，那不就是update解决的事嘛！手指一划，敲下一条命令(生产环境下慎用！)：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum -y update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;没有效果！采用upgrade升级(生产环境下慎用！)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum -y upgrade 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好吧，没有用，内核没有变化。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pic1.zhimg.com/80/v2-4a093bf461d62e55ac3ebbdb069a426c_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;3.正确尝试&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;先导入一个公钥。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装一下CentOS 7.x的ELRepo包。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
# CentOS 8则采用下面的命令
# yum install -y https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后依次执行下面的命令，等待进度条走完，下载升级：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yum --enablerepo=elrepo-kernel install kernel-ml -y &amp;amp;&amp;amp;
sed -i s/saved/0/g /etc/default/grub &amp;amp;&amp;amp;
grub2-mkconfig -o /boot/grub2/grub.cfg 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://pic3.zhimg.com/80/v2-d5db24c6a44e19af568c3cc69e6847ba_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;重启系统：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再次查看CentOS的内核版本，发现已经把内核升级成了5.16.12：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uname -a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://pic4.zhimg.com/80/v2-f70c9d41b717ce7539084ed1e960c683_720w.webp&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以开心的玩耍了~&lt;/p&gt;
</content:encoded></item><item><title>CentOS7配置阿里云镜像源（超详细过程）</title><link>https://6wd.cn/posts/centos7-aliyun-mirror/</link><guid isPermaLink="true">https://6wd.cn/posts/centos7-aliyun-mirror/</guid><description>此方法亲测有效，适用于CentOS7版本所有的环境。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;前言&lt;/h3&gt;
&lt;p&gt;此方法亲测有效，适用于&lt;a href=&quot;https://so.csdn.net/so/search?q=CentOS7&amp;amp;spm=1001.2101.3001.7020&quot;&gt;CentOS7&lt;/a&gt;版本所有的环境。
CentOS7本地yum源的配置，请参考本人的另一篇博客文章：https://blog.csdn.net/KingveyLee/article/details/114979418
RedHat7本地yum源的配置，请参考本人的另一篇博客文章：https://blog.csdn.net/KingveyLee/article/details/114981036&lt;/p&gt;
&lt;h3&gt;一、环境准备&lt;/h3&gt;
&lt;p&gt;你需要准备一台干净的CentOS7的环境，且可以ping的通外网~尤其是mirrors.aliyun.com。
简单测试一下，如果通的话，再执行以下步骤完成设置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ping mirrors.aliyun.com
1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;二、手动配置阿里云源&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;备份官方的原yum源的配置&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;下载Centos-7.repo文件&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;最小化安装，如果没有wget的命令，可使用curl代替wget，执行如下语句代替：
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;清除及生成缓存。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 清除yum缓存
yum clean all
# 缓存阿里云源
yum makecache
# 测试阿里云源 
yum list
123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;三、脚本配置本地源&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;找个目录，创建脚本文件：&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;本人以/root/目录为例&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;vi /root/auto_aliyun.sh
1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;编写如下内容：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# 备份官方的原yum源的配置
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 下载Centos-7.repo文件,或者curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo，取决于你是否有wget的命令
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 清除yum缓存
yum clean all
# 缓存本地yum源
yum makecache
12345678910
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;按ESC。输入:wq保存，完成镜像阿里云源的脚本文件的编写&lt;/li&gt;
&lt;li&gt;赋予脚本可执行的权限&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;chmod +x /root/auto_aliyun.sh
1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;执行脚本文件，即可&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;/root/auto_aliyun.sh
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Docker中文管理面板</title><link>https://6wd.cn/posts/docker-chinese-panel/</link><guid isPermaLink="true">https://6wd.cn/posts/docker-chinese-panel/</guid><description>源码仓库https://github.com/eysp/portainer-ce</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;portainer-ce中文版&lt;/h1&gt;
&lt;p&gt;源码仓库https://github.com/eysp/portainer-ce&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其中arm和ppc64le架构没有设备测试，反馈bug 到GitHub issues&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;pull的已数量突破100K，我不懂编程，非常感谢大家的支持&lt;/em&gt;，想看预览图的点这里https://www.right.com.cn/forum/thread-4066518-1-1.html&lt;/p&gt;
&lt;p&gt;&lt;em&gt;已更新到2.19.1，新版删除左上角升级企业版的广告，删除首次登录弹出英文提示的公告，汉化的广告也隐藏，总之这是一个纯净版&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;如果汉化对你有帮助请往下拉支持我，另外欢迎大家进q群交流，群号758648462（备注portainer）&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;汉化作者：ysp QQ：360354879，基于CE版本更新汉化。工作量居大，感谢作者的辛苦奉献。&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;感谢群里@我不是矿神 指导js精简 | @52Fancy 提供编译脚本&lt;/h1&gt;
&lt;p&gt;一键安装代码**&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -d --restart=always --name=&quot;portainer&quot; -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock 6053537/portainer-ce
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;163镜像安装，portainer-ce中文，访问dockerhub网速不好的尝试&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -d --restart=always --name=&quot;portainer&quot; -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock hub-mirror.c.163.com/6053537/portainer-ce
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;访问hub.docker.com网络慢，或者以上代码都无法安装成功尝试以下代码&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull hub-mirror.c.163.com/6053537/portainer-ce
docker run -d --restart=always --name=&quot;portainer&quot; -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data 6053537/portainer-ce
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>docker常用命令</title><link>https://6wd.cn/posts/docker-common-commands/</link><guid isPermaLink="true">https://6wd.cn/posts/docker-common-commands/</guid><description>启动docker</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Docker 容器相关命令&lt;/h1&gt;
&lt;p&gt;启动&lt;a href=&quot;https://so.csdn.net/so/search?q=docker&amp;amp;spm=1001.2101.3001.7020&quot;&gt;docker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;systemctl start docker&lt;/p&gt;
&lt;p&gt;关闭docker&lt;/p&gt;
&lt;p&gt;systemctl stop docker&lt;/p&gt;
&lt;p&gt;查看docker的运行状态&lt;/p&gt;
&lt;p&gt;systemctl &lt;a href=&quot;https://so.csdn.net/so/search?q=status&amp;amp;spm=1001.2101.3001.7020&quot;&gt;status&lt;/a&gt; docker&lt;/p&gt;
&lt;p&gt;容器是基于Docker镜像被创建的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker run [Options] image&lt;/code&gt;运行容器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run [Options] image

#参数说明
--name=&quot;名字&quot;           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
	-p ip:主机端口:容器端口  配置主机端口映射到容器端口
	-p 主机端口:容器端口（常用）
	-p 容器端口
-P                     随机指定端口
-e					   环境设置
-v					   容器数据卷挂载

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;运行并进入容器centos&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@localhost ~]# docker run -it centos /bin/bash
[root@ce2bbae9f151 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;进入容器&lt;/strong&gt;，因为通常我们的容器都是使用后台方式来运行的，有时需要进入容器修改配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker exec -it 容器id /bin/bash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# docker exec 进入容器后开启一个新的终端，可以在里面操作
docker exec -it 容器id /bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker attach 容器id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  # docker attach 进入容器正在执行的终端
  docker attach 容器id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;退出容器&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exit 	# 停止容器并退出（后台方式运行则仅退出）
Ctrl+P+Q  # 不停止容器退出

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt; 查看运行的容器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 查看当前正在运行的容器
docker ps 
     
-a   # 查看所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q   # 只显示容器的id

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker start 容器id&lt;/code&gt; 启动容器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker start 容器id          # 启动容器
docker restart 容器id        # 重启容器
docker stop 容器id           # 停止当前运行的容器
docker kill 容器id           # 强制停止当前容器

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker logs 容器id&lt;/code&gt;查看容器运行日志&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker logs -tf 容器id
docker logs --tail num 容器id  # num为要显示的日志条数
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker top 容器id&lt;/code&gt;查看容器中进程信息&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker top 容器id

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker inspect 容器id&lt;/code&gt;查看容器的元数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker inspect 容器id

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于centos7系统&lt;/p&gt;
&lt;p&gt;centos7使用firewall命令来开启和关闭防火墙。&lt;/p&gt;
&lt;p&gt;1.systemctl命令&lt;/p&gt;
&lt;p&gt;（1）systemctl  status firewalld.service查看防火墙的状态；&lt;/p&gt;
&lt;p&gt;（2）systemctl  start firewalld.service启动防火墙；&lt;/p&gt;
&lt;p&gt;（3）systemctl  stop firewalld.service关闭防火墙；&lt;/p&gt;
&lt;p&gt;（4）systemctl  restart firewalld.service重启防火墙；&lt;/p&gt;
&lt;p&gt;（5）systemctl  enable firewalld.service开机启动防火墙；&lt;/p&gt;
&lt;p&gt;（6）systemctl  disable firewalld.service开机禁用防火墙；&lt;/p&gt;
&lt;p&gt;（7）systemctl  is-enabled firewalld.service查看防火墙是否开机启动；&lt;/p&gt;
&lt;p&gt;2.Firewall区域管理&lt;/p&gt;
&lt;p&gt;firewall引入了zone概念，firewall能将不同的网络连接归类到不同的信任级别，为了便于理解，这里附上级别说明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; block(阻塞区域)拒绝所有外部的连接，返回icmp-host-prohibited,允许内部发起的连接；

dmz(隔离区域)允许受限制的进入连接；

drop(丢弃区域)丢弃所有进入的包，而不给出任何响应；

external(外部区域)只有指定的连接被接受，一般用于路由转发；

home(家庭区域)允许受信任的计算机被限制的进入连接；

internal(内部区域)信任网络上其他计算机，不会损坏你的计算机。只有选择接受传入的网络连接；

public(公共区域)不信任网络上的任何计算机，只有选择接受传入的网络连接；
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;trusted(信任区域)信任所有连接；&lt;/p&gt;
&lt;p&gt;work(工作区域)允许受信任的计算机被限制的进入连接。&lt;/p&gt;
&lt;p&gt;查看区域管理命令示例：&lt;/p&gt;
&lt;p&gt;（1）firewall-cmd --list-all-zones查看域详情列表；&lt;/p&gt;
&lt;p&gt;（2）firewall-cmd --get-zones查看支持的区域列表；&lt;/p&gt;
&lt;p&gt;（3）firewall-cmd --get-default-zone查看默认的区域列表；&lt;/p&gt;
&lt;p&gt;（4）firewall-cmd --set-default-zone=home设置默认的区域；&lt;/p&gt;
&lt;p&gt;（5）firewall-cmd --zone=home --list-all查看home区域l；&lt;/p&gt;
&lt;p&gt;（6）firewall-cmd --get-active-zone查看活动的区域；&lt;/p&gt;
&lt;p&gt;（7）firewall-cmd --permanent-new-zone=myself创建自己的区域；&lt;/p&gt;
&lt;p&gt;（8）firewall-cmd --permanent-delete-zone=myself删除区域；&lt;/p&gt;
&lt;p&gt;3.Firewall服务端口管理&lt;/p&gt;
&lt;p&gt;在下面提到的命令示例中，带&quot;--permanent&quot;永久生效的策略记录（除了查看）执行后，必须执行&quot;--reload&quot;参数后才能立即生效，否则需要重启后再生效。不带&quot;--permanent&quot;的命令立即生效，但是reload或者restart后失效。&lt;/p&gt;
&lt;p&gt;（1）firewall-cmd --state查看防火墙状态；&lt;/p&gt;
&lt;p&gt;（2）firewall-cmd --get services查看已被firewall提供的一些常用服务；&lt;/p&gt;
&lt;p&gt;（3）firewall-cmd --zone=public --permanent --list-services查看某域的服务（注：加了--permanent表示永久服务，不加显示所有服务，包含临时服务；不加--zone表示默认区域）；&lt;/p&gt;
&lt;p&gt;（4）firewall-cmd --zone=public--permanent --add-service=http添加某域的服务；&lt;/p&gt;
&lt;p&gt;（5）firewall-cmd --zone=public--permanent --remove-service=http移除某域的服务（注：加了--permanent表示永久服务，不加显示所有服务，包含临时服务；不加--zone表示默认区域）；&lt;/p&gt;
&lt;p&gt;（6）firewall-cmd --zone=home--permanent --add-por=5000/tcp添加端口；&lt;/p&gt;
&lt;p&gt;（7）firewall-cmd --zone=home--permanent --remove-por=5000/tcp删除端口；&lt;/p&gt;
&lt;p&gt;（8）firewall-cmd --zone=home--permanent --add-por=5000-5005/tcp添加多端口（注：加了--permanent表示永久服务，不加显示所有服务，包含临时服务；不加--zone表示默认区域；端口后面的tcp和udp表示协议类型）；&lt;/p&gt;
&lt;p&gt;（9）firewall-cmd --zone=public --permanent --list-ports查看端口情况（注：加了--permanent表示永久服务，不加显示所有服务，包含临时服务；不加--zone表示默认区域）；&lt;/p&gt;
&lt;p&gt;（10）firewall-cmd --zone=public --query-service=ssh查询服务是否被允许（不加--zone表示默认区域）；&lt;/p&gt;
&lt;p&gt;（11）firewall-cmd --permanent --zone=public --add-forward-port=80:proto=tcp:toport=8080将80端口的流量转发至8080端口；&lt;/p&gt;
&lt;p&gt;（12）firewall-cmd --permanent --zone=public --add-forward-port=80:proto=tcp:toaddr=192.168.1.1将80端口的流量转发至192.168.1.1；&lt;/p&gt;
&lt;p&gt;（13）firewall-cmd --permanent --zone=public --add-forward-port=80:proto=tcp:toaddr=192.168.1.1:toport=8080将80端口的流量转发至192.168.1.1的端口8080端口（注：不加ip地址，默认转发到本地的端口；不加--zone表示默认区域；不加--permanent表示临时增加，reload或则restart后失效）。&lt;/p&gt;
&lt;p&gt;4.手动编写服务&lt;/p&gt;
&lt;p&gt;可以将某个程序需要的端口写在一个自己编写的服务里，然后直接添加服务就可以。&lt;/p&gt;
&lt;p&gt;/usr/lib/firewalld/services创建自己的服务，格式可以拷贝/etc/firewalld/services任意一个服务。&lt;/p&gt;
&lt;p&gt;（1）查找服务：&lt;/p&gt;
&lt;p&gt;firewalld-cmd --get-srvice |grep myself&lt;/p&gt;
&lt;p&gt;（2）重新加载配置：&lt;/p&gt;
&lt;p&gt;firewall-cmd --reload&lt;/p&gt;
&lt;p&gt;1、安装软件的命令格式
rpm -ivh filename.rpm
1
2、卸载软件的命令格式
rpm -e filename.rpm
1
3、升级软件的命令格式
　rpm -Uvh filename.rpm
1
4、查询软件描述信息的命令格式
rpm -qpi filename.rpm
1
5、列出软件文件信息的命令格式
rpm -qpl filename.rpm
1
6、查询文件属于哪个RPM的命令格式
rpm -qf filename.rpm&lt;/p&gt;
</content:encoded></item><item><title>docker镜像操作</title><link>https://6wd.cn/posts/docker-image-operations/</link><guid isPermaLink="true">https://6wd.cn/posts/docker-image-operations/</guid><description>Docker中的Emby容器的系统目录通常位于容器内部的特定路径中，这取决于您在创建容器时指定的挂载点和配置。通常情况下，Emby的系统目录包括配置文件、数据库和其他运行时数据。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;docker创建的容器，容器目录在哪里&lt;/h2&gt;
&lt;p&gt;Docker中的Emby容器的系统目录通常位于容器内部的特定路径中，这取决于您在创建容器时指定的挂载点和配置。通常情况下，Emby的系统目录包括配置文件、数据库和其他运行时数据。&lt;/p&gt;
&lt;p&gt;您可以通过以下步骤来查找Emby容器的系统目录：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;查找Emby容器的ID或名称：运行 &lt;code&gt;docker ps&lt;/code&gt; 命令，找到正在运行的Emby容器的ID或名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进入容器的Shell：运行以下命令来进入Emby容器的Shell（替换 &lt;code&gt;CONTAINER_ID&lt;/code&gt; 为您的容器ID或名称）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it CONTAINER_ID /bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;寻找Emby的系统目录：一旦进入容器的Shell，您可以浏览容器内部的文件系统，通常Emby的系统目录位于 &lt;code&gt;/config&lt;/code&gt; 或类似的路径中。您可以使用 &lt;code&gt;cd&lt;/code&gt; 命令来导航到相应的目录，然后执行 &lt;code&gt;ls&lt;/code&gt; 命令查看其内容。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;请注意，路径和位置可能会因Emby容器的不同版本和配置而有所不同。如果您在创建容器时进行了自定义配置，系统目录的位置可能会有所改变。&lt;/p&gt;
&lt;h3&gt;如果bash用不了&lt;/h3&gt;
&lt;p&gt;抱歉，看来在您的Emby容器中并没有找到 &lt;code&gt;/bin/bash&lt;/code&gt; 这个Shell。这可能是因为容器内并没有默认的bash shell。&lt;/p&gt;
&lt;p&gt;您可以尝试使用容器内存在的其他Shell，比如 &lt;code&gt;/bin/sh&lt;/code&gt; 或 &lt;code&gt;/bin/ash&lt;/code&gt;。您可以使用以下命令来进入容器的Shell：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it CONTAINER_ID /bin/sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it CONTAINER_ID /bin/ash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一旦您成功进入了容器的Shell，您可以使用 &lt;code&gt;ls&lt;/code&gt; 命令来查找Emby的系统目录。通常情况下，Emby的配置文件和数据存储在 &lt;code&gt;/config&lt;/code&gt; 或类似的路径中。请注意，具体路径可能因Emby版本和容器配置而有所不同。&lt;/p&gt;
&lt;p&gt;要退出容器内的Shell模式，您可以输入 &lt;code&gt;exit&lt;/code&gt; 命令，然后按下回车键。这会使您返回到主机操作系统的命令行界面。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将关闭您在容器内打开的Shell会话，并将您带回到之前的命令行终端。&lt;/p&gt;
&lt;h2&gt;如何将docker容器打包成镜像&lt;/h2&gt;
&lt;p&gt;将Docker容器打包成镜像通常需要使用Docker命令 &lt;code&gt;docker commit&lt;/code&gt; 来创建一个新的镜像。以下是基本步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;确认容器状态：&lt;/strong&gt; 在您想要打包成镜像的容器内部，确保容器处于一个稳定的状态，您可以保存为一个镜像。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;获取容器ID或名称：&lt;/strong&gt; 使用 &lt;code&gt;docker ps&lt;/code&gt; 命令找到您要打包成镜像的容器的ID或名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建镜像：&lt;/strong&gt; 运行 &lt;code&gt;docker commit&lt;/code&gt; 命令来创建一个新的镜像。命令的格式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker commit CONTAINER_ID NEW_IMAGE_NAME:TAG
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中，&lt;code&gt;CONTAINER_ID&lt;/code&gt; 是容器的ID或名称，&lt;code&gt;NEW_IMAGE_NAME&lt;/code&gt; 是您想要为新镜像设置的名称，&lt;code&gt;TAG&lt;/code&gt; 是镜像的标签（如版本号等）。示例命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker commit my_container my_image:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将基于 &lt;code&gt;my_container&lt;/code&gt; 容器创建一个名为 &lt;code&gt;my_image&lt;/code&gt; 的新镜像，标签为 &lt;code&gt;latest&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;验证镜像创建：&lt;/strong&gt; 运行 &lt;code&gt;docker images&lt;/code&gt; 命令，您将能够看到刚刚创建的新镜像在列表中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;上传镜像（可选）：&lt;/strong&gt; 如果您想要分享或在其他地方使用这个新创建的镜像，您可以使用 &lt;code&gt;docker push&lt;/code&gt; 命令将镜像上传到Docker Hub或其他容器注册表。注意，上传镜像需要您在Docker Hub上有一个账号。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;请注意，使用 &lt;code&gt;docker commit&lt;/code&gt; 创建镜像可能不是最佳的实践，因为它不会包含完整的构建历史和Dockerfile信息。更好的方式是使用 Dockerfile 来构建镜像，这样可以更好地追踪镜像的构建过程和配置。&lt;/p&gt;
</content:encoded></item><item><title>emby linux一件脚本</title><link>https://6wd.cn/posts/emby-linux-one-click-script/</link><guid isPermaLink="true">https://6wd.cn/posts/emby-linux-one-click-script/</guid><description>echo &apos;-------------------web 端开心-------------------&apos;</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;echo &quot;-------------------web 端开心-------------------&quot;
echo &quot;使用脚本前，请先进入到 emby 的 system 目录下&quot;
echo &quot;官方包直接安装的路径为：cd /opt/emby-server/system/&quot;
echo &quot;&quot;
echo &quot;docker 安装请自己找路径进入再执行&quot;
echo &quot;-------------------我们的域名：https://hexsen.com-------------------&quot;
rm -f Emby.Web.dll
wget https://ff.6wd.cn/file/emby/Emby.Web.dll
rm -f MediaBrowser.Model.dll
wget https://ff.6wd.cn/file/emby/MediaBrowser.Model.dll
echo &quot;核心开心完成...&quot;lient/
cd dashboard-ui/embypremiere/
rm -f embypremiere.js
wget https://ff.6wd.cn/file/emby/embypremiere.js
chmod 777 /embypremiere.js
echo &quot;web 开心完成...&quot;
cd ../../
rm -f Emby.Server.Implementations.dll
wget https://ff.6wd.cn/file/emby/Emby.Server.Implementations.dll
echo &quot;Implementations 替换认证...&quot;
chmod 644 Emby.Web.dll Emby.Server.Implementations.dll MediaBrowser.Model.dll
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>emby本地破解方法</title><link>https://6wd.cn/posts/emby-local-crack-method/</link><guid isPermaLink="true">https://6wd.cn/posts/emby-local-crack-method/</guid><description>getexpDate    返回值  DateTimeOffset.UtcNow.AddDays(999.0);（RegRecord）</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Emby.Server.Implementations.dll&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;get_expDate    返回值  DateTimeOffset.UtcNow.AddDays(999.0);（RegRecord）
get_isValid    返回值  true;（RegRecord）
get_registered 返回值  true;（RegRecord）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;源码所在地&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/05/20230905151128.png&quot; alt=&quot;image-20230905151121569&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;MediaBrowser.Model.dll&lt;/h2&gt;
&lt;p&gt;源码位置&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/05/20230905151453.png&quot; alt=&quot;image-20230905151453638&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get_IsMBSupporter 返回值  true;

何先生建议不修改此项：get_SupporterKey 返回值  &quot;何先生破解&quot;;

关闭检测更新
方法
hasUpdateAvailable 返回值 false (systeminfo)

EnableAutomaticRestart 返回值 false
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Emby.Web.dll&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;提取 Emby.Web.dashboard_ui.modules.emby_apiclient.connectionmanager.js 

搜索 timeSinceLastValidation=Date.now()-(feature.lastValidDate||0);
将 return timeSinceLastValidation&amp;lt;=864e5?(console.log(&quot;getRegistrationInfo returning cached info&quot;),Promise.resolve()):
替换为 if (true) return console.log(&quot;getRegistrationInfo returning cached info&quot;),Promise.resolve();

提取 Emby.Web.dashboard_ui.modules.registrationservices.registrationservices.js 
//如果是 mac 客户端，文件在/Applications/Emby.app/Contents/Resources/www/modules/registrationservices/registrationservices.js

搜索 validateFeature 最后

从 _exports.default={validateFeature:function(feature,options){ 后面
全部替换
return Promise.resolve();},showPremiereInfo:showPremiereInfo}});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;embypremiere.js&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;文位置在system\dashboard-ui\embypremiere&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;搜索 _loading.default.show(),
将前面的 return 删除

搜索 Plugins/SecurityInfo
将 getJSON(apiClient.getUrl(&quot;Plugins/SecurityInfo&quot;)).then(function(info){ 到 if(statusInfo) 中间的代码替换为：
page.querySelector(&quot;.txtSupporterKey&quot;).value = info.SupporterKey || &quot;&quot;,
            page.querySelector(&quot;.txtSupporterKey&quot;).classList.add(&quot;invalidEntry&quot;), 
            page.querySelector(&quot;.notSupporter&quot;).classList.add(&quot;hide&quot;),
            page.querySelector(&quot;.supporterContainer&quot;).classList.add(&quot;hide&quot;),key = info.SupporterKey;
                    var statusInfo = {
                  &quot;deviceStatus&quot;: &quot;0&quot;,
                  &quot;planType&quot;: &quot;Lifetime&quot;,
                  &quot;subscriptions&quot;: {}
                };
比如下面：
page.querySelector(&quot;.txtSupporterKey&quot;).value=info.SupporterKey||&quot;&quot;,info.SupporterKey&amp;amp;&amp;amp;!info.IsMBSupporter?(page.querySelector(&quot;.txtSupporterKey&quot;).classList.add(&quot;invalidEntry&quot;),page.querySelector(&quot;.notSupporter&quot;).classList.remove(&quot;hide&quot;)):(page.querySelector(&quot;.txtSupporterKey&quot;).classList.remove(&quot;invalidEntry&quot;),page.querySelector(&quot;.notSupporter&quot;).classList.add(&quot;hide&quot;)),info.IsMBSupporter?(page.querySelector(&quot;.supporterContainer&quot;).classList.add(&quot;hide&quot;),function(key){key=&quot;key=&quot;+key+&quot;&amp;amp;serverId=&quot;+ApiClient.serverId();return fetch(&quot;https://mb3admin.com/admin/service/registration/getStatus&quot;,{method:&quot;POST&quot;,body:key,headers:{&quot;Content-Type&quot;:&quot;application/x-www-form-urlencoded&quot;}}).then(function(response){return response.json()})}(info.SupporterKey).then(function(statusInfo){

替换

page.querySelector(&quot;.txtSupporterKey&quot;).value = info.SupporterKey || &quot;&quot;,
            page.querySelector(&quot;.txtSupporterKey&quot;).classList.add(&quot;invalidEntry&quot;), 
            page.querySelector(&quot;.notSupporter&quot;).classList.add(&quot;hide&quot;),
            page.querySelector(&quot;.supporterContainer&quot;).classList.add(&quot;hide&quot;),key = info.SupporterKey;
                    var statusInfo = {
                  &quot;deviceStatus&quot;: &quot;0&quot;,
                  &quot;planType&quot;: &quot;Lifetime&quot;,
                  &quot;subscriptions&quot;: {}
                };

然后删除替换 var subs,key;_loading.default.hide()})):(page.querySelector(&quot;.supporterContainer&quot;).classList.remove(&quot;hide&quot;),page.querySelector(&quot;.isSupporter&quot;).classList.add(&quot;hide&quot;),_loading.default.hide(),Promise.resolve())});

为 }),_loading.default.hide();
        
在 classList.remove(&quot;hide&quot;)}}) 后面添加 ,_loading.default.hide()

如   querySelector(&quot;.isSupporter&quot;).classList.remove(&quot;hide&quot;)}}),_loading.default.hide()  
将 page.querySelector(&quot;.txtSupporterKey&quot;)前的return删除
搜索删除 ),_loading.default.hide(
/*
删除 var subs,key;
            })) : (page.querySelector(&quot;.supporterContainer&quot;).classList.remove(&quot;hide&quot;), page.querySelector(&quot;.isSupporter&quot;).classList.add(&quot;hide&quot;)), _loading.default.hide()
 
在 }) 后面添加 ,_loading.default.hide();

例如 querySelector(&quot;.isSupporter&quot;).classList.remove(&quot;hide&quot;)}}),_loading.default.hide()  
*/

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;/Contents/Resources/www/modules/emby-apiclient/connectionmanager.js 文件修改，针对 mac 客户端&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;//搜索以下代码
getRegistrationInfo(feature, apiClient, options) { 中间的代码全部替换为以下代码 } 

//替换代码
      getRegistrationInfo(feature, apiClient, options) {
        const params = {
          serverId: apiClient.serverId(),
          deviceId: this.deviceId(),
          deviceName: this.deviceName(),
          appName: this.appName(),
          appVersion: this.appVersion()
        };
      
        // Simulate successful validation without making a request
        const simulatedResponse = {
          cacheExpirationDays: 999
        };
      
        // Generate cache key
        const cacheKey = getCacheKey(feature, apiClient, options);
      
        // Store simulated response in app storage
        this.appStorage.setItem(cacheKey, JSON.stringify({
          lastValidDate: Date.now(),
          deviceId: params.deviceId,
          cacheExpirationDays: simulatedResponse.cacheExpirationDays,
          lastUpdated: Date.now()
        }));
      
        // Return a resolved Promise
        return Promise.resolve();
      }
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>在线升级版本：ESXI6.5升级7.0</title><link>https://6wd.cn/posts/esxi-65-to-70-online-upgrade/</link><guid isPermaLink="true">https://6wd.cn/posts/esxi-65-to-70-online-upgrade/</guid><description>将一台使用ESXI6.7的虚升级条件</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;将一台使用ESXI6.7的虚升级条件
1、首先确保硬件是否能升级到7.0版本，注意：物理网卡驱动为e1000e不能升级，如果是igbn（只要不是e1000e都行），则可以顺利升级。拟机升级到了7.0版本。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210118.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;升级方法 升级方法有补丁升级、在线升级和U盘升级三种方式，我使用的是补丁升级，下面是升级过程。&lt;/h4&gt;
&lt;h2&gt;1.查询+下载补丁&lt;/h2&gt;
&lt;p&gt;VMware-&lt;a href=&quot;https://so.csdn.net/so/search?q=ESXi&amp;amp;spm=1001.2101.3001.7020&quot;&gt;ESXi&lt;/a&gt;-7.0b-16324942-depot.zip&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://my.vmware.com/cn/group/vmware/patch#search&quot;&gt;Login | VMware Customer Connect&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;2、上传文件&lt;/h2&gt;
&lt;p&gt;通过Web管理界面，将文件VMware-ESXi-7.0b-16324942-depot.zip上传到ESXI存储设备的根目录。如下图所示：&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210147.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3.在Terminal终端软件上&lt;a href=&quot;https://so.csdn.net/so/search?q=SSH&amp;amp;spm=1001.2101.3001.7020&quot;&gt;SSH&lt;/a&gt;到ESXi&lt;/h2&gt;
&lt;p&gt;$ ssh root@X.X.X.X&lt;/p&gt;
&lt;p&gt;自己服务器的IP地址，然后输入账号密码。&lt;/p&gt;
&lt;h2&gt;5、删除不兼容驱动&lt;/h2&gt;
&lt;p&gt;先找到存储设备位置并记录下来，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210158.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/vmfs/volumes/60c85952-d6d7deec-9ef6-40f2e930abd8&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;进入执行以下命令：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cd /vmfs/volumes/60c85952-d6d7deec-9ef6-40f2e930abd8&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;升级第一步&lt;/strong&gt;，找到升级模块名称。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;esxcli software sources profile list -d /vmfs/volumes/5cb88c50-f1c6a935-c840-406231072a3a/VMware-ESXi-7.0b-16324942-depot.zip &lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210211.jpeg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里显示有三个模块，我们要升级的模块为“ESXi-7.0b-16324942-standard”&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;升级第二步&lt;/strong&gt;，检查是否能正常升级。注意用查到的升级模块替换对应的参数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;esxcli software profile update -p ESXi-7.0b-16324942-standard -d /vmfs/volumes/5cb88c50-f1c6a935-c840-406231072a3a/VMware-ESXi-7.0b-16324942-depot.zip --dry-run&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210224.jpeg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果出现跟上图一样的情况，就说明老版本集成的驱动与7.0版本不兼容。需要卸载老版本集成的不兼容驱动。&lt;/p&gt;
&lt;p&gt;先记下不兼容的驱动文件版本名称，这里是 &lt;a href=&quot;https://so.csdn.net/so/search?q=sata&amp;amp;spm=1001.2101.3001.7020&quot;&gt;sata&lt;/a&gt;-xahci-1.3-1。输入以下命令查看原&lt;a href=&quot;https://so.csdn.net/so/search?q=%E7%B3%BB%E7%BB%9F%E9%9B%86%E6%88%90&amp;amp;spm=1001.2101.3001.7020&quot;&gt;系统集成&lt;/a&gt;的所有驱动，找到不兼容驱动的文件名称：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;esxcli software vib list&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210242.jpeg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;该不兼容驱动的文件名称为“sata-xahci”，执行以下命令删除集成驱动：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;esxcli software vib remove -n sata-xahci&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210326.jpeg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果有多个不兼容驱动，可以一起进行删除。&lt;/p&gt;
&lt;h2&gt;6、正常升级&lt;/h2&gt;
&lt;p&gt;解决了驱动兼容问题以后，执行下面的升级命令：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;esxcli software profile update -p ESXi-7.0b-16324942-standard -d /vmfs/volumes/5cb88c50-f1c6a935-c840-406231072a3a/VMware-ESXi-7.0b-16324942-depot.zip
如果升级正常，就会出现大量的字符。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210336.jpeg&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接着手动输入重启命令，升级完成。（下图中已经接着升级到了7.01版本）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;reboot&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此，升级过程全部完成。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127210358.png&quot; alt=&quot;image-20240127210357965&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>esxi7升级83种方式！</title><link>https://6wd.cn/posts/esxi7-to-esxi8-three-methods/</link><guid isPermaLink="true">https://6wd.cn/posts/esxi7-to-esxi8-three-methods/</guid><description>现在可以下载esxi 8.0版本，许多人可能会考虑将他们的esxi7升级8来安装新版本。让我们通过三种方式了解esxi升级8.0的不同方式。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;现在可以下载esxi 8.0版本，许多人可能会考虑将他们的esxi7升级8来安装新版本。让我们通过三种方式了解esxi升级8.0的不同方式。&lt;/p&gt;
&lt;h2&gt;引入新的vSphere 8&lt;/h2&gt;
&lt;p&gt;如果你使用vSphere 7并且关注IT新闻，你可能听说过VMware发布了稳定的新版本vSphere 8.0。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.abackup.com/enterprise-backup/image6540/virtual-machine/vmware-vsphere-8.png&quot;&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215211.png&quot; alt=&quot;vsphere 8&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;vSphere 8.0支持每个虚拟机可以运行8个vGPU，与vSphere 7 U3相比增加了两倍，让您可以运行更多、更强大的虚拟机，并更快地执行任务。此外，还有更多新品vSphere 8 功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vSphere分布式服务引擎&lt;/li&gt;
&lt;li&gt;Tanzu Kubernetes Grid 2.0&lt;/li&gt;
&lt;li&gt;Lifecycle Management&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么，您是否需要立即从vSphere 7升级到vSphere 8？这取决于您的需求。但为了避免发生意外，提前做好esxi7升级8.0和vCenter 8的准备总是必不可少的。接下来，本文将提供从vSphere 7升级到vSphere 8的3种方式，并回答一些常见问题。&lt;/p&gt;
&lt;h2&gt;vSphere 8的预升级&lt;/h2&gt;
&lt;p&gt;在开始升级到vSphere 8之前，您应该对vSphere环境执行一些维护和管理活动。&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;**检查兼容性：**vSphere 8不支持6.5或更早版本的任何组件。因此，您可能先需要将某些组件升级到版本6.7以上，并在继续升级之前检查这些不兼容性组件。&lt;/li&gt;
&lt;li&gt;**健康检查：**如果环境不处于健康状态，可能会发生错误，可能需要回滚。&lt;/li&gt;
&lt;li&gt;**SSO域拓扑重新配置：**您可以选择自动执行外部平台服务控制器（Platform Services Controller）融合，或在升级之前手动执行聚合或域重新指向任务。&lt;/li&gt;
&lt;li&gt;**移除vCenter HA：**停用和移除vCenter HA可简化升级工作流程，并在升级失败时更容易进行故障排除。&lt;/li&gt;
&lt;li&gt;**备份您的环境：**升级前备份您的vSphere环境非常重要，包括ESXi VM、ESXi和vCenter 配置、Platform Services Controller、分布式虚拟交换机等。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;通过傲梅企业备份旗舰版可以批量备份由vCenter管理的虚拟机：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.abackup.com/cyber-backup.html&quot;&gt;傲梅企业备份旗舰版&lt;/a&gt;是一款不需要代理的VM备份软件，支持付费和免费版本的VMware ESXi。它还允许您批量备份由vCenter Server管理的多个虚拟机，并集中监控这些虚拟机的数据保护，让您摆脱繁重而费力的管理任务。&lt;/p&gt;
&lt;h2&gt;如何将vSphere 7升级到8&lt;/h2&gt;
&lt;p&gt;在将ESXi 7主机升级到ESXi 8之前，您应该首先检查ESXi8的安装要求，包括硬件、兼容性要求等。我将通过以下3种方式升级到ESXi 8：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用ISO镜像文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用vSphere Lifecycle Manager&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用ESXCLI命令&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**注意：**如果升级由vCenter Server管理的主机，您必须在升级ESXi主机之前更新vCenter Server。如果您没有按照正确的顺序升级您的环境，您可能会丢失数据并无法访问服务器。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215305.png&quot; alt=&quot;esxi升级过程&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;✔ 使用ISO从esxi7升级8&lt;/h3&gt;
&lt;p&gt;你应该下载ESXi 8.0 ISO映像在将esxi7升级8之前。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;访问您的VMware ESXi Web客户端（ESXi 7.0），右键单击左侧清单中的**“管理”&lt;strong&gt;并选择&lt;/strong&gt;“进入维护模式”**。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215316.png&quot; alt=&quot;进入维护模式&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;您可以将ISO挂载到您的远程控制台，将引导配置为从ISO引导并重新启动您的服务器。开始ESXi 8.0引导，引导至安装程序/升级程序。然后按照菜单选择安装ESXI的磁盘。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://www.abackup.com/enterprise-backup/image6540/virtual-machine/boot-into-installer.png&quot; alt=&quot;esxi8引导&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;升级过程成功完成后，安装程序会要求您移除安装介质，然后重新启动。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://www.abackup.com/enterprise-backup/image6540/virtual-machine/complete-upgrading-esxi-8-using-iso.png&quot;&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215349.png&quot; alt=&quot;重新启动&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;✔ 使用vSphere Lifecycle Manager将esxi7升级8&lt;/h3&gt;
&lt;p&gt;对于由vCenter在集群级别管理的主机中您可以使用vSphere Lifecycle Manager作为虚拟中心服务器。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;启动vSphere Client并登录到vCenter Server，然后导航到vSphereCluster的属性，单击**“更新”&lt;strong&gt;选项卡。然后单击&lt;/strong&gt;“映像”&amp;gt;“设置映像”**。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215527.png&quot; alt=&quot;设置映像&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;从ESXi版本的下拉列表中选择ESXi 8.0版本。点击**“保存”**。&lt;/li&gt;
&lt;li&gt;确认继续完成映像设置。&lt;/li&gt;
&lt;li&gt;检查集群级别的合规性。我们需要修复主机。在这里，我单击**“全部修复”**按钮。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215428.png&quot; alt=&quot;全部修复&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提示操作影响的对话框将弹出。单击**“开始修复”**按钮。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;主机开始修复。几分钟后，您将看到ESXi主机重新启动，并在从vSphere Lifecycle Manager升级后引导至ESXi 8.0。&lt;/p&gt;
&lt;h3&gt;✔ 使用命令行升级到ESXi 8&lt;/h3&gt;
&lt;p&gt;接下来，我们可以使用命令行升级现有的ESXi主机。只需几个命令即可轻松完成此操作，包括以下命令：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;esxcli network firewall ruleset set -e true -r httpClient&lt;/li&gt;
&lt;li&gt;esxcli software profile update -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml -p ESXi-8.0.0-20513097-standard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.abackup.com/enterprise-backup/image6540/virtual-machine/esxcli-command-to-upgrade-to-esxi-8.png&quot;&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/27/20240127215448.png&quot; alt=&quot;命令行升级esxi&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当您看到**“The update completed successfully”**时，您需要重新启动ESXi主机。&lt;/p&gt;
&lt;p&gt;Esxi7升级8的过程很简单。在大多数情况下，许多人会尝试在实验室环境中执行此操作，因为大多数人可能会在其生产环境中推迟。但是，如果要将ESXi主机升级到8.0版本，则必须备份VMware ESXi以防发生故障。&lt;/p&gt;
&lt;h2&gt;问答：有关esxi升级8.0的常见问题解答&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ESXi 6.7 将支持多长时间？&lt;/strong&gt;
vSphere 6.7计划于2022年10月15日达到停止维护，并于2023年11月15日达到停止技术支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ESXi版本可以高于vCenter吗？&lt;/strong&gt;
不可以，VMware不建议使用内部版本号高于vCenter Server的ESXi主机。vCenter Server版本必须与ESXi主机版本相同或更高，或者内部版本号必须高于或与ESXi主机内部版本号相同。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;我可以远程升级ESXi吗？&lt;/strong&gt;
可以的，您可以通过在线捆绑包将ESXi更新到新版本。此方法适合拥有免费ESXi许可证但无法访问脱机捆绑包的用户。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;我可以回滚ESXi升级吗？&lt;/strong&gt;
可以的，您可以使用直接控制台用户界面恢复到先前版本或ESXi内部版本。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;将现有esxi7升级8非常简单，可以通过多种方式完成，包括使用ISO、命令行和vSphere Lifecycle Manager。希望本文提供的多种方法有助于快速使您的实验室环境保持更新的状态。&lt;/p&gt;
</content:encoded></item><item><title>防火墙常用命令</title><link>https://6wd.cn/posts/firewall-common-commands/</link><guid isPermaLink="true">https://6wd.cn/posts/firewall-common-commands/</guid><description>systemctl status firewalld.service</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;CentOS6/7&lt;/h1&gt;
&lt;h3&gt;查看防火墙状态&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl status firewalld.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行上述命令后，如果看到有绿色字样标注的“active（running）”，说明防火墙是开启状态。&lt;/p&gt;
&lt;h3&gt;开启防火墙&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl start firewalld.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;关闭防火墙&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop firewalld.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关闭后，可查看防火墙状态，当显示disavtive（dead）的字样，说明CentOS 7防火墙已经关闭。
但要注意的是，上面的命令只是临时关闭了CentOS 7防火墙，当重启操作系统后，防火墙服务还是会再次启动。如果想要永久关闭防火墙则还需要禁用防火墙服务。&lt;/p&gt;
&lt;h3&gt;禁用防火墙服务&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl disable firewalld.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;查看防火墙规则&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd –list-all
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;查询端口是否开放&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd –query-port=8080/tcp
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;重启防火墙&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd –reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;开放指定(如8080)端口&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --zone=public --add-port=8080/tcp --permanent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(修改配置后需要重启防火墙)&lt;/p&gt;
&lt;h3&gt;移除某个防火墙开启的端口&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --zone=public --remove-port=5000-6000/tcp --permanent1.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(修改配置后需要重启防火墙)&lt;/p&gt;
&lt;h1&gt;CentOS Stream 8/9&lt;/h1&gt;
&lt;h3&gt;查看防火墙状态&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl status firewalld

firewall-cmd --state
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;开启/关闭/重启防火墙&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;systemctl start firewalld
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl stop firewalld
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart firewalld
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;放行指定端口&lt;/h3&gt;
&lt;p&gt;firewall-cmd --zone=public --add-port=端口号/tcp --permanent&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --zone=public --add-port=80/tcp --permanent # http
firewall-cmd --zone=public --add-port=443/tcp --permanent #https
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;放行范围端口&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --zone=public --add-port=5000-6000/tcp --permanent1.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除防火墙端口&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --zone=public --remove-port=5000-6000/tcp --permanent1.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改防火墙后，都要对防火墙进行刷新&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查看防火墙某个端口是否开放与开放哪些端口&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;firewall-cmd --query-port=端口号/tcp
firewall-cmd --zone=public --list-ports
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Ubuntu&lt;/h1&gt;
&lt;p&gt;在 &lt;a href=&quot;https://so.csdn.net/so/search?q=Ubuntu&amp;amp;spm=1001.2101.3001.7020&quot;&gt;Ubuntu&lt;/a&gt; 中，可以使用 &lt;code&gt;ufw&lt;/code&gt;（Uncomplicated &lt;a href=&quot;https://so.csdn.net/so/search?q=Firewall&amp;amp;spm=1001.2101.3001.7020&quot;&gt;Firewall&lt;/a&gt;）来管理防火墙。以下是在 Ubuntu 中查看、开启、关闭和永久关闭防火墙的方法：&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;查看防火墙状态：&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;要查看 Ubuntu 中 &lt;code&gt;ufw&lt;/code&gt; 防火墙的状态，可以执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ufw status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将显示当前防火墙规则的状态，包括是否启用和允许的规则。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;开启防火墙：&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;如果防火墙没有启用，可以使用以下命令来启用 &lt;code&gt;ufw&lt;/code&gt; 防火墙：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ufw enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启用防火墙后，它将按照默认规则开始工作，通常会拒绝所有传入连接，但允许所有传出连接。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;关闭防火墙：&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;要关闭 &lt;code&gt;ufw&lt;/code&gt; 防火墙，可以执行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ufw disable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://so.csdn.net/so/search?q=%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99&amp;amp;spm=1001.2101.3001.7020&quot;&gt;关闭防火墙&lt;/a&gt;后，所有传入和传出的连接将被允许，不再受到防火墙的限制。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;永久关闭防火墙：&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;如果想永久关闭 &lt;code&gt;ufw&lt;/code&gt; 防火墙，可以执行以下步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;停止 &lt;code&gt;ufw&lt;/code&gt; 服务：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl stop ufw&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁用 &lt;code&gt;ufw&lt;/code&gt; 服务的自动启动：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo systemctl disable ufw&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启系统，以确保防火墙不会在系统启动时重新启用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>halo自动备份到alist-s3脚本</title><link>https://6wd.cn/posts/halo-auto-backup-alist-s3/</link><guid isPermaLink="true">https://6wd.cn/posts/halo-auto-backup-alist-s3/</guid><description>- Python 3.x</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Halo 备份和 S3 上传教程&lt;/h1&gt;
&lt;h2&gt;环境要求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.x&lt;/li&gt;
&lt;li&gt;&lt;code&gt;boto3&lt;/code&gt; 库：用于与 S3 兼容服务交互&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requests&lt;/code&gt; 库：用于发送 HTTP 请求&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;前提要求：&lt;code&gt;如果你还没有安装alist或者任何s3服务的，你可以参考我的这篇文章&lt;/code&gt;(&lt;a href=&quot;https://6wd.cn/2024/08/29/1724927379116#%E8%BF%99%E4%B8%80%E9%83%A8%E5%88%86%E5%B0%B1%E6%98%AF%E4%BD%BF%E7%94%A8composer%E6%9D%A5%E5%AE%89%E8%A3%85AWS-S3%E4%BB%A5%E5%8F%8A%E9%98%BF%E9%87%8COSS%E7%9A%84SDK%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;Alist/S3/阿里ossz制作随机图片api | 枫の屋 (6wd.cn)&lt;/a&gt;)&lt;/h2&gt;
&lt;h2&gt;注：如果你完成了alist的s3配置或者任何s3服务，您可以继续往下看了&lt;/h2&gt;
&lt;h2&gt;步骤一：安装依赖&lt;/h2&gt;
&lt;p&gt;使用以下命令安装所需的库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install boto3 requests
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;步骤二：创建 Python 脚本&lt;/h2&gt;
&lt;p&gt;创建一个新的 Python 脚本（例如 &lt;code&gt;backup_script.py&lt;/code&gt;），并将以下代码粘贴到文件中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 代码示例
import os
import base64
import time
import requests
import json
import boto3
from botocore.exceptions import NoCredentialsError, PartialCredentialsError
from datetime import datetime, timedelta  # 确保导入 timedelta
import logging

# 设置日志配置
log_file_path = &apos;/www/wwwroot/Docker/halo/backup-auto/backup_log.txt&apos;
logging.basicConfig(filename=log_file_path, level=logging.INFO, format=&apos;%(asctime)s - %(levelname)s - %(message)s&apos;)

# Halo用户信息
user = &quot;username&quot;  # 替换为您的 Halo 用户名
password = &quot;password&quot;  # 替换为您的 Halo 密码

# 自定义 S3 兼容服务配置
aws_access_key_id = &quot;aws-id&quot;  # 替换为您的 AWS 访问密钥ID
aws_secret_access_key = &quot;aws-key&quot;  # 替换为您的 AWS 秘密访问密钥
aws_bucket_name = &quot;bucket-name&quot;  # 替换为您的 S3 存储桶名称
aws_region = &quot;auto&quot;  # S3 存储桶所在的 AWS 区域
endpoint_url = &quot;http://ip:端口&quot;  # 自定义的 S3 兼容服务的 endpoint(ip+端口/域名)

# 网站地址
website = &quot;https://6wd.cn&quot;  #halo域名地址
# halo备份文件夹路径
backup_halo_path = &quot;~/halo/halo2/backups&quot; #填写你的备份文件地址

# 设置有效期（天）
expiry_days = 3  # 可以设置为任何值，例如3天
expires_at = (datetime.utcnow() + timedelta(days=expiry_days)).strftime(&apos;%Y-%m-%dT%H:%M:%S.%f&apos;)[:-3] + &apos;Z&apos;

# Halo API不变
backup_api = website + &quot;/apis/migration.halo.run/v1alpha1/backups&quot;
check_api = website + &quot;/apis/migration.halo.run/v1alpha1/backups?sort=metadata.creationTimestamp%2Cdesc&quot;

# 获取当前时间
now_time = datetime.now().strftime(&apos;%Y-%m-%dT%H:%M:%S.%f&apos;)[:-3] + &apos;Z&apos;
auth_header = &quot;Basic &quot; + base64.b64encode((user + &quot;:&quot; + password).encode()).decode()

payload = json.dumps({
    &quot;apiVersion&quot;: &quot;migration.halo.run/v1alpha1&quot;,
    &quot;kind&quot;: &quot;Backup&quot;,
    &quot;metadata&quot;: {
        &quot;generateName&quot;: &quot;suki-backup-&quot;,
        &quot;name&quot;: &quot;&quot;
    },
    &quot;spec&quot;: {
        &quot;expiresAt&quot;: expires_at,  # 设置有效期
    }
})
headers = {
    &apos;Content-Type&apos;: &apos;application/json&apos;,
    &apos;Authorization&apos;: auth_header,
}

# 发送备份请求
response = requests.post(backup_api, headers=headers, data=payload)
logging.info(response.text)  # 记录响应内容

if response.status_code == 201:
    logging.info(&quot;备份请求成功！&quot;)
    while True:
        time.sleep(10)  # 等待10秒后再次检查状态
        check_response = requests.get(check_api, headers=headers)
        if check_response.status_code == 200:
            backup_data = json.loads(check_response.text)
            items = backup_data.get(&quot;items&quot;, [])
            if items and items[0][&quot;status&quot;][&quot;phase&quot;] == &quot;SUCCEEDED&quot;:
                logging.info(&quot;备份完成！&quot;)
                # 捕获带有时间戳的最新文件
                backup_files = [f for f in os.listdir(backup_halo_path) if f.endswith(&apos;.zip&apos;)]
                backup_files.sort(reverse=True)
                if backup_files:
                    new_backup_name = backup_files[0]
                    file_path = os.path.join(backup_halo_path, new_backup_name)
                    logging.info(f&quot;文件准备上传：{file_path}&quot;)
                    break
            elif items and items[0][&quot;status&quot;][&quot;phase&quot;] == &quot;RUNNING&quot;:
                logging.info(&quot;正在备份！&quot;)
        else:
            logging.error(f&quot;查询备份请求失败！错误代码：{check_response.status_code}&quot;)
else:
    logging.error(f&quot;备份请求失败！错误代码：{response.status_code}&quot;)

# 检查文件是否存在并上传到自定义 S3 兼容服务
if os.path.exists(file_path):
    def upload_to_s3(file_path):
        try:
            # 创建 S3 客户端
            s3_client = boto3.client(
                &apos;s3&apos;,
                aws_access_key_id=aws_access_key_id,
                aws_secret_access_key=aws_secret_access_key,
                endpoint_url=endpoint_url,
                region_name=aws_region
            )

            logging.info(f&quot;正在上传文件 {file_path} 到存储桶 {aws_bucket_name}...&quot;)
            # 使用 upload_file 方法上传整个文件
            s3_client.upload_file(file_path, aws_bucket_name, os.path.basename(file_path))
            logging.info(&quot;上传完成！&quot;)
            return True

        except FileNotFoundError:
            logging.error(f&quot;文件不存在：{file_path}&quot;)
            return False
        except NoCredentialsError:
            logging.error(&quot;AWS 凭证未找到，请检查配置。&quot;)
            return False
        except PartialCredentialsError:
            logging.error(&quot;AWS 凭证不完整，请检查配置。&quot;)
            return False
        except Exception as e:
            logging.error(f&quot;上传过程中发生错误：{e}&quot;)
            return False

    # 尝试上传到自定义 S3 兼容服务
    upload_to_s3(file_path)
else:
    logging.error(f&quot;文件不存在：{file_path}&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;步骤三：配置脚本&lt;/h2&gt;
&lt;p&gt;在脚本中，您需要输入以下信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Halo 用户名&lt;/strong&gt;：在提示中输入您的 Halo 用户名。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Halo 密码&lt;/strong&gt;：在提示中输入您的 Halo 密码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS 访问密钥ID&lt;/strong&gt;：在提示中输入您的 AWS 访问密钥ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS 秘密访问密钥&lt;/strong&gt;：在提示中输入您的 AWS 秘密访问密钥。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S3 存储桶名称&lt;/strong&gt;：输入您创建的 S3 存储桶名称。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自定义 S3 兼容服务的 endpoint&lt;/strong&gt;：输入您的 S3 服务的 endpoint (ip+端口/域名)。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;步骤四：设置有效期&lt;/h2&gt;
&lt;p&gt;您可以在脚本中设置备份的有效期（以天为单位）。例如，将 &lt;code&gt;expiry_days&lt;/code&gt; 设置为 &lt;code&gt;3&lt;/code&gt; 表示有效期为 3 天。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;expiry_days = 3  # 备份有效期（天）
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;步骤五：运行脚本&lt;/h2&gt;
&lt;p&gt;在终端中运行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 /path/to/your/backup_script.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;步骤六：查看日志&lt;/h2&gt;
&lt;p&gt;所有输出信息将显示在终端中。确保检查 S3 存储桶，以确认文件是否上传成功。&lt;/p&gt;
&lt;h2&gt;步骤七：设置自动化&lt;/h2&gt;
&lt;p&gt;自动化一般使用宝塔的&lt;code&gt;计划任务&lt;/code&gt;点击右上角的“添加任务”按钮，在“任务类型”中选择“Shell 脚本”或“Python 脚本”，在“任务内容”中输入以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 /www/wwwroot/Docker/halo/backup-auto/backup_script.py &amp;gt;&amp;gt; /www/wwwroot/Docker/halo/backup-auto/backup_log.txt 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条命令会将脚本的标准输出和错误输出都重定向到 &lt;code&gt;backup_log.txt&lt;/code&gt; 文件中。&lt;/p&gt;
&lt;p&gt;在“定时”部分，选择您希望执行任务的频率（例如：每小时、每天等）。点击“提交”按钮，保存您的定时任务。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/18/20240918050029.png&quot; alt=&quot;image-20240918050023067&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以手动运行一次任务，确保一切正常，并查看日志文件确认任务是否如预期执行。（&lt;code&gt;不要着急！！！他会有几分钟延迟没有日志，这是脚本正在执行，请不要连续点击，否则服务器会炸掉&lt;/code&gt;）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/18/20240918050055.png&quot; alt=&quot;image-20240918050053173&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果在设置过程中遇到任何问题，或者有其他问题需要解决，请告诉我！&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;确保您的 AWS 凭证正确且具有上传权限。&lt;/li&gt;
&lt;li&gt;确保脚本能够访问指定的 S3 存储桶。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>如何升级nodejs版本</title><link>https://6wd.cn/posts/how-to-upgrade-nodejs/</link><guid isPermaLink="true">https://6wd.cn/posts/how-to-upgrade-nodejs/</guid><description>$ node -v</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;方法一： 用n升级nodejs（建议使用此方法）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看当前node版本
$ node -v

# 清除npm缓存
$ npm cache clean -f

# 全局安装n
$ npm install -g n

# 升级到最新稳定版
$ n stable

# 升级到最新版
$ n latest

# 升级到定制版
$ n v14.6.0

# 切换使用版本
$ n 13.10.0 (ENTER)

# 删除制定版本
$ n rm 13.10.0

# 用制定的版本执行脚本
$ n use 13.10.0 some.js

# 升级完成查看 node版本
$ node -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;
如果在第一步安装n模块报错npm ERR! code EBADPLATFORM
&lt;img src=&quot;http://cdn.6wd.cn/2024/02/05/20240205230317.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
遇到这样错误信息，先将生成的node_modules文件夹删除，再在命令后面加上 --force重新运行；
如：npm install --force即可；
如果不行，再反复执行上面的步骤。&lt;/p&gt;
&lt;h3&gt;方法二： 用&lt;a href=&quot;https://so.csdn.net/so/search?q=NVM&amp;amp;spm=1001.2101.3001.7020&quot;&gt;NVM&lt;/a&gt;来升级nodejs&lt;/h3&gt;
&lt;p&gt;github 下载nvm&lt;/p&gt;
&lt;p&gt;配置项目到环境变量中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ source ~/.bashrc

$ nvm --version

# 升级到到定制版

$ nvm install 13.10.0

# 升级到最新版

$ nvm install lastest

# 升级到稳定版

$ nvm install stable
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方法三：官网下载&lt;/h3&gt;
&lt;p&gt;去&lt;a href=&quot;https://nodejs.org/en/download/&quot;&gt;官网&lt;/a&gt;下载 LTS版本的 node
然后安装即可&lt;/p&gt;
</content:encoded></item><item><title>状态码含义</title><link>https://6wd.cn/posts/http-status-codes-meaning/</link><guid isPermaLink="true">https://6wd.cn/posts/http-status-codes-meaning/</guid><description>详细介绍:https://cloud.tencent.com/developer/chapter/13553</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;详细介绍:https://cloud.tencent.com/developer/chapter/13553
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Http状态码&lt;/th&gt;
&lt;th&gt;状态码含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收，且仍未被拒绝。客户端应当继续发送请求的剩余部分，或者如果请求已经完成，忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;服务器已经理解了客户端的请求，并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后，服务器将会切换到在Upgrade消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。例如，切换到新的HTTP版本比旧版本更有优势，或者切换到一个实时且同步的协议以传送利用此类特性的资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;由WebDAV（RFC 2518）扩展的状态码，代表处理将被继续执行。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;请求已成功，请求所希望的响应头或数据体将随此响应返回。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;请求已经被实现，而且有一个新的资源已经依据请求的需要而建立，且其URI已经随Location头信息返回。假如需要的资源无法及时建立的话，应当返回&apos;202 Accepted&apos;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;202&lt;/td&gt;
&lt;td&gt;服务器已接受请求，但尚未处理。正如它可能被拒绝一样，最终该请求可能会也可能不会被执行。在异步操作的场合下，没有比发送这个状态码更方便的做法了。返回202状态码的响应的目的是允许服务器接受其他过程的请求（例如某个每天只执行一次的基于批处理的操作），而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息，以及指向处理状态监视器或状态预测的指针，以便用户能够估计操作是否已经完成。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;203&lt;/td&gt;
&lt;td&gt;服务器已成功处理了请求，但返回的实体头部元信息不是在原始服务器上有效的确定集合，而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。例如，包含资源的元数据可能导致原始服务器知道元信息的超级。使用此状态码不是必须的，而且只有在响应不使用此状态码便会返回200 OK的情况下才是合适的。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;服务器成功处理了请求，但不需要返回任何实体内容，并且希望返回更新了的元信息。响应可能通过实体头部的形式，返回新的或更新后的元信息。如果存在这些头部信息，则应当与所请求的变量相呼应。如果客户端是浏览器的话，那么用户浏览器应保留发送了该请求的页面，而不产生任何文档视图上的变化，即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。由于204响应被禁止包含任何消息体，因此它始终以消息头后的第一个空行结尾。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;td&gt;服务器成功处理了请求，且没有返回任何内容。但是与204响应不同，返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后，立即重置表单，以便用户能够轻松地开始另一次输入。与204响应一样，该响应也被禁止包含任何消息体，且以消息头后的第一个空行结束。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;206&lt;/td&gt;
&lt;td&gt;服务器已经成功处理了部分GET请求。类似于FlashGet或者迅雷这类的HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。该请求必须包含Range头信息来指示客户端希望得到的内容范围，并且可能包含If-Range来作为请求条件。响应必须包含如下的头部域：Content-Range用以指示本次响应中返回的内容的范围；如果是Content-Type为multipart/byteranges的多段下载，则每一multipart段中都应包含Content-Range域用以指示本段的内容范围。假如响应中包含Content-Length，那么它的数值必须匹配它返回的内容范围的真实字节数。Date ETag和/或Content-Location，假如同样的请求本应该返回200响应。Expires,Cache-Control，和/或Vary，假如其值可能与之前相同变量的其他响应对应的值不同的话。假如本响应请求使用了If-Range强缓存验证，那么本次响应不应该包含其他实体头；假如本响应的请求使用了If-Range弱缓存验证，那么本次响应禁止包含其他实体头；这避免了缓存的实体内容和更新了的实体头信息之间的不一致。否则，本响应就应当包含所有本应该返回200响应中应当返回的所有实体头部域。假如ETag或Last-Modified头部不能精确匹配的话，则客户端缓存应禁止将206响应返回的内容与之前任何缓存过的内容组合在一起。任何不支持Range以及Content-Range头的缓存都禁止缓存206响应返回的内容。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;207&lt;/td&gt;
&lt;td&gt;由WebDAV(RFC 2518)扩展的状态码，代表之后的消息体将是一个XML消息，并且可能依照之前子请求数量的不同，包含一系列独立的响应代码。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;被请求的资源有一系列可供选择的回馈信息，每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。除非这是一个HEAD请求，否则该响应应当包括一个资源特性及地址的列表的实体，以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由Content-Type定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力，自动作出最合适的选择。当然，RFC 2616规范并没有规定这样的自动选择该如何进行。如果服务器本身已经有了首选的回馈选择，那么在Location中应当指明这个回馈的URI；浏览器可能会将这个Location值作为自动重定向的地址。此外，除非额外指定，否则这个响应也是可缓存的。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301&lt;/td&gt;
&lt;td&gt;被请求的资源已永久移动到新位置，并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能，拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定，否则这个响应也是可缓存的。新的永久性的URI应当在响应的Location域中返回。除非这是一个HEAD请求，否则响应的实体中应当包含指向新的URI的超链接及简短说明。如果这不是一个GET或者HEAD请求，因此浏览器禁止自动进行重定向，除非得到用户的确认，因为请求的条件可能因此发生变化。注意：对于某些使用HTTP/1.0协议的浏览器，当它们发送的POST请求得到了一个301响应的话，接下来的重定向请求将会变成GET方式。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;302&lt;/td&gt;
&lt;td&gt;请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的，客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下，这个响应才是可缓存的。新的临时性的URI应当在响应的Location域中返回。除非这是一个HEAD请求，否则响应的实体中应当包含指向新的URI的超链接及简短说明。如果这不是一个GET或者HEAD请求，那么浏览器禁止自动进行重定向，除非得到用户的确认，因为请求的条件可能因此发生变化。注意：虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法，但是很多现存的浏览器将302响应视作为303响应，并且使用GET方式访问在Location中规定的URI，而无视原先请求的方法。状态码303和307被添加了进来，用以明确服务器期待客户端进行何种反应。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;td&gt;对应当前请求的响应可以在另一个URI上被找到，而且客户端应当采用GET的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的URI不是原始资源的替代引用。同时，303响应禁止被缓存。当然，第二个请求（重定向）可能被缓存。新的URI应当在响应的Location域中返回。除非这是一个HEAD请求，否则响应的实体中应当包含指向新的URI的超链接及简短说明。注意：许多HTTP/1.1版以前的浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动，302状态码应该可以胜任，因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;td&gt;如果客户端发送了一个带条件的GET请求且该请求已被允许，而文档的内容（自上次访问以来或者根据请求的条件）并没有改变，则服务器应当返回这个状态码。304响应禁止包含消息体，因此始终以消息头后的第一个空行结尾。该响应必须包含以下的头信息：Date，除非这个服务器没有时钟。假如没有时钟的服务器也遵守这些规则，那么代理服务器以及客户端可以自行将Date字段添加到接收到的响应头中去（正如RFC 2068中规定的一样），缓存机制将会正常工作。ETag和/或Content-Location，假如同样的请求本应返回200响应。Expires,Cache-Control，和/或Vary，假如其值可能与之前相同变量的其他响应对应的值不同的话。假如本响应请求使用了强缓存验证，那么本次响应不应该包含其他实体头；否则（例如，某个带条件的GET请求使用了弱缓存验证），本次响应禁止包含其他实体头；这避免了缓存了的实体内容和更新了的实体头信息之间的不一致。假如某个304响应指明了当前某个实体没有缓存，那么缓存系统必须忽视这个响应，并且重复发送不包含限制条件的请求。假如接收到一个要求更新某个缓存条目的304响应，那么缓存系统必须更新整个条目以反映所有在响应中被更新的字段的值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;305&lt;/td&gt;
&lt;td&gt;被请求的资源必须通过指定的代理才能被访问。Location域中将给出指定的代理所在的URI信息，接收者需要重复发送一个单独的请求，通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。注意：RFC 2068中没有明确305响应是为了重定向一个单独的请求，而且只能被原始服务器建立。忽视这些限制可能导致严重的安全后果。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;306&lt;/td&gt;
&lt;td&gt;在最新版的规范中，306状态码已经不再被使用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;307&lt;/td&gt;
&lt;td&gt;请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的，客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下，这个响应才是可缓存的。新的临时性的URI应当在响应的Location域中返回。除非这是一个HEAD请求，否则响应的实体中应当包含指向新的URI的超链接及简短说明。因为部分浏览器不能识别307响应，因此需要添加上述必要信息以便用户能够理解并向新的URI发出访问请求。如果这不是一个GET或者HEAD请求，那么浏览器禁止自动进行重定向，除非得到用户的确认，因为请求的条件可能因此发生变化。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;1、语义有误，当前请求无法被服务器理解。除非进行修改，否则客户端不应该重复提交这个请求。2、请求参数有误。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;td&gt;当前请求需要用户验证。该响应必须包含一个适用于被请求资源的WWW-Authenticate信息头用以询问用户信息。客户端可以重复提交一个包含恰当的Authorization头信息的请求。如果当前请求已经包含了Authorization证书，那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问，且浏览器已经至少尝试了一次验证，那么浏览器应当向用户展示响应中包含的实体信息，因为这个实体信息中可能包含了相关诊断信息。参见RFC 2617。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;402&lt;/td&gt;
&lt;td&gt;该状态码是为了将来可能的需求而预留的。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403&lt;/td&gt;
&lt;td&gt;服务器已经理解请求，但是拒绝执行它。与401响应不同的是，身份验证并不能提供任何帮助，而且这个请求也不应该被重复提交。如果这不是一个HEAD请求，而且服务器希望能够讲清楚为何请求不能被执行，那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应，假如它不希望让客户端获得任何信息。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;请求失败，请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话，应当使用410状态码来告知旧资源因为某些内部的配置机制问题，已经永久的不可用，而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;td&gt;请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表。鉴于PUT，DELETE方法会对服务器上的资源进行写操作，因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法，对于此类请求均会返回405错误。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;406&lt;/td&gt;
&lt;td&gt;请求的资源的内容特性无法满足请求头中的条件，因而无法生成响应实体。除非这是一个HEAD请求，否则该响应就应当返回一个包含可以让用户或者浏览器从中选择最合适的实体特性以及地址列表的实体。实体的格式由Content-Type头中定义的媒体类型决定。浏览器可以根据格式及自身能力自行作出最佳选择。但是，规范中并没有定义任何作出此类自动选择的标准。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;407&lt;/td&gt;
&lt;td&gt;与401响应类似，只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个Proxy-Authenticate用以进行身份询问。客户端可以返回一个Proxy-Authorization信息头用以验证。参见RFC 2617。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;408&lt;/td&gt;
&lt;td&gt;请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;409&lt;/td&gt;
&lt;td&gt;由于和被请求的资源的当前状态之间存在冲突，请求无法完成。这个代码只允许用在这样的情况下才能被使用：用户被认为能够解决冲突，并且会重新提交新的请求。该响应应当包含足够的信息以便用户发现冲突的源头。冲突通常发生于对PUT请求的处理中。例如，在采用版本检查的环境下，某次PUT提交的对特定资源的修改请求所附带的版本信息与之前的某个（第三方）请求向冲突，那么此时服务器就应该返回一个409错误，告知用户请求无法完成。此时，响应实体中很可能会包含两个冲突版本之间的差异比较，以便用户重新提交归并以后的新版本。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;410&lt;/td&gt;
&lt;td&gt;被请求的资源在服务器上已经不再可用，而且没有任何已知的转发地址。这样的状况应当被认为是永久性的。如果可能，拥有链接编辑功能的客户端应当在获得用户许可后删除所有指向这个地址的引用。如果服务器不知道或者无法确定这个状况是否是永久的，那么就应该使用404状态码。除非额外说明，否则这个响应是可缓存的。410响应的目的主要是帮助网站管理员维护网站，通知用户该资源已经不再可用，并且服务器拥有者希望所有指向这个资源的远端连接也被删除。这类事件在限时、增值服务中很普遍。同样，410响应也被用于通知客户端在当前服务器站点上，原本属于某个个人的资源已经不再可用。当然，是否需要把所有永久不可用的资源标记为&apos;410 Gone&apos;，以及是否需要保持此标记多长时间，完全取决于服务器拥有者。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;411&lt;/td&gt;
&lt;td&gt;服务器拒绝在没有定义Content-Length头的情况下接受请求。在添加了表明请求消息体长度的有效Content-Length头之后，客户端可以再次提交该请求。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;412&lt;/td&gt;
&lt;td&gt;服务器在验证在请求的头字段中给出先决条件时，没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息（请求头字段数据）中设置先决条件，以此避免该请求方法被应用到其希望的内容以外的资源上。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;413&lt;/td&gt;
&lt;td&gt;服务器拒绝处理当前请求，因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下，服务器可以关闭连接以免客户端继续发送此请求。如果这个状况是临时的，服务器应当返回一个Retry-After的响应头，以告知客户端可以在多少时间以后重新尝试。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;414&lt;/td&gt;
&lt;td&gt;请求的URI长度超过了服务器能够解释的长度，因此服务器拒绝对该请求提供服务。这比较少见，通常的情况包括：本应使用POST方法的表单提交变成了GET方法，导致查询字符串（Query String）过长。重定向URI“黑洞”，例如每次重定向把旧的URI作为新的URI的一部分，导致在若干次重定向后URI超长。客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器。这类服务器使用固定长度的缓冲读取或操作请求的URI，当GET后的参数超过某个数值后，可能会产生缓冲区溢出，导致任意代码被执行[1]。没有此类漏洞的服务器，应当返回414状态码。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;415&lt;/td&gt;
&lt;td&gt;对于当前请求的方法和所请求的资源，请求中提交的实体并不是服务器中所支持的格式，因此请求被拒绝。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;416&lt;/td&gt;
&lt;td&gt;如果请求中包含了Range请求头，并且Range中指定的任何数据范围都与当前资源的可用范围不重合，同时请求中又没有定义If-Range请求头，那么服务器就应当返回416状态码。假如Range使用的是字节范围，那么这种情况就是指请求指定的所有数据范围的首字节位置都超过了当前资源的长度。服务器也应当在返回416状态码的同时，包含一个Content-Range实体头，用以指明当前资源的长度。这个响应也被禁止使用multipart/byteranges作为其Content-Type。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;417&lt;/td&gt;
&lt;td&gt;在请求头Expect中指定的预期内容无法被服务器满足，或者这个服务器是一个代理服务器，它有明显的证据证明在当前路由的下一个节点上，Expect的内容无法被满足。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;421&lt;/td&gt;
&lt;td&gt;从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常，这里的IP地址指的是从服务器上看到的客户端地址（比如用户的网关或者代理服务器地址）。在这种情况下，连接数的计算可能涉及到不止一个终端用户。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;422&lt;/td&gt;
&lt;td&gt;从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常，这里的IP地址指的是从服务器上看到的客户端地址（比如用户的网关或者代理服务器地址）。在这种情况下，连接数的计算可能涉及到不止一个终端用户。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;422&lt;/td&gt;
&lt;td&gt;请求格式正确，但是由于含有语义错误，无法响应。（RFC 4918 WebDAV）423 Locked当前资源被锁定。（RFC 4918 WebDAV）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;424&lt;/td&gt;
&lt;td&gt;由于之前的某个请求发生的错误，导致当前请求失败，例如PROPPATCH。（RFC 4918 WebDAV）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;425&lt;/td&gt;
&lt;td&gt;在WebDav Advanced Collections草案中定义，但是未出现在《WebDAV顺序集协议》（RFC 3658）中。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;426&lt;/td&gt;
&lt;td&gt;客户端应当切换到TLS/1.0。（RFC 2817）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;449&lt;/td&gt;
&lt;td&gt;由微软扩展，代表请求应当在执行完适当的操作后进行重试。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;服务器遇到了一个未曾预料的状况，导致了它无法完成对请求的处理。一般来说，这个问题都会在服务器的程序码出错时出现。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;501&lt;/td&gt;
&lt;td&gt;服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法，并且无法支持其对任何资源的请求。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;td&gt;作为网关或者代理工作的服务器尝试执行请求时，从上游服务器接收到无效的响应。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;td&gt;由于临时的服务器维护或者过载，服务器当前无法处理请求。这个状况是临时的，并且将在一段时间以后恢复。如果能够预计延迟时间，那么响应中可以包含一个Retry-After头用以标明这个延迟时间。如果没有给出这个Retry-After信息，那么客户端应当以处理500响应的方式处理它。注意：503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;504&lt;/td&gt;
&lt;td&gt;作为网关或者代理工作的服务器尝试执行请求时，未能及时从上游服务器（URI标识出的服务器，例如HTTP、FTP、LDAP）或者辅助服务器（例如DNS）收到响应。注意：某些代理服务器在DNS查询超时时会返回400或者500错误&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;505&lt;/td&gt;
&lt;td&gt;服务器不支持，或者拒绝支持在请求中使用的HTTP版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;506&lt;/td&gt;
&lt;td&gt;由《透明内容协商协议》（RFC 2295）扩展，代表服务器存在内部配置错误：被请求的协商变元资源被配置为在透明内容协商中使用自己，因此在一个协商处理中不是一个合适的重点。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;507&lt;/td&gt;
&lt;td&gt;服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV(RFC 4918)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;509&lt;/td&gt;
&lt;td&gt;服务器达到带宽限制。这不是一个官方的状态码，但是仍被广泛使用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;510&lt;/td&gt;
&lt;td&gt;获取资源所需要的策略并没有没满足。（RFC 2774）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>Hyper-V Centos7 网络设置 虚拟机固定IP</title><link>https://6wd.cn/posts/hyperv-centos7-static-ip/</link><guid isPermaLink="true">https://6wd.cn/posts/hyperv-centos7-static-ip/</guid><description>在网上看到很多篇文章，自己也去试验过，结果实现的效果都不是很理想，并不是自己所需要的，下面是我自己研究，最后成功的经验，希望能够帮到大家。少走一些弯路。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在网上看到很多篇文章，自己也去试验过，结果实现的效果都不是很理想，并不是自己所需要的，下面是我自己研究，最后成功的经验，希望能够帮到大家。少走一些弯路。&lt;/p&gt;
&lt;h2&gt;需求&lt;/h2&gt;
&lt;p&gt;1.无论物理机的网络环境怎么变化，都需要保持虚拟机的IP地址不变，保证我本机使用xshell等终端访问始终用同一个IP地址，或者在安装了其他软件后，访问虚拟机的IP地址保持不变。&lt;/p&gt;
&lt;p&gt;2.物理机可访问虚拟机，虚拟机是否可访问网络都行。重点保证本机可访问虚拟机，以及虚拟机之间能互相访问。&lt;/p&gt;
&lt;p&gt;3.无论物理机的网络环境怎么变化，虚拟机可以连接到外网。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;hyper-v会自动生成一个default switch，根据微软的描述，default switch是为了无论物理机的网络环境怎么变化，虚拟机可以连接到外网。 一句话，物理机可以上网，虚拟机就可以。&lt;/p&gt;
&lt;p&gt;这里以centos7为例&lt;/p&gt;
&lt;h2&gt;固定IP&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;新建虚拟机&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115114511815.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;应用虚拟机&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115121400519.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置虚拟交换机的IP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;打开控制面板，进入网络与共享中心，更改适配器的设置。找到刚才创建的虚拟机交换机。右键属性，修改IP地址。IP地址随你喜好，我这里用的IP:192.168.137.1，子网:255.255.255.0
&lt;img src=&quot;https://img-blog.csdnimg.cn/2018111512182633.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;修改虚拟机IP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;打开虚拟机进入到network-scripts目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /etc/sysconfig/network-scripts
vi ifcfg-eth0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PS: 不是所有的都是&lt;code&gt;ifcfg-eth0&lt;/code&gt;文件，这个需要自己去查看。
主要修改一下键值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BOOTPROTO=static # 将dhcp设置为static
DEVICE=eth0 #名称
ONBOOT=yes # 开机启动
IPADDR=192.168.137.200 # 这个需要和你前面设置的IP网段一样
GATEWAY=192.168.137.1 # 网关
DNS1=192.168.137.1 # 第一个DNS
NETMASK=255.255.255.0 #子网掩码
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置完成效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/2018111512310266.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;重启网络&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart network
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看IP&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip addr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115123643134.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;
现在就可以用xshell连接到虚拟机了！！！不要告诉我你不会xshell。。。
记得把虚拟机关机，因为后面我们还有操作需要在虚拟机关机状态下完成。&lt;/p&gt;
&lt;h2&gt;连接外网&lt;/h2&gt;
&lt;p&gt;现在xshell可以连接了，但是你如果ping百度的话，可能是ping不通的，现在就是要把网络添加到虚拟机上，前面说过，hyper-v会自动生成一个default switch，它可以让你的虚拟机无论物理机在什么网络下，都可以自动分配网络给虚拟机。现在我们就要用到这个default switch。&lt;/p&gt;
&lt;p&gt;给虚拟机添加一个硬件配置。为什么我的是灰色的？这就是因为没有关掉虚拟机。
&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115124339468.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;
添加完成之后你就可以看到右边的硬件中多了一项 网络适配器，这个网络适配器就选择 default switch。
&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115124641869.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个时候最好重启一下虚拟机，当然这个虚拟交换机IP最好是自动获取,DNS，也自动获取。系统会自动分配。
打开xshell 查看一下 IP&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip addr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115125025558.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个是时候，在ping 百度。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ping www.baidu.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20181115125315309.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ2ODI5,size_16,color_FFFFFF,t_70&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到这里就大功告成了！！！&lt;/p&gt;
</content:encoded></item><item><title>JavaScript常用方法整理</title><link>https://6wd.cn/posts/javascript-common-methods/</link><guid isPermaLink="true">https://6wd.cn/posts/javascript-common-methods/</guid><description>连接两个或更多的数组，并返回结果。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Array 对象方法&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-concat&quot;&gt;concat()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;连接两个或更多的数组，并返回结果。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-copyWithin&quot;&gt;copyWithin()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;从数组的指定位置拷贝元素到数组的另一个指定位置中。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-entries&quot;&gt;entries()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;返回数组的可迭代对象。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-every&quot;&gt;every()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;检测数值元素的每个元素是否都符合条件。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-fill&quot;&gt;fill()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;使用一个固定值来填充数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-filter&quot;&gt;filter()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;检测数值元素，并返回符合条件所有元素的数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-find&quot;&gt;find()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;返回符合传入测试（函数）条件的数组元素。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-findIndex&quot;&gt;findIndex()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;返回符合传入测试（函数）条件的数组元素索引。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-forEach&quot;&gt;forEach()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;数组每个元素都执行一次回调函数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-from&quot;&gt;from()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;通过给定的对象中创建一个数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-includes&quot;&gt;includes()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;判断一个数组是否包含一个指定的值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-indexOf&quot;&gt;indexOf()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;搜索数组中的元素，并返回它所在的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-join&quot;&gt;join()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;把数组的所有元素放入一个字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-keys&quot;&gt;keys()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;返回数组的可迭代对象，包含原始数组的键(key)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-lastIndexOf&quot;&gt;lastIndexOf()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;搜索数组中的元素，并返回它最后出现的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-map&quot;&gt;map()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;通过指定函数处理数组的每个元素，并返回处理后的数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-pop&quot;&gt;pop()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;删除数组的最后一个元素并返回删除的元素。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-push&quot;&gt;push()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;向数组的末尾添加一个或更多元素，并返回新的长度。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-reduce&quot;&gt;reduce()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;将数组元素计算为一个值（从左到右）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-reduceRight&quot;&gt;reduceRight()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;将数组元素计算为一个值（从右到左）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-reverse&quot;&gt;reverse()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;反转数组的元素顺序。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-shift&quot;&gt;shift()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;删除并返回数组的第一个元素。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-slice&quot;&gt;slice()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;选取数组的一部分，并返回一个新数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-some&quot;&gt;some()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;检测数组元素中是否有元素符合指定条件。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-sort&quot;&gt;sort()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;对数组的元素进行排序。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-splice&quot;&gt;splice()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;从数组中添加或删除元素。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-toString&quot;&gt;toString()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;把数组转换为字符串，并返回结果。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#arr-unshift&quot;&gt;unshift()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;向数组的开头添加一个或更多元素，并返回新的长度。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://sakura-sky.cn/2024/03/01/1709282429432#Array-isArray&quot;&gt;Array.isArray()&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;判断对象是否为数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;arr.concat()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
连接两个或更多的数组，并返回结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.concat(...items: ConcatArray&amp;lt;number&amp;gt;[]): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
let ls = [9, 10]
nums.concat(ls) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.copyWithin()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
从数组的指定位置拷贝元素到数组的另一个指定位置中。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
// start 默认为 0，end 默认为 array.length
(method) Array&amp;lt;number&amp;gt;.copyWithin(target: number, start?: number | undefined, end?: number | undefined): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
var fruits = [&quot;Banana&quot;, &quot;Orange&quot;, &quot;Apple&quot;, &quot;Mango&quot;];
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
// 以下代码是将整个数组的内容一个复制到位置4上，即：将 [1, 2, 3, 4, 5, 6, 7, 8] 复制到位置4上。暂且给这个数组起名叫做 tmp，方便和 nums 做区分。
// 复制会覆盖原有内容，且不会改变数组长度，多余的部分会被丢弃。所以 tmp 的 [1, 2, 3, 4] 会覆盖掉 nums 的 [5, 6, 7, 8]，而 tmp 的 [5, 6, 7, 8] 会因为超出数组长度而被丢弃。
nums.copyWithin(4) // [1, 2, 3, 4, 1, 2, 3, 4]
nums.copyWithin(0,4) // [5, 6, 7, 8, 5, 6, 7, 8]
// 当传递 end 参数时，复制的范围是 start 到 end-1，end 本身并不在范围内。如下面的 start = 3，end = 5 复制的内容就是 [4, 5]，不包括6
nums.copyWithin(0, 3, 5) // [4, 5, 3, 4, 5, 6, 7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.entries()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
返回数组的可迭代对象。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.entries(): IterableIterator&amp;lt;[number, number]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS

let nums = [1, 2, 3, 4, 5, 6, 7, 8]
let x = nums.entries()
x.next().value // [ 0, 1 ]
x.next().value // [ 1, 2 ]
x.next().value // [ 2, 3 ]
x.next().value // [ 3, 4 ]
for (const iterator of x) {
  console.log(iterator);
}
// 因为前面已经next四次了，所以for循环从第五个开始。
// [ 4, 5 ]
// [ 5, 6 ]
// [ 6, 7 ]
// [ 7, 8 ]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.every()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
检测数值元素的每个元素是否都符合条件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.every(predicate: (value: number, index: number, array: number[]) =&amp;gt; unknown, thisArg?: any): boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.every(item =&amp;gt; item &amp;gt; 0) // true
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.fill()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
使用一个固定值来填充数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.fill(value: number, start?: number | undefined, end?: number | undefined): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.fill(0) // [0, 0, 0, 0, 0, 0, 0, 0]
nums.fill(0,4) // [1, 2, 3, 4, 0, 0, 0, 0]
nums.fill(0,0,4) // [0, 0, 0, 0, 5, 6, 7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.filter()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
检测数值元素，并返回符合条件所有元素的数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.filter(predicate: (value: number, index: number, array: number[]) =&amp;gt; unknown, thisArg?: any): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.filter(item =&amp;gt; item &amp;gt; 4) // [5, 6, 7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.find()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
返回符合传入测试（函数）条件的第一个数组元素。如果没有符合条件的元素返回 undefined。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.find(predicate: (value: number, index: number, obj: number[]) =&amp;gt; unknown, thisArg?: any): number | undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.find(item =&amp;gt; item &amp;gt; 4) // 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.findIndex()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
返回符合传入测试（函数）条件的第一个数组元素索引。如果没有符合条件的元素返回 -1。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.findIndex(predicate: (value: number, index: number, obj: number[]) =&amp;gt; unknown, thisArg?: any): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.find(item =&amp;gt; item &amp;gt; 4) // 4
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.forEach()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
数组每个元素都执行一次回调函数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.forEach(callbackfn: (value: number, index: number, array: number[]) =&amp;gt; void, thisArg?: any): void
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.forEach(item =&amp;gt; console.log(item))
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.from()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
通过给定的对象中创建一个数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) ArrayConstructor.from&amp;lt;number&amp;gt;(iterable: Iterable&amp;lt;number&amp;gt; | ArrayLike&amp;lt;number&amp;gt;): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
// 数组去重
let arr = Array.from(new Set([1, 2, 1, 2]))
console.log(arr)
// [1, 2]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.includes()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
判断一个数组是否包含一个指定的值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.includes(searchElement: number, fromIndex?: number | undefined): boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.includes(1); // true
nums.includes(10); // false
nums.includes(1, 1) // false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.indexOf()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
搜索数组中的元素，并返回它所在的位置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.indexOf(searchElement: number, fromIndex?: number | undefined): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.indexOf(5); // 4
nums.indexOf(5, 5); // -1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.join()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
把数组的所有元素放入一个字符串。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.join(separator?: string | undefined): string
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.join(); // 1,2,3,4,5,6,7,8
nums.join(&apos;-&apos;); // 1-2-3-4-5-6-7-8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.keys()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
返回数组的可迭代对象，包含原始数组的键(key)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.keys(): IterableIterator&amp;lt;number&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS

// 相较于entries()，key()只有索引，没有值。
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
for (const key of nums.keys()) {
  console.log(nums[key]);
}
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.lastIndexOf()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
搜索数组中的元素，并返回它最后出现的位置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.lastIndexOf(searchElement: number, fromIndex?: number | undefined): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 3]

nums.lastIndexOf(3); // 8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.map()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
通过指定函数处理数组的每个元素，并返回处理后的数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
// 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.map(item =&amp;gt; item + 1); // [2, 3, 4, 5, 6, 7, 8, 9]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.pop()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
删除数组的最后一个元素并返回删除的元素。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.pop(): number | undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.pop() // 8
console.log(nums)
// [1, 2, 3, 4, 5, 6, 7]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.push()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
向数组的末尾添加一个或更多元素，并返回新的长度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.push(...items: number[]): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.push(9, 10) // 10
console.log(nums);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.reduce()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
将数组元素计算为一个值（从左到右）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) =&amp;gt; number): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.reduce((sum, now) =&amp;gt; sum + now) // 36
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.reduceRight()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
将数组元素计算为一个值（从右到左）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) =&amp;gt; number): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.reduceRight((sum, now) =&amp;gt; sum + now) // 36
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.reverse()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
反转数组的元素顺序。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.reverse(): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.reverse() // [8, 7, 6, 5, 4, 3, 2, 1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.shift()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
删除并返回数组的第一个元素。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.shift(): number | undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.shift()
console.log(nums) 
// [2, 3, 4, 5, 6, 7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.slice()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
选取数组的一部分，并返回一个新数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.slice(start?: number | undefined, end?: number | undefined): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.slice(0, 2) // [1, 2]
nums.slice(6) // [7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.some()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
检测数组元素中是否有元素符合指定条件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.some(predicate: (value: number, index: number, array: number[]) =&amp;gt; unknown, thisArg?: any): boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.some(item =&amp;gt; item &amp;gt; 7) // true
nums.some(item =&amp;gt; item &amp;gt; 8) // false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.sort()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
对数组的元素进行排序。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.sort(compareFn?: ((a: number, b: number) =&amp;gt; number) | undefined): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [5, 4, 3, 6, 2, 1, 7, 8]
nums.sort() // [1, 2, 3, 4, 5, 6, 7, 8]
nums.sort((a, b) =&amp;gt; a - b) // [1, 2, 3, 4, 5, 6, 7, 8]
nums.sort((a, b) =&amp;gt; b - a) // [8, 7, 6, 5, 4, 3, 2, 1]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.splice()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
从数组中添加或删除元素。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.splice(start: number, deleteCount?: number | undefined): number[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
// 只传一个参数时会删除这个索引之后的所有元素，这里删除8
nums.splice(7); // [8]
// [1, 2, 3, 4, 5, 6, 7]

// 从0开始删除两个元素
nums.splice(0, 2); // [1, 2]
// [3, 4, 5, 6, 7]

// 在0位置添加1,2
nums.splice(0, 0, 1, 2); // []
// [1, 2, 3, 4, 5, 6, 7]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.toString()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
把数组转换为字符串，并返回结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.toString(): string
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.toString() // 1,2,3,4,5,6,7,8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;arr.unshift()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
向数组的开头添加一个或更多元素，并返回新的长度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) Array&amp;lt;number&amp;gt;.unshift(...items: number[]): number
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
nums.unshift(0) // 9
// [1, 2, 3, 4, 5, 6, 7, 8]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Array.isArray()&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;作用：&lt;/strong&gt;
判断对象是否为数组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;签名：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TS
(method) ArrayConstructor.isArray(arg: any): arg is any[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;例子：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JS
let nums = [1, 2, 3, 4, 5, 6, 7, 8]
Array.isArray(nums); // true
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;String 对象方法&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;charAt()&lt;/td&gt;
&lt;td&gt;返回在指定位置的字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;charCodeAt()&lt;/td&gt;
&lt;td&gt;返回在指定的位置的字符的 Unicode 编码。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;concat()&lt;/td&gt;
&lt;td&gt;连接两个或更多字符串，并返回新的字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;endsWith()&lt;/td&gt;
&lt;td&gt;判断当前字符串是否是以指定的子字符串结尾的（区分大小写）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fromCharCode()&lt;/td&gt;
&lt;td&gt;将 Unicode 编码转为字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;indexOf()&lt;/td&gt;
&lt;td&gt;返回某个指定的字符串值在字符串中首次出现的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;includes()&lt;/td&gt;
&lt;td&gt;查找字符串中是否包含指定的子字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lastIndexOf()&lt;/td&gt;
&lt;td&gt;从后向前搜索字符串，并从起始位置（0）开始计算返回字符串最后出现的位置。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;match()&lt;/td&gt;
&lt;td&gt;查找找到一个或多个正则表达式的匹配。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;repeat()&lt;/td&gt;
&lt;td&gt;复制字符串指定次数，并将它们连接在一起返回。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;replace()&lt;/td&gt;
&lt;td&gt;在字符串中查找匹配的子串，并替换与正则表达式匹配的子串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;replaceAll()&lt;/td&gt;
&lt;td&gt;在字符串中查找匹配的子串，并替换与正则表达式匹配的所有子串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;search()&lt;/td&gt;
&lt;td&gt;查找与正则表达式相匹配的值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slice()&lt;/td&gt;
&lt;td&gt;提取字符串的片断，并在新的字符串中返回被提取的部分。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;split()&lt;/td&gt;
&lt;td&gt;把字符串分割为字符串数组。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;startsWith()&lt;/td&gt;
&lt;td&gt;查看字符串是否以指定的子字符串开头。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;substr()&lt;/td&gt;
&lt;td&gt;从起始索引号提取字符串中指定数目的字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;substring()&lt;/td&gt;
&lt;td&gt;提取字符串中两个指定的索引号之间的字符。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLowerCase()&lt;/td&gt;
&lt;td&gt;把字符串转换为小写。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toUpperCase()&lt;/td&gt;
&lt;td&gt;把字符串转换为大写。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;trim()&lt;/td&gt;
&lt;td&gt;去除字符串两边的空白。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleLowerCase()&lt;/td&gt;
&lt;td&gt;根据本地主机的语言环境把字符串转换为小写。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleUpperCase()&lt;/td&gt;
&lt;td&gt;根据本地主机的语言环境把字符串转换为大写。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;valueOf()&lt;/td&gt;
&lt;td&gt;返回某个字符串对象的原始值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString()&lt;/td&gt;
&lt;td&gt;返回一个字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Number 对象方法&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;isFinite()&lt;/td&gt;
&lt;td&gt;检测指定参数是否为无穷大。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isInteger()&lt;/td&gt;
&lt;td&gt;检测指定参数是否为整数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isNaN()&lt;/td&gt;
&lt;td&gt;检测指定参数是否为 NaN。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isSafeInteger()&lt;/td&gt;
&lt;td&gt;检测指定参数是否为安全整数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toExponential()&lt;/td&gt;
&lt;td&gt;把对象的值转换为指数计数法。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toFixed()&lt;/td&gt;
&lt;td&gt;把数字转换为字符串，结果的小数点后有指定位数的数字。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleString(locales, options) 返回数字在特定语言环境下的表示字符串。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toPrecision()&lt;/td&gt;
&lt;td&gt;把数字格式化为指定的长度。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString()&lt;/td&gt;
&lt;td&gt;把数字转换为字符串，使用指定的基数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;valueOf()&lt;/td&gt;
&lt;td&gt;返回一个 Number 对象的基本数字值。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Date 对象方法&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;getDate()&lt;/td&gt;
&lt;td&gt;从 Date 对象返回一个月中的某一天 (1 ~ 31)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getDay()&lt;/td&gt;
&lt;td&gt;从 Date 对象返回一周中的某一天 (0 ~ 6)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getFullYear()&lt;/td&gt;
&lt;td&gt;从 Date 对象以四位数字返回年份。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getHours()&lt;/td&gt;
&lt;td&gt;返回 Date 对象的小时 (0 ~ 23)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getMilliseconds()&lt;/td&gt;
&lt;td&gt;返回 Date 对象的毫秒(0 ~ 999)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getMinutes()&lt;/td&gt;
&lt;td&gt;返回 Date 对象的分钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getMonth()&lt;/td&gt;
&lt;td&gt;从 Date 对象返回月份 (0 ~ 11)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getSeconds()&lt;/td&gt;
&lt;td&gt;返回 Date 对象的秒数 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getTime()&lt;/td&gt;
&lt;td&gt;返回 1970 年 1 月 1 日至今的毫秒数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getTimezoneOffset()&lt;/td&gt;
&lt;td&gt;返回本地时间与格林威治标准时间 (GMT) 的分钟差。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCDate()&lt;/td&gt;
&lt;td&gt;根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCDay()&lt;/td&gt;
&lt;td&gt;根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCFullYear()&lt;/td&gt;
&lt;td&gt;根据世界时从 Date 对象返回四位数的年份。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCHours()&lt;/td&gt;
&lt;td&gt;根据世界时返回 Date 对象的小时 (0 ~ 23)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCMilliseconds()&lt;/td&gt;
&lt;td&gt;根据世界时返回 Date 对象的毫秒(0 ~ 999)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCMinutes()&lt;/td&gt;
&lt;td&gt;根据世界时返回 Date 对象的分钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCMonth()&lt;/td&gt;
&lt;td&gt;根据世界时从 Date 对象返回月份 (0 ~ 11)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getUTCSeconds()&lt;/td&gt;
&lt;td&gt;根据世界时返回 Date 对象的秒钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;parse()&lt;/td&gt;
&lt;td&gt;返回1970年1月1日午夜到指定日期（字符串）的毫秒数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setDate()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中月的某一天 (1 ~ 31)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setFullYear()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中的年份（四位数字）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setHours()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中的小时 (0 ~ 23)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setMilliseconds()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中的毫秒 (0 ~ 999)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setMinutes()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中的分钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setMonth()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中月份 (0 ~ 11)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setSeconds()&lt;/td&gt;
&lt;td&gt;设置 Date 对象中的秒钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setTime()&lt;/td&gt;
&lt;td&gt;以毫秒设置 Date 对象。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCDate()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCFullYear()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中的年份（四位数字）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCHours()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中的小时 (0 ~ 23)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCMilliseconds()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCMinutes()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中的分钟 (0 ~ 59)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCMonth()&lt;/td&gt;
&lt;td&gt;根据世界时设置 Date 对象中的月份 (0 ~ 11)。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setUTCSeconds()&lt;/td&gt;
&lt;td&gt;用于根据世界时 (UTC) 设置指定时间的秒字段。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toDateString()&lt;/td&gt;
&lt;td&gt;把 Date 对象的日期部分转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toISOString()&lt;/td&gt;
&lt;td&gt;使用 ISO 标准返回字符串的日期格式。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toJSON()&lt;/td&gt;
&lt;td&gt;以 JSON 数据格式返回日期字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleDateString()&lt;/td&gt;
&lt;td&gt;根据本地时间格式，把 Date 对象的日期部分转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleTimeString()&lt;/td&gt;
&lt;td&gt;根据本地时间格式，把 Date 对象的时间部分转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleString()&lt;/td&gt;
&lt;td&gt;根据本地时间格式，把 Date 对象转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString()&lt;/td&gt;
&lt;td&gt;把 Date 对象转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toTimeString()&lt;/td&gt;
&lt;td&gt;把 Date 对象的时间部分转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toUTCString()&lt;/td&gt;
&lt;td&gt;根据世界时，把 Date 对象转换为字符串。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Math 对象方法&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;abs(x)&lt;/td&gt;
&lt;td&gt;返回 x 的绝对值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;acos(x)&lt;/td&gt;
&lt;td&gt;返回 x 的反余弦值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;asin(x)&lt;/td&gt;
&lt;td&gt;返回 x 的反正弦值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;atan(x)&lt;/td&gt;
&lt;td&gt;以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;atan2(y,x) 返回从 x 轴到点 (x,y) 的角度（介于 -PI/2 与 PI/2 弧度之间）。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ceil(x)&lt;/td&gt;
&lt;td&gt;对数进行上舍入。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cos(x)&lt;/td&gt;
&lt;td&gt;返回数的余弦。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;exp(x)&lt;/td&gt;
&lt;td&gt;返回 Ex 的指数。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;floor(x)&lt;/td&gt;
&lt;td&gt;对 x 进行下舍入。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;log(x)&lt;/td&gt;
&lt;td&gt;返回数的自然对数（底为e）。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max(x,y,z,…,n) 返回 x,y,z,…,n 中的最高值。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;min(x,y,z,…,n) 返回 x,y,z,…,n中的最低值。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pow(x,y) 返回 x 的 y 次幂。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;random() 返回 0 ~ 1 之间的随机数。&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;round(x)&lt;/td&gt;
&lt;td&gt;四舍五入。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sin(x)&lt;/td&gt;
&lt;td&gt;返回数的正弦。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sqrt(x)&lt;/td&gt;
&lt;td&gt;返回数的平方根。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tan(x)&lt;/td&gt;
&lt;td&gt;返回角的正切。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tanh(x)&lt;/td&gt;
&lt;td&gt;返回一个数的双曲正切函数值。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;trunc(x)&lt;/td&gt;
&lt;td&gt;将数字的小数部分去掉，只保留整数部分。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;文章作者:&lt;/strong&gt; &lt;a href=&quot;https://blog.leonus.cn/&quot;&gt;Leonus&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>轻薄本办公本在接通电源的时候风扇大，温度高如何解决</title><link>https://6wd.cn/posts/laptop-fan-noise-on-ac-power/</link><guid isPermaLink="true">https://6wd.cn/posts/laptop-fan-noise-on-ac-power/</guid><description>计算机/HKEYLOCALMACHINE/SYSTEM/CurrentControlSet/Control/Power/PowerSettings/54533251-82be-4824-96c1...</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;轻薄本/办公本在接通电源的时候风扇大，温度高如何解决&lt;/h1&gt;
&lt;h2&gt;1，首先我们需要去开启两个选项，如果不开启这两个选项电源管理中就无法进行设置&lt;/h2&gt;
&lt;h3&gt;打开注册表管理器搜索以下两个路径，分别将&lt;code&gt;Attributes&lt;/code&gt;中的值设置为&lt;code&gt;2&lt;/code&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\54533251-82be-4824-96c1-47b60b740d00\be337238-0d82-4146-a960-4f3749d470c7

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\54533251-82be-4824-96c1-47b60b740d00\75b0ae3f-bce0-45a7-8c89-c9611c25e100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如图：&lt;strong&gt;两个值都需要进行更改&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/21/20240921230814.png&quot; alt=&quot;image-20240921230812294&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2，打开控制面板找到电源选项，新建电源选项&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/21/20240921231055.png&quot; alt=&quot;image-20240921231053553&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3，将这两个选项根据自己实际情况进行更改&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/21/20240921231208.png&quot; alt=&quot;image-20240921231205996&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;更改完成我们就可以明显感受到电脑温度下来了！！&lt;/h2&gt;
</content:encoded></item><item><title>Linux(CentOS8)上 安装 Docker 详细步骤</title><link>https://6wd.cn/posts/linux-centos8-install-docker/</link><guid isPermaLink="true">https://6wd.cn/posts/linux-centos8-install-docker/</guid><description>lz 用的是centos 8 的版本，如果在安装 docker 时报错：Failed to start docker.service: Unit docker.service not found.</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;1. 安装前&lt;/h3&gt;
&lt;p&gt;lz 用的是centos 8 的版本，如果在安装 docker 时报错：&lt;code&gt;Failed to start docker.service: Unit docker.service not found.&lt;/code&gt;
是因为系统会默认为你要安装的是和docker 功能相似的 podman-docker。
所以需要先卸载掉 podman：&lt;code&gt;dnf remove podman&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;2. 安装 docker&lt;/h3&gt;
&lt;p&gt;看了很多人的安装步骤，和官网的安装步骤是一致的：官网地址&lt;a href=&quot;https://docs.docker.com/engine/install/centos/#prerequisites&quot;&gt;docker安装&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;2.1 第一步就是先卸载原先 docker 版本：&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt; sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.2 再安装 docker 仓库&lt;/h4&gt;
&lt;p&gt;安装所需软件包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo yum install -y yum-utils device-mapper-persistent-data lvm2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置 docker 仓库：推荐阿里云&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo yum-config-manager --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 安装最新版本（latest）的 docker-ce：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo yum install docker-ce
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 启动并加入开机自启&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 启动 docker
sudo systemctl start docker
# 设置 docker 开机自启
sudo systemctl enable docker
# 查看已有镜像
sudo docker images
# 查看容器 ID，如果想要查看包括未在运行的容器在 ps 后➕ -a 即可
sudo docker ps

# 管理容器
# 1. 进入容器。退出容器使用 exit 即可
docker run -it imageID /bin/bash
# -d 使容器后台运行 --name 后是指定那个容器的名字
docker run -d --name XXX imageID
# 进入后台运行的容器：XXX 是上一步指定的名字
docker exec -it XXX /bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 测试 docker 安装是否成功：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sudo docker run hello-world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;到此就结束了：）&lt;/p&gt;
</content:encoded></item><item><title>mysql字符类型</title><link>https://6wd.cn/posts/mysql-character-types/</link><guid isPermaLink="true">https://6wd.cn/posts/mysql-character-types/</guid><description>MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;MySQL 数据类型&lt;/h1&gt;
&lt;p&gt;MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。&lt;/p&gt;
&lt;p&gt;MySQL 支持多种类型，大致可以分为三类：数值、日期/时间和字符串(字符)类型。&lt;/p&gt;
&lt;h2&gt;数值类型&lt;/h2&gt;
&lt;p&gt;MySQL 支持所有标准 SQL 数值数据类型。&lt;/p&gt;
&lt;p&gt;这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC)，以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。&lt;/p&gt;
&lt;p&gt;关键字INT是INTEGER的同义词，关键字DEC是DECIMAL的同义词。&lt;/p&gt;
&lt;p&gt;BIT数据类型保存位字段值，并且支持 MyISAM、MEMORY、InnoDB 和 BDB表。&lt;/p&gt;
&lt;p&gt;作为 SQL 标准的扩展，MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT。下面的表显示了需要的每个整数类型的存储和范围。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;大小&lt;/th&gt;
&lt;th&gt;范围（有符号）&lt;/th&gt;
&lt;th&gt;范围（无符号）&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TINYINT&lt;/td&gt;
&lt;td&gt;1 Bytes&lt;/td&gt;
&lt;td&gt;(-128，127)&lt;/td&gt;
&lt;td&gt;(0，255)&lt;/td&gt;
&lt;td&gt;小整数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMALLINT&lt;/td&gt;
&lt;td&gt;2 Bytes&lt;/td&gt;
&lt;td&gt;(-32 768，32 767)&lt;/td&gt;
&lt;td&gt;(0，65 535)&lt;/td&gt;
&lt;td&gt;大整数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEDIUMINT&lt;/td&gt;
&lt;td&gt;3 Bytes&lt;/td&gt;
&lt;td&gt;(-8 388 608，8 388 607)&lt;/td&gt;
&lt;td&gt;(0，16 777 215)&lt;/td&gt;
&lt;td&gt;大整数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT或INTEGER&lt;/td&gt;
&lt;td&gt;4 Bytes&lt;/td&gt;
&lt;td&gt;(-2 147 483 648，2 147 483 647)&lt;/td&gt;
&lt;td&gt;(0，4 294 967 295)&lt;/td&gt;
&lt;td&gt;大整数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BIGINT&lt;/td&gt;
&lt;td&gt;8 Bytes&lt;/td&gt;
&lt;td&gt;(-9,223,372,036,854,775,808，9 223 372 036 854 775 807)&lt;/td&gt;
&lt;td&gt;(0，18 446 744 073 709 551 615)&lt;/td&gt;
&lt;td&gt;极大整数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;4 Bytes&lt;/td&gt;
&lt;td&gt;(-3.402 823 466 E+38，-1.175 494 351 E-38)，0，(1.175 494 351 E-38，3.402 823 466 351 E+38)&lt;/td&gt;
&lt;td&gt;0，(1.175 494 351 E-38，3.402 823 466 E+38)&lt;/td&gt;
&lt;td&gt;单精度 浮点数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DOUBLE&lt;/td&gt;
&lt;td&gt;8 Bytes&lt;/td&gt;
&lt;td&gt;(-1.797 693 134 862 315 7 E+308，-2.225 073 858 507 201 4 E-308)，0，(2.225 073 858 507 201 4 E-308，1.797 693 134 862 315 7 E+308)&lt;/td&gt;
&lt;td&gt;0，(2.225 073 858 507 201 4 E-308，1.797 693 134 862 315 7 E+308)&lt;/td&gt;
&lt;td&gt;双精度 浮点数值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DECIMAL&lt;/td&gt;
&lt;td&gt;对DECIMAL(M,D) ，如果M&amp;gt;D，为M+2否则为D+2&lt;/td&gt;
&lt;td&gt;依赖于M和D的值&lt;/td&gt;
&lt;td&gt;依赖于M和D的值&lt;/td&gt;
&lt;td&gt;小数值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;日期和时间类型&lt;/h2&gt;
&lt;p&gt;表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。&lt;/p&gt;
&lt;p&gt;每个时间类型有一个有效值范围和一个&quot;零&quot;值，当指定不合法的MySQL不能表示的值时使用&quot;零&quot;值。&lt;/p&gt;
&lt;p&gt;TIMESTAMP类型有专有的自动更新特性，将在后面描述。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;大小 ( bytes)&lt;/th&gt;
&lt;th&gt;范围&lt;/th&gt;
&lt;th&gt;格式&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DATE&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1000-01-01/9999-12-31&lt;/td&gt;
&lt;td&gt;YYYY-MM-DD&lt;/td&gt;
&lt;td&gt;日期值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TIME&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&apos;-838:59:59&apos;/&apos;838:59:59&apos;&lt;/td&gt;
&lt;td&gt;HH:MM:SS&lt;/td&gt;
&lt;td&gt;时间值或持续时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YEAR&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1901/2155&lt;/td&gt;
&lt;td&gt;YYYY&lt;/td&gt;
&lt;td&gt;年份值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATETIME&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&apos;1000-01-01 00:00:00&apos; 到 &apos;9999-12-31 23:59:59&apos;&lt;/td&gt;
&lt;td&gt;YYYY-MM-DD hh:mm:ss&lt;/td&gt;
&lt;td&gt;混合日期和时间值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TIMESTAMP&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&apos;1970-01-01 00:00:01&apos; UTC 到 &apos;2038-01-19 03:14:07&apos; UTC结束时间是第 &lt;strong&gt;2147483647&lt;/strong&gt; 秒，北京时间 &lt;strong&gt;2038-1-19 11:14:07&lt;/strong&gt;，格林尼治时间 2038年1月19日 凌晨 03:14:07&lt;/td&gt;
&lt;td&gt;YYYY-MM-DD hh:mm:ss&lt;/td&gt;
&lt;td&gt;混合日期和时间值，时间戳&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;字符串类型&lt;/h2&gt;
&lt;p&gt;字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;大小&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CHAR&lt;/td&gt;
&lt;td&gt;0-255 bytes&lt;/td&gt;
&lt;td&gt;定长字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;0-65535 bytes&lt;/td&gt;
&lt;td&gt;变长字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TINYBLOB&lt;/td&gt;
&lt;td&gt;0-255 bytes&lt;/td&gt;
&lt;td&gt;不超过 255 个字符的二进制字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TINYTEXT&lt;/td&gt;
&lt;td&gt;0-255 bytes&lt;/td&gt;
&lt;td&gt;短文本字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BLOB&lt;/td&gt;
&lt;td&gt;0-65 535 bytes&lt;/td&gt;
&lt;td&gt;二进制形式的长文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEXT&lt;/td&gt;
&lt;td&gt;0-65 535 bytes&lt;/td&gt;
&lt;td&gt;长文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEDIUMBLOB&lt;/td&gt;
&lt;td&gt;0-16 777 215 bytes&lt;/td&gt;
&lt;td&gt;二进制形式的中等长度文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEDIUMTEXT&lt;/td&gt;
&lt;td&gt;0-16 777 215 bytes&lt;/td&gt;
&lt;td&gt;中等长度文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LONGBLOB&lt;/td&gt;
&lt;td&gt;0-4 294 967 295 bytes&lt;/td&gt;
&lt;td&gt;二进制形式的极大文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LONGTEXT&lt;/td&gt;
&lt;td&gt;0-4 294 967 295 bytes&lt;/td&gt;
&lt;td&gt;极大文本数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：char(n) 和 varchar(n) 中括号中 n 代表字符的个数，并不代表字节个数，比如 CHAR(30) 就可以存储 30 个字符。&lt;/p&gt;
&lt;p&gt;CHAR 和 VARCHAR 类型类似，但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。&lt;/p&gt;
&lt;p&gt;BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR，不同的是它们包含二进制字符串而不要非二进制字符串。也就是说，它们包含字节字符串而不是字符字符串。这说明它们没有字符集，并且排序和比较基于列值字节的数值值。&lt;/p&gt;
&lt;p&gt;BLOB 是一个二进制大对象，可以容纳可变数量的数据。有 4 种 BLOB 类型：TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。&lt;/p&gt;
&lt;p&gt;有 4 种 TEXT 类型：TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型，可存储的最大长度不同，可根据实际情况选择。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;枚举与集合类型（Enumeration and Set Types）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ENUM&lt;/strong&gt;: 枚举类型，用于存储单一值，可以选择一个预定义的集合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SET&lt;/strong&gt;: 集合类型，用于存储多个值，可以选择多个预定义的集合。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;空间数据类型（Spatial Data Types）&lt;/h2&gt;
&lt;p&gt;GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION: 用于存储空间数据（地理信息、几何图形等）。&lt;/p&gt;
</content:encoded></item><item><title>Navicat报错 1130的解决方法</title><link>https://6wd.cn/posts/navicat-error-1130/</link><guid isPermaLink="true">https://6wd.cn/posts/navicat-error-1130/</guid><description>Navicat 连接mysql8.x版本报1130错误</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;【Mysql】Navicat 连接mysql8.x时候报错 1130的解决方法&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Navicat 连接mysql8.x版本报1130错误&lt;/strong&gt;
&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
是无法给远程连接的用户权限问题
1.登录mysql
mysql -u root -p
2.创建用户并设置密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;create user &apos;root&apos;@&apos;%&apos; identified with mysql_native_password by &apos;123456&apos;;
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;root：用户名
123456：密码
创建成功&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3.授权远程访问&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grant all privileges on *.* to &apos;root&apos;@&apos;%&apos; with grant option;
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;root：用户名
&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;4.修改加密规则（mysql8.0版本）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER &apos;root&apos;@&apos;%&apos; IDENTIFIED BY &apos;root&apos; PASSWORD EXPIRE NEVER;
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;5.刷新权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flush privileges;
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;6.重新用&lt;a href=&quot;https://so.csdn.net/so/search?q=navicat&amp;amp;spm=1001.2101.3001.7020&quot;&gt;navicat&lt;/a&gt;连接mysql
&lt;img src=&quot;http://cdn.6wd.cn/2023/10/02/20231002162044.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>一键更改root密码并开启远程</title><link>https://6wd.cn/posts/one-click-change-root-password/</link><guid isPermaLink="true">https://6wd.cn/posts/one-click-change-root-password/</guid><description>curl -sSL http://sudo.6wd.cn/setup-ssh.sh -o setup-ssh.sh &amp;&amp; bash setup-ssh.sh</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;h3&gt;我提供了一键脚本，如果您不想继续看下去&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;curl -sSL http://sudo.6wd.cn/setup-ssh.sh -o setup-ssh.sh &amp;amp;&amp;amp; bash setup-ssh.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;脚本内容 (setup-ssh.sh)&lt;/h3&gt;
&lt;p&gt;若没有提供密码，则使用默认密码 &lt;code&gt;Suki520.&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# ==============================================
# SSH安全配置脚本 (支持密钥+密码选项+Root登录)
# 版本: 4.2.5 (兼容性修复)
# 最后更新: 2025-11-26
# ==============================================

# 初始化设置
SCRIPT_VERSION=&quot;4.2.5&quot;
SSH_PORT=22  # 默认SSH端口
KEY_GENERATED=false
PASSWORD_AUTH_ENABLED=&quot;yes&quot;
PRIVATE_KEY_CONTENT=&quot;&quot; # 用于存储私钥内容

# 颜色定义
BLACK=&apos;\033[0;30m&apos;
RED=&apos;\033[1;31m&apos;
GREEN=&apos;\033[1;32m&apos;
YELLOW=&apos;\033[1;33m&apos;
BLUE=&apos;\033[1;34m&apos;
PURPLE=&apos;\033[1;35m&apos;
CYAN=&apos;\033[1;36m&apos;
WHITE=&apos;\033[1;37m&apos;
NC=&apos;\033[0m&apos;

# Emoji定义
CHECK=&quot;✅&quot;
CROSS=&quot;❌&quot;
WARN=&quot;⚠️&quot;
INFO=&quot;ℹ️&quot;
LOCK=&quot;🔒&quot;
FIRE=&quot;🔥&quot;
NET=&quot;🌐&quot;
KEY=&quot;🔑&quot;
TOOLS=&quot;🛠️&quot;
CONF=&quot;⚙️&quot;
PASS=&quot;🔑&quot;
SUCCESS=&quot;🎉&quot;
PC=&quot;💻&quot;
SERVER=&quot;🖥️&quot;
SAVE=&quot;💾&quot;

# ==============================================
# 修复: 进度条 (POSIX /bin/sh 兼容)
# ==============================================
progress_bar() {
    local duration=${1:-2}
    local bar_length=30
    local sleep_interval=$(awk &quot;BEGIN {print $duration / $bar_length}&quot;)
  
    echo -ne &quot;${PURPLE}${TOOLS} 进度 [&quot;
  
    local i=0
    while [ &quot;$i&quot; -lt &quot;$bar_length&quot; ]; do
        local color_code=$((i % 6))
        case $color_code in
            0) echo -ne &quot;${RED}&quot;;;
            1) echo -ne &quot;${YELLOW}&quot;;;
            2) echo -ne &quot;${GREEN}&quot;;;
            3) echo -ne &quot;${CYAN}&quot;;;
            4) echo -ne &quot;${BLUE}&quot;;;
            5) echo -ne &quot;${PURPLE}&quot;;;
        esac
  
        echo -ne &quot;&amp;gt;&quot;
        sleep $sleep_interval
        i=$((i + 1))
    done
  
    echo -e &quot;${PURPLE}] ${GREEN}完成!${NC}&quot;
}

# ==============================================
# 修复: 旋转动画 (POSIX /bin/sh 兼容)
# ==============================================
spinner() {
    local pid=$!
    local delay=0.1
    local spinstr=&apos;|/-\&apos;
  
    while kill -0 $pid 2&amp;gt;/dev/null; do
        local temp=${spinstr#?}
        printf &quot; [%c]  &quot; &quot;$spinstr&quot;
        local spinstr=$temp${spinstr%&quot;$temp&quot;}
        sleep $delay
        printf &quot;\b\b\b\b\b\b&quot;
    done
    printf &quot;    \b\b\b\b&quot;
}

# 显示横幅
show_banner() {
    clear
    echo -e &quot;${CYAN}&quot;
    cat &amp;lt;&amp;lt; &quot;EOF&quot;
                                            
 $$$$$$\           _$$$$$$\                     $$\             
$$  __$$\         /$$  __$$\                   $$ |            
$$ /  \__|$$\  $$\  $$\  $$$$$$$ |     $$$$$$$\ $$$$$$$\  
$$$$$$$\  $$ | $$ | $$ |$$  __$$ |    $$  _____|$$  __$$\ 
$$  __$$\ $$ | $$ | $$ |$$ /  $$ |    $$ /      $$ |  $$ |
$$ /  $$ |$$ | $$ | $$ |$$ |  $$ |    $$ |      $$ |  $$ |
 $$$$$$  |\$$$$$\$$$$  |\$$$$$$$ |$$\ \$$$$$$$\ $$ |  $$ |
 \______/  \_____\____/  \_______|\__| \_______|\__|  \__|
                                            
EOF
    echo -e &quot;${NC}版本: ${SCRIPT_VERSION} ${TOOLS}&quot;
    echo -e &quot;${CYAN}==============================================${NC}&quot;
    echo -e &quot;${WHITE}${SERVER} 正在为您配置安全的SSH环境...${NC}&quot;
    echo -e &quot;${CYAN}==============================================${NC}&quot;
    echo &quot;&quot;
}

# 检查root权限
check_root() {
    echo -ne &quot;${BLUE}${KEY} 正在检查root权限...&quot;
    if [ &quot;$(id -u)&quot; -ne 0 ]; then
        echo -e &quot;\n${RED}${CROSS} 错误: 请使用root用户运行此脚本${NC}&quot;
        exit 1
    else
        echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
    fi
}

# 系统检测
detect_system() {
    echo -ne &quot;${BLUE}${PC} 正在检测系统信息...&quot;
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_ID=${ID}
        OS_VERSION=${VERSION_ID}
    elif [ -f /etc/redhat-release ]; then
        OS_ID=$(awk &apos;{print $1}&apos; /etc/redhat-release | tr &apos;[:upper:]&apos; &apos;[:lower:]&apos;)
        OS_VERSION=$(awk &apos;{print $4}&apos; /etc/redhat-release)
    else
        OS_ID=$(uname -s)
        OS_VERSION=$(uname -r)
    fi

    case ${OS_ID} in
        debian|ubuntu|raspbian|kali|linuxmint|pop) OS_GROUP=&quot;debian&quot; ;;
        centos|rhel|fedora|rocky|almalinux) OS_GROUP=&quot;rhel&quot; ;;
        alpine) OS_GROUP=&quot;alpine&quot; ;;
        arch|manjaro) OS_GROUP=&quot;arch&quot; ;;
        *) OS_GROUP=&quot;unknown&quot; ;;
    esac
  
    echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
    echo -e &quot;${YELLOW}${INFO} 系统: ${OS_ID} ${OS_VERSION}${NC}&quot;
}

# 安装依赖
install_deps() {
    echo -e &quot;${BLUE}${TOOLS} 正在安装必要组件...${NC}&quot;
  
    case ${OS_GROUP} in
        debian)
            echo -e &quot;${PURPLE}${TOOLS} 使用APT包管理器${NC}&quot;
            echo -ne &quot;  ${BLUE}更新软件源...&quot;
            apt-get update &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
            spinner
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
  
            echo -ne &quot;  ${BLUE}安装组件...&quot;
            DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server curl ufw fail2ban bc &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
            spinner
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            ;;
        rhel)
            echo -e &quot;${PURPLE}${TOOLS} 使用YUM/DNF包管理器${NC}&quot;
            echo -ne &quot;  ${BLUE}安装组件...&quot;
            (yum install -y openssh-server curl firewalld fail2ban bc &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 || dnf install -y openssh-server curl firewalld fail2ban bc &amp;gt; /dev/null 2&amp;gt;&amp;amp;1) &amp;amp;
            spinner
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
  
            echo -ne &quot;  ${BLUE}启动防火墙...&quot;
            systemctl enable firewalld --now &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
            spinner
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            ;;
        alpine)
            echo -e &quot;${PURPLE}${TOOLS} 使用APK包管理器${NC}&quot;
            echo -ne &quot;  ${BLUE}安装组件...&quot;
            apk add openssh curl bc &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
            spinner
            apk add fail2ban ufw &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            ;;
        arch)
            echo -e &quot;${PURPLE}${TOOLS} 使用PACMAN包管理器${NC}&quot;
            echo -ne &quot;  ${BLUE}安装组件...&quot;
            pacman -Sy --noconfirm openssh curl ufw fail2ban bc &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
            spinner
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            ;;
    esac
    echo -e &quot;${GREEN}${CHECK} 组件安装完成${NC}&quot;
    progress_bar 1
}

# 密码设置选项 - 简化版本
set_root_password() {
    echo -e &quot;\n${CYAN}${PASS} &amp;gt;&amp;gt;&amp;gt; 请选择root密码设置方式:${NC}&quot;
    echo -e &quot;1) ${GREEN}使用随机密码 (推荐) ${LOCK}${NC}&quot;
    echo -e &quot;2) ${YELLOW}使用固定默认密码 (不安全) ${WARN}${NC}&quot;
    echo -e &quot;3) ${BLUE}手动输入自定义密码 ${KEY}${NC}&quot;
    echo -n -e &quot;${WHITE}${PASS} 请输入选项 [1-3]: ${NC}&quot;
    read -r choice
  
    case $choice in
        1)
            echo -ne &quot;${BLUE}${KEY} 正在生成随机密码...&quot;
            if command -v openssl &amp;amp;&amp;gt; /dev/null; then
                ROOT_PASSWORD=$(openssl rand -base64 16 | tr -d &apos;/+=&apos;)
            else
                ROOT_PASSWORD=$(head -c 16 /dev/urandom | base64 | tr -d &apos;/+=&apos;)
            fi
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            ;;
        2)
            ROOT_PASSWORD=&quot;Server123!&quot;  # 默认固定密码
            echo -e &quot;${YELLOW}${WARN} 警告: 使用固定密码存在安全风险!${NC}&quot;
            ;;
        3)
            while true; do
                echo -n -e &quot;${BLUE}${KEY} 请输入自定义密码: ${NC}&quot;
                read -s ROOT_PASSWORD
                echo
                if [ &quot;$(echo &quot;$ROOT_PASSWORD&quot; | wc -c)&quot; -ge 8 ]; then
                    break
                else
                    echo -e &quot;${RED}${CROSS} 密码必须至少8个字符!${NC}&quot;
                fi
            done
            ;;
        *)
            echo -e &quot;${RED}${CROSS} 无效选项，使用随机密码${NC}&quot;
            if command -v openssl &amp;amp;&amp;gt; /dev/null; then
                ROOT_PASSWORD=$(openssl rand -base64 16 | tr -d &apos;/+=&apos;)
            else
                ROOT_PASSWORD=$(head -c 16 /dev/urandom | base64 | tr -d &apos;/+=&apos;)
            fi
            ;;
    esac
  
    # 设置密码 - 使用交互式方式
    echo -e &quot;${BLUE}${KEY} 正在设置root密码...${NC}&quot;
    echo -e &quot;${YELLOW}${INFO} 请稍后，系统可能会提示输入新密码${NC}&quot;
    
    # 使用passwd命令交互式设置密码
    if printf &quot;%s\n%s\n&quot; &quot;${ROOT_PASSWORD}&quot; &quot;${ROOT_PASSWORD}&quot; | passwd root &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
        echo -e &quot;${GREEN}${CHECK} Root密码已设置${NC}&quot;
    else
        echo -e &quot;${YELLOW}${WARN} 自动设置密码失败，请手动执行以下命令:${NC}&quot;
        echo -e &quot;${GREEN}passwd root${NC}&quot;
        echo -e &quot;${YELLOW}${INFO} 使用此密码: ${ROOT_PASSWORD}${NC}&quot;
        echo -n -e &quot;${YELLOW}${WARN} 按回车键继续...${NC}&quot;
        read -r
    fi
    
    progress_bar 0.5
}

# SSH密钥配置
setup_ssh_key_auth() {
    echo -e &quot;\n${CYAN}${KEY} &amp;gt;&amp;gt;&amp;gt; SSH密钥认证配置:${NC}&quot;
    echo -n -e &quot;${WHITE}${KEY} 是否要生成新的SSH密钥对 (ed25519) 用于root登录? (y/N): ${NC}&quot;
    read -r gen_key
  
    case &quot;$gen_key&quot; in
        [Yy]*)
            echo -ne &quot;${BLUE}${KEY} 正在生成 ed25519 密钥对...&quot;
            mkdir -p /root/.ssh
            chmod 700 /root/.ssh
      
            # 生成临时密钥文件
            ssh-keygen -t ed25519 -f /root/.ssh/id_script_gen -N &quot;&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
      
            # 将公钥添加到 authorized_keys
            cat /root/.ssh/id_script_gen.pub &amp;gt;&amp;gt; /root/.ssh/authorized_keys
            chmod 600 /root/.ssh/authorized_keys
      
            # 存储私钥内容（不包含多余的分隔符）
            PRIVATE_KEY_CONTENT=$(cat /root/.ssh/id_script_gen)
      
            # 清理临时密钥文件
            rm -f /root/.ssh/id_script_gen /root/.ssh/id_script_gen.pub
      
            KEY_GENERATED=true
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            echo -e &quot;${YELLOW}${WARN} 密钥已生成! 私钥将在脚本最后显示，请务必保存!${NC}&quot;
            progress_bar 1
            ;;
        *)
            echo -e &quot;${YELLOW}${INFO} 跳过密钥生成。${NC}&quot;
            KEY_GENERATED=false
            ;;
    esac
}

# SSH配置 - Debian兼容性修复版本
# SSH配置 - 完全修复Debian兼容性问题
configure_ssh() {
    echo -e &quot;\n${BLUE}${CONF} 正在配置SSH...${NC}&quot;
  
    # 备份原配置
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d_%H%M%S)
  
    # 交互式设置端口
    while true; do
        echo -n -e &quot;${CYAN}${NET} 请输入SSH端口 [默认: 22]: ${NC}&quot;
        read -r custom_port
        if [ -z &quot;$custom_port&quot; ]; then
            SSH_PORT=22
            break
        elif echo &quot;$custom_port&quot; | grep -q &apos;^[0-9]\+$&apos;; then
            case $custom_port in
                0* | *[!-0-9]*) 
                    echo -e &quot;${RED}${CROSS} 无效端口号!${NC}&quot; ;;
                *)
                    if [ &quot;$custom_port&quot; -ge 1 ] &amp;amp;&amp;amp; [ &quot;$custom_port&quot; -le 65535 ]; then
                        SSH_PORT=$custom_port
                        break
                    else
                        echo -e &quot;${RED}${CROSS} 端口必须在 1-65535 之间!${NC}&quot;
                    fi
                    ;;
            esac
        else
            echo -e &quot;${RED}${CROSS} 无效端口号! 请输入数字${NC}&quot;
        fi
    done
    echo -e &quot;${GREEN}${CHECK} SSH端口将设置为: ${SSH_PORT}${NC}&quot;

    # 交互式设置密码登录
    echo -n -e &quot;${CYAN}${LOCK} 是否要禁用密码登录 (推荐使用密钥登录)? (y/N): ${NC}&quot;
    read -r disable_pass
  
    # 默认保持密码登录启用
    PASSWORD_AUTH_ENABLED=&quot;yes&quot;
  
    case &quot;$disable_pass&quot; in
        [Yy]*)
            if [ &quot;$KEY_GENERATED&quot; = false ]; then
                echo -e &quot;${YELLOW}${WARN} 警告: 您没有在本脚本中生成密钥。${NC}&quot;
                echo -n -e &quot;${RED}${LOCK} 您是否确定已安装了其他SSH密钥? 否则将无法登录! (y/N): ${NC}&quot;
                read -r confirm_disable
                case &quot;$confirm_disable&quot; in
                    [Yy]*)
                        PASSWORD_AUTH_ENABLED=&quot;no&quot;
                        echo -e &quot;${GREEN}${LOCK} 密码登录已禁用。${NC}&quot;
                        ;;
                    *)
                        echo -e &quot;${YELLOW}${INFO} 密码登录将保持启用。${NC}&quot;
                        PASSWORD_AUTH_ENABLED=&quot;yes&quot;
                        ;;
                esac
            else
                PASSWORD_AUTH_ENABLED=&quot;no&quot;
                echo -e &quot;${GREEN}${LOCK} 密码登录已禁用 (将使用生成的密钥登录)。${NC}&quot;
            fi
            ;;
        *)
            # 用户输入n或直接回车，保持密码登录启用
            echo -e &quot;${YELLOW}${INFO} 密码登录保持启用。${NC}&quot;
            PASSWORD_AUTH_ENABLED=&quot;yes&quot;
            ;;
    esac
  
    # 生成兼容Debian的SSH配置
    cat &amp;gt; /etc/ssh/sshd_config &amp;lt;&amp;lt;- EOF
# SSH安全配置 - 脚本版本 ${SCRIPT_VERSION} (Debian兼容版)
Port ${SSH_PORT}
Protocol 2

# 认证设置
PermitRootLogin yes
PubkeyAuthentication yes
PasswordAuthentication ${PASSWORD_AUTH_ENABLED}
ChallengeResponseAuthentication no
UsePAM yes
PermitEmptyPasswords no

# 安全设置
MaxAuthTries 3
MaxSessions 10
LoginGraceTime 60
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive yes

# 连接设置
X11Forwarding no
AllowTcpForwarding yes
AllowAgentForwarding yes

# 其他设置
PrintMotd no
PrintLastLog yes
StrictModes yes
IgnoreRhosts yes
HostbasedAuthentication no
Compression delayed
Banner none

Subsystem sftp /usr/lib/openssh/sftp-server
EOF

    # 检测SSH服务名称和验证方式
    detect_ssh_info() {
        # 检测服务名称
        if systemctl is-active ssh &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
            SERVICE_NAME=&quot;ssh&quot;
        elif systemctl is-active sshd &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
            SERVICE_NAME=&quot;sshd&quot;
        else
            # 尝试启动来检测
            if systemctl start ssh &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
                SERVICE_NAME=&quot;ssh&quot;
            elif systemctl start sshd &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
                SERVICE_NAME=&quot;sshd&quot;
            else
                SERVICE_NAME=&quot;ssh&quot;  # 默认使用ssh
            fi
        fi
        
        # 检测验证命令
        if command -v sshd &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
            TEST_CMD=&quot;sshd -t&quot;
        elif [ -f /usr/sbin/sshd ]; then
            TEST_CMD=&quot;/usr/sbin/sshd -t&quot;
        else
            TEST_CMD=&quot;none&quot;
        fi
        
        echo &quot;${SERVICE_NAME}:${TEST_CMD}&quot;
    }

    # 验证SSH配置
    echo -ne &quot;${BLUE}${CONF} 验证SSH配置语法...&quot;
    
    SSH_INFO=$(detect_ssh_info)
    SERVICE_NAME=$(echo &quot;$SSH_INFO&quot; | cut -d: -f1)
    TEST_CMD=$(echo &quot;$SSH_INFO&quot; | cut -d: -f2)
    
    if [ &quot;$TEST_CMD&quot; != &quot;none&quot; ] &amp;amp;&amp;amp; $TEST_CMD &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
        echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
    else
        echo -e &quot; ${YELLOW}${WARN} 跳过验证${NC}&quot;
        if [ &quot;$TEST_CMD&quot; = &quot;none&quot; ]; then
            echo -e &quot;${YELLOW}${INFO} 未找到sshd命令，配置语法验证已跳过${NC}&quot;
        fi
    fi

    # 重启SSH服务
    echo -ne &quot;${BLUE}${CONF} 重启SSH服务...&quot;
    
    # 使用检测到的服务名称重启
    if systemctl restart &quot;$SERVICE_NAME&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
        echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
        RESTART_SUCCESS=true
    else
        # 尝试其他重启方式
        if /etc/init.d/&quot;$SERVICE_NAME&quot; restart &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
            echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            RESTART_SUCCESS=true
        else
            echo -e &quot; ${RED}${CROSS}${NC}&quot;
            echo -e &quot;${YELLOW}${WARN} 服务重启失败，尝试直接启动...${NC}&quot;
            systemctl start &quot;$SERVICE_NAME&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || \
            /etc/init.d/&quot;$SERVICE_NAME&quot; start &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
            RESTART_SUCCESS=false
        fi
    fi

    # 等待服务启动
    sleep 3

    # 检查服务状态
    echo -ne &quot;${BLUE}${CONF} 检查SSH服务状态...&quot;
    if systemctl is-active &quot;$SERVICE_NAME&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
        echo -e &quot; ${GREEN}${CHECK} ${SERVICE_NAME}服务运行正常${NC}&quot;
        
        # 检查端口监听
        echo -ne &quot;${BLUE}${CONF} 检查端口监听...&quot;
        if netstat -tln 2&amp;gt;/dev/null | grep -q &quot;:${SSH_PORT} &quot;; then
            echo -e &quot; ${GREEN}${CHECK} 端口${SSH_PORT}监听正常${NC}&quot;
        elif ss -tln 2&amp;gt;/dev/null | grep -q &quot;:${SSH_PORT} &quot;; then
            echo -e &quot; ${GREEN}${CHECK} 端口${SSH_PORT}监听正常${NC}&quot;
        else
            echo -e &quot; ${YELLOW}${WARN} 端口${SSH_PORT}未监听${NC}&quot;
            echo -e &quot;${YELLOW}${INFO} 等待服务完全启动...${NC}&quot;
            sleep 5
            
            # 再次检查
            if netstat -tln 2&amp;gt;/dev/null | grep -q &quot;:${SSH_PORT} &quot;; then
                echo -e &quot;${GREEN}${CHECK} 端口${SSH_PORT}现在已监听${NC}&quot;
            else
                echo -e &quot;${RED}${CROSS} 端口${SSH_PORT}仍然未监听${NC}&quot;
                echo -e &quot;${YELLOW}${WARN} 请手动检查SSH服务: systemctl status ${SERVICE_NAME}${NC}&quot;
            fi
        fi
    else
        echo -e &quot; ${RED}${CROSS} ${SERVICE_NAME}服务未运行${NC}&quot;
        echo -e &quot;${YELLOW}${WARN} 尝试手动启动...${NC}&quot;
        systemctl start &quot;$SERVICE_NAME&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
        sleep 2
    fi
    
    # 显示最终状态
    echo -e &quot;${BLUE}${CONF} SSH配置完成总结:${NC}&quot;
    echo -e &quot;  ${BLUE}• ${WHITE}服务名称: ${GREEN}${SERVICE_NAME}${NC}&quot;
    echo -e &quot;  ${BLUE}• ${WHITE}SSH端口: ${GREEN}${SSH_PORT}${NC}&quot;
    echo -e &quot;  ${BLUE}• ${WHITE}密码登录: ${GREEN}${PASSWORD_AUTH_ENABLED}${NC}&quot;
    
    progress_bar 1
}

# 防火墙配置
setup_firewall() {
    echo -e &quot;${BLUE}${FIRE} 正在配置防火墙...${NC}&quot;
  
    case ${OS_GROUP} in
        debian|alpine|arch)
            if command -v ufw &amp;amp;&amp;gt; /dev/null; then
                echo -e &quot;${PURPLE}${FIRE} 使用UFW防火墙${NC}&quot;
                echo -ne &quot;  ${BLUE}配置规则...&quot;
                ufw allow ${SSH_PORT}/tcp &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
                (yes | ufw enable) &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
                spinner
                echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            else
                echo -e &quot;${YELLOW}${WARN} 未检测到UFW，跳过防火墙配置${NC}&quot;
            fi
            ;;
        rhel)
            if command -v firewall-cmd &amp;amp;&amp;gt; /dev/null; then
                echo -e &quot;${PURPLE}${FIRE} 使用Firewalld防火墙${NC}&quot;
                echo -ne &quot;  ${BLUE}配置规则...&quot;
                firewall-cmd --permanent --add-port=${SSH_PORT}/tcp &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
                firewall-cmd --reload &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
                spinner
                echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
            else
                echo -e &quot;${YELLOW}${WARN} 未检测到Firewalld，跳过防火墙配置${NC}&quot;
            fi
            ;;
        *)
            echo -e &quot;${YELLOW}${WARN} 未知的系统组，跳过防火墙配置${NC}&quot;
            ;;
    esac
    progress_bar 0.8
}

# Fail2Ban配置
setup_fail2ban() {
    if ! command -v fail2ban-client &amp;amp;&amp;gt; /dev/null; then
        echo -e &quot;${YELLOW}${WARN} 未检测到Fail2Ban，跳过配置${NC}&quot;
        return
    fi

    echo -e &quot;${BLUE}${FIRE} 正在配置fail2ban...${NC}&quot;
  
    # 简单的fail2ban配置
    cat &amp;gt; /etc/fail2ban/jail.local &amp;lt;&amp;lt;- EOF
[sshd]
enabled = true
port = ${SSH_PORT}
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
EOF

    echo -ne &quot;${BLUE}${FIRE} 启动fail2ban服务...&quot;
    systemctl enable fail2ban &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
    systemctl restart fail2ban &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
    spinner
    echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
    progress_bar 0.5
}

# 显示私钥信息
show_private_key() {
    if [ &quot;$KEY_GENERATED&quot; = true ] &amp;amp;&amp;amp; [ -n &quot;$PRIVATE_KEY_CONTENT&quot; ]; then
        echo -e &quot;\n${CYAN}==============================================&quot;
        echo -e &quot;  ${YELLOW}${WARN} 重要: 请立即保存您的新SSH私钥 ${WARN}${NC}&quot;
        echo -e &quot;==============================================&quot;
        echo -e &quot;${WHITE}${SAVE} 保存说明:${NC}&quot;
        echo -e &quot;  ${BLUE}• ${WHITE}将以下内容完整复制并保存到您本地电脑的 .ssh 目录中${NC}&quot;
        echo -e &quot;  ${BLUE}• ${WHITE}文件名建议: id_ed25519_server${NC}&quot;
        echo -e &quot;  ${BLUE}• ${WHITE}保存后设置权限: ${GREEN}chmod 600 ~/.ssh/id_ed25519_server${NC}&quot;
        echo -e &quot;&quot;
        echo -e &quot;${WHITE}${KEY} SSH私钥内容:${NC}&quot;
        echo -e &quot;${GREEN}${PRIVATE_KEY_CONTENT}${NC}&quot;
        echo -e &quot;&quot;
        echo -e &quot;${YELLOW}${WARN} 注意: 此私钥仅显示一次，请立即保存!${NC}&quot;
        echo -e &quot;${CYAN}==============================================&quot;
    fi
}

# 显示连接信息
show_connection_info() {
    echo -e &quot;${WHITE}${SERVER} SSH连接信息:${NC}&quot;
    echo -e &quot;  ${BLUE}• ${NET} 公网IP: ${GREEN}${PUBLIC_IP}${NC}&quot;
    echo -e &quot;  ${BLUE}• ${NET} 内网IP: ${GREEN}${LOCAL_IP}${NC}&quot;
    echo -e &quot;  ${BLUE}• ${CONF} SSH端口: ${GREEN}${SSH_PORT}${NC}&quot;
    echo -e &quot;&quot;
    echo -e &quot;  ${BLUE}• ${KEY} 使用以下命令连接:${NC}&quot;
    echo -e &quot;    ${GREEN}ssh root@${PUBLIC_IP} -p ${SSH_PORT}${NC}&quot;
    if [ -n &quot;$LOCAL_IP&quot; ] &amp;amp;&amp;amp; [ &quot;$LOCAL_IP&quot; != &quot;127.0.0.1&quot; ]; then
        echo -e &quot;    ${GREEN}ssh root@${LOCAL_IP} -p ${SSH_PORT}${NC}&quot;
    fi
}

# 显示登录方式信息
show_auth_info() {
    echo -e &quot;${WHITE}${LOCK} 登录方式:${NC}&quot;
    if [ &quot;$PASSWORD_AUTH_ENABLED&quot; = &quot;yes&quot; ]; then
        echo -e &quot;  ${BLUE}• ${PASS} 密码登录: ${GREEN}已启用${NC}&quot;
        echo -e &quot;  ${YELLOW}• ${PASS} 当前root密码: ${GREEN}${ROOT_PASSWORD}${NC}&quot;
    else
        echo -e &quot;  ${BLUE}• ${PASS} 密码登录: ${RED}已禁用${NC}&quot;
    fi
  
    if [ &quot;$KEY_GENERATED&quot; = true ]; then
        echo -e &quot;  ${BLUE}• ${KEY} 密钥登录: ${GREEN}已启用 (新密钥已生成)${NC}&quot;
    else
        echo -e &quot;  ${BLUE}• ${KEY} 密钥登录: ${GREEN}已启用 (请使用您自己的密钥)${NC}&quot;
    fi
}

# 显示安全建议
show_security_tips() {
    echo -e &quot;${CYAN}==============================================&quot;
    echo -e &quot;${WHITE}${INFO} 安全建议:${NC}&quot;
    if [ &quot;$PASSWORD_AUTH_ENABLED&quot; = &quot;yes&quot; ]; then
        echo -e &quot;  ${BLUE}• ${LOCK} 立即登录并修改密码 (执行: ${GREEN}passwd${BLUE})${NC}&quot;
    fi
    if [ &quot;$KEY_GENERATED&quot; = true ]; then
        echo -e &quot;  ${BLUE}• ${SAVE} 立即保存上面的私钥到安全位置${NC}&quot;
    fi
    echo -e &quot;  ${BLUE}• ${WARN} 记录密码/密钥后清除终端历史 (执行: ${GREEN}history -c${BLUE})${NC}&quot;
    echo -e &quot;${CYAN}==============================================&quot;
}

# 显示结果
show_result() {
    echo -ne &quot;${BLUE}${NET} 正在获取网络信息...&quot;
    LOCAL_IP=$( (ip -4 addr show | grep -E &apos;inet (10\.|172\.|192\.168\.)&apos; | awk &apos;{print $2}&apos; | cut -d&apos;/&apos; -f1 | head -n1) || echo &quot;未知&quot;)
    PUBLIC_IP=$( (curl -s4 --connect-timeout 5 ifconfig.me || curl -s4 --connect-timeout 5 icanhazip.com || echo &quot;无法获取&quot;) 2&amp;gt;/dev/null )
    echo -e &quot; ${GREEN}${CHECK}${NC}&quot;
  
    clear
    echo -e &quot;${CYAN}&quot;
    cat &amp;lt;&amp;lt; &quot;EOF&quot;
  _____                _       _   _                 _ 
 / ____|              | |     | | (_)               | |
| |     ___  _ __ ___ | | __ _| |_ _  ___  _ __ ___| |
| |    / _ \| &apos;_ ` _ \| |/ _` | __| |/ _ \| &apos;__/ _ \ |
| |____ (_) | | | | | | | (_| | |_| | (_) | | |  __/_|
 \_____\___/|_| |_| |_|_|\__,_|\__|_|\___/|_|  \___(_)
                                                
EOF
    echo -e &quot;${NC}&quot;
  
    echo -e &quot;${CYAN}==============================================&quot;
    echo -e &quot;            ${SUCCESS} SSH 配置已完成 ${SUCCESS}&quot;
    echo -e &quot;==============================================&quot;
    echo -e &quot;${NC}&quot;
  
    # 显示连接信息
    show_connection_info
    echo &quot;&quot;
  
    # 显示登录方式信息
    show_auth_info
  
    # 如果生成了密钥，显示私钥
    show_private_key
  
    # 显示安全建议
    show_security_tips
  
    echo -e &quot;${GREEN}${SUCCESS} 配置完成! 感谢使用本脚本! ${SUCCESS}${NC}&quot;
    echo -e &quot;${CYAN}==============================================&quot;
    
    # 最后的连接测试提醒
    echo -e &quot;\n${YELLOW}${INFO} 请立即测试SSH连接是否正常!${NC}&quot;
    echo -e &quot;${YELLOW}${INFO} 如果无法连接，请检查防火墙和SELinux设置。${NC}&quot;
}

# 脚本自删除
self_delete() {
    echo -e &quot;\n${YELLOW}${INFO} 正在清除脚本...${NC}&quot;
    rm -f &quot;$0&quot;
    echo -e &quot;${GREEN}${CHECK} 脚本已删除${NC}&quot;
}

# 主流程
main() {
    show_banner
    check_root
    detect_system
    install_deps
    set_root_password
    setup_ssh_key_auth
    configure_ssh
    setup_firewall
    setup_fail2ban
    show_result
    self_delete
}

# 执行主函数
main
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用方法&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;将脚本上传到服务器&lt;/strong&gt;（与之前相同）：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;scp setup-ssh.sh username@your_server_ip:/var/www/html/
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;设置脚本的执行权限&lt;/strong&gt;：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;ssh username@your_server_ip
sudo chmod +x /var/www/html/setup-ssh.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;一键命令示例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;curl -sSL http://your_server_ip/setup-ssh.sh -o setup-ssh.sh &amp;amp;&amp;amp; bash setup-ssh.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安全提示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;默认密码&lt;/strong&gt;：使用默认密码可能带来安全隐患，建议在生产环境中始终使用强密码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPS&lt;/strong&gt;：如果可能，使用 HTTPS 来保护传输中的数据。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>php基础课程文档</title><link>https://6wd.cn/posts/php-basics-course/</link><guid isPermaLink="true">https://6wd.cn/posts/php-basics-course/</guid><description>现在是2023年9月，本系列课程基于php8，但是现在市面上大多数还是php7的，所以我们讲的大部分知识都是7和8通用的，后面会专门讲8相对于7的特性和区别等。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;课程介绍&lt;/h1&gt;
&lt;p&gt;现在是2023年9月，本系列课程基于php8，但是现在市面上大多数还是php7的，所以我们讲的大部分知识都是7和8通用的，后面会专门讲8相对于7的特性和区别等。
课程包含基础知识和实战项目：
正所谓纸上得来终觉浅，绝知此事须躬行，只学习基础知识很容易忘记，但结合实战项目就能记得很牢固，所以每隔几节课就会有一个小项目来巩固知识。&lt;/p&gt;
&lt;p&gt;关于知识星球：
本课程是完全公开且免费的，除了课程外，还有专门交流和写作业的社区，那就是PHP的星球（&lt;a href=&quot;https://PHP.fun&quot;&gt; https://PHP.fun &lt;/a&gt; ），里面会总结一些学员常见的问题，还会布置作业，可以在里面提交答案，然后我来分析代码有没有问题或者有更优的处理方法。这种作业的形式，可以让你真正学会，而不是眼睛会了手不会。&lt;/p&gt;
&lt;p&gt;除此之外，PHP还提供一对一带徒陪跑服务，这个是收费的，价格很亲民，有需要的话请详细咨询我。咱们的课程是23年9月开始边录边发的，所以有问题或者建议可以在评论区提，我会在后面的课程中做优化。&lt;/p&gt;
&lt;p&gt;学习网站推荐：
&lt;a href=&quot;https://www.w3school.com.cn/php/index.asp&quot;&gt;PHP 教程 (w3school.com.cn)&lt;/a&gt;
&lt;a href=&quot;https://www.runoob.com/php/php-tutorial.html&quot;&gt;PHP 教程 | 菜鸟教程 (runoob.com)&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;关于php&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PHP 是 &quot;PHP Hypertext Preprocessor&quot; 的首字母缩略词&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PHP 是开源免费的，并且使用广泛&lt;/strong&gt; , 可供免费下载和使用，可商用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PHP 脚本在服务器上执行&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PHP 是解释型语言，按顺序从上往下执行，无需编译，直接运行&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它强大到足以成为在网络上最大的博客系统的核心（WordPress）！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它深邃到足以运行最大的社交网络（facebook）！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;而它的易用程度足以成为初学者的首选服务器端语言！&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;什么是 PHP 文件？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PHP 文件能够包含文本、HTML、CSS 以及 PHP 代码&lt;/li&gt;
&lt;li&gt;PHP 文件的后缀是 &quot;.php&quot;&lt;/li&gt;
&lt;li&gt;PHP 代码在服务器上执行，而结果以纯文本返回浏览器&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;PHP 能够做什么？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PHP 能够生成动态页面内容 （Html页面渲染）&lt;/li&gt;
&lt;li&gt;PHP 能够创建、打开、读取、写入、删除以及关闭服务器上的文件 （文件操作）&lt;/li&gt;
&lt;li&gt;PHP 能够接收表单数据 （例如注册登录）&lt;/li&gt;
&lt;li&gt;PHP 能够发送并取回 cookies （记录用户状态等信息）&lt;/li&gt;
&lt;li&gt;PHP 能够添加、删除、修改数据库中的数据 （数据操作）&lt;/li&gt;
&lt;li&gt;PHP 能够限制用户访问网站中的某些页面 （权限管理）&lt;/li&gt;
&lt;li&gt;PHP 能够对数据进行加密和压缩&lt;/li&gt;
&lt;li&gt;PHP 通常用于小程序 app 浏览器插件等的后端服务接口&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过 PHP，您可以不受限于只输出 HTML。您还能够输出图像、PDF 文件、甚至 Flash 影片。您也可以输出任何文本，比如 XHTML 和 XML。&lt;/p&gt;
&lt;h3&gt;为什么使用 PHP？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PHP 是跨平台的，可运行于各种平台（Windows, Linux, Unix, Mac OS X 等等）&lt;/li&gt;
&lt;li&gt;PHP 兼容几乎所有服务器（Apache，Nginx, IIS 等等）&lt;/li&gt;
&lt;li&gt;PHP 支持多种数据库 (Mysql)&lt;/li&gt;
&lt;li&gt;PHP 是免费的。请从官方 PHP 资源下载：&lt;a href=&quot;http://www.php.net/&quot;&gt;www.php.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PHP 易于学习，并可高效地运行在服务器端&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;最好应具备的基础知识&lt;/h2&gt;
&lt;p&gt;在继续学习之前，您需要对下面的知识有基本的了解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;JavaScript（入门级这个无所谓）&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;环境安装和编辑器推荐&lt;/h1&gt;
&lt;p&gt;编辑器根据自己喜好即可，我推荐vscode /notepad-- /notepad next /phpstorm
环境我推荐使用phpstudy（小皮）
演示创建一个站点&lt;/p&gt;
&lt;p&gt;注意：把电脑文件扩展名显示出来&lt;/p&gt;
&lt;p&gt;![[Pasted image 20230920100234.png]]&lt;/p&gt;
&lt;h1&gt;php语法&lt;/h1&gt;
&lt;h3&gt;基础 PHP 语法&lt;/h3&gt;
&lt;p&gt;PHP 脚本以 &lt;code&gt;&amp;lt;?php&lt;/code&gt; 开头，以 &lt;code&gt;?&amp;gt;&lt;/code&gt; 结尾：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php // 此处是 PHP 代码 ?&amp;gt;

&amp;lt;?php
// 此处是 PHP 代码
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHP 脚本可放置于文档中的&lt;strong&gt;任何&lt;/strong&gt;位置，文件扩展名是 &quot;.php&quot;。
PHP 文件通常包含 HTML 标签以及一些 PHP 脚本代码，注意： html js css可以写在php文件里运行，但php不能写在html js css文件里运行。&lt;/p&gt;
&lt;p&gt;PHP 语句以分号结尾（;）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;h1&amp;gt;我的第一张 PHP 页面&amp;lt;/h1&amp;gt;

&amp;lt;?php
echo &quot;Hello PHP!&quot;;
?&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;输出方法：echo 和 print&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;不同点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;echo - 能够输出一个以上的字符串，英文逗号隔开&lt;/li&gt;
&lt;li&gt;print - 只能输出一个字符串，并&lt;strong&gt;始终返回 1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;echo 比 print 稍快，并且开销低&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
echo &quot;&amp;lt;h2&amp;gt;PHP123!&amp;lt;/h2&amp;gt;&quot;;
echo &quot;Hello world!&amp;lt;br&amp;gt;&quot;;
echo &quot;PHP&quot;, &quot; string&quot;, 1, &quot; 2 &quot;;
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相同点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;都是一个语言结构，有无括号均可使用：echo 或 echo()  print 或 print()&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;注释&lt;/h3&gt;
&lt;p&gt;注释不会被作为程序来读取和执行。它唯一的作用是供代码编辑者阅读（让别人阅读明白，提醒自己做过什么，特别是一些函数方法的用途等）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// 这是单行注释

# 这也是单行注释

/*
这是多行注释块
它横跨了
多行
随意换行没问题
echo &apos;PHP&apos;;
*/
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;变量&lt;/h3&gt;
&lt;p&gt;变量是存储信息的容器，有点类似初中数学里的代数 &lt;code&gt;x=1,y=2&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$a=5;
$_a = 5;
$b=6;
$c=$a+$b;
echo $c;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;=号并不是真实的等号，而是叫赋值&lt;/p&gt;
&lt;h4&gt;变量命名规则&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;变量以 $ 符号开头，其后是变量的名称&lt;/li&gt;
&lt;li&gt;变量名称必须以字母或下划线开头&lt;/li&gt;
&lt;li&gt;变量名称不能以数字开头，不能有空格&lt;/li&gt;
&lt;li&gt;变量名称只能包含字母 数字 字符和 下划线（A-z、0-9 以及 _）&lt;/li&gt;
&lt;li&gt;变量名称对大小写敏感（$y 与 $Y 是两个不同的变量）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注释：PHP 变量名称对大小写敏感！&lt;/p&gt;
&lt;p&gt;推荐的几种命名方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下划线命名法 &lt;code&gt;$first_name = &apos;zhang&apos;;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;小驼峰命名法 &lt;code&gt;$firstName = &apos;zhang&apos;;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;大驼峰命名法 &lt;code&gt;$FirstName = &apos;zhang&apos;;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$txt=&quot;Hello world!&quot;;
$a=5;
$b=8.5;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不必告知 PHP 变量的数据类型，php会根据它的值，自动把变量转换为正确的数据类型&lt;/p&gt;
&lt;p&gt;变量也有&lt;strong&gt;作用域&lt;/strong&gt;之分，等到后面函数的时候再说。&lt;/p&gt;
&lt;h4&gt;空白符&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;
echo &apos;PHP

你在干什么

？

&apos;;

/**

我在

看抖音小姐姐


*/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;大小写敏感&lt;/h3&gt;
&lt;p&gt;所有用户定义的函数、类和关键词（例如 if、else、echo 等等）都对大小写&lt;strong&gt;不敏感&lt;/strong&gt;，
但是所有变量都对大小写&lt;strong&gt;敏感&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ECHO &quot;Hello PHP!&amp;lt;br&amp;gt;&quot;;
echo &quot;Hello PHP!&amp;lt;br&amp;gt;&quot;;

EcHo &quot;Hello PHP!&amp;lt;br&amp;gt;&quot;;
PRint &quot;Hello PHP!&amp;lt;br&amp;gt;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$color=&quot;red&quot;;
echo &quot;My car is &quot; . $color . &quot;&amp;lt;br&amp;gt;&quot;;
echo &quot;My house is &quot; . $COLOR . &quot;&amp;lt;br&amp;gt;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;命令行的使用&lt;/h2&gt;
&lt;p&gt;可以像python一样在命令行里运行php
用cmd或者vscode插件&lt;/p&gt;
&lt;p&gt;可以获取用户输入的内容&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$input = readline(&quot;请输入内容：&quot;); 
echo &quot;您输入的内容是： &quot; . $input;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;请输入内容：&quot;; 
$input = fgets(STDIN); 
echo &quot;您输入的内容是： &quot; . $input;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;数据类型&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;字符串、整数、浮点数、逻辑（布尔型）、数组、对象、NULL、资源类型&lt;/strong&gt;
用var_dump() 会返回变量的数据类型和值，一般用于开发调试时使用&lt;/p&gt;
&lt;p&gt;只获取数据类型 &lt;code&gt;echo gettype($a);&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;字符串&lt;/h3&gt;
&lt;p&gt;字符串是字符序列，比如 &quot;Hello world!&quot;。&lt;/p&gt;
&lt;p&gt;字符串可以是引号内的任何文本，可以使用单引号或双引号
注意双引号和单引号的区别&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$x = &quot;Hello world!&quot;;
echo $x;
echo &quot;&amp;lt;br&amp;gt;&quot;; 
$x = &apos;Hello world!&apos;;
var_dump($x);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;整数&lt;/h3&gt;
&lt;p&gt;和数学里的整数有些区别&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整数必须有至少一个数字（0-9）&lt;/li&gt;
&lt;li&gt;整数不能包含逗号或空格&lt;/li&gt;
&lt;li&gt;整数不能有小数点&lt;/li&gt;
&lt;li&gt;整数正负均可&lt;/li&gt;
&lt;li&gt;可以用三种格式规定整数：十进制、十六进制（前缀是 0x）或八进制（前缀是 0）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$x = 5985;
var_dump($x);
echo &quot;&amp;lt;br&amp;gt;&quot;; 
$x = -345; // 负数
var_dump($x);
echo &quot;&amp;lt;br&amp;gt;&quot;; 
$x = 0x8C; // 十六进制数
var_dump($x);
echo &quot;&amp;lt;br&amp;gt;&quot;;
$x = 047; // 八进制数
var_dump($x);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;浮点数&lt;/h3&gt;
&lt;p&gt;浮点数是有小数点或指数形式的数字&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$x = 10.365;
var_dump($x);
echo &quot;&amp;lt;br&amp;gt;&quot;; 
$x = 2.4e3;
var_dump($x);
echo &quot;&amp;lt;br&amp;gt;&quot;; 
$x = 8E-5;
var_dump($x);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;逻辑（布尔值）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$x=true;
$y=false;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;数组&lt;/h3&gt;
&lt;p&gt;在一个变量中存储多个值
分为一维数组和多维数组，认识即可，不要深究，后面会专门讲&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$cars=array(&quot;Volvo&quot;,&quot;BMW&quot;,&quot;SAAB&quot;);
$_cars=[&quot;Volvo&quot;,&quot;BMW&quot;,&quot;SAAB&quot;];
var_dump($cars);
var_dump($_cars);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;对象&lt;/h3&gt;
&lt;p&gt;需要用到类和封装的知识
等学到类的时候再讲&lt;/p&gt;
&lt;h3&gt;Null&lt;/h3&gt;
&lt;p&gt;特殊的 NULL 值表示变量无值。NULL 是数据类型 NULL 唯一可能的值
注意：可以通过设置变量值为 NULL 来清空变量数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$x=&quot;Hello world!&quot;; 
var_dump($x);

$x=null; 
var_dump($x);

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;resource 资源类型&lt;/h3&gt;
&lt;p&gt;等学到数据库的时候再讲&lt;/p&gt;
&lt;h2&gt;初级实战 - 个人博客的开头部分&lt;/h2&gt;
&lt;p&gt;实战目标：
html简单介绍
复习变量声明和输出
复习注释
了解变量重复赋值&lt;/p&gt;
&lt;h2&gt;EOF(heredoc) 定界符使用说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;以 &amp;lt;&amp;lt;&amp;lt;EOF 开始标记开始，以 EOF 结束标记结束&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;结束标记必须顶头写，独自占一行，不能有缩进和空格&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在结束标记末尾要有分号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;EOF&lt;/strong&gt; 可以用任意其它字符代替，开始标记和结束标记相同即可，比如常用大写的 EOT、EOD、EOF 来表示，但是不只限于那几个(也可以用：JSON、HTML等)，只要保证开始标记和结束标记不在正文中出现即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;位于开始标记和结束标记之间的变量可以被正常解析，但是函数则不可以。在 heredoc 中，变量不需要用连接符 . 或 , 来拼接&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当内容需要内嵌引号（单引号或双引号）时，不需要加转义符，本身对单双引号转义。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$name=&quot;变量会被解析&quot;;
$a=&amp;lt;&amp;lt;&amp;lt;EOF
$name&amp;lt;br&amp;gt;
看上面的name已经不是name啦！！！&amp;lt;br&amp;gt;
EOF;
echo $a;

echo &apos;&amp;lt;hr&amp;gt;&apos;;

$a=&amp;lt;&amp;lt;&amp;lt;EOF
&amp;lt;a&amp;gt;html格式会被解析&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;你看看a标签显示了没？
你看看br显示了没？
&amp;lt;br&amp;gt;
EOF;
echo $a;

echo &apos;&amp;lt;hr&amp;gt;&apos;;

echo &amp;lt;&amp;lt;&amp;lt;EOF
&quot;双引号外所有被排列好的格式都会被保留&quot;

&quot;但是双引号内会保留转义符的转义效果,比如table:\t和换行：\n下一行&quot;

你看页面里有\t吗？
\n \t 和引号没关系吧？

那单&apos;引&apos;号呢？&apos;\t \n 是否能看到？&apos;
EOF;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;运算符&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;注：资料来源于菜鸟教程 www.runoob.com&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;算术运算符&lt;/h3&gt;
&lt;p&gt;![[Pasted image 20230922152416.png]]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php 
$x=10; 
$y=6;
echo ($x + $y); // 输出16
echo &apos;&amp;lt;br&amp;gt;&apos;;  // 换行
 
echo ($x - $y); // 输出4
echo &apos;&amp;lt;br&amp;gt;&apos;;  // 换行
 
echo ($x * $y); // 输出60
echo &apos;&amp;lt;br&amp;gt;&apos;;  // 换行
 
echo ($x / $y); // 输出1.6666666666667
echo &apos;&amp;lt;br&amp;gt;&apos;;  // 换行
 
echo ($x % $y); // 输出4
echo &apos;&amp;lt;br&amp;gt;&apos;;  // 换行
 
echo -$x;

//整数之间的整除，参数也必须是整数，向下取整
var_dump(intdiv(10, 3));
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;赋值运算符&lt;/h3&gt;
&lt;p&gt;![[Pasted image 20230922155033.png]]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php 
$x=10; 
echo $x; // 输出10
 
$y=20; 
$y += 100;
$y = $y + 100;
echo $y; // 输出120
 
$z=50;
$z -= 25;
echo $z; // 输出25
 
$i=5;
$i *= 6;
echo $i; // 输出30
 
$j=10;
$j /= 5;
echo $j; // 输出2
 
$k=15;
$k %= 4;
echo $k; // 输出3
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;递增/递减运算符&lt;/h3&gt;
&lt;p&gt;![[Pasted image 20230922160114.png]]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$x=10; 
echo ++$x; // 输出11
 
$y=10; 
echo $y++; // 输出10
 
$z=5;
echo --$z; // 输出4
 
$i=5;
echo $i--; // 输出5
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;比较运算符&lt;/h3&gt;
&lt;p&gt;![[Pasted image 20230922160145.png]]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$x=100; 
$y=&quot;100&quot;;
 
var_dump($x == $y);
echo &quot;&amp;lt;br&amp;gt;&quot;;
var_dump($x === $y);
echo &quot;&amp;lt;br&amp;gt;&quot;;
var_dump($x != $y);
echo &quot;&amp;lt;br&amp;gt;&quot;;
var_dump($x !== $y);
echo &quot;&amp;lt;br&amp;gt;&quot;;
 
$a=50;
$b=90;
 
var_dump($a &amp;gt; $b);
echo &quot;&amp;lt;br&amp;gt;&quot;;
var_dump($a &amp;lt; $b);
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;逻辑运算符&lt;/h3&gt;
&lt;p&gt;![[Pasted image 20230922160442.png]]&lt;/p&gt;
&lt;h4&gt;and 和 &amp;amp;&amp;amp; 的区别， or 和 || 的区别&lt;/h4&gt;
&lt;p&gt;主要体现在优先级：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;amp;&amp;amp;  运算符的优先级比  and  运算符高。&lt;/li&gt;
&lt;li&gt;这意味着，在一个表达式中， &amp;amp;&amp;amp;  运算符会先被执行，然后才是  and  运算符。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php 
// 在表达式中使用&amp;amp;&amp;amp;运算符
$bool = true &amp;amp;&amp;amp; false; 

// 显示&amp;amp;&amp;amp;运算符的运算结果
echo &quot;&amp;amp;&amp;amp;运算符的结果为：&quot;;
if($bool){
    echo &apos;true&apos;;
}
else{
    echo &apos;false&apos;;
}

echo &apos;----&apos;;
// 在表达式中使用and运算符
$bool = true and false; 
// 显示and运算符的运算结果
echo &quot;and运算符的结果为：&quot;;
if($bool){
    echo &apos;true&apos;;
}
else{
    echo &apos;false&apos;;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;阻断效果&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;//or-前面语句值为真，or后面不执行；否则，执行
$result = 0 or var_dump(&apos;执行我的语句&apos;);  //输出-执行我的语句
var_dump($result);  //int 0
$result = 2 or var_dump(&apos;执行我的语句&apos;);  //不输出
var_dump($result);  //int 2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;条件语句 (条件分支)&lt;/h2&gt;
&lt;h4&gt;if语句&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;仅当指定条件成立时执行代码&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (条件)
{
    条件成立时要执行的代码;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;if...else...语句&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;在条件成立时执行一块代码，条件不成立时执行另一块代码&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (条件)
{  
    条件成立时执行的代码; 
}  
else  
{  
    条件不成立时执行的代码;  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;if...elseif....else&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;if (条件)
{
    if条件成立时执行的代码;
}
elseif (条件)
{
    elseif条件成立时执行的代码;
}
elseif (条件)
{
    elseif条件成立时执行的代码;
}
else
{
    条件不成立时执行的代码;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;switch&lt;/h4&gt;
&lt;p&gt;注意：break很重要，不要漏掉&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
switch (n)
{
	case label1:
	    如果 n=label1，此处代码将执行;
	    break;
	case label2:
	    如果 n=label2，此处代码将执行;
	    break;
	default:
	    如果 n 既不等于 label1 也不等于 label2，此处代码将执行;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;什么时候适合用switch？
适合条件比较多，并且条件单一固定值匹配时用&lt;/p&gt;
&lt;h2&gt;循环&lt;/h2&gt;
&lt;p&gt;让相同的代码块一次又一次地重复运行&lt;/p&gt;
&lt;h3&gt;for 循环&lt;/h3&gt;
&lt;p&gt;用于预先知道脚本需要运行的次数的情况&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (初始值; 条件; 增量)
{
    要执行的代码(叫循环体);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;初始值&lt;/strong&gt;：主要是初始化一个变量值，用于设置一个计数器（但可以是任何在循环的开始被执行一次的代码）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;条件&lt;/strong&gt;：循环执行的限制条件。如果为 TRUE，则循环继续。如果为 FALSE，则循环结束。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;增量&lt;/strong&gt;：主要用于递增计数器（但可以是任何在循环的结束被执行的代码）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;注释：&lt;strong&gt;上面的&lt;/strong&gt;初始值&lt;/strong&gt;和&lt;strong&gt;增量&lt;/strong&gt;参数可为空，或者有多个表达式（用逗号分隔）。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for ($i=1,$j=0; $i&amp;lt;=5; )
{
    echo &quot;数字为 &quot; . $i.$j . PHP_EOL;
    $i++;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;while 循环&lt;/h3&gt;
&lt;p&gt;只要指定的条件成立，则循环执行代码块，直到指定的条件不成立&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (条件)
{
    要执行的代码;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意避免死循环&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$i=1;
while($i&amp;lt;=5)
{
    echo &quot;The number is &quot; . $i . &quot;&amp;lt;br&amp;gt;&quot;;
    $i++;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;do...while&lt;/h3&gt;
&lt;p&gt;语句会至少执行一次代码，然后检查条件，只要条件成立，就会重复进行循环&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;do
{
    要执行的代码;
}
while (条件);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$i=1;
do
{
    $i++;
    echo &quot;The number is &quot; . $i . &quot;&amp;lt;br&amp;gt;&quot;;
}
while ($i&amp;lt;=5);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;continue和break&lt;/h3&gt;
&lt;h4&gt;continue&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;  for ($i=0; $i &amp;lt; 5; $i++) { 
    if($i == 3){
        continue;
    }
    echo $i;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;break&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;for ($i=0; $i &amp;lt; 5; $i++) { 
    if($i&amp;gt;3){
        break;
    }
    echo $i;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;break 2&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;for ($i = 0; $i &amp;lt; 3; $i++) {
        echo &quot;外层循环: &quot; . $i . &quot;&amp;lt;br&amp;gt;&quot;;
    
        for ($j = 0; $j &amp;lt; 5; $j++) {
            echo &quot;内层循环: &quot; . $j . &quot;&amp;lt;br&amp;gt;&quot;;
        
            if ($j == 2) {
                break 2; // 跳出两层循环
            }
        }
 }

echo &apos;已跳出全部循环&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;在while中使用continue break和break2&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;    $a = 10;
    while ($a &amp;lt;= 20) {
        $a++;

        if($a == 15){
            //continue;
            break;
        }

        echo $a.&apos;---&apos;;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    $a = 10;
    while ($a &amp;lt;= 20) {
        $a++;

        if($a == 15){
            for ($i=0; $i &amp;lt; 5; $i++) { 
                if($i==3){
                    break 2;
                }
                echo &apos;&amp;lt;br&amp;gt;&apos;.$i.&apos;&amp;lt;br&amp;gt;&apos;;
            }
        }

        echo $a.&apos;---&apos;;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;foreach 循环&lt;/h3&gt;
&lt;p&gt;用于遍历数组，等学数组一起讲&lt;/p&gt;
&lt;h2&gt;数组&lt;/h2&gt;
&lt;p&gt;数组能够在单个变量中存储多个值，并且可以根据 键 访问其中的 值&lt;/p&gt;
&lt;h4&gt;数值数组&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$PHP = array(&quot;PHP1&quot;,&quot;PHP2&quot;,&quot;PHP3&quot;,&quot;PHP4&quot;,&quot;PHP5&quot;);
$PHP = [&quot;PHP1&quot;,&quot;PHP2&quot;,&quot;PHP3&quot;,&quot;PHP4&quot;,&quot;PHP5&quot;];

var_dump($PHP[1]);
var_dump($PHP[5]);

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
$PHP2 = [];
$PHP2[3] = &apos;3&apos;;

var_dump($PHP2);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;关联数组&lt;/h3&gt;
&lt;p&gt;关联数组是使用您分配给数组的指定的键的数组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$age=[&quot;PHP&quot;=&amp;gt;&quot;35&quot;,&quot;dong&quot;=&amp;gt;&quot;37&quot;];

//或者

$age[&apos;PHP&apos;]=&quot;35&quot;;  
$age[&apos;dong&apos;]=&quot;37&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;获取数组的长度 - count() 函数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;echo count($PHP);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;遍历数组&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;for($i=0;$i&amp;lt;count($PHP);$i++) {
	echo $PHP[$i];
	echo &quot;&amp;lt;br&amp;gt;&quot;; 
}

foreach ($PHP as $value)
{
    要执行代码;
}

foreach ($PHP as $key =&amp;gt; $value)
{
    要执行代码;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;for可以，while也可以，但最常用的是foreach&lt;/p&gt;
&lt;h3&gt;多维数组&lt;/h3&gt;
&lt;p&gt;多维数组是包含一个或多个数组的数组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  $PHPArr = [
    [
        &quot;免费课&quot;=&amp;gt;[
            &quot;PHP课&quot;,
            &quot;php&quot;,
            &quot;python&quot;
        ],
        &quot;体验课&quot;=&amp;gt;[
            &quot;php&quot;,
            &quot;js&quot;,
            &quot;vue&quot;
        ]
    ],
    [
        &quot;收费课&quot;=&amp;gt;[
            &quot;油猴脚本&quot;,
            &quot;浏览器插件&quot;,
            &quot;666&quot;
        ]
    ]
  ];

  print_r( $PHPArr );
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt; $PHPArr = [
   &quot;test&quot; =&amp;gt; [
        &quot;免费课&quot;=&amp;gt;[
            &quot;PHP课&quot;,
            &quot;php&quot;,
            &quot;python&quot;,
        ],
        &quot;体验课&quot;=&amp;gt;[
            &quot;php&quot;,
            &quot;js&quot;,
            &quot;vue&quot;,
        ]
    ],
   &quot;product&quot; =&amp;gt; [
        &quot;免费课&quot;=&amp;gt;[
            &quot;产品1&quot;,
            &quot;产品2&quot;,
        ],
        &quot;体验课&quot;=&amp;gt;[
            &quot;产品3&quot;,
            &quot;产品4&quot;,
        ]
    ]
  ];

  print_r( $PHPArr );
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;遍历多维数组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach ($PHP as $key =&amp;gt; $value)
{
    要执行代码;
	foreach ($value as $kk =&amp;gt; $vv)
	{
	    要执行代码;
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;初级实战2 - 个人博客的开头部分&lt;/h2&gt;
&lt;p&gt;实战目标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;复习运算符的使用&lt;/li&gt;
&lt;li&gt;复习条件语句的使用&lt;/li&gt;
&lt;li&gt;复习循环&lt;/li&gt;
&lt;li&gt;学会使用数组&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;任务：
循环数组：输出顶部导航栏，输出博客标题和时间
条件语句：如果为第一个导航，则给出突出显示
运算：输出数字的大小从大到小排列&lt;/p&gt;
&lt;h2&gt;函数&lt;/h2&gt;
&lt;p&gt;函数是一段可重复使用的代码块，可以将一系列操作封装起来，使代码更加模块化、可维护和可重用，来大大节省我们的开发时间和代码量，提高编程效率。&lt;/p&gt;
&lt;h3&gt;内置函数&lt;/h3&gt;
&lt;p&gt;内置函数有很多，之前学的print_r() count() 就是一个内置函数，
获取当前时间 time()，date(&apos;Y-m-d H:i:s&apos;)&lt;/p&gt;
&lt;p&gt;这节我们主要讲自定义函数&lt;/p&gt;
&lt;h3&gt;创建（定义）函数 和 调用&lt;/h3&gt;
&lt;p&gt;PHP 函数准则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;函数的名称应该提示出它的功能&lt;/li&gt;
&lt;li&gt;函数名称以字母或下划线开头（不能以数字开头）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;function functionName() { 
// 要执行的代码 
}
//调用
functionName();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function test(){
    echo &apos;我的名字是：写代码的PHP&apos;;
}

test();

// 获取当前的时间
function nowTime(){
	echo date(&apos;Y-m-d H:i:s&apos;);
}

nowTime();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;添加参数&lt;/h3&gt;
&lt;p&gt;为了给函数添加更多的功能，我们可以添加参数，参数类似变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function myName($name){
	echo &quot;我的名字是：$name&quot;;
}

myName(&quot;PHP&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 获取当前的时间
function nowTime($type){
    if($type==&quot;time&quot;){
        echo date(&apos;Y-m-d H:i:s&apos;);
    }
    else if($type==&quot;day&quot;){
        echo date(&apos;Y-m-d&apos;);
    }
}

nowTime(&quot;time&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;多个参数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;function plus($a,$b)
{
  echo $a+$b;
}

plus(2,3);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;//严格模式
declare(strict_types=1);
function plus(int $a,int $b)
{
  echo $a+$b;
}

plus(&apos;2&apos;,&apos;13&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;返回值&lt;/h3&gt;
&lt;p&gt;return ， 可有可无，但一般都有&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function plus($a,$b)
{
  return $a+$b;
}

echo plus(2,3);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;变量作用域&lt;/h2&gt;
&lt;p&gt;讲完了函数，就可以学习前面提到过的变量作用域了&lt;/p&gt;
&lt;p&gt;变量的作用域是脚本中变量可被引用/使用的部分。&lt;/p&gt;
&lt;h3&gt;局部 和 全局(global) 作用域&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在所有函数外部定义的变量，拥有全局作用域&lt;/li&gt;
&lt;li&gt;除了函数外，全局变量可以被脚本中的任何部分访问&lt;/li&gt;
&lt;li&gt;要在一个函数中访问一个全局变量，需要使用 global 关键字&lt;/li&gt;
&lt;li&gt;函数内部声明的变量是局部变量，仅能在函数内部访问&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$PHP=&quot;写代码的PHP&quot;;
function test(){
	global $PHP;
	$age=&quot;35&quot;;
	echo $PHP;
}
test();
echo $age;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;static 作用域&lt;/h3&gt;
&lt;p&gt;当一个函数完成时，它的所有变量通常都会被删除。然而，有时候希望某个局部变量不要被删除。
要做到这一点，请在第一次声明变量时使用 &lt;strong&gt;static&lt;/strong&gt; 关键字&lt;/p&gt;
&lt;p&gt;每次调用该函数时，该变量将会保留着函数前一次被调用时的值，但是该变量仍然是函数的局部变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function myTest()
{
    static $a=0;
    echo $a;
    $a++;
    echo PHP_EOL;    // 换行符
}
 
myTest();
myTest();
myTest();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;函数的参数作用域&lt;/h3&gt;
&lt;p&gt;参数是通过调用代码将值传递给函数的局部变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function test($PHP){
	echo $PHP;
}

test(&apos;PHP&apos;);
var_dump($PHP);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;unset和isset函数&lt;/h3&gt;
&lt;p&gt;unset()可以删除变量，isset() 可以判断变量是否存在&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
$PHP=&quot;写代码的PHP&quot;;

function test(){
	// global $PHP;
	$age=&quot;35&quot;;
    var_dump(isset($age));
	unset($age);

    var_dump(isset($age));
}
test();
var_dump($PHP);

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;超级全局变量&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;- $GLOBALS
- $_SERVER

- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;$GLOBALS&lt;/h4&gt;
&lt;p&gt;是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print_r($GLOBALS);

$PHP=&quot;PHP&quot;;
$age=35;
function test3(){
	global $PHP,$age;
	$age = &quot;38&quot;;
    $PHP = &quot;写代码的PHP&quot;;
}
test3();
echo $age;
echo $PHP;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$PHP=&quot;PHP&quot;;
$age=35;

function test2(){
    $GLOBALS[&quot;age&quot;]=&quot;38&quot;;
    $GLOBALS[&quot;PHP&quot;] = &quot;写代码的PHP&quot;;

    echo $GLOBALS[&quot;PHP&quot;].&apos;---&apos;.$GLOBALS[&quot;age&quot;];
}

test2();
echo PHP_EOL; 
echo $age;
echo $PHP;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;$_SERVER&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$_SERVER&lt;/code&gt; 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。&lt;/li&gt;
&lt;li&gt;这个数组中的项目由 Web 服务器创建。&lt;/li&gt;
&lt;li&gt;不能保证每个服务器都提供全部项目；服务器可能会忽略一些，或者提供一些没有在这里列举出来的项目。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;print_r($_SERVER)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;资料来自 &lt;a href=&quot;https://www.runoob.com/php/php-superglobals.html&quot;&gt;PHP 超级全局变量 | 菜鸟教程 (runoob.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;![[Pasted image 20230927152355.png]]
![[Pasted image 20230927152441.png]]&lt;/p&gt;
&lt;h2&gt;初级实战3 - 函数的使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;编写一个函数getFactors，接受一个正整数参数，计算并返回该整数的所有因子（除了1和自身的所有正整数因子）。&lt;/li&gt;
&lt;li&gt;注：因子是能够整除给定数的正整数（例如，对于数值 24，它的因子包括 1、2、3、4、6、8、12 和 24。因为这些数都可以整除 24，没有余数。）&lt;/li&gt;
&lt;li&gt;补充知识：怎么往数组内插入数据&lt;/li&gt;
&lt;li&gt;要求使用函数&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;其他运算符&lt;/h2&gt;
&lt;h3&gt;数组运算符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;+号运算符（合并）
注意：只会保留第一个数组中的键值对，而忽略后面数组中相同键名的元素，如果想要合并两个数组并覆盖相同键名的元素，可以使用array_merge()函数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  $a = [
    &quot;m&quot; =&amp;gt; &quot;测试&quot;,
    &quot;n&quot; =&amp;gt; &quot;PHP&quot;
  ];

  $b = [
    &quot;m&quot; =&amp;gt; &quot;测试2&quot;,
    &quot;o&quot;=&amp;gt;&quot;测试o&quot;,
    &quot;p&quot;=&amp;gt;&quot;测试p&quot;,
    &quot;q&quot;=&amp;gt;[
        &quot;cs&quot;=&amp;gt;&quot;二维测试&quot;
    ]
  ];

  $c=[
    &quot;m&quot; =&amp;gt; &quot;测试3&quot;,
    &quot;cc&quot;=&amp;gt;123
  ];

  print_r($a+$b+$c);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;==&lt;/li&gt;
&lt;li&gt;===
有相同的键/值对，且顺序相同、类型相同&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;    $a = [1,2,3];
    $b = [1,2,&quot;3&quot;];
	var_dump($a == $b);
	var_dump($a === $b);
	
    $a = [
        &quot;a&quot;=&amp;gt;123,
        &quot;b&quot;=&amp;gt;456,
    ];

    $b = [
        &quot;b&quot;=&amp;gt;456,
        &quot;a&quot;=&amp;gt;123,
    ];

    var_dump($a == $b);
    var_dump($a === $b);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;!= 和 &amp;lt;&amp;gt;&lt;/li&gt;
&lt;li&gt;!==&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;三元运算符 ?:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// $name = $username?$username:&quot;测试&quot;;

$name = isset($username)?$username:&quot;测试&quot;;

// $name = $username?:&quot;测试&quot;;
var_dump($name);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;空合并运算符 ??&lt;/h3&gt;
&lt;p&gt;用于简化处理可能为null的变量或数组元素的情况。
它的作用是判断一个变量是否未定义或者为null，如果未定义或为null，则返回指定的默认值；否则返回该变量的值&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$name = $username ?? &quot;PHP&quot;;
echo $name;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;组合比较符 &amp;lt;=&amp;gt;&lt;/h3&gt;
&lt;p&gt;可比较整型 浮点型 字符串&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$c = $a &amp;lt;=&amp;gt; $b; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果 $a &amp;gt; $b, 则 $c 的值为 1
如果 $a == $b, 则 $c 的值为 0
如果 $a &amp;lt; $b, 则 $c 的值为 -1&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$a = &quot;acd&quot;;
$b = &quot;ace&quot;;

var_dump($a &amp;lt;=&amp;gt; $b);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;比较&lt;/h2&gt;
&lt;h3&gt;数据类型的比较&lt;/h3&gt;
&lt;p&gt;虽然 PHP 是弱类型语言，但也需要明白变量类型及它们的意义
因为我们经常需要对 PHP 变量进行比较，包含松散和严格比较。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;松散比较：使用两个等号 == 比较，只比较值，不比较类型。&lt;/li&gt;
&lt;li&gt;严格比较：用三个等号（全等） === 比较，除了比较值，也比较类型。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，&quot;42&quot; 是一个字符串而 42 是一个整数。false 是一个布尔值而 &quot;false&quot; 是一个字符串。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
if(42 == &quot;42&quot;) {
    echo &apos;1、值相等&apos;;
}
 
echo PHP_EOL; // 换行符
 
if(42 === &quot;42&quot;) {
    echo &apos;2、类型相等&apos;;
} else {
    echo &apos;3、类型不相等&apos;;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;问题：如果只想比较类型是否相同，怎么比较？&lt;/p&gt;
&lt;h3&gt;比较undefined、 0、false、null、空值&lt;/h3&gt;
&lt;p&gt;分析 isset() is_null() empty()的区别&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var_dump(!isset($name));
var_dump(is_null($name));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$name = null;
var_dump(!isset($name));
var_dump(is_null($name));
var_dump(empty($name));
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;empty&lt;/h4&gt;
&lt;p&gt;注意：empty() 函数对于未定义的变量也会返回true，因此在使用empty() 函数之前，应该确保变量已经被定义&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$var1 = &quot;&quot;; // 空字符串
$var2 = 0; // 整数0
$var3 = null; // null
$var4 = false; // false
$var5 = array(); // 空数组 []

var_dump(empty($var1));
var_dump(empty($var2));
var_dump(empty($var3));
var_dump(empty($var4));
var_dump(empty($var5));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;字符串相关函数&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;  $strZh = &quot;我是写代码的PHP&quot;;

  $strEn = &quot;Hello PHP,I am a person who loves to share&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;strlen()  获取字符串长度&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strpos() 在字符串内查找一个字符或一段指定的文本，返回第一次出现的位置或false&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;stripos() 同上，但不区分大小写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strrpos() 同上上，返回最后一次出现的位置或false&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strripos() 同上，但不区分大小写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;explode()  把字符串打散成数组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;implode() 把数组拼接成字符串&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strtoupper() 把字符串转换为大写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strtolower() 把字符串转换为小写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ucfirst() 将单词的首字母转换为大写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;lcfirst() 将单词的首字母转换为小写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ucwords() 将字符串中每个单词的首字母转换为大写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;str_replace($search, $replace, $string) 将字符串中的某个子字符串替换为另一个字符串&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strrev()：将字符串反转&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;trim()：去除字符串两端的空格&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;substr() 截取字符串的一部分&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mb_substr() 截取字符串的一部分(中文)  需要安装扩展mbstring&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;初级实战4 - 字符串函数的使用&lt;/h2&gt;
&lt;p&gt;编写一个函数，接受一个英文字符串参数&quot;Hello PHP, HOW Are You?&quot;，将字符串中的每个单词的首字母转换为小写，并返回修改后的字符串。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;考察字符串的函数使用&lt;/li&gt;
&lt;li&gt;考察数组的使用&lt;/li&gt;
&lt;li&gt;考察循环的使用&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  $str = &apos;Hello PHP,HOW,Are,You&apos;;

  $arr = explode(&apos; &apos;,$str);
  //   print_r($arr);

  $newArr = [];
  foreach ($arr as $key =&amp;gt; $value) {
    if(strpos($value,&apos;,&apos;) !== false){
        $valueArr = explode(&apos;,&apos;,$value);
        $newValueArr = [];
        foreach ($valueArr as $kk =&amp;gt; $vv) {
            $newValueArr[] = lcfirst($vv); 
        }

        $newArr[] = implode(&apos;,&apos;,$newValueArr);
    }
    else{

        $newArr[]= lcfirst($value); 
    }
  }

  echo implode(&apos; &apos;,$newArr);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;数组相关函数&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$array = [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;array()：创建一个数组。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;count()：返回数组中元素的数量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_push($array, $newElement)：将一个或多个元素添加到数组的末尾。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_unshift($array, $newElement)：将一个或多个元素添加到数组的开头。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_pop()：删除并返回数组中的最后一个元素。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_shift()：删除并返回数组中的第一个元素。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_slice()：从数组中提取一部分元素，组成新的数组。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_merge()：合并两个或多个数组。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_reverse()：反转数组中的元素的顺序。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;in_array()：检查数组中是否存在某个值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_key_exists()：检查数组中是否存在某个键。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_keys()：返回数组中的所有键，组成新数组。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_values()：返回数组中的所有值，组成新数组。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_search()：在数组中搜索给定的值，并返回对应的键。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_unique()：移除数组中的重复值（原数组不变）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;max() min() 最大值和最小值&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sort() 数组排序（升序）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;rsort() 数组排序（降序）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_sum() 数组求和&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;array_product() 数组求乘积&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;暂时就想到这些函数，后面如果我们遇到了会再做补充。&lt;/p&gt;
&lt;h2&gt;初级实战5 - 数组函数的使用&lt;/h2&gt;
&lt;p&gt;编写一个PHP函数 &lt;code&gt;testArray($numbers)&lt;/code&gt; ，该函数接收一个整数数组 &lt;code&gt;$numbers&lt;/code&gt; 作为参数，并返回一个关联数组，包含以下统计信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;count&quot; ：数组中的元素个数。&lt;/li&gt;
&lt;li&gt;&quot;sum&quot; ：数组中所有元素的总和。&lt;/li&gt;
&lt;li&gt;&quot;average&quot; ：数组中元素的平均值。&lt;/li&gt;
&lt;li&gt;&quot;max&quot; ：数组中的最大值。&lt;/li&gt;
&lt;li&gt;&quot;min&quot; ：数组中的最小值。&lt;/li&gt;
&lt;li&gt;&quot;sorted&quot; ：按照从小到大排序的数组。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试数组：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$numbers = [5, 9, 3, 2, 7, 1, 6];
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;时间、日期相关知识&lt;/h2&gt;
&lt;h4&gt;函数&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;time() 获取当前时间戳（10位），例如：1697520502&lt;/li&gt;
&lt;li&gt;microtime(true) 返回一个浮点数时间戳（秒数和微秒数的总和）&lt;/li&gt;
&lt;li&gt;date(格式，时间戳) 日期格式化&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$time = time();
echo date(&apos;Y-m-d H:i:s&apos;,$time);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;strtotime(string)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;strtotime(&quot;next Monday&quot;);

$baseTime = strtotime(&quot;2023-10-01&quot;);
echo strtotime(&quot;next Monday&quot;, $baseTime);

$baseTime = time();
echo strtotime(&quot;+1 day&quot;, $baseTime);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;mktime($hour, $minute, $second, $month, $day, $year)  生成时间戳&lt;/li&gt;
&lt;li&gt;&lt;code&gt;date_create()&lt;/code&gt; 来创建一个日期时间对象 &lt;code&gt;date_create(&apos;2023-11-01&apos;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;date_format()&lt;/code&gt; 用于将日期和时间格式化为指定的字符串格式&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;date_format($date, &quot;Y-m-d H:i:s&quot;);
date_format($date, &quot;Y年m月d日 H:i:s&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;date_diff() 计算两个日期之间的差&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$date1 = date_create(&apos;2023-10-20 12:00:00&apos;);
$date2 = date_create(&apos;2023-10-21 12:00:00&apos;);
$diff = date_diff($date2, $date1);
echo $diff-&amp;gt;format(&apos;%a 天&apos;);
echo $diff-&amp;gt;format(&apos;%m 月&apos;);
echo $diff-&amp;gt;format(&apos;%y 年 %m 月 %d 天&apos;);

-  %Y ：完整年份的差异 
-  %y ：年份的差异（两位数） 
-  %m ：月份的差异 
-  %d ：天数的差异 
-  %a ：总共的天数差异 
-  %H ：小时的差异 
-  %h ：小时的差异（12小时制） 
-  %I ：分钟的差异 
-  %S ：秒数的差异 
-  %R ：正负
-  %r ：正负(必须是负的才会显示)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strftime($format, $timestamp)&lt;/code&gt; ：根据指定的格式，将时间戳格式化为可读的日期和时间字符串，支持本地化的日期和时间格式 (php8已废弃)。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$timestamp = time();
$dateString = strftime(&quot;%A %Y-%m-%d %H:%M:%S&quot;, $timestamp);
echo $dateString;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;gmdate($format, $timestamp)&lt;/code&gt; ：根据指定的格式，将GMT时间戳格式化为可读的日期和时间字符串。
&lt;code&gt;gmdate()&lt;/code&gt; 和 &lt;code&gt;date()&lt;/code&gt;的区别
&lt;code&gt;gmdate()&lt;/code&gt; 函数使用格林威治标准时间（GMT）作为默认的日期/时间基准，会忽略服务器的时区设置，始终返回格林威治标准时间（GMT）的日期和时间；
&lt;code&gt;date()&lt;/code&gt; 函数则使用本地时间作为基准，它会根据当前服务器的时区设置来格式化日期和时间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;date_default_timezone_set($timezone)&lt;/code&gt; ：设置默认的时区。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&quot;UTC&quot;, &quot;localtime&quot;本地时区, &quot;Asia/Shanghai&quot;上海&lt;/p&gt;
&lt;p&gt;注意：只能在脚本开始时设置默认时区，不能在运行时动态设置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;timezone_identifiers_list()&lt;/code&gt; ：返回所有可用时区标识符的数组。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;DateTime对象&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$dateTime = new DateTime(&quot;2023-11-01 12:34:56&quot;);
//增加或减少指定的时间间隔
$dateTime-&amp;gt;modify(&apos;+1 day&apos;);
$dateTime-&amp;gt;modify(&apos;-1 hour&apos;);

//设置日期部分 setDate($year, $month, $day)
$dateTime-&amp;gt;setDate(2024, 1, 3);

//设置时间部分 setTime($hour, $minute, $second)
$dateTime-&amp;gt;setTime(13, 1, 5);

// 设置时区
$dateTime-&amp;gt;setTimezone(new DateTimeZone(&quot;Asia/Shanghai&quot;)); 
// 获取时区
$dateTimeZone = $dateTime-&amp;gt;getTimezone(); 
print_r($dateTimeZone-&amp;gt;getName());
print_r($dateTimeZone-&amp;gt;getLocation());

//将日期时间格式化为指定的字符串格式
echo $dateTime-&amp;gt;format(&quot;Y-m-d H:i:s&quot;);

//获取时间戳
$timestamp = $dateTime-&amp;gt;getTimestamp();
echo $timestamp;

//计算时间差
$dateTime2 = new DateTime(&apos;2023-12-05&apos;);
$diff = $dateTime-&amp;gt;diff($dateTime2);
echo $diff-&amp;gt;format(&apos;%R %m %d %h %i %s&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$datetime = new DateTime(&apos;2024-01-01&apos;);
$interval = new DateInterval(&apos;P1D&apos;); // 一天的时间间隔
$datetime-&amp;gt;add($interval);
//$datetime-&amp;gt;sub($interval);

echo $datetime-&amp;gt;format(&apos;Y-m-d&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;特殊的变量写法和常量&lt;/h2&gt;
&lt;p&gt;交流社区地址：https://PHP.fun&lt;/p&gt;
&lt;h3&gt;特殊的变量写法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$a =&apos;PHP&apos;;
$$a = &quot;测试&quot;;

echo $a;
echo &apos; ---- &apos;;
echo $$a;
echo &apos; ---- &apos;;
echo $PHP;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际使用场景：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
for ($i=0; $i &amp;lt; 5; $i++) { 
    $a = &quot;PHP&quot;.$i;
    $$a = &quot;测试-&quot;.$i;
}

echo $PHP1;
echo $PHP2;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;常量&lt;/h3&gt;
&lt;p&gt;常量值被定义后，在脚本的其他任何地方都不能被改变。
命名规则和变量类似，严格区分大小写，但无需$符
&lt;strong&gt;注意：&lt;/strong&gt; 默认是全局的，可以在整个运行的脚本的任何地方使用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define(&quot;PHP&quot;, &quot;写代码的PHP PHP.fun&quot;);
echo PHP;

echo &apos;&amp;lt;hr&amp;gt;&apos;;

const PHP1 = &quot;猫大叔&quot;;
echo PHP1;

$a = 2;
define(&quot;PHP&quot;.$a, &quot;PHP1&quot;);
echo constant(&quot;PHP&quot;.$a);

echo &apos;&amp;lt;hr&amp;gt;&apos;;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际使用场景：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for ($i=0; $i &amp;lt; 5; $i++) { 
    $a = &quot;PHP&quot;.$i;
    // $$a = &quot;测试-&quot;.$i;
    define($a,&apos;测试-&apos;.$i);
}

echo PHP1;
echo PHP2;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;const和define的区别&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;const不能在条件语句中定义常量&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$a = 1;
if($a==1){
    define(&quot;PHP&quot;.$a, &quot;PHP1&quot;);
    echo constant(&quot;PHP&quot;.$a);
    
    const PHP2 = &quot;猫大叔&quot;;
    echo PHP2;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;const用于类成员变量的定义，define不可以用于类成员变量的定义，可用于全局常量。&lt;/li&gt;
&lt;li&gt;const可在类中使用，define不能&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;class ceshi {
    
    const Ceshi = &apos;PHP&apos;;
    public function cc()
    {
        define(&apos;MS&apos;,&apos;写代码的PHP&apos;);
        echo self::Ceshi;
    }

}
$c = new ceshi;
$c-&amp;gt;cc();

echo &apos;----&apos;;
echo MS;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;常量和变量的区别：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;常量前面没有美元符号($)，而且不能有&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;常量可以不用理会变量的作用域在任何地方定义和访问&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;常量一旦定义就不能重新定义或取消定义&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;常量的值只能是标量（字符串、整数、浮点数、布尔值）,注意：现在也支持数组了&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;获取所有的常量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get_defined_constants()
get_defined_constants(true)
get_defined_constants(true)[&quot;user&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;魔术常量&lt;/h3&gt;
&lt;p&gt;魔术常量：它的值随着它在代码中的位置改变而改变&lt;/p&gt;
&lt;h5&gt;&lt;code&gt;__LINE__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;文件中的当前行号&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;这是第 &quot; &apos; . __LINE__ . &apos; &quot; 行&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__FILE__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;文件的完整路径和文件名，包含（盘符）根目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;该文件的完整路径为 &quot; &apos; . __FILE__ . &apos; &quot; &apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__DIR__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;文件所在的目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;该文件位于 &quot; &apos; . __DIR__ . &apos; &quot; &apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__FUNCTION__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;该函数被定义时的名字（区分大小写）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function test() {
    echo  &apos;函数名为：&apos; . __FUNCTION__ ;
}
test();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__CLASS__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;该类被定义时的名字（区分大小写）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
class testClass {
    function test() {
        echo &apos;类名为：&apos;  . __CLASS__ . &quot;&amp;lt;br&amp;gt;&quot;;
        echo  &apos;函数名为：&apos; . __FUNCTION__ ;
    }
}
$t = new testClass();
$t-&amp;gt;test();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__NAMESPACE__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;命名空间&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace MyProject; 
echo &apos;命名空间为：&quot;&apos;, __NAMESPACE__, &apos;&quot;&apos;; // 输出 &quot;MyProject&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__METHOD__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;包含了：命名空间 类名 函数名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace PHP;
class MyClass {
    public function myMethod() {
        echo __METHOD__; // 输出：PHP\MyClass::myMethod
    }
}

$obj = new MyClass();
$obj-&amp;gt;myMethod();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__TRAIT__&lt;/code&gt;&lt;/h5&gt;
&lt;p&gt;当前使用的 trait 的名称&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;trait MyTrait {
    public function myMethod() {
        echo &quot;trait的名称为: &quot; . __TRAIT__;
    }
}

class MyClass {
    use MyTrait;
}

$obj = new MyClass();
$obj-&amp;gt;myMethod();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;包含文件&lt;/h2&gt;
&lt;p&gt;在当前文件内引入其他PHP文件、HTML文件或文本文件等，一般用于包含公共方法，公共页面等，例如header footer sider等网页通用部分。&lt;/p&gt;
&lt;h3&gt;include 和 require 语句&lt;/h3&gt;
&lt;p&gt;区别：
&lt;strong&gt;include 和 require 除了处理错误的方式不同之外，在其他方面都是相同的：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;require 生成一个致命错误（E_COMPILE_ERROR），在错误发生后脚本会停止执行。&lt;/li&gt;
&lt;li&gt;include 生成一个警告（E_WARNING），在错误发生后脚本会继续执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此：
如果你希望被包含的文件是必需的且缺少文件会导致脚本无法正常运行，应使用require（推荐）。
如果你希望被包含的文件是可选的，或者即使缺少文件也希望脚本继续执行，可以使用include。&lt;/p&gt;
&lt;h4&gt;例如：&lt;/h4&gt;
&lt;h5&gt;header.php&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php 
	$siteTitle = &quot;PHP星球(PHP.fun)&quot;;
?&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
&amp;lt;title&amp;gt;&amp;lt;?php echo $siteTitle;?&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;index.php&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php include &apos;header.php&apos;; ?&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;欢迎来到&amp;lt;?php echo $siteTitle;?&amp;gt; !&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;有问必答。&amp;lt;/p&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;include_once 和 require_once 语句&lt;/h3&gt;
&lt;p&gt;和上面的一样，但他只会调用一次，防止重复调用&lt;/p&gt;
&lt;h2&gt;面向对象（OO）&lt;/h2&gt;
&lt;h3&gt;概念&lt;/h3&gt;
&lt;h4&gt;对象：&lt;/h4&gt;
&lt;p&gt;在现实世界里我们所面对的事情都是对象，如苹果 猫 电视机等。
而在面向对象的程序设计(OOP)中，对象是一个由信息及对信息进行处理的描述所组成的整体，是对现实世界的抽象。&lt;/p&gt;
&lt;p&gt;例如：
小猫 名字：Tom，性别：公，花色：橘色；会叫，会吃饭，会打闹
小狗 名字：Jack，性别：公，花色：黑色；会叫，会吃饭，会打闹&lt;/p&gt;
&lt;p&gt;区分：谁在叫，谁在吃饭，谁在打闹&lt;/p&gt;
&lt;h4&gt;面向对象：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;面向对象是一种编程思想和方法，它将程序中的&lt;strong&gt;数据&lt;/strong&gt;和&lt;strong&gt;操作数据&lt;/strong&gt;的方法封装在一起，形成&quot;对象&quot;，并通过对象之间的交互和消息传递来完成程序的功能。&lt;/li&gt;
&lt;li&gt;面向对象编程(OOP)强调数据的&lt;strong&gt;封装、继承、多态&lt;/strong&gt;和&lt;strong&gt;动态绑定&lt;/strong&gt;等特性，使得程序具有更好的可扩展性、可维护性和可重用性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;对象的主要三个特性：&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;对象的行为：对象可以执行的操作，比如：开灯，关灯就是行为。&lt;/li&gt;
&lt;li&gt;对象的形态：对对象不同的行为是如何响应的，比如：颜色，尺寸，外型。&lt;/li&gt;
&lt;li&gt;对象的表示：对象的表示就相当于身份证，具体区分在相同的行为与状态下有什么不同（在面向对象编程中，对象的表示通常通过类来实现）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;面向对象编程的三个主要特性：&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;封装：指将对象的属性和方法封装在一起，使得外部无法直接访问和修改对象的内部状态。通过使用访问控制修饰符（public、private、protected）来限制属性和方法的访问权限，从而实现封装。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;继承：指可以创建一个新的类，该类继承（extends）了父类的属性和方法，并且可以添加自己的属性和方法。通过继承，可以避免重复编写相似的代码，并且可以实现代码的重用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多态：指可以使用一个父类类型的变量来引用不同子类类型的对象，从而实现对不同对象的统一操作。多态可以使得代码更加灵活，具有更好的可扩展性和可维护性。在 PHP 中，多态可以通过实现接口（interface）和使用抽象类（abstract class）来实现。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;类（class）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;定义了一件事物的抽象特点。&lt;/li&gt;
&lt;li&gt;类的定义包含了数据的形式以及对数据的操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;类的定义和调用&lt;/h4&gt;
&lt;h5&gt;类的定义&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
	public $name = &quot;小猫仔&quot;;
    public function eat() {
        echo &quot; 在吃饭.&quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;类的调用&lt;/h5&gt;
&lt;p&gt;new 实例化对象&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$cat = new Animal;
//$cat = new Animal();
echo $cat-&amp;gt;name;
$cat-&amp;gt;eat();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;方法和属性&lt;/h4&gt;
&lt;h5&gt;类方法（函数）&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
	public $name = &quot;小猫仔&quot;;
    public function eat() {
        echo &quot; 在吃饭.&quot;;
    }
    function say() {
        echo &quot; 在说话.&quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;$this&lt;/h5&gt;
&lt;p&gt;代表自身的对象&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
	public $name = &quot;小猫仔&quot;;
    public function eat() {
        echo $this-&amp;gt;name.&quot; 在吃饭.&quot;;
    }
    function say() {
        echo $this-&amp;gt;name.&quot; 在说话.&quot;;
    }
}

$cat = new Animal;
$cat-&amp;gt;name = &quot;小花&quot;;
$cat-&amp;gt;say();

$dog = new Animal;
$dog-&amp;gt;name = &quot;小黑&quot;;
$dog-&amp;gt;say();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;访问控制&lt;/h5&gt;
&lt;p&gt;关键字 public、private、protected&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;public（公有）&lt;/strong&gt;：公有的类成员可以在任何地方被访问。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;protected（受保护）&lt;/strong&gt;：受保护的类成员则可以被其自身以及其子类和父类访问（咱家的）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;private（私有）&lt;/strong&gt;：私有的类成员则只能被其定义所在的类访问（自己的）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;&lt;code&gt;__construct&lt;/code&gt;构造函数&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;构造函数是一种特殊的方法，在创建一个新对象时，它会被自动调用。&lt;/li&gt;
&lt;li&gt;它可以用来 &lt;strong&gt;初始化&lt;/strong&gt; 对象的属性或执行其他必要的操作&lt;/li&gt;
&lt;li&gt;没有返回值&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  class Animal {
	private $name;
	private $birth;
	private $age;

    public function __construct($name,$birth)
    {
        $this-&amp;gt;name = $name;
        $this-&amp;gt;birth = $birth;
        
        $days = (time() - strtotime($this-&amp;gt;birth))/3600/24;
        $this-&amp;gt;age = floor($days);
    }

    public function eat() {
        echo  $this-&amp;gt;name.&quot; 在吃饭.&quot;;
    }
}

$cat = new Animal(&quot;猫仔&quot;,&quot;2023-05-23&quot;);
echo $cat-&amp;gt;name;
echo &apos; -- &apos;;
echo $cat-&amp;gt;birth;
echo &apos; -- &apos;;
echo $cat-&amp;gt;age;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;&lt;code&gt;__destruct&lt;/code&gt;析构函数&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;析构函数是一种特殊的方法，它在对象被销毁时自动调用&lt;/li&gt;
&lt;li&gt;它可以用来执行一些清理操作，例如释放资源或关闭数据库连接。&lt;/li&gt;
&lt;li&gt;当对象不再被引用或脚本执行结束时，析构函数会被自动调用。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;class MyClass {
    public function say($i)
    {
      echo &apos;saying-&apos;.$i;
    }
    public function __destruct() {
        echo &quot;析构函数被调用\n&quot;;
    }
}

// 创建对象
$obj = new MyClass();

// 执行其他操作...
for ($i=0; $i &amp;lt; 4; $i++) {
    if($i==3){
        unset($obj);
    }
    if($obj)
        $obj-&amp;gt;say($i);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;static 静态变量 和 self&lt;/h5&gt;
&lt;p&gt;「静态」指的是无需对类进行实例化，就可以直接调用这些属性和方法
所有对静态变量进行的操作都会对所有对象起作用
举例：小猫小狗听到指令来吃饭，指令变化，全部都要听从&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static $cat = &quot;PHP&quot;;

echo self::$cat;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;类常量&lt;/h5&gt;
&lt;p&gt;静态属性与类常量相似，唯一的区分是类常量不可以更改，静态属性可以更改
使用场景：所有的对象共用一个属性&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const PHP = &quot;PHP&quot;;

echo self::PHP;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;static 静态方法&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;public static function say() {
        echo self::$name;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以调用静态方法、静态变量
可以调用非静态方法、非静态变量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public function eat() {

        echo $this-&amp;gt;name.&quot; 在吃饭.&quot;;

}
public static function say() {

        echo (new self)-&amp;gt;eat();

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;类的继承（extends）：&lt;/h4&gt;
&lt;p&gt;指可以创建一个新的类，该类继承（extends）了父类的属性和方法，并且可以添加自己的属性和方法。通过继承，可以避免重复编写相似的代码，并且可以实现代码的重用。&lt;/p&gt;
&lt;p&gt;注意：继承不一定能访问&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    public $name=&quot;小动物&quot;;
    protected $age=3;
    private $birth=&apos;2023&apos;;
}

class Cat extends Animal {}


var_dump(new Animal);
var_dump(new Cat);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    protected $name;

    public function __construct($name) {
        $this-&amp;gt;name = $name;
    }

    public function eat() {
        echo $this-&amp;gt;name . &quot; 在吃饭.&quot;;
    }
}

class Cat extends Animal {
    public function meow() {
        echo $this-&amp;gt;name . &quot; 在喵呜.&quot;;
    }
}

$cat = new Cat(&quot;Tom&quot;);
var_dump($cat);
$cat-&amp;gt;eat();  // 继承自父类 Animal 的方法
$cat-&amp;gt;meow();  // 子类 Cat 自己的方法
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;方法和属性重写&lt;/h5&gt;
&lt;p&gt;如果从父类继承的方法或属性不能满足子类的需求，可以对其进行改写&lt;/p&gt;
&lt;h5&gt;final 关键字&lt;/h5&gt;
&lt;p&gt;作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;防止类被继承&lt;/li&gt;
&lt;li&gt;防止类的方法被重写&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果在一个类前加final，那么这个类就不能被继承；&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;final class myClass {
    // 类的内容
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果在一个方法前加final，那么这个方法就不能被重写&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    final public function eat() {
        echo $this-&amp;gt;name . &quot; 在吃饭.&quot;;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：final不能用于属性&lt;/p&gt;
&lt;h5&gt;调用父类方法&lt;/h5&gt;
&lt;p&gt;parent::
&lt;strong&gt;parent::__construct()&lt;/strong&gt;&lt;/p&gt;
&lt;h5&gt;静态延迟绑定 static&lt;/h5&gt;
&lt;p&gt;是指在运行时根据实际调用的类来确定静态方法或属性的绑定
语法：&lt;code&gt;static::$name&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    protected static $name=&quot;小动物&quot;;

    public static function eat() {
        echo self::$name. &quot; 在吃饭.&quot;;
        echo &apos; ---- &apos;;
        echo static::$name. &quot; 在吃饭.&quot;;
    }
}

class Cat extends Animal {
    protected static $name=&quot;小猫&quot;;
}

Animal::eat();
Cat::eat();

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;类的多态&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;多态性允许不同类的对象对相同的消息作出不同的响应。&lt;/li&gt;
&lt;li&gt;多态性通过方法重写（覆盖）和方法重载来实现。&lt;/li&gt;
&lt;li&gt;方法重写是指子类重写父类的方法，以改变方法的实现细节。&lt;/li&gt;
&lt;li&gt;方法重载是指在同一个类中根据参数个数或类型不同来实现不同功能。&lt;/li&gt;
&lt;li&gt;需要注意的是，多态性只适用于继承关系的类。子类必须重写父类的方法才能实现多态性。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    protected $name=&quot;动物&quot;;
    public function makeSound() {
        echo &quot;$this-&amp;gt;name 在吼叫。&quot;;
    }
}

class Dog extends Animal {
    protected $name=&quot;小狗&quot;;
    public function makeSound() {
        echo &quot;$this-&amp;gt;name 在汪汪。&quot;;
    }
}

class Cat extends Animal {
    protected $name=&quot;小猫&quot;;
    public function makeSound() {
        echo &quot;$this-&amp;gt;name 在喵喵。&quot;;
    }
}

$animal = new Animal();
$dog = new Dog();
$cat = new Cat();

$animal-&amp;gt;makeSound();
$dog-&amp;gt;makeSound();
$cat-&amp;gt;makeSound();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;方法重载&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;$args = func_get_args(); 
$numArgs = func_num_args();

function test(){

    $args = func_get_args(); 
    $numArgs = func_num_args();
    
    var_dump($args[1]);
    var_dump($numArgs);
}

test(1,2,3,4);

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    public function makeSound() {
        echo &quot;动物在吼叫&quot;;
    }
}


class Cat extends Animal {
    public function makeSound() {
        // $args = func_get_args();
        $numArgs = func_num_args();
        
        switch($numArgs){
            case 2:
                echo &apos;执行参数个数为2的事件&apos;;
                break;
            case 3:
                echo &apos;执行参数个数为3的事件&apos;;
                break;
            default:
                echo &apos;执行默认事件&apos;;
        }
    }
}

// $animal = new Animal();
$cat = new Cat();

$cat-&amp;gt;makeSound(&quot;测试&quot;,&quot;2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;接口和抽象类&lt;/h4&gt;
&lt;h5&gt;interface(接口)&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;interface Animals {
	public function a();
	public function b();
}

class Cat implements Animals {
	public function a(){
	
	};
	public function b(){
	
	};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接口是指一组方法的集合，不是类，不能被实例化。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以指定某个类必须&lt;strong&gt;实现&lt;/strong&gt;哪些方法，但不需要定义这些方法的具体内容&lt;/li&gt;
&lt;li&gt;只可以使用public&lt;/li&gt;
&lt;li&gt;通常用于定义一些规范，让代码更加有条理 不易出错。
例如：小动物必须要吃饭和睡觉，否则就会死！这是必须的，每个小动物都必须有这2个方法！&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
interface Animals {
    const PHP = &quot;PHP&quot;;
    public function eat();
    public function sleep($hours);
    public static function jump();
}
  
class Cat implements Animals {
    public function eat() {
        echo &quot;Cat 在吃饭.&quot;;
    }

    public function sleep($hours) {
        echo &quot;Cat 要睡 $hours 小时.&quot;;
    }

    public static function jump(){
        echo &apos;跳跳跳&apos;;
    }
}

$cat = new Cat();
$cat-&amp;gt;eat();
$cat-&amp;gt;sleep(18);

echo Cat::PHP;
echo Cat::jump();
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;interface Animals {
    public function eat();
    public function sleep($hours);
}
interface Sports {
    public function run();
    public function jump();
}
class Cat implements Animals,Sports {
    public function eat() {
        echo &quot;Cat 在吃饭&quot;;
    }

    public function sleep($hours) {
        echo &quot;Cat 要睡 $hours 小时&quot;;
    }

    public function run() {
        echo &quot;Cat 在跑步&quot;;
    }

    public function jump() {
        echo &quot;Cat 在蹦跳&quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;抽象类和抽象方法&lt;/h5&gt;
&lt;p&gt;和接口非常类似，使用它也是定义一种约束或规范，适合较大型的项目或库使用&lt;/p&gt;
&lt;h6&gt;抽象类&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;abstract class Animals{

}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;抽象类是一种特殊的类，只能被继承，不能被实例化&lt;/li&gt;
&lt;li&gt;抽象类用于定义一组相关的方法，但这些方法的具体实现由继承它的子类来完成。&lt;/li&gt;
&lt;li&gt;子类继承抽象类后，必须实现抽象类中的所有抽象方法。&lt;/li&gt;
&lt;li&gt;抽象类可以包含抽象方法和普通方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h6&gt;抽象方法&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;abstract public function xxx();
abstract protected function xxx();
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;抽象方法是没有具体实现的方法，只有方法的声明，而不需要方法体。&lt;/li&gt;
&lt;li&gt;抽象方法只能存在于抽象类中。&lt;/li&gt;
&lt;li&gt;可以使用protected，但不能使用private私有。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;abstract class Animals
{
    abstract public function eat();
    abstract protected function sleep($hours);

    public function play()
    {
      echo &apos;玩耍&apos;;
    }
}

class Cat extends Animals
{
    public function eat()
    {
        echo &quot;Cat 在吃饭.&quot;;
    }

    protected function sleep($hours)
    {
        echo &quot;Cat 要睡 $hours 小时.&quot;;
    }
}


$cat = new Cat();
$cat-&amp;gt;eat();
//$cat-&amp;gt;sleep(12);
$cat-&amp;gt;play();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;抽象类与接口的区别&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;抽象类可以包含非抽象方法的实现，而接口只能包含方法的声明，没有方法的实现。&lt;/li&gt;
&lt;li&gt;类只能继承一个抽象类，但可以实现多个接口。&lt;/li&gt;
&lt;li&gt;抽象类可以有构造函数，而接口不能有构造函数。&lt;/li&gt;
&lt;li&gt;抽象类中的方法可以有public、protected和private访问修饰符，而接口中的方法只能是public。&lt;/li&gt;
&lt;li&gt;子类继承抽象类时，必须实现抽象类中的所有抽象方法，否则子类也必须声明为抽象类。
子类实现接口时，必须实现接口中的所有方法。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;&lt;code&gt;trait&lt;/code&gt;代码复用&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;解决类的单一继承问题&lt;/li&gt;
&lt;li&gt;可同时使用多个trait，用逗号隔开&lt;/li&gt;
&lt;li&gt;把常用的、通用的代码抽离出来，写成trait&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;trait A{

}
trait B{

}
class C {
	use A,B;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;和类的继承非常像，但是trait里面不能有类常量，且trait不能被实例化。
根据下面类的继承来修改，对比看下他们的相同点：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Animal {
    protected $name;
    const PHP=&quot;PHP&quot;;

    public function __construct($name) {
        $this-&amp;gt;name = $name;
    }

    public function eat() {
        echo $this-&amp;gt;name . &quot; 在吃饭.&quot;;
    }
}

class Cat extends Animal {
    public function meow() {
        echo $this-&amp;gt;name . &quot; 在喵呜.&quot;;
    }
}

$cat = new Cat(&quot;Tom&quot;);
var_dump($cat);
$cat-&amp;gt;eat();  // 继承自父类 Animal 的方法
$cat-&amp;gt;meow();  // 子类 Cat 自己的方法
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;trait中可使用抽象方法&lt;/li&gt;
&lt;li&gt;trait中可使用静态属性和静态方法&lt;/li&gt;
&lt;li&gt;trait中可使用其他trait&lt;/li&gt;
&lt;li&gt;trait中可使用parent&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
class MainClass{
    public function main()
    {
      echo &apos;这是主方法的&apos;.__METHOD__;
    }
}
trait Animal {

    public function eat() {
        parent::main();
        echo $this-&amp;gt;name . &quot; 在吃饭.&quot;;
        echo __TRAIT__;
    }
}

class Cat extends MainClass {
    use Animal;
    protected $name;
    public function __construct($n) {
        $this-&amp;gt;name = $n;
    }
    public function meow() {
        echo $this-&amp;gt;name . &quot; 在喵呜.&quot;;
        echo __TRAIT__;
    }
}

$cat = new Cat(&quot;Tom&quot;);
var_dump($cat);
$cat-&amp;gt;eat();  // 继承自父类 Animal 的方法
echo &apos;----&apos;;
$cat-&amp;gt;meow();  // 子类 Cat 自己的方法
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;同名冲突&lt;/h5&gt;
&lt;p&gt;当一个类同时引入了多个Trait，并且这些Trait中存在同名方法时，就会产生方法冲突。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use A,B{
	//A::eat insteadof B;
    B::eat insteadof A;
    //别名定义
    A::eat as Aeat;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;trait A
{
    public function eat(){
        echo &apos;这是A的&apos;;
    }
}

trait B
{
    public function eat(){
        echo &apos;这是B的&apos;;
    }
}

class T{
    use A,B{
        A::eat insteadof B;
        B::eat as Beat;
    }
}

$t = new T;

$t-&amp;gt;eat();
$t-&amp;gt;Beat();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;表单和请求&lt;/h2&gt;
&lt;p&gt;主要用到了&lt;code&gt;$_GET&lt;/code&gt; 和 &lt;code&gt;$_POST&lt;/code&gt;超全局变量，分别对应两种不同的请求方式&lt;/p&gt;
&lt;h4&gt;表单&lt;/h4&gt;
&lt;p&gt;input select radio checkbox submit&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;form action=&quot;./user.php&quot; method=&quot;post&quot;&amp;gt;
    用户名: &amp;lt;input type=&quot;text&quot; name=&quot;username&quot;&amp;gt;
    密码: &amp;lt;input type=&quot;text&quot; name=&quot;password&quot;&amp;gt;
    &amp;lt;select multiple name=&quot;arr[]&quot;&amp;gt;
        &amp;lt;option value=&quot;&quot;&amp;gt;请选择:&amp;lt;/option&amp;gt;
        &amp;lt;option value=&quot;1&quot;&amp;gt;大猫&amp;lt;/option&amp;gt;
        &amp;lt;option value=&quot;2&quot;&amp;gt;二猫&amp;lt;/option&amp;gt;
        &amp;lt;option value=&quot;3&quot;&amp;gt;三猫&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;提交&quot;&amp;gt;
&amp;lt;/form&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;关于网络请求&lt;/h4&gt;
&lt;p&gt;GET请求和POST请求是两种常用的HTTP请求方法，用于从客户端向服务器发送数据&lt;/p&gt;
&lt;h5&gt;GET请求：&lt;/h5&gt;
&lt;p&gt;通过URL（网址）参数将数据附加在URL上发送给服务器。这些参数以键值对的形式出现在URL的末尾，使用问号&quot;?&quot;将URL和参数分隔开。&lt;/p&gt;
&lt;h5&gt;POST请求：&lt;/h5&gt;
&lt;p&gt;将数据作为请求的主体发送给服务器，而不是附加在URL上。这使得POST请求更适合发送敏感数据或超长大段内容，例如表单中的密码、博客文本内容等。&lt;/p&gt;
&lt;h5&gt;区别：&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;GET参数对任何人都是可见的，POST参数对任何人都是不可见的&lt;/li&gt;
&lt;li&gt;GET对发送信息的量也有限制，不适合大型的变量值，它的值不能超过 2000 个字符；POST对发送信息的量没有限制（默认POST 发送的最大值为 8 MB，但可通过设置 php.ini 的 post_max_size 进行更改；发送的变量数最大值max_input_vars）&lt;/li&gt;
&lt;li&gt;可以在收藏夹中收藏GET请求页面，或者发送带参数的网址给别人可以直接访问，例如带页码的网址、带商品id的淘宝商品、带文章id的博文。这一点POST做不到。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;超全局变量&lt;code&gt;$_REQUEST&lt;/code&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$_REQUEST&lt;/code&gt; 变量包含了 &lt;code&gt;$_GET&lt;/code&gt;、&lt;code&gt;$_POST&lt;/code&gt; 和 &lt;code&gt;$_COOKIE&lt;/code&gt; 的内容
&lt;code&gt;$_SERVER&lt;/code&gt;获取请求方式&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;htmlspecialchars()函数&lt;/h4&gt;
&lt;p&gt;用于将字符串中的特殊字符转换为HTML实体，以避免在HTML文档中引起解析错误或安全漏洞。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; （和号） 成为 &lt;code&gt;&amp;amp;amp;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;&lt;/code&gt; （双引号） 成为 &lt;code&gt;&amp;amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&apos;&lt;/code&gt; （单引号） 成为 &lt;code&gt;&amp;amp;#039;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&lt;/code&gt; （小于） 成为 &lt;code&gt;&amp;amp;lt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;gt;&lt;/code&gt; （大于） 成为 &lt;code&gt;&amp;amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;mysql数据库&lt;/h2&gt;
&lt;p&gt;本课程只讲解最简单的增删改查语句，不做更深入的语句讲解。&lt;/p&gt;
&lt;p&gt;配置环境变量&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysql -u root -p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看数据库列表：
&lt;code&gt;SHOW DATABASES;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使用数据库
&lt;code&gt;USE xxx;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看数据表列表：
&lt;code&gt;SHOW TABLES;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;数据库工具：SQL_Front(小皮内置)、Navicat、DBeaver&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;操作数据库的方式：MySQLi 和 PDO&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;MySQLi&lt;/h3&gt;
&lt;p&gt;首先要启用扩展mysqli&lt;/p&gt;
&lt;p&gt;面向过程&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$servername = &quot;localhost&quot;;
$username = &quot;root&quot;;
$password = &quot;root&quot;;
 
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
 
// 检测连接
if (!$conn) {
    die(&quot;连接失败: &quot; . mysqli_connect_error());
}
echo &quot;连接成功&quot;;

//关闭
mysqli_close($conn);
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;面向对象&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$servername = &quot;localhost&quot;;
$username = &quot;root&quot;;
$password = &quot;root&quot;;
 
// 创建连接
$conn = new mysqli($servername, $username, $password);
 
// 检测连接
if ($conn-&amp;gt;connect_error) {
    die(&quot;连接失败: &quot; . $conn-&amp;gt;connect_error);
} 
echo &quot;连接成功&quot;;

//关闭
$conn-&amp;gt;close();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;resource 资源类型&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;is_resource() 是否为资源类型&lt;/li&gt;
&lt;li&gt;get_resource_type() 获取资源的类型名称&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$servername = &quot;localhost&quot;;
$username = &quot;root&quot;;
$password = &quot;root&quot;;
$conn = mysql_connect($servername, $username, $password);
var_dump(is_resource($conn));
var_dump(gettype($conn));
var_dump(get_resource_type($conn));
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$handle = fopen(&quot;test.txt&quot;, &quot;r&quot;);
var_dump($handle);
var_dump(is_resource($handle));
var_dump(gettype($handle));
var_dump(get_resource_type($handle));

//$content = fread($handle, filesize(&quot;test.txt&quot;));
//echo $content; 
fclose($handle);
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;接下来将主讲面向对象方式操作&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;创建数据库&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// 创建数据库
$sql = &quot;CREATE DATABASE IF NOT EXISTS PHPDB&quot;;
//if (mysqli_query($conn, $sql)) {
if ($conn-&amp;gt;query($sql) === TRUE) {
    echo &quot;数据库创建成功&quot;;
} else {
    echo &quot;数据库创建失败 &quot; . $conn-&amp;gt;error;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;创建数据库表&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;NOT NULL - 每一行都必须含有值（不能为空），null 值是不允许的。&lt;/li&gt;
&lt;li&gt;DEFAULT value - 设置默认值&lt;/li&gt;
&lt;li&gt;UNSIGNED - 使用无符号数值类型，0 及正数&lt;/li&gt;
&lt;li&gt;AUTO INCREMENT - 设置 MySQL 字段的值在新增记录时每次自动增长 1&lt;/li&gt;
&lt;li&gt;PRIMARY KEY - 设置数据表中每条记录的唯一标识。 通常列的 PRIMARY KEY 设置为 ID 数值，与 AUTO_INCREMENT 一起使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个表都应该有一个主键(本列为 &quot;id&quot; 列)，主键必须包含唯一的值。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//$conn-&amp;gt;query(&quot;USE PHPDB&quot;);
// 使用 sql 创建数据表
$sql = &quot;CREATE TABLE IF NOT EXISTS user (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
  username VARCHAR(30) NOT NULL COMMENT \&quot;用户名\&quot;,
  password VARCHAR(64) NOT NULL COMMENT &apos;密码&apos;,
  phone VARCHAR(11),
  status INT(1) NOT NULL DEFAULT 1,
  create_date TIMESTAMP
  ) COMMENT &apos;用户&apos;&quot;;
//if (mysqli_query($conn, $sql)) {
if ($conn-&amp;gt;query($sql) === TRUE) {
    echo &quot;数据表创建成功&quot;;
} else {
    echo &quot;数据表创建错误: &quot; . $conn-&amp;gt;error;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注：如果要加注释，那么后面加上 COMMENT 即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;插入数据&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 如果列设置 AUTO_INCREMENT (如 &quot;id&quot; 列) 或 TIMESTAMP (如 &quot;create_date&quot; 列)，我们就不需要在 SQL 语句中指定值； MySQL 会自动为该列添加值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;INSERT INTO table_name (column1, column2, column3,...)
VALUES (value1, value2, value3,...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用&lt;code&gt;$conn-&amp;gt;query($sql) === TRUE&lt;/code&gt;来判断是否插入成功&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;INSERT INTO user (username, password, phone)
VALUES (&apos;da mao&apos;, &apos;123456&apos;, 13888888888)&quot;;
//if (mysqli_query($conn, $sql)) {
if ($conn-&amp;gt;query($sql) === TRUE) {
    echo &quot;新记录插入成功&quot;;
} else {
    echo &quot;错误: &quot; . $sql . &quot;&amp;lt;br&amp;gt;&quot; . $conn-&amp;gt;error;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;字符串进行转义处理&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;$conn-&amp;gt;real_escape_string($string);&lt;/code&gt;
可以确保特殊字符被正确转义，从而避免了SQL注入等安全问题，并保证查询语句的语法正确性，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$name=&quot;这是一个&apos;送命题&apos;&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;插入多条数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;INSERT INTO user (username, password, phone)
VALUES 
    (&apos;大猫&apos;, &apos;123456&apos;, 13888888888),
    (&apos;小猫&apos;, &apos;123456&apos;, 13888888887),
    (&apos;中猫&apos;, &apos;123456&apos;, 13888888886)
    &quot;;
$conn-&amp;gt;query($sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;foreach循环插入，或者使用语句：
&lt;code&gt;mysqli_multi_query()&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;INSERT INTO user (username, password, phone)
VALUES (&apos;大猫&apos;, &apos;123456&apos;, 13888888888);&quot;;

$sql .= &quot;INSERT INTO user (username, password, phone)
VALUES (&apos;小猫&apos;, &apos;123456&apos;, 13888888887);&quot;;

$sql.= &quot;INSERT INTO user (username, password, phone)
VALUES (&apos;中猫&apos;, &apos;123456&apos;, 13888888886);&quot;;

//if (mysqli_multi_query($conn, $sql)) {
if ($conn-&amp;gt;multi_query($sql) === TRUE) {
    echo &quot;新记录插入成功&quot;;
} else {
    echo &quot;错误: &quot; . $sql . &quot;&amp;lt;br&amp;gt;&quot; . $conn-&amp;gt;error;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;查询数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;SELECT column1,column2 FROM table_name
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;SELECT * FROM user&quot;;
$result = $conn-&amp;gt;query($sql);
//if (mysqli_num_rows($result) &amp;gt; 0) {
if ($result-&amp;gt;num_rows &amp;gt; 0) {
    echo &quot;$result-&amp;gt;num_rows 条结果&quot;;
    // 输出数据
    //while($row = mysqli_fetch_assoc($result)) {
    while($row = $result-&amp;gt;fetch_assoc()) {
        echo &quot;id: &quot; . $row[&quot;id&quot;]. &quot; - Name: &quot; . $row[&quot;username&quot;]. &quot; &quot; . $row[&quot;phone&quot;]. &quot;&amp;lt;br&amp;gt;&quot;;
    }
} else {
    echo &quot;0 条结果&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$result-&amp;gt;num_rows&lt;/code&gt; 获取到的数据条数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$result-&amp;gt;fetch_assoc()&lt;/code&gt; 是一种用于从结果集中获取一行数据的函数。它以关联数组的形式返回结果，其中列名作为键，对应的值则是该行中各列的值&lt;/li&gt;
&lt;li&gt;除了fetch_assoc 还有 fetch_row和fetch_array和fetch_all&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;while($row = $result-&amp;gt;fetch_row()) {
    echo &quot;id: &quot; . $row[0]. &quot; - Name: &quot; . $row[1]. &quot; &quot; . $row[2]. &quot;&amp;lt;br&amp;gt;&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;    //$datas = mysqli_fetch_all($result, MYSQLI_ASSOC);
    $datas = $result-&amp;gt;fetch_all(MYSQLI_ASSOC);
    var_dump($datas);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;free_result()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;释放结果集所占用的内存资源。在使用 &lt;code&gt;query()&lt;/code&gt; 函数执行查询后，会返回一个结果集对象，该结果集对象占用一定的内存空间。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//mysqli_free_result($result);
$result-&amp;gt;free_result();
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;where 条件筛选&lt;/h5&gt;
&lt;p&gt;WHERE用于在查询中指定筛选条件，来限制返回的行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT 列名
FROM 表名
WHERE 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;条件判断：
&lt;code&gt;&amp;gt; &amp;lt; = != &amp;lt;&amp;gt; &amp;gt;= &amp;lt;=&lt;/code&gt;
&lt;code&gt;like &quot;%xxx%&quot;&lt;/code&gt; &lt;code&gt;like &quot;%xxx&quot;&lt;/code&gt; &lt;code&gt;like &quot;xxx%&quot;&lt;/code&gt;
&lt;code&gt;between and &lt;/code&gt;
&lt;code&gt;is null&lt;/code&gt; &lt;code&gt;is not null&lt;/code&gt;
&lt;code&gt;in (a,b,c)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and or not 括号&lt;/p&gt;
&lt;h5&gt;order by 排序&lt;/h5&gt;
&lt;p&gt;ASC升序 、DESC降序
根据两列进行排序，用逗号隔开即可，注意：只有第一列的值相同时才使用第二列&lt;/p&gt;
&lt;h5&gt;offset limit&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;SELECT 列名
FROM 表名
LIMIT 行数 OFFSET 偏移量;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;更新数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;UPDATE 表名
SET column1=value, column2=value2,...
WHERE 条件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：如果省去 WHERE 子句，所有的记录都会被更新&lt;/p&gt;
&lt;p&gt;使用计算表达式更新字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UPDATE 表名 SET 列名 = 列名 + 值 WHERE 条件;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;UPDATE user SET num = num*3 WHERE id = 2&quot;;
$result = $conn-&amp;gt;query($sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;删除数据&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;DELETE FROM 表名
WHERE 条件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：如果省去 WHERE 子句，所有的记录都会被删除&lt;/p&gt;
&lt;p&gt;删除表中的重复行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DELETE t1 FROM 表名 t1, 表名 t2 WHERE t1.列名 = t2.列名 AND t1.id &amp;gt; t2.id;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改数据表&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;修改数据表名：
ALTER TABLE 旧表名 RENAME 新表名;

重置自增起始值为1：
ALTER TABLE 表名 AUTO_INCREMENT = 1;

添加新的列：
ALTER TABLE 表名 ADD COLUMN 列名 数据类型;

修改列名和数据类型：
ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列名 新数据类型;

修改列的默认值： 
ALTER TABLE 表名 ALTER COLUMN 列名 SET DEFAULT 默认值;

删除列：
ALTER TABLE 表名 DROP COLUMN 列名;

修改列的注释：
ALTER TABLE 表名 MODIFY COLUMN 列名 数据类型 COMMENT &apos;新注释&apos;;

删除数据表：
DROP TABLE IF EXISTS 表名

清空数据表：
TRUNCATE TABLE 表名;

删除数据库：
DROP database
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;咱们只讲了最基本的mysql，关于关联查询 索引 等更深入的知识就需要专门学习了。&lt;/p&gt;
&lt;h4&gt;预处理语句&lt;/h4&gt;
&lt;p&gt;预处理语句（Prepared Statements），用于执行带有参数的SQL语句。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;预处理语句可以提高安全性，对于防止 SQL 注入是非常有用的&lt;/li&gt;
&lt;li&gt;允许重复使用相同的sql模板而只需更改参数，提高执行效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;关于sql注入&lt;/h5&gt;
&lt;p&gt;当涉及到SQL查询时，注入攻击是一种常见的安全漏洞&lt;/p&gt;
&lt;h6&gt;1. 直接执行用户输入的SQL查询：&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;$query = $_GET[&apos;query&apos;];
$result = $conn-&amp;gt;query($query);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果用户能够直接执行他们自己构造的SQL查询，就会产生严重的安全问题。恶意用户可以执行任意的SQL语句，包括删除、修改或泄露敏感数据。&lt;/p&gt;
&lt;h6&gt;2. 使用字符串拼接的方式构建SQL查询：&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;$username = $_POST[&apos;username&apos;];
$password = $_POST[&apos;password&apos;];

$sql = &quot;SELECT * FROM user WHERE username = &apos;&quot; . $username . &quot;&apos; AND password = &apos;&quot; . $password . &quot;&apos;&quot;;
$result = $conn-&amp;gt;query($sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方式存在安全风险，如果用户在输入框中输入恶意代码，可以破坏原始的SQL查询结构，例如输入 &lt;code&gt;&apos; OR 1=1 --&lt;/code&gt; ，会导致查询条件永远为真，从而绕过身份验证。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;转义特殊字符也不保险：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;$username = $conn-&amp;gt;real_escape_string($_POST[&apos;username&apos;]);
$password = $conn-&amp;gt;real_escape_string($_POST[&apos;password&apos;]);

$query = &quot;SELECT * FROM users WHERE username = &apos;&quot; . $username . &quot;&apos; AND password = &apos;&quot; . $password . &quot;&apos;&quot;;
$result = $conn-&amp;gt;query($query);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们使用 &lt;code&gt;-&amp;gt;real_escape_string()&lt;/code&gt; 函数对用户输入的用户名和密码进行转义，以防止SQL注入，但仍然可能存在注入漏洞。
假设用户在用户名输入框中输入 &lt;code&gt;admin&apos;--&lt;/code&gt; ，并在密码输入框中输入任意值。由于转义字符未正确处理，生成的SQL查询语句如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM users WHERE username = &apos;admin&apos;--&apos; AND password = &apos;password&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这种情况下， &lt;code&gt;--&lt;/code&gt; 是SQL注释的开始，后面的 &lt;code&gt;AND password = &apos;password&apos;&lt;/code&gt; 将被忽略。这样，攻击者可以绕过密码验证并成功登录，即使没有提供正确的密码。&lt;/p&gt;
&lt;h5&gt;预处理方法&lt;/h5&gt;
&lt;p&gt;查询&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$sql = &quot;SELECT * FROM user WHERE username = ? AND password = ? &quot;;
$stmt = $conn-&amp;gt;prepare($sql);
//绑定
$stmt-&amp;gt;bind_param(&quot;ss&quot;, $username, $password);
//执行
$stmt-&amp;gt;execute();

//获取结果
$result = $stmt-&amp;gt;get_result();
print_r(&apos;&amp;lt;pre&amp;gt;&apos;);
print_r($result-&amp;gt;fetch_all());

//关闭
$stmt-&amp;gt;close();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;插入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 预处理
$sql = &quot;INSERT INTO user (username, password, phone)
VALUES (?, ?, ?)&quot;;
$stmt = $conn-&amp;gt;prepare($sql);
//绑定
$stmt-&amp;gt;bind_param(&quot;sss&quot;, $username, $password, $phone);
//执行
$stmt-&amp;gt;execute();

//获取结果
if ($stmt-&amp;gt;affected_rows &amp;gt; 0) {
    echo &quot;插入成功&quot;;
} else {
    echo &quot;插入失败&quot;;
}


//关闭
$stmt-&amp;gt;close();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中的&lt;code&gt;?&lt;/code&gt;为占位符&lt;/p&gt;
&lt;p&gt;通过告诉数据库参数的数据类型，可以降低 SQL 注入的风险。参数有以下四种类型:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;i - integer（整型）&lt;/li&gt;
&lt;li&gt;d - double（双精度浮点型）&lt;/li&gt;
&lt;li&gt;s - string（字符串）&lt;/li&gt;
&lt;li&gt;b - BLOB（binary large object:二进制大对象）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个参数都需要指定类型。&lt;/p&gt;
&lt;p&gt;php8新方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$name=&quot;这是一个&apos;送命题&apos;&quot;;
//mysqli_execute_query
$sql = &quot;INSERT INTO user (username, password, phone)
VALUES (?, ?, ?)&quot;;
$conn-&amp;gt;execute_query($sql,[$name,&apos;123456&apos;,&apos;13888888888&apos;]);
$conn-&amp;gt;execute_query($sql,[$name,&apos;123456&apos;,&apos;13888888888&apos;]);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PDO&lt;/h3&gt;
&lt;p&gt;安装php_pdo_mysql扩展，用phpinfo() 函数来查看是否安装了PDO扩展&lt;/p&gt;
&lt;p&gt;PDO执行sql语句分为2种方法：&lt;/p&gt;
&lt;p&gt;exec() 方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;适用于执行不返回结果集的SQL语句，例如INSERT、UPDATE和DELETE等操作。&lt;/li&gt;
&lt;li&gt;exec() 方法返回受影响的行数（即被插入、更新或删除的行数），如果没有受影响的行，返回0。&lt;/li&gt;
&lt;li&gt;通常用于执行不需要获取结果集的简单操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;query() 方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;适用于执行返回结果集的SQL语句，例如SELECT查询。&lt;/li&gt;
&lt;li&gt;query() 方法返回一个PDOStatement对象，你可以使用该对象的方法（如 fetch() 、 fetchAll() ）来获取查询结果。&lt;/li&gt;
&lt;li&gt;通常用于执行需要获取结果集的查询操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;创建连接&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$dbms=&apos;mysql&apos;;     //数据库类型
$host=&apos;localhost&apos;; //数据库主机名
$dbName=&apos;PHPdb&apos;;    //使用的数据库
$user=&apos;root&apos;;      //数据库连接用户名
$pass=&apos;root&apos;;          //对应的密码
$dsn=&quot;$dbms:host=$host;dbname=$dbName&quot;;

try {
    $conn = new PDO($dsn, $user, $pass); //初始化一个PDO对象
    echo &quot;连接成功&amp;lt;br/&amp;gt;&quot;;
	// 关闭连接
    $conn = null;
} catch (PDOException $e) {
    die (&quot;错误!: &quot; . $e-&amp;gt;getMessage() . &quot;&amp;lt;br/&amp;gt;&quot;);
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;创建数据库&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;	//设置 PDO 错误模式为异常
	$conn-&amp;gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	//PDO::ERRMODE_WARNING 警告
	//PDO::ERRMODE_SILENT 错误码
	//$conn-&amp;gt;errorCode()
	//$conn-&amp;gt;errorInfo()

    // 创建数据库
    $sql = &quot;CREATE DATABASE 数据库名&quot;;
    $conn-&amp;gt;exec($sql);
    echo &quot;数据库创建成功&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;创建数据表&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;    $sql = &quot;CREATE TABLE IF NOT EXISTS user6 (
        id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
        username VARCHAR(30) NOT NULL COMMENT \&quot;用户名\&quot;,
        password VARCHAR(64) NOT NULL COMMENT &apos;密码&apos;,
        phone VARCHAR(11),
        status INT(1) NOT NULL DEFAULT 1,
        create_date TIMESTAMP
        ) COMMENT &apos;用户&apos;&quot;;
    $conn-&amp;gt;exec($sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;查询数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;	// 执行查询语句
    $sql = &quot;SELECT * FROM user WHERE id&amp;lt;5&quot;;
    $result = $conn-&amp;gt;query($sql);

    // 获取结果
    $result = $result-&amp;gt;fetchAll(PDO::FETCH_ASSOC);
    var_dump($result);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;更新数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;	$sql = &quot;UPDATE user SET num = num+3 WHERE id =2&quot;;
    $stmt = $conn-&amp;gt;exec($sql);
    var_dump($stmt);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;删除数据&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;	$sql = &quot;DELETE FROM user WHERE id =26&quot;;
    $stmt = $conn-&amp;gt;exec($sql);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;插入数据&lt;/h5&gt;
&lt;p&gt;和mysqli的类似，不做特殊说明了
预处理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    // 执行插入语句
    $sql = &quot;INSERT INTO 表名 (列1, 列2, 列3) VALUES (:value1, :value2, :value3)&quot;;
    $stmt = $conn-&amp;gt;prepare($sql);

    // 绑定参数
    $stmt-&amp;gt;bindParam(&apos;:value1&apos;, $value1);
    $stmt-&amp;gt;bindParam(&apos;:value2&apos;, $value2);
    $stmt-&amp;gt;bindParam(&apos;:value3&apos;, $value3);

    // 设置参数值
    $value1 = &quot;值1&quot;;
    $value2 = &quot;值2&quot;;
    $value3 = &quot;值3&quot;;

    // 执行插入语句
    $stmt-&amp;gt;execute();
    
	// 获取插入的条数
    $rowCount = $stmt-&amp;gt;rowCount();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;批量插入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    $sql = &quot;INSERT INTO user (username, password, phone) VALUES (?,?,?)&quot;;
    $stmt = $conn-&amp;gt;prepare($sql);

    // 执行插入语句
    $stmt-&amp;gt;execute([&quot;test1&quot;,&quot;1234&quot;,&quot;13888888888&quot;]);
    $stmt-&amp;gt;execute([&quot;test2&quot;,&quot;1232&quot;,&quot;13888888888&quot;]);
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;事务&lt;/h6&gt;
&lt;p&gt;事务（Transaction）是一组数据库操作的集合，这些操作要么全部成功执行，要么全部回滚（撤销）。事务提供了一种机制来确保数据库操作的一致性和完整性。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    try {
        // 开始事务
        $conn-&amp;gt;beginTransaction();
    
        // 执行批量插入语句
        $sql = &quot;INSERT INTO user (username, password, phone) VALUES (?,?,?)&quot;;
        $stmt = $conn-&amp;gt;prepare($sql);
    
        $data = array(
            array(&quot;值1&quot;, &quot;值2&quot;, &quot;值3&quot;),
            array(&quot;值4&quot;, &quot;值5&quot;, &quot;值6&quot;),
            array(&quot;值7&quot;, &quot;值8&quot;, &quot;值9&quot;)
        );
        
        $insertedRows = 0;
        foreach ($data as $row) {
            $stmt-&amp;gt;execute($row);
            $insertedRows += $stmt-&amp;gt;rowCount();
        }
    
        // 提交事务
        $conn-&amp;gt;commit();
    
        echo &quot;批量插入成功&quot;;
    } catch(PDOException $e) {
        // 回滚事务
        $conn-&amp;gt;rollback();
        echo &quot;插入失败: &quot; . $e-&amp;gt;getMessage();
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作业：把PDO里没有用预处理的改为预处理方式。如果有时间，可以把上面的增删改查封装为一个DB类，方便调用。
后面我们实战的时候也会讲PDO类的二次封装和调用。&lt;/p&gt;
&lt;h2&gt;cookie session&lt;/h2&gt;
&lt;h3&gt;cookie&lt;/h3&gt;
&lt;p&gt;cookie 常用于识别用户。
cookie 是一种服务器留在用户计算机上的小文件。
每当同一台计算机通过浏览器请求页面时，这台计算机将会发送 cookie。
通过 PHP，能够创建并取回 cookie 的值。&lt;/p&gt;
&lt;h5&gt;创建cookie&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;setcookie(name, value, expire, path, domain);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参数说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;name ：Cookie的名称。&lt;/li&gt;
&lt;li&gt;value ：Cookie的值。&lt;/li&gt;
&lt;li&gt;expire ：Cookie的过期时间，可以是一个Unix时间戳（例如： time() + 3600  表示一小时后过期），或者是一个具体的日期时间字符串（例如： &quot;2024-01-01 00:00:00&quot; ）。&lt;/li&gt;
&lt;li&gt;path ：可选参数，指定Cookie的有效路径。默认为当前路径。&lt;/li&gt;
&lt;li&gt;domain ：可选参数，指定Cookie的有效域名。默认为空，表示当前域名。&lt;/li&gt;
&lt;li&gt;secure ：可选参数，指定是否仅通过安全的HTTPS连接传输Cookie。默认为 false 。&lt;/li&gt;
&lt;li&gt;httponly：可选参数，指定是否仅通过HTTP协议访问Cookie。默认为 false 。&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$expire=time()+60*60*24*7;
setcookie(&quot;username&quot;, &quot;PHP&quot;, $expire);
setcookie(&quot;userid&quot;, &quot;1&quot;, $expire);

setcookie(&quot;user[name]&quot;, &quot;PHP&quot;, $expire);
setcookie(&quot;user[phone]&quot;, &quot;18611112222&quot;, $expire);
setcookie(&quot;user[age]&quot;, &quot;35&quot;, $expire);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;获取cookie&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;// 输出 cookie 值
if(isset($_COOKIE[&quot;username&quot;])){
	echo $_COOKIE[&quot;username&quot;];
}	

// 查看所有 cookie
print_r($_COOKIE);

&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;删除 Cookie&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;setcookie(&quot;username&quot;, &quot;&quot;, time()-3600);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;session&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;用于在服务器上存储关于用户会话（session）的信息，并且对于程序中的所有页面都是可用的。&lt;/li&gt;
&lt;li&gt;会话信息是临时的，在用户离开网站后将被删除。&lt;/li&gt;
&lt;li&gt;它允许在同一个用户的多个请求之间保持数据的状态，便于传递数据。
Session 的工作机制是：为每个访客创建一个唯一的 id (UID)，并基于这个 UID 来存储变量。UID 存储在 cookie 中，或者通过 URL 进行传导。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;启动session&lt;/h4&gt;
&lt;p&gt;通常，将该函数放在PHP文件的顶部&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;session_start();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;存取 Session 变量&lt;/h4&gt;
&lt;p&gt;一旦Session启动，可以使用 &lt;code&gt;$_SESSION&lt;/code&gt; 超全局变量来存储和访问Session数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 存储 session 数据 
$_SESSION[&apos;username&apos;]=&apos;PHP&apos;;

//取值
echo $_SESSION[&apos;username&apos;];

&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;if(isset($_SESSION[&apos;views&apos;]))
{
    $_SESSION[&apos;views&apos;]=$_SESSION[&apos;views&apos;]+1;
}
else
{
    $_SESSION[&apos;views&apos;]=1;
}
echo &quot;浏览量：&quot;. $_SESSION[&apos;views&apos;];
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;销毁 Session&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;if(isset($_SESSION[&apos;views&apos;]))
{
    unset($_SESSION[&apos;views&apos;]);
}

//销毁
session_destroy();
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：session_destroy() 将重置 session，您将失去所有已存储的 session 数据&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Session和Cookie的关系和区别&lt;/h4&gt;
&lt;p&gt;关系：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Session和Cookie都是用于在不同请求之间保持数据的状态。&lt;/li&gt;
&lt;li&gt;Session使用Cookie来跟踪和标识用户，通过在Cookie中存储Session ID来关联服务器端的Session数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存储位置：Cookie数据存储在客户端的浏览器中，而Session数据存储在服务器端。&lt;/li&gt;
&lt;li&gt;容量限制：Cookie的容量限制通常较小，一般为几KB，而Session的容量限制较大，通常取决于服务器的配置。&lt;/li&gt;
&lt;li&gt;安全性：由于Cookie存储在客户端，可能会被篡改或窃取，因此存储敏感信息的安全性较低。相比之下，Session数据存储在服务器端，相对更安全。&lt;/li&gt;
&lt;li&gt;生命周期：Cookie可以设置过期时间，可以在浏览器关闭后仍然保持，具有较长的生命周期。而Session通常在用户关闭浏览器或一段时间不活动后自动过期。&lt;/li&gt;
&lt;li&gt;存储方式：Cookie以键值对的形式存储数据，可以在客户端进行读取和修改。Session数据存储在服务器端，客户端只保存了一个Session ID。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在实际应用中，Cookie通常用于存储一些较小、不敏感的数据，如用户首选项、购物车信息等。而Session通常用于存储用户的身份验证信息、敏感数据等，因为Session数据存储在服务器端，相对更安全。&lt;/p&gt;
&lt;h2&gt;实战案例：个人中心&lt;/h2&gt;
&lt;p&gt;案例介绍：
我们会用最基础的原生 php 方式去做这个项目，不用任何前后端框架，考虑到一些学员没有前端基础，所以我会尽量少的使用 js，但会用到 fetch 请求等基础语句，并且 html 和 css 会有入门级的讲解（简单）；
我会尽可能多的使用学到的知识，以达到学以致用的效果；
我们会使用面向对象去对一些常用的方法进行封装，例如数据库操作，让大家学会在实际项目中使用类和对象。&lt;/p&gt;
&lt;p&gt;讲解的内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什么是前端，什么是后端；什么是前台，什么是后台&lt;/li&gt;
&lt;li&gt;页面搭建 (从 0 到 1)&lt;/li&gt;
&lt;li&gt;什么是 json&lt;/li&gt;
&lt;li&gt;简单的 Api 接口和请求&lt;/li&gt;
&lt;li&gt;Php 调试代码&lt;/li&gt;
&lt;li&gt;封装类&lt;/li&gt;
&lt;li&gt;文件包含&lt;/li&gt;
&lt;li&gt;数据库的使用&lt;/li&gt;
&lt;li&gt;用户状态&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;![[Pasted image 20231116090904.png]]&lt;/p&gt;
&lt;h3&gt;用户注册&lt;/h3&gt;
&lt;h3&gt;用户登录&lt;/h3&gt;
&lt;h3&gt;用户中心&lt;/h3&gt;
&lt;h4&gt;个人信息&lt;/h4&gt;
&lt;h4&gt;登录记录&lt;/h4&gt;
&lt;h4&gt;修改密码&lt;/h4&gt;
&lt;h4&gt;退出登录&lt;/h4&gt;
&lt;h1&gt;实战补充知识&lt;/h1&gt;
&lt;h3&gt;&lt;code&gt;str_repeat()&lt;/code&gt; 和 &lt;code&gt;rtrim ()&lt;/code&gt; &lt;code&gt;ltrim()&lt;/code&gt; 函数&lt;/h3&gt;
&lt;h3&gt;&lt;code&gt;floor()&lt;/code&gt; 和 &lt;code&gt;ceil()&lt;/code&gt; &lt;code&gt;round()&lt;/code&gt; 函数&lt;/h3&gt;
&lt;h3&gt;&lt;code&gt;md5()&lt;/code&gt; 加密&lt;/h3&gt;
&lt;h3&gt;die 和 exit 函数&lt;/h3&gt;
&lt;h3&gt;常量 DIRECTORY_SEPARATOR&lt;/h3&gt;
&lt;h3&gt;Pdo 补充知识&lt;/h3&gt;
&lt;p&gt;$stmt-&amp;gt;closeCursor()
If($condition instanceof Closure)&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;dirname ()&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;dirname&lt;/code&gt; 函数用于返回指定路径的目录部分。它接受一个字符串参数，该参数是一个文件或目录的路径，并返回该路径的父级目录。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$path = &apos;/var/www/html/index.php&apos;;
$directory = dirname($path);
echo $directory;  // 输出: /var/www/html

$path = &apos;/var/www/html/&apos;;
$directory = dirname($path);
echo $directory;  // 输出: /var/www

$path = &apos;/var/www/html&apos;;
$directory = dirname($path);
echo $directory;  // 输出: /var/www
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;header ()函数&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;header()&lt;/code&gt; 函数用于发送原始的 HTTP 头信息。它通常用于在服务器响应中设置 HTTP 头，例如设置重定向、设置响应状态码、设置内容类型等。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;header(string $header, bool $replace = true, int $http_response_code = null): void
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参数说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$header ：要设置的 HTTP 头信息，以字符串形式表示。&lt;/li&gt;
&lt;li&gt;$replace （可选）：指定是否替换之前设置的相同类型的 HTTP 头信息。默认为  true ，表示替换。&lt;/li&gt;
&lt;li&gt;$http_response_code（可选）：指定要设置的响应状态码。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;//重定向
header(&quot;Location: ./login.php&quot;);
//设置响应状态码：
header(&quot;HTTP/1.1 404 Not Found&quot;);
//设置内容类型
header(&quot;Content-Type: application/json&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意： &lt;code&gt;header()&lt;/code&gt; 函数必须在发送任何实际输出之前调用，包括 HTML 标记、空格、换行符等。如果在输出之后调用 &lt;code&gt;header()&lt;/code&gt; 函数，将会导致 &quot;headers already sent&quot; 错误。&lt;/p&gt;
&lt;h3&gt;静态变量的使用&lt;/h3&gt;
&lt;p&gt;与类或函数相关联，而不是与对象或函数的实例相关联。
静态变量在整个脚本的执行过程中保持其值不变。&lt;/p&gt;
&lt;h4&gt;类&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;class MyClass {
    public static $count = 0;
    public static function toObj()
    {
      return new self;
    }
    public function plusCount() {
        self::$count++;
        echo self::$count.PHP_EOL;
    }
}
MyClass::toObj()-&amp;gt;plusCount();
MyClass::toObj()-&amp;gt;plusCount();
MyClass::toObj()-&amp;gt;plusCount();
echo MyClass::$count;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;普通函数&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;静态变量只在函数的作用域内有效，不同函数中的同名静态变量是相互独立的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;function myFunction() {
    static $count = 0;
    
    $count++;
    echo $count.PHP_EOL;
}

function mySecond() {
    static $count = 0;
    echo $count.PHP_EOL;
}
myFunction();
myFunction();
myFunction();

mySecond();
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;关于phpinfo()&lt;/h1&gt;
</content:encoded></item><item><title>php讲课思路与大纲</title><link>https://6wd.cn/posts/php-teaching-outline/</link><guid isPermaLink="true">https://6wd.cn/posts/php-teaching-outline/</guid><description>这是个选择语句，代码如下</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;PHP流程控制语句知识点：&lt;/h2&gt;
&lt;h3&gt;一、条件判断语句：&lt;/h3&gt;
&lt;h4&gt;1. if语句&lt;/h4&gt;
&lt;p&gt;这是个选择语句，代码如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 基础语法
if (条件) {//这里的条件是一个bool类型的值（true,false），当这里的条件为true时进入大括号内（执行大括号内的代码块）。
  代码块;//代码块内写想要执行的代码
}

# if...else 除了基础语法的if语句还有一个适用于不属于条件1的其他结果，就是if...else...
if(条件){
    代码块1;//代码块1内写想要执行的代码
}else{
    代码块2;//此处写当条件的结果为false时，进入else的代码块。
}

# if...elseif...else... 这个就用于多条件判断（根据两个以上的条件执行不同的代码）
if (条件1) {
  条件1为 true 时执行的代码;
} elseif (条件2) {//当代码运行到此处就代表条件1的结果为false，再判断条件2的结果，如果也为false那就继续往下走（条件2的方法体不执行！！）
  条件2为 true 时执行的代码;
} else {
  条件为 false 时执行的代码;
}

# 例子：
$time = rand(0,23);//这里的作用是调用rand方法生成随机数（0-23之间）-------（1）
if($time&amp;gt;=7&amp;amp;&amp;amp;$time&amp;lt;12){//这里的作用是判断时间在7-12点之间 ---------------（2）
    echo &apos;早上好，又是美好的一天&apos;;
}elseif($time&amp;gt;=12&amp;amp;&amp;amp;$time&amp;lt;2){//同（1）
    echo &apos;中午啦，起来重睡&apos;;//同（2）
}elseif($time&amp;gt;=2&amp;amp;&amp;amp;$time&amp;lt;8){//同（1）
    echo &apos;下午了，想想晚上吃啥&apos;;//同（2）
}else{//当代码运行到这里代表上面条件都为false，此时执行else中的代码。
    echo &apos;这都几点了，还不睡？？？&apos;//同（2）
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过上述模板和例子，我们可以明白if选择语句的基础用法，同时也明白每个区域的作用。&lt;/p&gt;
&lt;p&gt;注：在php中if的执行语句块为一行的时候，可以神略大括号！&lt;/p&gt;
&lt;h4&gt;2. switch语句：&lt;/h4&gt;
&lt;p&gt;如果您希望有选择地执行若干代码块之一，请使用 Switch 语句。使用 Switch 语句可以避免冗长的 if..elseif..else 代码块。&lt;/p&gt;
&lt;p&gt;switch要搭配case关键字来使用，但是要注意在代码内有一个异常情况，我介绍完例子会解释&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 标准语法
switch (表达式){//这里的表达式一般为基础数据表达式
case 值1://case关键字用于判断表达式的值是否等于后面的值，若为true则执行冒号（:）后面的代码块，若为false则继续判断
  表达式 = 值1 时执行的代码 ;
  break;  //这个break是个重点，我下面会说
case 值2://...
  表达式 = 值2 时执行的代码 ;
  break;
default://这里代表上面的条件都为true时执行这里的内容，也可以看作“默认执行方法”
  表达式的值不等于 值1 及 值2 时执行的代码;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注:当break不写的时候，可能会存在数据穿透的异常，可能会把结果为true后的的所有代码块都执行（在开发中要十分注意）&lt;/p&gt;
&lt;h3&gt;二、循环控制语句：&lt;/h3&gt;
&lt;h4&gt;3. while循环：&lt;/h4&gt;
&lt;p&gt;在编写代码时，经常需要反复运行同一代码块。所以我们可以使用循环来重复执行这样的任务，而不是在脚本中添加若干几乎相等的代码块，使整个代码十分臃肿。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;while&lt;/em&gt; - 只要指定条件为真，则循环代码块&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例代码及解释如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (条件为真) {
  要执行的代码;
}
# 这个真没啥讲的，举个例子吧
# 比如:康总需要反复往返于郑州和新郑,就是典型的循环结构.假设康总投资这个项目需要往返郑州100次,每次访问都会计数一次.难道写一百遍同样的代码?显然对于智商极高的程序员来说不可能这样处理。
# 示例：

//while后面接布尔值判断,为真执行,为假停止
$count=0;
//循环开始处
while($count &amp;lt; 100){//$count小于100的时候执行,也就是$count为0至99的时候执行.如果$count不小于100了,循环停止执行后续的代码
    echo &quot;这是康总第 $count 次出差&quot;;
    PHP_EOL;//这行相当于html中的&amp;lt;br&amp;gt;换行
    //每次执行让$count+1,这样的话,就不会产生$count永远小于100的情况了
    $count++;
}
//循环结束
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4. do…while循环：&lt;/h4&gt;
&lt;p&gt;说说区别吧:do…while与while的语法结构基本一样,也是一个布尔型循环,功能也基本一样.基础语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;do{
   代码块;
}while(判断)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;do…while与while区别是,它们的值得检查时机不同.
do…while不论while判断是否成立,先执行一次代码块循环语句,保证会执行一次(表达式的真值在每次循环结束后检查)
然而我们之前的while循环会检查条件表达式,结果为true则执行,结果为false则不执行.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$i=0;
do {
  echo $i++;
}while($i&amp;lt;0);
//输出结果是0
//这里涉及到两个知识点
1, 已知$i=0，在while后面的条件判断中，判断条件为$i&amp;lt;0 (结果为false)，但是却执行了一次循环，代表了什么？
    代表do...while就算结果是false也最少执行一次。
2, echo $i++ 输出为0，应为 $i++ 的意义是先赋值再自加一（也可见说先传值）
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;5. for循环：&lt;/h4&gt;
&lt;p&gt;如果您已经提前确定脚本运行的次数，可以使用 for 循环。基础语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (表达式1;表达式2;表达式3) {
/*
    1、表达式1是初始化赋值,可以同时赋值多个代码;
    2、表示式2在每次循环开始前求值,如果值为true,则继续循环,执行嵌套的循环语句,如果值为false,则终止循环.
    3、表达式3在每次循环之后被求值.
    4、表达式1和表达式3是可以不在括号内写.
*/
  代码块;
}

# 我举个例子吧，当你需要计算1-100的和
$sum = 0;//初始化一个值用于存储每次循环结束的结果
for($i = $sum;$i &amp;lt;= 100;$i++){//这行的意思是定义了一个变量$i让他等于$sum，为什么第二次循环不把第一次循环结束的$sum再重新赋值给$i?
    						//	因为for循环中表达式一中的初始化赋值只赋值一遍！
    $sum += $i;//+=赋值运算
}
echo $sum;//结果是5050
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;6. foreach循环：&lt;/h4&gt;
&lt;p&gt;foreach 循环只适用于数组，并用于遍历数组中的每个键/值 对。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach ($array as $value) {
  代码块;
}
//每进行一次循环迭代，当前数组元素的值就会被赋值给 $value 变量，并且数组指针会逐一地移动，直到到达最后一个数组元素。
$phone = array(&quot;huawei&quot;,&quot;vivo&quot;,&quot;oppo&quot;,&quot;mi&quot;,&quot;iphone&quot;);//创建数组
foreach($phone as $value) {//数组值赋值给 $value 变量
   echo &quot;Value=&quot; . $value;//打印！
   echo &quot;&amp;lt;br&amp;gt;&quot;;//换行
}
# 用的有点少，自己补充一下啊哈！！
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;三、跳转控制语句：&lt;/h3&gt;
&lt;h4&gt;7. break语句：&lt;/h4&gt;
&lt;p&gt;break是被用在上面所提的各种循环和switch语句中的。他的作用是跳出当前的语法结构，执行下面的语句。break语句可以带一个参数n，表示跳出循环的层数，如果要跳出多重循环的话，可以用n来表示跳出的层数，如果不带参数默认是跳出本重循环。&lt;/p&gt;
&lt;p&gt;就不举例了，很简单的！&lt;/p&gt;
&lt;h4&gt;8. Continue语句：&lt;/h4&gt;
&lt;p&gt;continue是用来用在循环结构中，控制程序放弃本次循环continue语句之后的代码并转而进行下一次循环。continue本身并不跳出循环结构，只是放弃这一次循环。如果在非循环结构中(例如if语句中，switch语句中)使用continue，程序将会出错。&lt;/p&gt;
&lt;p&gt;太晚了，这个咱就自力更生吧！&lt;/p&gt;
</content:encoded></item><item><title>PowerEdge R720 上安装 ESXi 8</title><link>https://6wd.cn/posts/poweredge-r720-install-esxi8/</link><guid isPermaLink="true">https://6wd.cn/posts/poweredge-r720-install-esxi8/</guid><description>这是在我的 poweredge r720 上全新安装 ESXi 8 的演练，我正在使用 VMware 站点中的自定义戴尔映像，并且我正在使用 force 选项安装 ESXi 8，因为我的硬件被认为是旧的。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;&lt;a href=&quot;https://topvcf.com/2022/10/22/installing-esxi-8-on-poweredge-r720/&quot;&gt;在 PowerEdge R720 上安装 ESXi 8&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;这是在我的 poweredge r720 上全新安装 ESXi 8 的演练，我正在使用 VMware 站点中的自定义戴尔映像，并且我正在使用 force 选项安装 ESXi 8，因为我的硬件被认为是旧的。&lt;/p&gt;
&lt;p&gt;下载戴尔自定义映像&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://customerconnect.vmware.com/cn/downloads/info/slug/datacenter_cloud_infrastructure/vmware_vsphere/8_0#custom_iso&quot;&gt;VMware vSphere - VMware Customer Connect&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202747.png&quot; alt=&quot;img&quot; /&gt;下载ESXi 8戴尔自定义映像后，使用Rufus将其转换为USB可启动驱动器并将其插入服务器。&lt;/p&gt;
&lt;p&gt;否则，如果您有 IDRAC，则可以将 iso 附加到那里。&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202749.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进入 bios 启动管理器以从 USB 驱动器 F11 启动它&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202809.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择 BIOS 启动菜单&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202823.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择插入 USB 驱动器的位置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203315.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在安装程序上按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203306.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;重要！！！！&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/26/20240126180337.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;解决方法如下：&lt;/p&gt;
&lt;p&gt;1，在安装时ESXI 8.0启动的第一个画面，按shift + O组合键，速度要快。&lt;/p&gt;
&lt;p&gt;2，在显示的cdromBoot runweasel后输入autoPartitionOSDataSize=10240&lt;/p&gt;
&lt;p&gt;完整显示：cdromBoot runweasel autoPartitionOSDataSize=10240，注意大小写，8192表示指定OSDataSzie为10GB，对比6.7系统，给出8GB完全可以满足VMware tools、scratch以及coredump空间的需求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/26/20240126180342.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202835.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按回车键继续&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202835.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;推动 F11 接受协议&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202841.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择要安装 ESXi 8 的驱动器&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202835.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择键盘布局&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203254.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;输入要用于 root 帐户的密码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202848.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202848.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按回车键可强制安装不受支持的 ESXi 8&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202853.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;F11 安装&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202853.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202853.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;移除 USB 驱动器并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202900.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;转到 BIOS 启动管理器&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202859.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择 BIOS 引导菜单&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202859.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择安装了 ESXi 8 的驱动器&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202905.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202905.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202905.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按 F2 自定义系统&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203050.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;输入密码并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203100.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进入配置管理网络，按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203111.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Go VLAN 并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203122.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;输入管理VLAN并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203134.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;转到 IPv4 配置&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203146.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择“设置静态 ipv4”，键入 IP 地址、子网掩码和默认网关，然后按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202923.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择DNS配置并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202917.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择使用以下 dns 服务器，然后键入 esxi 主机的 dns IP 地址和 fqdn。&lt;/p&gt;
&lt;p&gt;按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202923.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按压 Esc&lt;/p&gt;
&lt;p&gt;按 Y 键重启管理网络&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203201.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择测试管理网络并按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202929.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202929.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按回车键&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202935.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按压 Esc&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203215.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;转到浏览器并输入 esxi 主机的 FQDN&lt;/p&gt;
&lt;p&gt;https://esxi-mon-00.vmware.local/&lt;/p&gt;
&lt;p&gt;输入凭据&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124202935.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;取消勾选加入，然后单击确定&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203228.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;全部完成后，不要忘记输入您的许可证密钥，以免它在 60 天后过期&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/24/20240124203238.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>PVE直通物理磁盘到 Proxmox VM 虚拟机</title><link>https://6wd.cn/posts/pve-passthrough-physical-disk/</link><guid isPermaLink="true">https://6wd.cn/posts/pve-passthrough-physical-disk/</guid><description>1.进入PVE WEB端的管理页面并登陆,打开PVE节点的shell，输入命令：</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;h2&gt;准备工作-PVE开启iommu直通&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1.进入PVE WEB端的管理页面并登陆,打开PVE节点的shell，输入命令：&lt;/strong&gt;
要忽略 dmesg 输出中的一些烦人的错误， 请运行以下命令(# 这一步对于直通来说不是必需的，但有助于保持干净。)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/modprobe.d/kvm.conf
options kvm ignore_msrs=Y report_ignored_msrs=0
# 按 Ctrl + X，然后按 Y + Enter 保存更改。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;**2.启动内核IOMMU支持
&lt;strong&gt;IOMMU（Input-Output Memory Management Unit）是一种硬件功能，用于管理设备对系统内存的访问。启用 IOMMU 后，可以在虚拟机中直接访问物理设备，并允许虚拟机独立于主机操作系统运行&lt;/strong&gt;
**&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/default/grub # 将以下行粘贴到其中，并在旧标签前面添加一个注释标签#,以下为常用的一些写法。
# 对于 Intel CPU
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on iommu=pt initcall_blacklist=sysfb_init pcie_acs_override=downstream,multifunction pci=nommconf&quot;
# 对于 AMD CPU (本文不涉及)
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet iommu=pt initcall_blacklist=sysfb_init pcie_acs_override=downstream,multifunction pci=nommconf&quot;
# 其他的一些写法(如果是AMD处理器,将intel改为amd)
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on iommu=pt i915.enable_gvt=1 video=efifb:off&quot; # 这是GVT模式，也就是共享模式，少部分cpu支持，但体验很好
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on iommu=pt video=efifb:off&quot; # 这是独占模式，都支持，但显示器没有pve的控制台输出，也只能直通个一个虚拟机
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction&quot;
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on initcall_blacklist=sysfb_init pcie_acs_override=downstream,multifunction&quot;
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on&quot; #本期教程我使用的就是这个
# 参数释义
1.iommu=pt：启用 Intel VT-d 或 AMD-Vi 的 IOMMU。这是一种硬件功能，用于管理设备对系统内存的访问。在虚拟化环境中，启用 IOMMU 后，可以将物理设备直通到虚拟机中，以便虚拟机可以直接访问硬件设备。“iommu=pt”不是必须的，PT模式只在必要的时候开启设备的IOMMU转换，可以提高未直通设备PCIe的性能，建议添加。
2.initcall_blacklist=sysfb_init：禁用 sysfb_init 内核初始化函数。这个函数通常用于在内核启动过程中初始化系统帧缓冲。在使用 GPU 直通的情况下，这个函数可能会干扰直通操作，因此需要禁用它。
3.i915.enable_gvt=1：启用 Intel GVT-g 虚拟 GPU 技术。这个选项用于创建一个虚拟的 Intel GPU 设备，以便多个虚拟机可以共享物理 GPU 设备。启用 GVT-g 需要在支持虚拟 GPU 的 Intel CPU 和主板上运行，并且需要正确配置内核和虚拟机。想开启GVT-g的就添加这条，显卡直通的就不要添加了。
4.initcall_blacklist=sysfb_init：屏蔽掉pve7.2以上的一个bug，方便启动时候就屏蔽核显等设备驱动；
5.pcie_acs_override=downstream,multifunction：便于iommu每个设备单独分组，以免直通导致物理机卡死等问题
6.pci=nommconf：意思是禁用pci配置空间的内存映射,所有的 PCI 设备都有一个描述该设备的区域（您可以看到lspci -vv），访问该区域的最初方法是通过 I/O 端口，而 PCIe 允许将此空间映射到内存以便更简单地访问。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3.使用以下命令更新 grub&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-grub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更新后可以重启电脑&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4.主机重新启动并运行后，运行以下命令,验证是否开启iommu&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dmesg | grep -e DMAR -e IOMMU -e AMD-Vi
# 如果没有输出，则说明有问题。你应该看到这样的东西；“DMAR: IOMMU enabled”
# 另外一种验证方式
dmesg | grep iommu
# 出现如下例子。则代表成功
[ 1.341100] pci 0000:00:00.0: Adding to iommu group 0
[ 1.341116] pci 0000:00:01.0: Adding to iommu group 1
[ 1.341126] pci 0000:00:02.0: Adding to iommu group 2
[ 1.341137] pci 0000:00:14.0: Adding to iommu group 3
[ 1.341146] pci 0000:00:17.0: Adding to iommu group 4
# 此时输入命令
find /sys/kernel/iommu_groups/ -type l
# 出现很多直通组，就代表成功了。如果没有任何东西，就是没有开启
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;5.对于某些平台，可能需要允许不安全中断。运行以下命令&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/modprobe.d/iommu_unsafe_interrupts.conf # 添加以下行；请注意，此选项可能会使您的系统不稳定。
options vfio_iommu_type1 allow_unsafe_interrupts=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;6.启用必要的内核模块，运行以下命令&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/modules # 添加以下行；
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;7.将驱动程序模块列入黑名单，以使虚拟机能够完全访问显卡等。运行以下命令&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/modprobe.d/pve-blacklist.conf # 添加以下行；
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
blacklist snd_hda_codec_hdmi
blacklist snd_hda_intel
blacklist snd_hda_codec
blacklist snd_hda_core
blacklist radeon
blacklist amdgpu
blacklist i915
options vfio_iommu_type1 allow_unsafe_interrupts=1
# 如果有重复项,记得删除,解释：屏蔽三大显卡驱动，屏蔽hdmi声音驱动；options
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;8**.查看直通设备**&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#执行 lspci -nn 可命令查看需要直通设备
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;9.更新模块并重新启动主机以应用更改&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update-initramfs -u -k all
reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;h2&gt;硬盘直通详细操作步骤&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;方式一：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直接PCI添加硬盘  (这里不推荐)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方式二：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1.在“数据中心-&amp;gt;pve-&amp;gt;磁盘”选项卡下，查找您想要直通给虚拟机的目标磁盘。找到它后，记下它的名称串行序列号(我的是9XG9TM11)。
注:可选步骤；点击擦除磁盘。这将删除磁盘的所有内容并将其完全擦除，因此请确保上面没有留下任何重要的内容！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930002753.png&quot; alt=&quot;image-20240930002739348&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2.接下来，在 Shell 终端中输入以下内容&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;find /dev/disk/by-id/ -type l|xargs -I{} ls -l {}|grep -v -E &apos;[0-9]$&apos; |sort -k11|cut -d&apos; &apos; -f9,10,11,12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930002851.png&quot; alt=&quot;image-20240930002851569&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后它会显示您想要的磁盘的完整路径。
像这样复制路径并记下它。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/dev/disk/by-id/{disk-serial}
我的是:/dev/disk/by-id/ata-ST91000640NS_9XG9TM11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.进入您要为其提供磁盘的虚拟机的“硬件”选项卡，并查看当前的磁盘类型（类型一般为scsi1、virtio0等），避免后续直通冲突。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930003056.png&quot; alt=&quot;image-20240930003056150&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再次返回 Shell 终端，然后输入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;qm set {vmid} -{disk-type}{number} /dev/disk/by-id/{disk-serial}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于 Linux，硬盘类型推荐； SCSI。
对于 Windows ，硬盘类型推荐； sata。
例子win（qm set 101 -sata1 /dev/disk/by-id/ata-ST91000640NS_9XG9TM11）
例子linux（qm set 100 -virtio1  /dev/disk/by-id/ata-ST91000640NS_9XG9TM11）
只要出现这个就代表挂载成功&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930005021.png&quot; alt=&quot;image-20240930005021583&quot; /&gt;&lt;/p&gt;
&lt;p&gt;前往101虚拟机-&amp;gt;硬件中查看&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930005039.png&quot; alt=&quot;image-20240930005039720&quot; /&gt;&lt;/p&gt;
&lt;p&gt;成功了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/09/30/20240930010108.png&quot; alt=&quot;image-20240930010108561&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>racamd重置idrac密码</title><link>https://6wd.cn/posts/racadm-reset-idrac-password/</link><guid isPermaLink="true">https://6wd.cn/posts/racadm-reset-idrac-password/</guid><description>ESXi版本的racadm 下载地址:https://www.dell.com/support/home/zh-cn/drivers/driversdetails?driverid=jywk1</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ESXi版本的racadm 下载地址:https://www.dell.com/support/home/zh-cn/drivers/driversdetails?driverid=jywk1&lt;/p&gt;
&lt;p&gt;ESXi下载的文件名为DellEMC-iDRACTools-Web-ESXi.VIB-9.4.0-3749_A00.tar.gz&lt;/p&gt;
&lt;p&gt;通过xftp或者ESXi网页版上传到ESXi的目录中&lt;/p&gt;
&lt;p&gt;ESXi目录为/vmfs/volumes/604454ef-89990d88-e0fe-1418776fbf60&lt;/p&gt;
&lt;p&gt;xftp可以直接传到根目录/&lt;/p&gt;
&lt;p&gt;以根目录为例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 解压
tar -xvf DellEMC-iDRACTools-Web-ESXi.VIB-9.4.0-3749_A00.tar.gz
# 切换目录
cd /iDRACTools/racadm/ESXi67
# 执行
esxcli software vib install -d Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip
# 结果报错
[MetadataDownloadError]
 Could not download from depot at zip:/var/log/vmware/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip?index.xml, skipping ((&apos;zip:/var/log/vmware/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip?index.xml&apos;, &apos;&apos;, &quot;Error extracting index.xml from /var/log/vmware/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip: [Errno 2] No such file or directory: &apos;/var/log/vmware/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip&apos;&quot;))
        url = zip:/var/log/vmware/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip?index.xml
 Please refer to the log file for more details.
# 报错原因是没传全路径，执行
esxcli software vib install -d /vmfs/volumes/datastore1/iDRACTools/racadm/ESXi67/Racadm-Dell-EMC-Web-9.4.0-3749.VIB-ESX67i.zip 
# 安装成功，执行
racadm getsysinfo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装完成&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/19/20240119210042.png&quot; alt=&quot;image-20240119210035078&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使用racadm命令获取root用户id；&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;racadm getconfig -u root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用racadm命令重置root用户密码；&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;racadm set iDRAC.Users.2.Password 123456    #123456为重置后的密码
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.dinghui.org/wp-content/uploads/2022/11/25b258c2e91fcbd10cda9849107154b.png&quot;&gt;&lt;img src=&quot;http://cdn.6wd.cn/2024/01/19/20240119210216.png&quot; alt=&quot;img&quot; /&gt;&lt;/a&gt;提示密码重置成功。&lt;/p&gt;
</content:encoded></item><item><title>远程桌面出现CredSSP无法连接</title><link>https://6wd.cn/posts/rdp-credssp-cannot-connect/</link><guid isPermaLink="true">https://6wd.cn/posts/rdp-credssp-cannot-connect/</guid><description>1、win+R打开运行窗口</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Windows远程桌面出现CredSSP加密数据修正问题解决方案&lt;/h1&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;*&lt;/em&gt;***问题现象:*****&lt;/strong&gt;*&lt;/h3&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-32-55--23-32-36--20200520105047408.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;*&lt;/em&gt;***解决方案：*****&lt;/strong&gt;*&lt;/h3&gt;
&lt;p&gt;&amp;lt;h4 style=&quot;color:red;&quot; &amp;gt;专业版请看方案一，家庭版请看方案二&amp;lt;/h4&amp;gt;&lt;/p&gt;
&lt;h2&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*方案一：**&lt;/em&gt;*&lt;/em&gt;*&lt;/h2&gt;
&lt;p&gt;1、win+R打开运行窗口&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-33-49--20200520105317414.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;2、输入gpedit.msc命令，点击“确定”&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-35-17--20200520105329174.png&quot; alt=&quot;img&quot; align=&apos;left&apos; /&amp;gt;&lt;/p&gt;
&lt;p&gt;3、依次展开“计算机配置”-&amp;gt;“管理模板”-&amp;gt;“系统”-&amp;gt;“凭据分配”设置名称： 加密数据库修正&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-44-27--20200520105246533.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;4、双击“加密数据库修正”，将状态改为“启用”，保护级别改为“易受攻击”，应用—&amp;gt;确定&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-45-12--20200520105406822.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;h2&gt;&lt;em&gt;&lt;em&gt;&lt;em&gt;*&lt;/em&gt;*方案二：**&lt;/em&gt;*&lt;/em&gt;*&lt;/h2&gt;
&lt;p&gt;1、win+R打开运行窗口&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-46-06--20200520105441435.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;2、输入regedit命令，点击“确定”，打开注册表文件&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-47-02--20200520105456203.png&quot; alt=&quot;img&quot; align=&quot;left&quot;/&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-47-19--20200520105509685.png&quot; alt=&quot;img&quot; align=&apos;left&apos;/&amp;gt;&lt;/p&gt;
&lt;p&gt;3、在注册表中进入如下路径：&lt;/p&gt;
&lt;p&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters&lt;/p&gt;
&lt;h4&gt;注意“一般系统下，大概到了System后面再没有后面的路径，需要自行手动新建”&lt;/h4&gt;
&lt;p&gt;先新建项“CredSSP”，然后在CredSSP下新建项“Parameters”&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-52-05--2020052010553064.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;然后在“Parameters”下新建DWORD(32位)，名称为“AllowEncryptionOracle”，设置值为“2”。&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;http://cdn.6wd.cn//2023/07/17/23-51-31--20200520105606802.png&quot; alt=&quot;img&quot; align=&quot;left&quot; /&amp;gt;&lt;/p&gt;
&lt;h3&gt;然后进行尝试，如果不行，请重启一下自己的计算机。&lt;/h3&gt;
</content:encoded></item><item><title>RustDesk中继以及管理端搭建教程</title><link>https://6wd.cn/posts/rustdesk-relay-setup/</link><guid isPermaLink="true">https://6wd.cn/posts/rustdesk-relay-setup/</guid><description>想必大家都有了解RustDesk吧，它分为社区版和专业版，专业版多了后台管理的功能，但是收费十分的昂贵！！下面我教大家用GitHub开源的后端管理项目来部署。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;hr&amp;gt;&lt;/p&gt;
&lt;p&gt;想必大家都有了解RustDesk吧，它分为社区版和专业版，专业版多了后台管理的功能，但是收费十分的昂贵！！下面我教大家用GitHub开源的后端管理项目来部署。&lt;/p&gt;
&lt;p&gt;项目来源：&lt;a href=&quot;https://github.com/lejianwen/rustdesk-api&quot;&gt;lejianwen/rustdesk-api: Custom Rustdesk Api Server, include web admin ,web client and odic login&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;作者其实写的已经很详细了，但是有些配置地方，我要补充一下，本次使用的服务端管理平台是1Panel，这个平台安装教程十分简单，我在这里就不赘述了。具体可以看官网。&lt;/p&gt;
&lt;h2&gt;新建模板&lt;/h2&gt;
&lt;p&gt;1，进入1panel之后，按照以下步骤点击&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025180306.png&quot; alt=&quot;image-20241025180306771&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2，名称我们可以随意，将docker compose复制到对应位置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;networks:
  rustdesk-net:
    external: false
services:
  hbbs:
    container_name: hbbs
    ports:
      - 21115:21115
      - 21116:21116 # 自定义 hbbs 映射端口
      - 21116:21116/udp # 自定义 hbbs 映射端口
      - 21118:21118 # web client
    image: rustdesk/rustdesk-server
    command: hbbs -r 服务器公网:端口 -k &amp;lt;key&amp;gt; # 填入个人域名或 IP + hbbr 暴露端口 这里的key要保证和下面的key一样，并且可以自己编写,端口需要和下面的hbbr端口一样，默认是21117
    volumes:
      - ./data:/root # 自定义挂载目录
    networks:
      - rustdesk-net
    depends_on:
      - hbbr
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 64M
  hbbr:
    container_name: hbbr
    ports:
      - 21117:21117 # 自定义 hbbr 映射端口
      - 21119:21119 # web client
    image: rustdesk/rustdesk-server
    command: hbbr -k &amp;lt;key&amp;gt;  # 与上文的key相同
    volumes:
      - ./data:/root
    networks:
      - rustdesk-net
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 64M
  rustdesk-api:
    container_name: rustdesk-api
    environment:
      - TZ=Asia/Shanghai
      - RUSTDESK_API_RUSTDESK_ID_SERVER=服务器公网IP:21116 #这里都需要替换为您的公网ip
      - RUSTDESK_API_RUSTDESK_RELAY_SERVER=服务器公网IP:21117 #这里都需要替换为您的公网ip
      - RUSTDESK_API_RUSTDESK_API_SERVER=http://服务器公网IP:21114 #这里都需要替换为您的公网ip
      - RUSTDESK_API_RUSTDESK_KEY=&amp;lt;key&amp;gt;
    ports:
      - 21114:21114
    image: lejianwen/rustdesk-api
    volumes:
      - /data/rustdesk/api:/app/data #将数据库挂载出来方便备份
    networks:
      - rustdesk-net
    restart: unless-stopped
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025183634.png&quot; alt=&quot;image-20241025183634693&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;创建容器&lt;/h2&gt;
&lt;p&gt;这里无论如何，在核对一边是否填完整，不然很麻烦&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025183847.png&quot; alt=&quot;image-20241025183847400&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这个就代表成功了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025184142.png&quot; alt=&quot;image-20241025184142547&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;完结&lt;/h2&gt;
&lt;p&gt;当看到这三个容器正常运行，即代表配置成功&lt;/p&gt;
&lt;p&gt;访问http://ip:21114即可登录后台，默认账户密码为admin/admin&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025184615.png&quot; alt=&quot;image-20241025184615500&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后就可以配置了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/10/25/20241025184748.png&quot; alt=&quot;image-20241025184748281&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>测试上下传网速</title><link>https://6wd.cn/posts/speedtest-up-down-bandwidth/</link><guid isPermaLink="true">https://6wd.cn/posts/speedtest-up-down-bandwidth/</guid><description>Speedtest 是一个旧宠。它用 Python 实现，并打包在 Apt 中，也可用 pip 安装。你可以将它作为命令行工具或在 Python 脚本中使用。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/sivel/speedtest-cli&quot;&gt;Speedtest&lt;/a&gt; 是一个旧宠。它用 Python 实现，并打包在 Apt 中，也可用 &lt;code&gt;pip&lt;/code&gt; 安装。你可以将它作为命令行工具或在 Python 脚本中使用。&lt;/p&gt;
&lt;p&gt;使用以下命令安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install speedtest-cli
sudo yum install speedtest-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo pip3 install speedtest-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后使用命令 &lt;code&gt;speedtest&lt;/code&gt; 运行它：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ speedtestRetrieving speedtest.net configuration...Testing from CenturyLink (65.128.194.58)...Retrieving speedtest.net server list...Selecting best server based on ping...Hosted by CenturyLink (Cambridge, UK) [20.49 km]: 31.566 msTesting download speed................................................................................Download: 68.62 Mbit/sTesting upload speed......................................................................................................Upload: 10.93 Mbit/s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它给你提供了互联网上传和下载的网速。它快速而且可脚本调用，因此你可以定期运行它，并将输出保存到文件或数据库中，以记录一段时间内的网络速度。&lt;/p&gt;
</content:encoded></item><item><title>系统镜像站</title><link>https://6wd.cn/posts/system-image-mirrors/</link><guid isPermaLink="true">https://6wd.cn/posts/system-image-mirrors/</guid><description>CentOS下载时版本选择：</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CentOS下载时版本选择：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 1. DVD版：常用版本，就是普通安装版，推荐。里面包含大量的常用软件，大部分情况下安装时无需再在线下载，体积为4G左右。	
 2. Everything版：包含所有软件组件，体积庞大，是DVD版的2倍
 3. LiveCD版：是一个光盘CentOS系统，可通过光盘启动电脑，启动出CentOS系统，也有图形界面，也有终端。也可以安装到计算机，但是有些内容可能还需要再次到网站下载
 4. Minimal版：精简版本，包含核心组件，体积600多MB
 5. NetInstall版：网络安装版本，一般不用这个版本
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.aliyun.com/mirror/&quot;&gt;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mirrors.huaweicloud.com/home&quot;&gt;华为开源镜像站_软件开发服务_华为云 (huaweicloud.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mirrors.tuna.tsinghua.edu.cn/&quot;&gt;清华大学开源软件镜像站 | Tsinghua Open Source Mirror&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mirrors.163.com/&quot;&gt;欢迎访问网易开源镜像站 (163.com)&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu开启root的ssh链接</title><link>https://6wd.cn/posts/ubuntu-enable-root-ssh/</link><guid isPermaLink="true">https://6wd.cn/posts/ubuntu-enable-root-ssh/</guid><description>1、先进行一下更新软件列表和更新软件，在此之前可以先换国内源，本文就不写了，官方源一样安装ssh。</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;1、先进行一下更新软件列表和更新软件，在此之前可以先换国内源，本文就不写了，官方源一样&lt;a href=&quot;https://so.csdn.net/so/search?q=%E5%AE%89%E8%A3%85ssh&amp;amp;spm=1001.2101.3001.7020&quot;&gt;安装ssh&lt;/a&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;安装配置SSH&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;4.1 具体配置SSH步骤&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#1、安装openssh-client
sudo apt install openssh-client
#2、安装openssh-server
sudo apt install openssh-server
#3、ssh服务重启
service  ssh  restart
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#4、安装net-tools (使用ifconfig时，需要net-tools)
sudo apt install net-tools

#5、查看ip,找到inet的值
ifconfig
#6、验证SSH是否正在运行
sudo systemctl status ssh

##如果为inactive（dead）,可以手动开启SSH##
/etc/init.d/ssh start

#补充：
#启用ssh的指令
启动ssh服务：
#sudo /etc/init.d/ssh start
停止ssh服务：
#sudo /etc/init.d/ssh stop
重启ssh服务：
#sudo /etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改sshd_config的内容&lt;/h4&gt;
&lt;p&gt;root用户在命令行或图形化界面中，也是无法直接登录，这是因为&lt;strong&gt;ubuntu23.04&lt;/strong&gt;系统&lt;code&gt;默认root用户是无法直接登录&lt;/code&gt;，需要&lt;code&gt;先登录普通用户($)&lt;/code&gt;，后使用&lt;code&gt;su root&lt;/code&gt;命令切换到&lt;code&gt;root用户(#)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;正确&lt;code&gt;设置和使用&lt;/code&gt;root用户后，此时会&lt;code&gt;发现root用户仍然无法直接登录xftp等远程登录软件&lt;/code&gt;，想要&lt;code&gt;直接远程登录root&lt;/code&gt;用户&lt;code&gt;需要配置系统sshd_config文件&lt;/code&gt;，该文件位于&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; 。&lt;/p&gt;
&lt;h5&gt;4.3.1 修改内容&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;#具体的操作步骤如下:
1、编辑sshd_config
sudo nano /etc/ssh/sshd_config  
或者(不推荐)
sudo vim /etc/ssh/sshd_config

3、将PermitRootLogin prohibit-password修改为PermitRootLogin yes，去掉前面的#号，表示允许root登录。。
   将port 22前面的#去掉。
 
  或者
3、将port 22前面的 #符号删除。
在Authentication的配置后面，增加上 PermitRootLogin yes ，表示允许root登录。
   


4、保存

5、cat /etc/ssh/sshd_config  或者cat sshd_config 查看是否修改成功

6、重启SSH服务(最后一步)。
service ssh restart
或者
/etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/27/20230927015030.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;效果图如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/27/20230927015104.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu获取本地root登录</title><link>https://6wd.cn/posts/ubuntu-get-local-root-login/</link><guid isPermaLink="true">https://6wd.cn/posts/ubuntu-get-local-root-login/</guid><description>使用过Ubuntu的都知道,在本地安装Ubuntu桌面版时,会让我们创建一个普通用户,用户目录(即目录)在/home/[username]/,在使用一些命令时需要在命令前加sudo然后输入密码才能获得权限才能执行,这样使用就很麻烦.而...</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;使用过Ubuntu的都知道,在本地安装&lt;a href=&quot;https://links.jianshu.com/go?to=https%3A%2F%2Fwww.ubuntu.org.cn%2Fdesktop&quot;&gt;Ubuntu桌面版&lt;/a&gt;时,会让我们创建一个普通用户,用户目录(即~目录)在&lt;code&gt;/home/[username]/&lt;/code&gt;,在使用一些命令时需要在命令前加&lt;code&gt;sudo&lt;/code&gt;然后输入密码才能获得权限才能执行,这样使用就很麻烦.而购买过阿里云、华为云等云服务器的都知道,购买的服务器版本,直接给我们root用户使用,用户目录在&lt;code&gt;/root/&lt;/code&gt;,在执行几乎所有的命令都有权限,不需要加&lt;code&gt;sudo&lt;/code&gt;,用起来很方便.
那么下面就记录一下Ubuntu桌面版设置root用户并使用root用户登录的方法.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设置root密码
1)登录普通用户,打开终端(方法很多,比如桌面空白如右键菜单,选择&apos;打开终端&apos;)
2)输入命令&lt;code&gt;sudo passwd root&lt;/code&gt;,提示输入当前用户的密码
3)提示&apos;输入新的UNIX密码&apos;,输入要设置的root密码,提示&apos;重新输入新的UNIX密码&apos;,再输入一次root密码
4)提示 &apos;passwd:已成功更新密码&apos;&lt;/li&gt;
&lt;li&gt;设置root用户登录图形桌面
1)在终端中输入命令&lt;code&gt;sudo vim /etc/pam.d/gdm-autologin&lt;/code&gt;
(前提是系统中安装有&lt;a href=&quot;https://links.jianshu.com/go?to=https%3A%2F%2Fwww.vim.org%2F&quot;&gt;vim编辑器&lt;/a&gt;,安装命令是&lt;code&gt;sudo apt-get install vim&lt;/code&gt;,也可以使用vi编辑器或nano编辑器)
2)注释&apos;auth requied pam_succeed_if.so user != root quiet success&apos;这一行,保存退出
3)在终端输入命令&lt;code&gt;sudo vim /etc/pam.d/gdm-password&lt;/code&gt;
4)注释&apos;auth requied pam_succeed_if.so user != root quiet success&apos;这一行,保存退出
5)在终端输入命令&lt;code&gt;sudo vi /root/.profile&lt;/code&gt;
6)在&apos;mesg n || true&apos;这一行前添加&apos;tty -s &amp;amp;&amp;amp; &apos;,改为&apos;tty -s &amp;amp;&amp;amp; mesg n || true&apos;
7)重启计算机,此时可以用&lt;strong&gt;ROOT&lt;/strong&gt;用户登录,也可以使用原来安装时自己创建的普通用户登录,但是选择了普通用户后的用户选择列表并没有root用户,需要点击&lt;code&gt;未列出&lt;/code&gt;手动输入root和密码来登录&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Ubuntu获取root权限</title><link>https://6wd.cn/posts/ubuntu-get-root-privileges/</link><guid isPermaLink="true">https://6wd.cn/posts/ubuntu-get-root-privileges/</guid><description>$是普通管员，#是系统管理员，在Ubuntu下，root用户默认是没有密码的，因此也就无法使用（据说是为了安全）。想用root的话，得给root用户设置一个密码：</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;$是普通管员，#是系统管理员，在&lt;a href=&quot;https://so.csdn.net/so/search?q=Ubuntu&amp;amp;spm=1001.2101.3001.7020&quot;&gt;Ubuntu&lt;/a&gt;下，root用户默认是没有密码的，因此也就无法使用（据说是为了安全）。想用root的话，得给root用户设置一个密码：&lt;/p&gt;
&lt;p&gt;在终端中输入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo passwd root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果想获得root权限，只需进行如下的操作：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;su root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果要再次禁用 root 帐号，那么可以执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo passwd -l root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/26/20230926005714.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果需要让此用户有root权限，执行命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@pc-googlh:# visudo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改文件如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# User privilege specification
root    ALL=(ALL:ALL) ALL
googlh  ALL=(ALL:ALL) ALL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后Ctrl + O写入，然后Ctrl + X退出&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/26/20230926005609.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
查看里面的文件是否写入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@pc-googlh:# sudo vim /etc/sudoers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;退出：&lt;code&gt;:qa&lt;/code&gt; 回车&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://cdn.6wd.cn/2023/09/26/20230926005609.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;p&gt;vim安装方法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@pc-googlh:# apt-get install vim
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;ubuntu建用户最好用adduser，虽然adduser和useradd是一样的在别的linux糸统下，但是我在ubuntu下用useradd时，并没有创建同名的用户主目录。使用adduser 会自动创建用户主目录，创建用户同名的组。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@pc-googlh:~# sudo adduser linuxidc
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ubuntu换源</title><link>https://6wd.cn/posts/ubuntu-switch-mirror/</link><guid isPermaLink="true">https://6wd.cn/posts/ubuntu-switch-mirror/</guid><description>本文系原创，转载请注明出处</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;本文系原创，转载请注明出处&lt;/strong&gt;
&lt;strong&gt;update 2022.04.23:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Ubuntu 22.04 &lt;/code&gt;的稳定版已经于 2022 年 4 月 21 日发布，&lt;code&gt;Ubuntu 22.04&lt;/code&gt; 稳定版下载地址：https://ubuntu.com/download/desktop&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Ubuntu 22.04 &lt;/code&gt;的稳定版计划于 2022 年 4 月 21 日发布。开发工作已经在紧锣密鼓地进行，它将遵循如下发布时间表：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2022 年 2 月 24 日：功能冻结&lt;/li&gt;
&lt;li&gt;2022 年 3 月 17 日：用户界面冻结&lt;/li&gt;
&lt;li&gt;2022 年 3 月 31 日：测试版发布&lt;/li&gt;
&lt;li&gt;2022 年 4 月 14 日：候选版本&lt;/li&gt;
&lt;li&gt;2022 年 4 月 21 日：最终稳定版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Linux 5.15 &lt;a href=&quot;https://so.csdn.net/so/search?q=LTS&amp;amp;spm=1001.2101.3001.7020&quot;&gt;LTS&lt;/a&gt;是Ubuntu 22.04的默认内核，GCC 11.2是默认的系统编译器，Mesa 22.0提供开源图形驱动支持。Canonical一直在为Ubuntu开发新的桌面安装程序，但是随着22.04 LTS的发布，现有的Ubiquity仍然是默认使用的。&lt;/p&gt;
&lt;p&gt;如果你想在备用机器或虚拟机上测试它，你可以从 Ubuntu 的网站下载&lt;code&gt;Ubuntu 22.04&lt;/code&gt; 每日构建版。
下载 &lt;code&gt;Ubuntu 22.04&lt;/code&gt; 每日构建（不稳定）https://cdimage.ubuntu.com/daily-live/current/
国内有很多&lt;code&gt;Ubuntu&lt;/code&gt;的镜像源，包括阿里的、网易的，还有很多教育网的源，比如：&lt;a href=&quot;https://so.csdn.net/so/search?q=%E6%B8%85%E5%8D%8E%E6%BA%90&amp;amp;spm=1001.2101.3001.7020&quot;&gt;清华源&lt;/a&gt;、中科大源。
我们这里以清华源为例讲解如何修改&lt;code&gt;Ubuntu 22.04&lt;/code&gt;里面默认的源。
编辑/etc/apt/sources.list文件, 在文件最前面添加以下条目(操作前请做好相应备份)：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;清华源&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 默认注释了源码镜像以提高 apt update 速度，如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse

# 预发布软件源，不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后执行命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其他几份国内源如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;阿里源&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;中科大源&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deb https://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;网易163源&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deb http://mirrors.163.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-backports main restricted universe multiverse
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>VMware Workstation 与 Hyper-V 不兼容</title><link>https://6wd.cn/posts/vmware-workstation-hyperv-incompatible/</link><guid isPermaLink="true">https://6wd.cn/posts/vmware-workstation-hyperv-incompatible/</guid><description>1、控制面板-&gt;控制面板-&gt;程序-&gt;启用或关闭Windows功能-&gt; 找到Hyper-V，点击关闭</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;解决VMware Workstation 与 &lt;a href=&quot;https://so.csdn.net/so/search?q=Hyper-V&amp;amp;spm=1001.2101.3001.7020&quot;&gt;Hyper-V&lt;/a&gt; 不兼容。请先从系统中移除 Hyper-V 角色，然后再运行 VMware Workstation的最全详解&lt;/h2&gt;
&lt;h2&gt;问题点：VMware Workstation 与 Hyper-V 不兼容。&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/30/20240830225023.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;一、请先从系统中移除 Hyper-V 角色，然后再运行 VMware Workstation。&lt;/h3&gt;
&lt;p&gt;1、控制面板-&amp;gt;控制面板-&amp;gt;程序-&amp;gt;启用或关闭Windows功能-&amp;gt; 找到Hyper-V，点击关闭
&lt;img src=&quot;https://cdn.6wd.cn/2024/08/30/20240830225023.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
2、然后win +x ,以windows powershell(管理员)身份运行
运行命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bcdedit /set hypervisorlaunchtype off
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.6wd.cn/2024/08/30/20240830225023.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
然后重启电脑即可&lt;/p&gt;
&lt;h3&gt;如果解决不了，往下看&lt;/h3&gt;
&lt;h3&gt;二、如果系统中找不到Hyper-V&lt;/h3&gt;
&lt;p&gt;复制下面代码，命名为Hyper-V.cmd，然后以管理员身份运行，等待，再重启电脑
代码如下（）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pushd &quot;%~dp0&quot;
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum &amp;gt;hyper-v.txt
for /f %%i in (&apos;findstr /i . hyper-v.txt 2^&amp;gt;nul&apos;) do dism /online /norestart /add-package:&quot;%SystemRoot%\servicing\Packages\%%i&quot;
del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后输入Y,重启电脑即可&lt;/p&gt;
&lt;h3&gt;三、系统中Hyper-V显示关闭，依旧报错&lt;/h3&gt;
&lt;p&gt;此时，只能修改注册表，然后重启电脑
具体步骤（示例）：
win+R -&amp;gt;regedit
然后依次点击，如下图\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity
&lt;img src=&quot;https://cdn.6wd.cn/2024/08/30/20240830225023.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
&lt;img src=&quot;https://cdn.6wd.cn/2024/08/30/20240830225023.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;
双击，各个名称，将最后两个修改为0，然后重启电脑即可&lt;/p&gt;
</content:encoded></item><item><title>vue 无法加载文件 CUsersXXXAppDataRoamingnpmvue.ps1，因为在此系统上禁止运行脚本</title><link>https://6wd.cn/posts/vue-ps1-script-blocked-fix/</link><guid isPermaLink="true">https://6wd.cn/posts/vue-ps1-script-blocked-fix/</guid><description>经过不断的查资料我知道了正确的解决办法，如下：</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;vue : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\vue.ps1，因为在此系统上禁止运行脚本&lt;/h1&gt;
&lt;p&gt;经过不断的查资料我知道了正确的解决办法，如下：
首先要启动&lt;a href=&quot;https://so.csdn.net/so/search?q=PowerShell&amp;amp;spm=1001.2101.3001.7020&quot;&gt;PowerShell&lt;/a&gt;（以管理员身份）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h4&gt;点击“开始”单击“ Windows PowerShell”然后右键点击Windows PowerShell，单击“以管理员身份运行”即以管理员身份启动&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;这时候右键单击如下图图标选择管理员那个运行&lt;/h4&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/03/04/20240304235616.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h4&gt;最后运行powershell（管理员身份）输入 &lt;code&gt;set-ExecutionPolicy RemoteSigned&lt;/code&gt; 就可以完美解决了。&lt;/h4&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/03/04/20240304235615.png&quot; alt=&quot;在这里插入图片描述&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>windows 安全中心Defender 存在威胁（历史记录），但点执行操作无反应，一直存在红叉</title><link>https://6wd.cn/posts/windows-defender-threat-stuck-fix/</link><guid isPermaLink="true">https://6wd.cn/posts/windows-defender-threat-stuck-fix/</guid><description>windows安全中心一直显示一个红叉，有一个威胁存在（可能这个威胁发现的时间很久之前，并不一定是当时扫描出来的），推荐你执行操作，但点击执行操作后无任何反应，威胁依然存在</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;windows 安全中心/Defender 存在威胁（历史记录），但点执行操作无反应，一直存在红叉&lt;/h1&gt;
&lt;h3&gt;1 问题详细描述分析&lt;/h3&gt;
&lt;p&gt;windows安全中心一直显示一个红叉，有一个威胁存在（可能这个威胁发现的时间很久之前，并不一定是当时扫描出来的），推荐你执行操作，但点击执行操作后无任何反应，威胁依然存在&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224748.png&quot; alt=&quot;img&quot; /&gt;
&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224334.png&quot; alt=&quot;img&quot; /&gt;&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224335.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击快速扫描后，并没有发现任何威胁，大概断定，这个问题是历史出现威胁，你手动或者其他软件把威胁处理后，windows的系统记录却奇怪的保留下来导致一直显示威胁，你执行操作也不会有任何用（这个威胁实际已经不存在了，windows的奇怪bug）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224802.png&quot; alt=&quot;img&quot; /&gt;&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224812.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;(3) 删除DetectionHistory目录下的相关文件 &lt;strong&gt;（问题最终解决方案，权限问题已解决）&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;删除&lt;code&gt;C:\ProgramData\Microsoft\Windows Defender\Scans\History\Service\DetectionHistory&lt;/code&gt;文件夹下的所有子文件夹即可（子文件夹名称应该均为数字），这样保护历史记录里“已组织访问受保护的文件夹”相关记录也被清除了，问题便得到解决&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有的帖子建议也删除C:\ProgramData\Microsoft\Windows Defender\Scans\History\Results中子文件夹Quick和Resource里的文件删除，这个重启Windows后查看快速扫描的记录不见了，个人觉得没必要删除。&lt;/p&gt;
&lt;p&gt;这种方法&lt;strong&gt;主要的坑在于权限问题，本人是通过安全模式启动删除成功的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在文件资源管理器进入C:\ProgramData\Microsoft\Windows Defender\Scans\因为权限问题直接进不去，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qny.sakura-sky.cn/2024%2F02%2F13%2F20240213224714.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;安全模式打开删除DetectionHistory方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Win+R打开运行，输入msconfig点击确定，引导，安全引导，确定后点击重启电脑，重启后进入安全模式即可通过文件资源管理器进入C:\ProgramData\Microsoft\Windows Defender\Scans\History\Service\DetectionHistory文件夹删除文件，删除后再用同样的方式关闭安全引导重启电脑即可&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>zerossl获取一年免费泛证书</title><link>https://6wd.cn/posts/zerossl-free-wildcard-cert/</link><guid isPermaLink="true">https://6wd.cn/posts/zerossl-free-wildcard-cert/</guid><description>本脚本推荐使用centos stream 8 ，在使用本脚本前，请先更新源，并且安装wget这个插件</description><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;环境配置：&lt;/h2&gt;
&lt;p&gt;本脚本推荐使用centos stream 8 ，在使用本脚本前，请先更新源，并且安装wget这个插件&lt;/p&gt;
&lt;h2&gt;开始教程&lt;/h2&gt;
&lt;h3&gt;首先去zerossl官网注册一个账号&lt;a href=&quot;https://app.zerossl.com/signup&quot;&gt;Dashboard - ZeroSSL&lt;/a&gt;(这个邮箱可以随便填，不会验证)&lt;/h3&gt;
&lt;h3&gt;新建脚本文件&lt;code&gt;zerossl.sh&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;将账号密码替换以下&lt;code&gt;User_Name，User_Pawd&lt;/code&gt;字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
# ZeroSSL 证书申请脚本
# 作者: null

# 用户邮箱
User_Name=&apos;邮箱&apos;
# 用户密码
User_Pawd=&apos;密码&apos;
# 密码编码
User_Pawd_E=$(echo -n &quot;${User_Pawd}&quot;|sha256sum |awk &apos;{print $1}&apos;)

# 登录信息
Login_Info=`curl -v -X POST -c cookie.db -A &apos;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0&apos; -H &apos;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&apos; -d &quot;postArray={\&quot;email_address\&quot;:\&quot;${User_Name}\&quot;,\&quot;password\&quot;:\&quot;${User_Pawd_E}\&quot;}&quot; &apos;https://app.zerossl.com/ajax/public_ajax_handler.php?type=sign_in&apos; 2&amp;gt;&amp;amp;1`

if [[ &quot;${Login_Info}&quot; =~ &apos;success&quot;:1,&apos; ]];then
	echo &quot;用户 ${User_Name} 登录成功.&quot;
else
	echo &quot;用户 ${User_Name} 登录失败.&quot;
	exit 1
fi

# Cookie
Login_Cpt=`echo &quot;${Login_Info}&quot;|awk -F&apos;[ :=;]+&apos; &apos;/Set-Cookie:[[:space:]]_cpt/ {print $4}&apos;`

User_Login_Cookie(){
	curl -s -b cookie.db -A &apos;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0&apos; &quot;${@}&quot;
}

Login_Auth=`User_Login_Cookie &apos;https://app.zerossl.com/dashboard&apos;`
if [ -z &quot;${Login_Auth}&quot; ];then
	echo &quot;$User_Name 未登录.&quot;
	exit 1
fi

# 密钥目录
SSL_Key_Dir=&apos;ssl_key&apos;
# 检查目录是否存在
if [ ! -d &quot;${SSL_Key_Dir}&quot; ];then
	mkdir &quot;${SSL_Key_Dir}&quot;
fi

if [ -z &quot;${1}&quot; ];then
	read -ep &apos;请输入域名:&apos; Gen_Domain
else
	Gen_Domain=&quot;${1}&quot;
fi

# 订阅
Subscription_Plan=`User_Login_Cookie -H &apos;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&apos; -d &apos;postArray={&quot;plan_id&quot;:&quot;512&quot;,&quot;payment_frequency&quot;:&quot;monthly&quot;}&apos; &quot;https://app.zerossl.com/ajax/advanced_ajax_handler.php?type=change_subscription_plan&amp;amp;_cpt=${Login_Cpt}&quot;`
if [[ &quot;${Subscription_Plan}&quot; =~ &apos;success&quot;:1,&apos; ]];then
	echo &quot;用户 ${User_Name} 订阅成功.&quot;
else
	echo &quot;用户 ${User_Name} 订阅失败.&quot;
	exit 1
fi

# 降级订阅
Downgrade_Plan=`User_Login_Cookie -H &apos;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&apos; -d &apos;postArray={&quot;plan_id&quot;:&quot;477&quot;,&quot;payment_frequency&quot;:&quot;monthly&quot;}&apos; &quot;https://app.zerossl.com/ajax/advanced_ajax_handler.php?type=change_subscription_plan&amp;amp;_cpt=${Login_Cpt}&quot;`

# ZeroSSL API 密钥
User_Token=`User_Login_Cookie &apos;https://app.zerossl.com/developer&apos; |grep -A 1 &apos;&quot;access_key&quot;&apos;|awk -F&apos;[ &amp;gt;&amp;lt;]+&apos; &apos;/span/ {print $3}&apos;`
if [ -z &quot;${User_Token}&quot; ];then
	echo &quot;用户密钥为空&quot;
	exit 1
fi

Gen_Domain_D=$(echo &quot;${Gen_Domain}&quot;|sed -r &apos;s/\*\./_/g;s/\./_/g&apos;)
echo &quot;域名信息: ${Gen_Domain} ${Gen_Domain_D}&quot;
Domain_Key_Path=&quot;${SSL_Key_Dir}/${Gen_Domain_D}.key&quot;
Domain_Csr_Path=&quot;${SSL_Key_Dir}/${Gen_Domain_D}_csr.pem&quot;
if [ ! -f &quot;${Domain_Key_Path}&quot; ];then
	openssl genrsa -out &quot;${Domain_Key_Path}&quot; 2048
fi

if [ ! -f &quot;${Domain_Csr_Path}&quot; ];then
	openssl req -new -key ${Domain_Key_Path} -out ${Domain_Csr_Path} -subj &quot;/C=CN/CN=${Gen_Domain}&quot;
fi

# 格式化
Domain_Csr_Code=$(cat &quot;${Domain_Csr_Path}&quot; | tr -d &apos;\n&apos;)
Post_Cert_Code=$(curl -s -X POST -H &apos;Content-Type: application/json&apos; -H &apos;User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0&apos; -d &quot;{\&quot;certificate_domains\&quot;: \&quot;${Gen_Domain}\&quot;, \&quot;certificate_validity_days\&quot;: 365, \&quot;certificate_csr\&quot;: \&quot;${Domain_Csr_Code}\&quot;,    \&quot;strict_domains\&quot;: 1}&quot; &quot;http://api.zerossl.com/certificates?access_key=${User_Token}&quot;)

if [[ &quot;${Post_Cert_Code}&quot; =~ &apos;success&apos; ]];then
	echo &quot;订单失败: ${Post_Cert_Code}&quot;
else
	echo &quot;订单成功: ${Post_Cert_Code}&quot;
fi

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用&lt;code&gt;sh zerossl.sh&lt;/code&gt;运行脚本&lt;/h3&gt;
&lt;p&gt;随后输入泛域名列如&lt;code&gt;*.xxx.com&lt;/code&gt;,普通域名可以直接使用&lt;code&gt;xxx.com,1.xxx.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234024.png&quot; alt=&quot;image-20240522234024193&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;此时代表申请成功，我们进入zerossl官网后台，点击进入Draft ---&amp;gt; verify进入配置&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234219.png&quot; alt=&quot;image-20240522234218974&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234318.png&quot; alt=&quot;image-20240522234318751&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;配置dns&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234403.png&quot; alt=&quot;image-20240522234403670&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;将cname值解析到域名内，这里以腾讯云为例&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234617.png&quot; alt=&quot;image-20240522234617308&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;回到zerossl后台，点击Verify Domains验证dns&lt;/h3&gt;
&lt;h3&gt;验证完成后就可以下载pem,cre文件，这时候并没有key,我们回到脚本位置的ssl_sky目录内就可以看到了&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522234907.png&quot; alt=&quot;image-20240522234906987&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;然后将key下载到本地,配置&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.sakura-sky.cn/2024/05/22/20240522235257.png&quot; alt=&quot;image-20240522235257302&quot; /&gt;&lt;/p&gt;
</content:encoded></item></channel></rss>