MySQL 锁机制详解

MySQL 锁机制详解

MySQL 锁是并发控制的核心,搞懂锁,才能避免死锁和性能问题。

1. 表锁 vs 行锁

表锁:锁整个表,开销小,并发低。

  • MyISAM 用的就是表锁
  • 适合读多写少的场景

行锁:锁单行数据,开销大,并发高。

  • InnoDB 用的就是行锁
  • 适合写多的场景

2. 共享锁 vs 排他锁

共享锁(S锁):读锁,多个读不互斥。

SELECT ... LOCK IN SHARE MODE

排他锁(X锁):写锁,一个写独占。

SELECT ... FOR UPDATE

3. 间隙锁

InnoDB 用间隙锁防止幻读。锁的是一个范围,不是具体行。

比如你查 id > 10 AND id < 20,间隙锁会把这个区间锁住,别人插不进来。

4. 死锁

两个事务互相等对方的锁,都不放,就死锁了。

避免死锁的方法:

  • 按相同顺序访问表
  • 事务尽量小,快速提交
  • 降低隔离级别
  • 加索引,减少行锁范围

5. 查看锁状态

-- 查看当前锁
SHOW OPEN TABLES WHERE In_use > 0;

-- 查看 InnoDB 锁
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

-- 查看锁等待
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

6. 行锁什么时候会变成表锁

行锁失效就会升级成表锁:

  • 没用索引
  • 索引失效
  • 全表扫描

所以加索引不仅是为了查得快,也是为了锁得准。

总结

MySQL 锁的核心:

  • InnoDB 默认行锁,MyISAM 是表锁
  • 共享锁读、排他锁写
  • 间隙锁防幻读
  • 死锁要避免:顺序访问、小事务、加索引

搞懂这些,数据库并发问题基本能解决一半。


emer 发布于  2026-10-4 10:46 

Linux 文件权限详解

Linux 文件权限详解

Linux 权限是服务器安全的基础,搞懂权限,服务器才不会乱。

1. 查看权限

用 ls -l 查看文件权限:

ls -l file.txt
-rw-r--r-- 1 user group 1024 Oct 4 10:00 file.txt

开头10个字符就是权限:

  • 第1个:文件类型(- 普通文件,d 目录)
  • 第2-4个:所有者权限
  • 第5-7个:所属组权限
  • 第8-10个:其他人权限

2. 三种权限

  • r(读)= 4
  • w(写)= 2
  • x(执行)= 1

数字加起来就是权限值:

  • 7 = 4+2+1 = rwx
  • 6 = 4+2 = rw-
  • 5 = 4+1 = r-x
  • 4 = 4 = r--

3. 修改权限 chmod

# 给所有者加执行权限
chmod u+x file.txt

# 给所有人只读权限
chmod 444 file.txt

# 所有者读写执行,组和其他人只读
chmod 744 file.txt

4. 修改所有者 chown

# 修改文件所有者
chown user:group file.txt

# 递归修改目录
chown -R user:group /data/www

5. 常用权限

  • 普通文件:644(所有者读写,其他人只读)
  • 目录:755(所有者读写执行,其他人读执行)
  • 脚本文件:755(所有者能执行)

6. 安全建议

  • 网站目录不要用 root 所有者
  • 上传目录禁止执行权限
  • 配置文件权限设为 600,只有所有者能读

总结

Linux 权限核心就是三组(所有者、组、其他人)× 三种(读、写、执行),用数字表示就是 r=4、w=2、x=1。搞懂这个,日常权限管理基本够用了。


emer 发布于  2026-10-4 10:45 

Docker 网络模式详解

Docker 四种网络模式详解

Docker 网络是容器通信的基础,搞懂四种网络模式,容器网络就不会乱。

1. bridge 模式(默认)

这是 Docker 默认的网络模式。容器在一个虚拟的 bridge 网络里,每个容器有自己的虚拟 IP,通过 NAT 访问外部网络。

# 启动容器,默认就是 bridge
docker run -d nginx

# 查看容器 IP
docker inspect 容器ID | grep IPAddress

特点:

  • 容器之间可以通过 IP 互相访问
  • 外部访问需要端口映射
  • 适合大多数场景

2. host 模式

容器直接用宿主机的网络,没有独立的网络栈。

docker run -d --net=host nginx

特点:

  • 网络性能最好,没有 NAT 开销
  • 端口直接用宿主机的,不用映射
  • 多个容器不能用同一个端口

适合对性能要求高的场景。

3. none 模式

容器没有网络,完全隔离。

docker run -d --net=none nginx

特点:

  • 没有任何网络
  • 安全级别最高
  • 适合不需要网络的离线计算任务

4. container 模式

新创建的容器和一个已存在的容器共享网络。

docker run -d --net=container:nginx容器ID redis

特点:

  • 两个容器共享网络栈
  • 可以用 localhost 互相访问
  • 适合紧密配合的服务

5. 自定义网络

