php处理表单须严格区分$_post与$_get:post用于敏感操作(如登录、上传),get仅限只读查询;字段校验用isset()判存在、!empty()或trim()判有效内容;所有输入需服务端过滤验证,输出html必须htmlspecialchars转义;关键表单必须实现csrf token防护。

PHP 接收表单数据时,$_POST 和 $_GET 别混用
表单提交方式(method="post" 还是 method="get")直接决定该用哪个超全局变量。用错会导致 $_POST 为空或 $_GET 拿不到值,不是代码有 bug,是根本没走对入口。
- 登录、注册、上传、修改等涉及敏感或较大数据的表单,必须用
POST,读取用$_POST['username'] - 搜索、分页、筛选等只读操作,可用
GET,但要注意 URL 长度限制和参数暴露风险,读取用$_GET['q'] - 别在
POST表单里写$_GET取值逻辑,也别把密码之类塞进GET—— 浏览器历史、服务器日志、代理缓存都会留痕
空值、未设置字段、字符串 "0" 的判断陷阱
empty() 和 isset() 行为差异大,尤其遇到 "0"、0、false 这类“假值”时,容易误判用户真实输入。
- 检查字段是否提交:用
isset($_POST['email']),它只管键是否存在,不关心值是不是空字符串 - 检查字段是否有有效内容:用
!empty($_POST['email']),但它会把"0"当空 —— 如果你的业务允许用户名为"0",就不能靠empty() - 更稳妥的写法:
array_key_exists('email', $_POST) && trim($_POST['email']) !== ''
过滤和验证不能只靠前端 JavaScript
前端校验能提升体验,但绕过它太容易了 —— 关掉 JS、用 cURL、改 HTML、抓包重发,都能跳过。PHP 层必须做独立验证,否则 SQL 注入、XSS、越权操作全可能发生。
- 邮箱别只用
filter_var($email, FILTER_VALIDATE_EMAIL)就完事,它不拒绝"a@b.c"这种明显无效格式,建议加长度限制和正则补充:preg_match('/^[^\s]+@[^\s]+\.[^\s]{2,}$/', $email) - 数字类型别信
is_numeric(),它接受"1e5"、"+123"、"0xFF"—— 用filter_var($id, FILTER_VALIDATE_INT)更准 - 所有输出到 HTML 的变量,必须过
htmlspecialchars($str, ENT_QUOTES, 'UTF-8'),否则用户输入<script>alert(1)</script>会直接执行
CSRF 防护不是可选项
没有 CSRF Token 的表单,攻击者可以诱导用户点击一个恶意链接,悄悄以用户身份提交请求 —— 比如改密码、删订单、转账。这不是“我网站没登录漏洞就没事”,而是只要用户已登录且 Cookie 有效,就可能中招。
立即学习“PHP免费学习笔记(深入)”;
- 生成 Token 存 session:
$_SESSION['csrf_token'] = bin2hex(random_bytes(32)); - 表单里加隐藏域:
<input type="hidden" name="token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>"> - 接收时比对:
hash_equals($_SESSION['csrf_token'] ?? '', $_POST['token'] ?? '')(注意用hash_equals防时序攻击) - Token 用一次即失效,提交后立即重置
$_SESSION['csrf_token']
真正难的不是写验证逻辑,而是每处 $_POST、$_GET、$_COOKIE 的取值点,都要想清楚:这个值有没有被过滤?有没有被转义?有没有被签名校验?漏掉一个,整条链路就可能崩。