生产环境推荐用自定义网络,不用默认的 bridge:

# 创建自定义网络
docker network create mynet

# 容器加入自定义网络
docker run -d --net=mynet --name web nginx
docker run -d --net=mynet --name app php

同一个自定义网络里的容器,可以直接用容器名互相访问,不用记 IP。

总结

四种网络模式各有适用场景:

  • 日常开发用默认 bridge
  • 性能要求高用 host
  • 安全要求高用 none
  • 容器间通信密集用自定义网络

搞懂这四种模式,Docker 网络基本就够用了。


emer 发布于  2026-10-4 10:44 

Redis 缓存穿透解决

Redis 缓存穿透解决方案

缓存穿透是指查询一个数据库里根本不存在的数据,因为缓存里也没有,所以每次请求都打到数据库。如果有人恶意攻击,数据库可能被打挂。

什么是缓存穿透

正常流程:先查缓存,缓存有就直接返回,没有再查数据库,然后写入缓存。

如果查询的数据数据库里也没有,那缓存永远都不会命中,每次请求都会查数据库,这就是缓存穿透。

解决方案一:缓存空值

最简单的办法,数据库查不到也往缓存里写一个空值,设个短过期时间。

$data = $redis->get($key);
if ($data === null) {
    $data = $db->query($sql);
    if ($data === null) {
        // 缓存空值,60秒过期
        $redis->setex($key, 60, '');
    } else {
        $redis->setex($key, 3600, $data);
    }
}

优点:简单直接
缺点:会占用更多缓存空间,大量空值缓存会浪费内存

解决方案二:布隆过滤器

在缓存前面加一层布隆过滤器,先判断数据是否存在,不存在直接返回。

布隆过滤器的原理是用一个大的位数组和多个哈希函数,把存在的数据标记为1。查询时如果所有哈希位置都是1,说明可能存在;只要有一个位置是0,说明一定不存在。

优点:内存占用小,效率高
缺点:有一定误判率(说存在可能不存在,说不存在一定不存在)

两种方案对比

方案 优点 缺点 适用场景
缓存空值 简单 浪费内存 数据量小,穿透不严重
布隆过滤器 内存效率高 有误差 数据量大,穿透严重

总结

缓存穿透是常见的缓存问题,小项目用缓存空值就够了,大项目数据量大就上布隆过滤器。两种方案都能解决问题,根据实际场景选就行。


emer 发布于  2026-10-4 10:43 

Nginx 反向代理配置

Nginx 反向代理配置详解

Nginx 反向代理是最常用的服务器配置之一,把请求转发给后端服务。本文讲清楚核心配置。

1. 基本配置

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2. 传递真实IP

后端服务要拿到用户真实IP,需要配置:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

3. 负载均衡

多台后端服务器,用 upstream 做负载均衡:

upstream backend {
    server 127.0.0.1:8080 weight=1;
    server 127.0.0.1:8081 weight=2;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

4. 超时设置

proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

5. 静态文件处理

静态文件直接由 Nginx 处理,不用转发给后端:

location ~* \.(js|css|png|jpg|gif)$ {
    root /data/www;
    expires 30d;
}

6. HTTPS 反向代理

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

总结

Nginx 反向代理的核心就是 proxy_pass,配上 proxy_set_header 传递必要信息,再加上超时和静态文件处理,基本够用了。


emer 发布于  2026-10-4 10:42 

MySQL 慢查询优化技巧

MySQL 慢查询优化实战技巧

数据库慢查询是生产环境最常见的性能问题之一。掌握慢查询优化技巧,能让系统性能提升数倍。

1. 开启慢查询日志

先开启慢查询日志,找出哪些 SQL 慢:

slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log

超过1秒的查询就会被记录。

2. 用 Explain 分析

慢 SQL 拿到后,用 EXPLAIN 分析执行计划:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:访问类型,ALL 是全表扫描,要优化
  • key:实际用到的索引
  • rows:扫描行数
  • Extra:额外信息,Using filesort、Using temporary 要警惕

3. 加索引

最直接的优化就是加索引:

ALTER TABLE users ADD INDEX idx_name(name);

加索引原则:

  • WHERE、JOIN、ORDER BY 字段优先
  • 区分度高的字段效果好
  • 联合索引遵循最左前缀

4. 避免 SELECT *

只查需要的字段:

-- 不好
SELECT * FROM users WHERE id = 1;

-- 好
SELECT id, name FROM users WHERE id = 1;

5. 深分页优化

LIMIT 100000, 10 很慢,因为要扫描10万行:

-- 不好
SELECT * FROM users LIMIT 100000, 10;

-- 好,用子查询
SELECT * FROM users 
WHERE id >= (SELECT id FROM users LIMIT 100000, 1)
LIMIT 10;

6. 大表拆小

单表数据量超过千万行,性能会下降。可以:

  • 按时间分表
  • 按用户ID分库
  • 归档历史数据

7. 总结

慢查询优化的核心思路:先找慢 SQL,再分析执行计划,然后加索引或改写 SQL。优化完记得对比前后效果,确保真的变快了。


emer 发布于  2026-10-4 10:41 

Linux 进程管理命令

Linux 进程管理常用命令

服务器上跑了多少进程?哪个进程占内存多?怎么杀进程?这些命令必须会。

1. 查看进程

# 查看所有进程
ps aux

# 查找指定进程
ps aux | grep nginx

# 实时查看
top

2. top 命令详解

top 是最常用的进程查看工具:

  • 第一行:系统负载
  • 第二行:任务数
  • 第三行:CPU 使用率
  • 第四行:内存使用
  • 第五行:Swap 使用

按 q 退出,按 k 杀进程。

3. 杀进程

# 按 PID 杀
kill 1234

# 强制杀
kill -9 1234

# 按名字杀
pkill nginx

# 杀掉所有同名进程
killall nginx

4. 查看端口占用

# 查看端口被谁占了
netstat -tlnp | grep 80

# 或者用 ss
ss -tlnp | grep 80

5. 查看进程树

# 查看进程父子关系
pstree

# 查看某个进程的子进程
pstree -p 1234

6. 后台运行

# 后台运行
nohup ./script.sh &

# 查看后台任务
jobs

# 把任务调到前台
fg %1

7. 查看资源占用

# 内存占用排行
ps aux --sort=-%mem | head

# CPU 占用排行
ps aux --sort=-%cpu | head

总结

日常运维就这几个命令:ps、top、kill、netstat、nohup。学会这些,服务器进程管理基本够用了。


emer 发布于  2026-10-4 10:38 

PHP 安全最佳实践

PHP 开发必须注意的安全问题

PHP 开发最容易出安全问题,几个常见坑一定要避开。

1. SQL 注入

最常见的安全漏洞。用户输入拼接到 SQL 里,被注入恶意 SQL。

解决方案:用预处理语句

// 不要这样
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];

// 要这样
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);

2. XSS 跨站脚本

用户输入直接输出到页面,被注入恶意 JS。

解决方案:输出时转义

echo htmlspecialchars($user_input);

3. CSRF 跨站请求伪造

别人伪造你的请求操作。

解决方案:加 Token 验证

// 表单里加 Token
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['token']; ?>">

// 后端验证
if ($_POST['csrf_token'] !== $_SESSION['token']) {
    die('CSRF 攻击');
}

4. 文件上传漏洞

用户上传 PHP 文件,直接拿到 webshell。

解决方案:

  • 限制文件类型
  • 重命名文件
  • 上传目录不执行 PHP

5. 密码明文存储

数据库被拖库,密码全泄露。

解决方案:用 password_hash

$hash = password_hash($password, PASSWORD_DEFAULT);

// 验证
password_verify($password, $hash);

6. 错误信息泄露

生产环境把报错直接展示给用户,暴露路径和代码。

解决方案:关闭 display_errors

display_errors = Off
log_errors = On

总结

PHP 安全的核心:用户输入都不可信,所有输出都要转义,数据库操作用预处理。安全开发意识比工具更重要。


emer 发布于  2026-10-4 10:37 

MySQL 索引原理详解

MySQL 索引为什么能提速

索引是数据库性能优化的核心,搞懂原理才能用对。

1. 为什么慢查询慢

没有索引,MySQL 就得全表扫描,一行一行找。100万行数据就得扫100万次,当然慢。

有了索引,就像书有目录,直接定位到位置,查几百万行也很快。

2. B+ 树索引

MySQL InnoDB 默认用 B+ 树做索引。

  • 树的高度低,一般3-4层
  • 一次查询只需3-4次磁盘IO
  • 叶子节点存数据,非叶子节点存索引

3. 聚簇索引 vs 二级索引

聚簇索引:数据和索引放在一起,按主键组织。一张表只有一个聚簇索引。

二级索引:索引和数据分开,叶子节点存主键值。查二级索引需要回表查主键。

4. 覆盖索引

如果查询的字段都在索引里,就不用回表了,叫覆盖索引。

-- name有索引
SELECT name FROM users WHERE name = '张三';
-- 覆盖索引,不用回表

5. 最左前缀

联合索引 (a, b, c),必须从最左列开始用:

  • WHERE a = 1 能用
  • WHERE a = 1 AND b = 2 能用
  • WHERE b = 2 用不了

6. 索引失效场景

  • 索引字段做函数运算
  • 隐式类型转换
  • like 以 % 开头
  • 联合索引不满足最左前缀

总结

索引是空间换时间。不是越多越好,太多索引会影响写入性能,占用额外存储空间。


emer 发布于  2026-10-4 10:36 

PHP 8.0 新特性

PHP 8.0 有哪些重磅更新

PHP 8.0 是一个大版本更新,带来了很多革命性的特性。

1. JIT 编译

PHP 8.0 引入了 JIT(即时编译),性能大幅提升,计算密集型场景性能翻倍。

2. 命名参数

array_filter(array: $array, callback: fn($x) => $x > 0);

不用按顺序传参,写参数名就行,可读性更好。

3. 枚举 Enum

enum Status: string
{
    case Pending = 'pending';
    case Active = 'active';
    case Rejected = 'rejected';
}

4. 构造函数属性提升

class User {
    public function __construct(
        public int $id,
        public string $name
    ) {}
}

不用再写 $this->id = $id 了,构造函数直接定义属性。

5. 空安全运算符

$user?->getAddress()?->city;

不用层层判断 null,有 null 直接返回 null。

6. Match 表达式

$result = match($status) {
    200 => '成功',
    404 => '未找到',
    default => '未知'
};

比 switch 更简洁,还能直接赋值。

7. 联合类型

function foo(int|string $input) {}

参数可以是多种类型。

总结

PHP 8.0 是现代 PHP 的起点,类型系统更完善,语法更现代。新项目强烈推荐用 PHP 8.0+。


emer 发布于  2026-10-4 10:34 

Git 常用命令汇总

Git 常用命令速查

Git 是开发必备工具,掌握常用命令就行,不用背太多。

1. 初始化与克隆

# 初始化仓库
git init

# 克隆远程仓库
git clone https://github.com/user/repo.git

2. 提交相关

# 查看状态
git status

# 添加到暂存区
git add .
git add file.php

# 提交
git commit -m "提交说明"

# 查看提交历史
git log --oneline

3. 分支操作

# 查看分支
git branch

# 创建分支
git branch feature

# 切换分支
git checkout feature

# 创建并切换
git checkout -b feature

# 合并分支
git merge feature

# 删除分支
git branch -d feature

4. 远程操作

# 拉取远程更新
git pull

# 推送本地提交
git push origin main

# 查看远程仓库
git remote -v

5. 撤销操作

# 撤销工作区修改
git checkout -- file.php

# 撤销暂存区
git reset HEAD file.php

# 回退到上个版本
git reset --hard HEAD~1

6. 暂存操作

# 暂存当前修改
git stash

# 恢复暂存
git stash pop

7. 标签

# 打标签
git tag v1.0.0

# 推送标签
git push origin v1.0.0

总结

日常开发就这几个命令:add、commit、push、pull、branch、merge。其他的用到再查就行,不用全背。


emer 发布于  2026-10-4 10:33 

Docker Compose 实战

Docker Compose 一键部署多容器

Docker Compose 可以用一个 YAML 文件定义和运行多个 Docker 容器,开发环境部署特别方便。

1. 基本结构

version: '3'
services:
  web:
    image: nginx
    ports:
      - "80:80"
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456

2. 常用命令

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 停止并删除容器
docker-compose down

# 重启某个服务
docker-compose restart web

3. PHP 开发环境示例

version: '3'
services:
  php:
    build: .
    ports:
      - "8000:80"
    volumes:
      - ./:/var/www/html
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: redis:alpine

volumes:
  mysql_data:

4. 数据卷

数据卷用来持久化数据,容器删了数据还在:

volumes:
  - ./data:/var/lib/mysql

5. 网络

默认同一 Compose 里的服务在同一个网络,可以直接用服务名互相访问。比如 PHP 容器里连数据库用 mysql:3306,不用写 IP。

总结

Docker Compose 适合本地开发和测试环境。生产环境部署建议用 K8s 或者更专业的编排工具。


emer 发布于  2026-10-4 10:32 

Nginx 日志分析技巧

Nginx 日志分析常用命令

Nginx 日志是排查问题、分析流量的重要工具。掌握几个常用命令,线上排查效率翻倍。

1. 查看访问量

# 总请求数
wc -l access.log

# 今天的请求数
grep "04/Oct/2026" access.log | wc -l

2. 分析 IP 访问量

# 访问最多的前10个IP
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

3. 分析 URL 访问量

# 访问最多的前10个URL
awk '{print $7}' access.log | sort | uniq -c | sort -nr | head -10

4. 分析状态码

# 统计各状态码数量
awk '{print $9}' access.log | sort | uniq -c | sort -nr

# 404错误数量
grep " 404 " access.log | wc -l

5. 分析流量

# 总流量
awk '{sum += $10} END {print sum/1024/1024 " MB"}' access.log

6. 实时监控

# 实时查看最新日志
tail -f access.log

# 实时查看502错误
tail -f access.log | grep " 502 "

7. 查找慢请求

# 响应时间超过1秒的请求
awk '$NF > 1' access.log | head -10

8. 排查爬虫

# 百度爬虫访问量
grep "Baiduspider" access.log | wc -l

总结

Nginx 日志分析主要靠 awk + sort + uniq 组合,掌握这几个命令,日常排查基本够用。复杂分析可以用 GoAccess 等可视化工具。


emer 发布于  2026-10-4 10:31 

Redis 持久化详解

Redis 两种持久化机制对比

Redis 是内存数据库,重启数据就没了,所以持久化很重要。Redis 有两种持久化方式:RDB 和 AOF。

1. RDB 快照

RDB 就是把整个内存数据快照存成文件。

优点:

  • 文件小,恢复快
  • 适合备份和灾难恢复

缺点:

  • 可能丢数据,两次快照之间的写入会丢

配置:

save 900 1        # 900秒内至少1个key变化就快照
save 300 10       # 300秒内至少10个key变化
save 60 10000     # 60秒内至少10000个key变化

2. AOF 日志

AOF 把每个写操作都记录到日志文件,重启时重放日志恢复数据。

优点:

  • 数据更安全,最多丢1秒
  • 日志可读,误删可以手动修复

缺点:

  • 文件比 RDB 大
  • 恢复慢

配置:

appendonly yes
appendfsync everysec   # 每秒刷盘一次

3. 混合持久化

Redis 4.0 支持混合持久化,RDB 做全量,AOF 做增量。

aof-use-rdb-preamble yes

生产环境推荐用这个,兼顾性能和数据安全。

4. 怎么选

  • 纯缓存场景:不要持久化,性能最好
  • 数据不能丢:用 AOF 或混合持久化
  • 需要快速恢复:用 RDB

总结

Redis 持久化没有完美方案,根据业务场景选。生产环境建议混合持久化,兼顾性能和数据安全。


emer 发布于  2026-10-4 10:30 

MySQL 8.0 新特性

MySQL 8.0 有哪些重要更新

MySQL 8.0 是目前最主流的大版本,相比 5.7 提升很大。

1. 性能提升

8.0 的性能比 5.7 提升约 2 倍,尤其是读取和写入并发场景下提升明显。

2. 原子 DDL

8.0 支持原子 DDL,建表、删表操作要么全成功要么全失败,不会出现一半成功一半失败的情况。

3. 窗口函数

支持窗口函数,比如 ROW_NUMBER()、RANK(),做排名统计很方便:

SELECT name, score,
  RANK() OVER (ORDER BY score DESC) as rank
FROM students;

4. CTE 公共表表达式

支持 WITH 语法,复杂 SQL 写起来更清晰:

WITH top_users AS (
  SELECT id, name FROM users WHERE vip = 1
)
SELECT * FROM top_users;

5. JSON 增强

JSON 操作函数更丰富,性能也更好,基本可以替代 MongoDB 的简单场景。

6. 隐藏索引

可以把索引设为隐藏状态,不删除但暂时不用,用来测试索引是否真的有用。

7. 字符集变化

默认字符集从 latin1 改成了 utf8mb4,支持 Emoji 表情。

总结

MySQL 8.0 是目前新项目的首选,性能好、特性全。老项目从 5.7 升级要注意兼容性,尤其是 SQL 模式和函数变化。


emer 发布于  2026-10-4 10:28 

PHP 7.4 新特性

PHP 7.4 有哪些实用新特性

PHP 7.4 是 7.x 系列的最后一个版本,带来了不少语法糖和性能优化,至今还有很多项目在用。

1. 类型属性

类的属性可以声明类型了:

class User {
    public int $id;
    public string $name;
    public ?string $email;
}

之前属性不能写类型,只能靠 PHPDoc 注释,现在直接写在代码里,IDE 提示更准确。

2. 箭头函数

支持短闭包:

$users = array_map(fn($user) => $user['name'], $users);

比传统的 function ($user) use (...) {} 简洁多了,自动捕获外层变量。

3. 空合并赋值

$data['user'] ??= [];

相当于:

if (!isset($data['user'])) {
    $data['user'] = [];
}

4. 数组展开

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$merged = [...$arr1, ...$arr2];

5. 数字字面量分隔

$amount = 1_000_000;
$price = 9_999.99;

大数字用下划线分隔,可读性提升。

6. 性能提升

PHP 7.4 比 7.3 性能提升约 10%,内存占用也更少。

总结

PHP 7.4 虽然不是大版本,但实用特性很多,尤其是类型属性和箭头函数,写起来舒服不少。新项目建议直接上 PHP 8+,老项目升级到 7.4 也很稳妥。


emer 发布于  2026-10-4 10:27 

PHP Session 与 Cookie:会话管理实战指南

前言

HTTP 是无状态的,你每次请求服务器都不认识你。Session 和 Cookie 就是用来解决这个问题的。本文讲清楚 PHP 中 Session 和 Cookie 的用法。

一、Cookie 是什么

Cookie 是存在浏览器里的小数据,每次请求自动带给服务器。

设置 Cookie

setcookie("username", "张三", time() + 3600, "/");

参数说明:

  • 第一个参数:名称
  • 第二个参数:值
  • 第三个参数:过期时间(时间戳)
  • 第四个参数:路径

读取 Cookie

echo $_COOKIE['username'];

删除 Cookie

setcookie("username", "", time() - 3600, "/");

把过期时间设成过去就行。

二、Session 是什么

Session 是存在服务器上的数据,通过 Session ID 识别用户。

启动 Session

session_start();

注意:必须在输出之前调用,不然会报错。

存数据

$_SESSION['user_id'] = 1;
$_SESSION['username'] = '张三';

读数据

echo $_SESSION['username'];

删除单个数据

unset($_SESSION['user_id']);

销毁 Session

session_destroy();

三、Session 和 Cookie 的区别

对比 Cookie Session
存储位置 浏览器 服务器
大小限制 4KB 无限制
安全性 低(用户能改) 高
生命周期 可设置 默认浏览器关闭就没

四、登录功能示例

登录页

<?php
session_start();

if ($_POST) {
    $username = $_POST['username'];
    $password = $_POST['password'];

    // 验证用户名密码
    if ($username == 'admin' && $password == '123456') {
        $_SESSION['user_id'] = 1;
        $_SESSION['username'] = $username;
        header('Location: dashboard.php');
        exit;
    } else {
        echo "用户名或密码错误";
    }
}
?>

判断是否登录

<?php
session_start();

if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
    exit;
}
?>

退出登录

<?php
session_start();
session_destroy();
header('Location: login.php');
exit;
?>

五、Session 配置

修改 Session 有效期

ini_set('session.gc_maxlifetime', 3600); // 1小时
session_start();

修改 Session 存储路径

session_save_path('/tmp/sessions');
session_start();

用 Redis 存储 Session

生产环境推荐用 Redis 存 Session,默认文件存储性能差。

php.ini 配置:

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

六、安全问题

1. Session 劫持

别人拿到你的 Session ID,就能冒充你。

防护:

  • 用 HTTPS
  • Session ID 定期更换
  • 绑定 IP(不太推荐,IP 会变)

2. Cookie 劫持

别人拿到你的 Cookie,就能冒充你。

防护:

  • 设置 HttpOnly,JS 读不到
  • 设置 Secure,只在 HTTPS 下传
  • 设置 SameSite,防止 CSRF
setcookie("token", $token, [
    'expires' => time() + 3600,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);

3. CSRF 攻击

别人伪造你的请求。

防护:

  • 表单加 CSRF Token
  • 验证 Referer

七、常见坑

  1. session_start() 在输出之后:报错 headers already sent
  2. Session 没销毁:退出登录后还能访问
  3. Cookie 大小限制:别存太多东西,超过 4KB 就丢
  4. Session 文件太多:默认文件存储,大了要清理

八、最佳实践

  1. 敏感数据用 Session,别存 Cookie
  2. Cookie 加 HttpOnly 和 Secure
  3. 生产环境用 Redis 存 Session
  4. 登录成功后重新生成 Session ID,防止固定攻击
// 登录成功后
session_regenerate_id(true);

总结

Session 和 Cookie 的核心要点:

  1. Cookie 存在浏览器,Session 存在服务器
  2. session_start() 必须在输出之前调用
  3. Session 更安全,Cookie 更轻量
  4. 生产环境用 Redis 存 Session
  5. Cookie 加 HttpOnly 和 Secure,防劫持

登录、权限、购物车,都离不开 Session 和 Cookie。搞懂这俩,PHP 后端才算入门。


emer 发布于  2026-10-4 10:21 

PHP Composer 入门:依赖管理完全指南

前言

Composer 是 PHP 的依赖管理工具,就像 Node 的 npm、Python 的 pip。现在写 PHP 项目,不会 Composer 根本没法干活。本文讲清楚 Composer 的核心用法。

一、安装 Composer

Linux / Mac

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Windows

去官网下载安装包,一路下一步就行。

验证安装

composer -V

二、初始化项目

# 在项目目录下
composer init

会问你几个问题,一路回车就行,然后会生成 composer.json 文件。

composer.json 长什么样

{
    "name": "yourname/project",
    "description": "项目描述",
    "require": {
        "monolog/monolog": "^2.0"
    }
}

三、安装依赖

1. 安装所有依赖

composer install

会根据 composer.lock 文件安装指定版本的依赖。

2. 添加新依赖

composer require monolog/monolog

会自动加到 composer.json 里,然后安装。

3. 安装指定版本

composer require monolog/monolog:^2.0

版本号说明

  • ^2.0:2.0 到 3.0 之前(不包括 3.0)
  • ~2.0:2.0 到 2.1 之前(不包括 2.1)
  • *:任意版本
  • 2.0.*:2.0 开头的版本

四、自动加载

Composer 最爽的就是自动加载,不用自己写 require。

引入自动加载

<?php
require 'vendor/autoload.php';

// 直接用类,不用 require
$log = new Monolog\Logger('name');

PSR-4 自动加载

在 composer.json 里配置:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

然后执行:

composer dump-autoload

这样 App\User 类就会从 src/User.php 加载。

五、常用命令

命令 作用
composer install 安装所有依赖
composer update 更新所有依赖
composer require 包名 添加依赖
composer remove 包名 删除依赖
composer dump-autoload 重新生成自动加载
composer show 查看已安装的包
composer self-update 更新 Composer 本身

六、开发环境依赖

有些包只在开发时用,比如测试工具:

composer require --dev phpunit/phpunit

线上部署的时候,不安装开发依赖:

composer install --no-dev

七、中国镜像

国外源太慢,换中国镜像:

# 阿里云镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 腾讯云镜像
composer config -g repo.packagist composer https://mirrors.tencent.com/composer/

换完之后速度飞起来。

八、composer.lock 的作用

  • 记录当前安装的依赖版本
  • 团队成员 install 的时候,装的版本一模一样
  • 一定要提交到 Git
git add composer.json composer.lock
git commit -m "update composer"

九、常见坑

  1. 没装 composer.lock:团队成员装的版本不一样,出 bug
  2. 自动加载不生效:改了 autoload 配置,忘了 dump-autoload
  3. 版本冲突:两个包依赖同一个库的不同版本
  4. 国内太慢:不换镜像,下载半天

十、最佳实践

  1. composer.json 和 composer.lock 都提交 Git
  2. 线上用 install --no-dev,不要用 update
  3. 用中文镜像,加速下载
  4. 改了自动加载配置,记得 dump-autoload

总结

Composer 的核心要点:

  1. require 添加依赖,install 安装依赖
  2. vendor/autoload.php 是自动加载入口
  3. composer.lock 要提交 Git,保证版本一致
  4. 换国内镜像,速度快很多
  5. 开发依赖用 --dev,线上不装

学会 Composer,PHP 开发效率提升一倍。


emer 发布于  2026-10-4 10:20 

MySQL 备份与恢复:mysqldump 实战指南

前言

数据库备份是生产环境的生命线。很多人没出事的时候不备份,出事了才后悔。本文讲清楚 MySQL 最常用的备份工具 mysqldump。

一、为什么要备份

  • 误操作:手滑删了表、删了数据
  • 服务器挂了:硬盘坏了、机器报废
  • 被攻击: ransomware 加密了数据库
  • 升级失败:新版本不兼容,数据回退

记住:没有备份的数据库,就是在裸奔。

二、mysqldump 是什么

mysqldump 是 MySQL 自带的逻辑备份工具,把数据导出成 SQL 文件。

优点:简单、通用、跨版本
缺点:大数据量慢

适合:中小数据库(< 50G)

三、备份数据库

1. 备份整个数据库

mysqldump -u root -p 数据库名 > backup.sql

输入密码后,就会生成 backup.sql 文件。

2. 备份所有数据库

mysqldump -u root -p --all-databases > all_backup.sql

3. 备份单个表

mysqldump -u root -p 数据库名 表名 > table_backup.sql

4. 备份多个表

mysqldump -u root -p 数据库名 表1 表2 > multi_backup.sql

四、恢复数据库

1. 恢复整个数据库

mysql -u root -p 数据库名 < backup.sql

注意:数据库要先存在。

CREATE DATABASE 数据库名;

2. 恢复所有数据库

mysql -u root -p < all_backup.sql

五、常用参数

--single-transaction

InnoDB 引擎下,保证备份一致性,不锁表:

mysqldump -u root -p --single-transaction 数据库名 > backup.sql

生产环境一定要加这个!

--routines

备份存储过程和函数:

mysqldump -u root -p --routines 数据库名 > backup.sql

--triggers

备份触发器:

mysqldump -u root -p --triggers 数据库名 > backup.sql

--events

备份事件调度器:

mysqldump -u root -p --events 数据库名 > backup.sql

--no-data

只备份表结构,不备份数据:

mysqldump -u root -p --no-data 数据库名 > schema.sql

--where

按条件备份:

mysqldump -u root -p 数据库名 表名 --where="id > 100" > partial.sql

六、完整备份命令

生产环境推荐用这个:

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --default-character-set=utf8mb4 \
  数据库名 > backup.sql

七、压缩备份

备份文件太大?压缩一下:

# 备份并压缩
mysqldump -u root -p 数据库名 | gzip > backup.sql.gz

# 解压并恢复
gunzip < backup.sql.gz | mysql -u root -p 数据库名

八、定时备份

写个脚本每天自动备份:

#!/bin/bash

# 备份目录
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d)

# 备份
mysqldump -u root -p密码 --single-transaction 数据库名 | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# 删除 7 天前的备份
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +7 -delete

加到 crontab:

# 每天凌晨 2 点备份
0 2 * * * /bin/bash /path/to/backup.sh

九、常见坑

  1. 备份不锁表:大表备份会锁表,一定要加 --single-transaction
  2. 字符集不对:备份文件乱码,加 --default-character-set=utf8mb4
  3. 没备份存储过程:导出后丢了,加 --routines
  4. 备份没验证:备份完一定要试恢复,不然真出事的时候哭都来不及

十、备份策略

  • 每天全量备份:小数据库
  • 每周全量 + 每天增量:大数据库
  • 异地备份:备份文件要存到别的服务器
  • 定期演练恢复:每个月测一次能不能恢复

总结

MySQL 备份的核心要点:

  1. mysqldump 是最常用的备份工具
  2. 生产环境加 --single-transaction,不锁表
  3. 备份要压缩,节省空间
  4. 定时备份,自动删除旧备份
  5. 备份一定要验证,能恢复才算备份成功

数据是公司最值钱的资产,备份这事儿千万别偷懒。


emer 发布于  2026-10-4 10:18 

Linux 常用命令:从文件操作到进程管理的完整指南

前言

Linux 是后端开发的必修课。很多新手面对黑窗口就发怵,其实只要掌握常用命令,日常开发就够用了。本文整理最常用的 Linux 命令。

一、文件操作

1. 查看目录

# 列出当前目录文件
ls

# 详细信息
ls -l

# 包括隐藏文件
ls -la

# 按时间排序
ls -lt

2. 切换目录

# 进入目录
cd /home/user

# 回到上一级
cd ..

# 回到用户主目录
cd ~

# 回到上次目录
cd -

3. 创建目录

# 创建目录
mkdir test

# 递归创建多级目录
mkdir -p a/b/c

4. 创建文件

# 创建空文件
touch test.txt

# 写入内容
echo "hello" > test.txt

# 追加内容
echo "world" >> test.txt

5. 复制文件

# 复制文件
cp test.txt test2.txt

# 复制目录
cp -r dir1 dir2

6. 移动/重命名

# 移动文件
mv test.txt /tmp/

# 重命名
mv old.txt new.txt

7. 删除文件

# 删除文件
rm test.txt

# 删除目录
rm -rf dir1

警告:rm -rf 很危险,一定要确认路径!

二、查看文件内容

1. cat

# 查看整个文件
cat test.txt

2. less

# 分页查看
less test.log

# 快捷键:
# 空格:下一页
# b:上一页
# /关键字:搜索
# q:退出

3. head / tail

# 看前 10 行
head -10 test.txt

# 看后 10 行
tail -10 test.txt

# 实时看日志(最常用)
tail -f /var/log/nginx/access.log

三、查找文件

1. find

# 按文件名查找
find / -name "nginx.conf"

# 按大小查找(大于 100M)
find / -size +100M

# 按修改时间查找(7 天内修改的)
find / -mtime -7

2. grep

# 在文件里搜索
grep "error" test.log

# 不区分大小写
grep -i "error" test.log

# 显示行号
grep -n "error" test.log

# 递归搜索目录
grep -r "function" /var/www/

# 配合管道使用
ps aux | grep nginx

四、系统状态

1. 查看进程

# 所有进程
ps aux

# 查找进程
ps aux | grep nginx

2. 杀死进程

# 按 PID 杀
kill 1234

# 强制杀
kill -9 1234

# 按名字杀
pkill nginx

3. 查看端口

# 查看所有监听端口
netstat -tlnp

# 查看某个端口
netstat -tlnp | grep 80

4. 查看磁盘

# 磁盘使用情况
df -h

# 当前目录大小
du -sh .

# 每个子目录大小
du -sh *

5. 查看内存

free -h

五、权限管理

1. chmod

# 给文件加执行权限
chmod +x test.sh

# 755:所有者可读写执行,其他人可读执行
chmod 755 test.sh

# 644:所有者可读写,其他人只读
chmod 644 test.txt

2. chown

# 修改文件所有者
chown www:www test.txt

六、压缩解压

1. tar

# 压缩
tar -zcvf website.tar.gz /var/www/html

# 解压
tar -zxvf website.tar.gz

2. zip

# 压缩
zip -r website.zip /var/www/html

# 解压
unzip website.zip

七、网络相关

1. curl

# 访问网页
curl https://www.baidu.com

# 查看响应头
curl -I https://www.baidu.com

# 发 POST 请求
curl -X POST -d "name=张三" https://api.example.com

2. wget

# 下载文件
wget https://example.com/file.zip

八、常用快捷键

快捷键 作用
Ctrl + C 终止当前命令
Ctrl + Z 暂停当前命令
Ctrl + D 退出终端
Tab 自动补全
Ctrl + R 搜索历史命令
!命令 执行最近一次的某命令

九、常用操作速查

操作 命令
看文件 cat / less / tail -f
找文件 find / grep
看进程 ps aux / top
看端口 netstat -tlnp
看磁盘 df -h / du -sh
改权限 chmod / chown

总结

Linux 常用命令的核心要点:

  1. 文件操作:ls / cd / mkdir / cp / mv / rm
  2. 查看内容:cat / less / tail -f
  3. 查找搜索:find / grep
  4. 进程管理:ps / kill / netstat
  5. 系统状态:df / du / free

不用背,用多了自然就记住了。先把这几个常用的练熟,日常开发基本够用。


emer 发布于  2026-10-4 10:17 
'); })();