滚动新闻 →
笔记本屏幕只能隐约看到图像,背光故障通常有哪些表现 黄奇帆退休后高调演讲犯大忌 传惹恼最高层被抓 Windows 11 快速访问怎么用?把常用文件夹固定到显眼位置 PHP $_POST 和 $*GET 怎么区别?实际网站开发中应该怎样使用 黄奇帆退休近十年突然被查 中共权力体系中的旧账与政治风险 时光倒流千年 欧洲古装匠心之作华丽重现 针孔摄影机拍下惊人真相 同事竟往她杯中下毒 外国势力伸手市选 加拿大候选人加紧应对 摩根大通获利首度不及预期 美股芯片股重挫 苏轼的词为什么能够写出普通人的生活 比三名男子还重!法国南瓜之王大赛冠军出炉 川普俄州妙语连珠 谈亚洲行:或会见金正恩 新白宫发言人首秀 会讲中文曾在北京工作 美反对中共制裁台邦交国两部长 谴责中共胁迫 葱在传统饮食文化中的使用 SpaceX发射龙飞船执行太空补给任务 四大看点 书法中的提按变化有什么作用 越来越长寿 纽约客平均83.2岁 亚裔居首 美使馆:斐济机构遭黑客入侵 疑中共所为 放映国有器官遭恐吓 台南通过反跨境镇压提案 让孩子明白强大不等于可以欺负别人 上海医院也现“丁义珍式”窗口 老人挂号需跪地 川普炮轰胡塞“学不乖” 誓言11月选后算账 柬埔寨华商邓丕兵 旗下电诈园区黑幕曝光 川普前往阿拉斯加集会:共和党候选人支持率升 4K视频对电脑有什么要求 网传肺鼠疫蔓延中国 资讯不透明加剧疑虑 不倒翁黄奇帆落马 五中全会前再掀政治风暴 北魏孝文帝改革改变了什么 牵扯丁薛祥还是栗战书? 黄奇帆落马原因众说纷纭 被黑客攻击?福建协和就诊系统崩溃 患者焦急等待 美中期选举民主党有望翻盘?六大因素左右选情 中共五中全会召开前 部署18项维稳措施曝光 卫生间通风不好可以从哪些方面改善 中国传统发酵食品有哪些共同特点 旅行行程中为什么需要留出休息时间 胶水黏上去的?华为智慧屏频脱落 投诉不断 汽车更换新电瓶后仍然亏电怎么办 广东酒店3人被困卫生间4小时 喷淋失控 1人骨折 新能源汽车未来会不会采用换电技术

PHP $_POST 和 $*GET 怎么区别?实际网站开发中应该怎样使用

发布时间: 2026-10-13 20:24:02    最后更新: 2026-10-13 21:37:02    阅读:9  约19 分钟阅读     

PHP $_POST 和 $*GET 怎么区别?实际网站开发中应该怎样使用
图片说明:示意图   图片来源:Public Domain(公有领域)
在PHP网站开发中,$_GET和$_POST几乎每天都会出现。搜索框、分页、筛选条件、文章ID、登录表单、用户注册、后台编辑页面以及API接口,都可能涉及这两个超全局数组。很多初学者把它们简单理解成“GET传普通数据,POST传敏感数据”,但这种理解并不完整。 $_GET和$_POST首先是PHP对HTTP请求参数提供的访问方式。它们背后的核心区别在于请求参数来自哪里,以及HTTP请求使用什么方法。至于数据是否安全、是否需要验证、是否应该进入数据库,则是另外一层问题。 $_GET的数据从哪里来 GET请求最常见的形式是URL查询字符串。例如: https://example.com/search.php?q=php&page=2 PHP可以通过: $q = $_GET['q'] ?? ''; $page = $_GET['page'] ?? 1; 读取这些参数。 在这个例子中,q和page都属于查询字符串参数。 GET非常适合表达“我要获取什么资源”或者“我要怎样筛选资源”。搜索、分页、分类、排序、文章ID等场景通常都非常适合使用GET。 例如新闻网站: /news.php?category=technology&page=3 这种URL具有非常明显的优势。用户可以收藏、复制、分享,也可以直接重新访问同一个地址得到相同的查询结果。 搜索引擎也能够理解这种URL结构。 因此,如果一个新闻网站把搜索关键词、分类和分页全部放进POST表单,用户就很难直接保存一个搜索结果页面的URL。对于需要被链接、收藏或者索引的查询操作,GET往往更加自然。 $_POST的数据从哪里来 POST请求通常把表单数据放在HTTP请求体中。例如:
PHP可以读取: $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; 这里最重要的一点是:POST数据虽然通常不会显示在浏览器地址栏中,但并不意味着“用户看不到”。 用户可以通过浏览器开发者工具看到请求内容,也可以使用浏览器扩展、代理工具、curl、Postman等工具自行构造POST请求。 因此,POST不是一种加密机制。 如果密码通过普通HTTP发送,攻击者仍然可能在传输过程中窃取密码。保护传输数据依靠HTTPS,而不是POST本身。 GET和POST最核心的区别并不是“安全与不安全” 这是PHP开发中非常容易形成的错误认识。 GET参数位于URL查询字符串中,因此可能出现在浏览器历史记录、服务器访问日志、代理日志、分析系统以及引用来源信息中。对于密码、身份认证令牌、支付数据等敏感信息,显然不适合放进URL。 POST的数据位于请求体中,在很多常见日志中不会像URL那样自动出现在访问记录里,但这并不代表它不会被记录,也不代表它自动受到保护。 所以更准确的理解是: GET和POST解决的是HTTP请求语义和参数传递方式的问题;HTTPS解决的是传输过程中的加密和完整性问题。 两者不能混为一谈。 GET并没有固定的2048字节限制 很多PHP教程会告诉开发者:“GET最多只能传2048个字符。” 这个说法过于绝对。 HTTP协议本身并没有规定一个统一的“GET只能2048字节”限制。实际URL长度受到浏览器、Web服务器、反向代理、负载均衡器以及应用框架等多个环节影响。 不同环境的限制并不完全相同。 因此,正确的工程实践不是背一个“2048字节”的数字,而是根据应用场景设计请求。 如果参数是搜索关键词、分页、筛选条件等少量数据,GET非常合适。如果需要提交大量表单数据,则通常应该考虑POST或者其他适合的HTTP方法。 对于大型文件上传,更不能简单理解成“POST就没有大小限制”。PHP、Nginx、Apache、反向代理以及应用本身都可能设置请求大小限制。 POST也不是“容量无限大” PHP处理POST请求时,至少需要考虑post_max_size等配置。 例如: post_max_size = 32M upload_max_filesize = 16M 其中upload_max_filesize主要限制单个上传文件,而post_max_size限制整个POST请求体能够达到的大小。 因此,如果用户上传文件时出现“文件明明没有超过upload_max_filesize,却还是上传失败”,就需要继续检查整个POST请求大小以及Web服务器、反向代理等其他限制。 大型文件系统还可能使用分块上传、断点续传或者对象存储的Multipart Upload机制,而不是单纯把PHP的POST限制不断调大。 GET特别适合查询和分页 假设网站有一个文章列表: /news.php?page=3&category=technology 这里使用GET非常合理。 服务器可以读取: $page = filter_input( INPUT_GET, 'page', FILTER_VALIDATE_INT ); $category = trim( $_GET['category'] ?? '' ); if ($page === false || $page === null || $page < 1) { $page = 1; } 这种设计的好处是页面状态直接体现在URL中。 用户可以把这个地址复制给其他人,也可以刷新页面,浏览器前进和后退也能够正常工作。 对于搜索引擎,这种URL结构同样比隐藏在POST请求中的搜索状态更容易被理解。 修改服务器状态通常应该使用POST 如果操作会改变服务器上的数据,就不应该为了方便而使用GET。 例如删除文章: /delete.php?id=100 虽然技术上可以实现,但设计上存在明显问题。 搜索引擎爬虫、预加载机制或者某些自动访问程序理论上都可能访问GET URL。如果这个GET请求具有删除数据的副作用,就可能产生严重问题。 更合理的是:
服务器收到POST之后,还需要验证当前用户身份、权限以及CSRF Token。 这里需要进一步说明,REST API中“创建、更新、删除”并不一定全部使用POST。现代HTTP API可能分别使用POST、PUT、PATCH和DELETE。PHP开发者不能把“所有修改都用POST”理解成HTTP协议的唯一标准,而应该根据接口语义选择合适的方法。 登录密码为什么通常使用POST 登录表单通常使用POST,因为密码不应该放进URL。 例如: /login.php?username=brian&password=123456 这种设计会把密码直接放进URL,是非常糟糕的实践。 正确做法是使用POST:
然后通过HTTPS保护整个通信过程。 这里还有一个容易忽略的问题:即使使用POST,也不能把密码写进应用日志、调试日志或者错误日志。 真正安全的登录系统还应该使用密码哈希、会话保护、登录失败限制以及适当的CSRF和身份认证机制。 $_GET和$_POST都必须进行服务器端验证 不能因为GET用于搜索,就认为GET参数可以直接使用。 例如: $id = $_GET['id']; 然后直接: $sql = "SELECT * FROM articles WHERE id = $id"; 依然存在SQL注入风险。 正确方式应该同时进行类型验证和参数化查询: $id = filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ); if ($id === false || $id === null || $id < 1) { http_response_code(400); exit('Invalid article ID'); } $stmt = $pdo->prepare( 'SELECT * FROM articles WHERE id = ?' ); $stmt->execute([$id]); 这里做了两件不同的事情。 FILTER_VALIDATE_INT负责判断输入是否符合整数规则,PDO预处理语句负责防止参数破坏SQL结构。 这两者不能互相替代。 不要把filter_var当成“万能过滤器” PHP提供了filter_var()和filter_input(),但它们并不是一个可以把所有用户输入变成“安全字符串”的万能工具。 例如: $email = filter_input( INPUT_POST, 'email', FILTER_VALIDATE_EMAIL ); 适合验证邮箱格式。 对于整数: $page = filter_input( INPUT_GET, 'page', FILTER_VALIDATE_INT ); 适合验证整数。 但用户名应该按照业务规则验证,HTML输出则需要HTML上下文的编码,SQL查询需要预处理语句,文件上传需要文件类型和存储位置控制。 不同问题必须使用不同的安全措施。 htmlspecialchars解决的是HTML输出问题 例如用户提交: 服务器将其保存到数据库以后,如果直接输出: echo $username; 就可能产生XSS。 如果这个数据要作为HTML文本输出,可以: echo htmlspecialchars( $username, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8' ); 这与GET还是POST没有直接关系。 无论数据来自: $_GET 还是: $_POST 只要最终进入HTML输出环境,都需要根据上下文正确编码。 同样,也不能把htmlspecialchars()提前应用于所有输入,然后把编码后的字符串直接保存到数据库。通常更合理的设计是保存业务数据,在最终输出到HTML时进行HTML编码。 PHP没有“接收GET前先用filter_var转换UTF-8”这种规则 原稿中提到PHP默认使用ISO-8859-1处理GET参数,并建议接收参数前通过filter_var()进行编码转换,这个说法需要纠正。 filter_var()不是字符编码转换工具。 现代PHP网站应该从整个系统层面统一字符编码,通常使用UTF-8,包括HTML页面、数据库连接、数据库表、应用程序源码和JSON接口等。 如果实际数据出现乱码,需要检查HTTP请求编码、HTML文档声明、数据库连接字符集、数据库表字符集以及数据本身,而不是在所有$_GET参数上统一调用某个过滤器。 例如PDO连接MySQL时,可以明确使用: $pdo = new PDO( $dsn, $username, $password, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ] ); 数据库连接的字符集则应该在DSN或连接初始化阶段正确配置,例如使用charset=utf8mb4。 GET和POST并不是简单的“缓存”和“不缓存” 原稿把GET描述成“更容易缓存”,把POST描述成“通常不会缓存”,方向上有一定背景,但如果作为工程规则就过于简单。 HTTP缓存主要由请求方法、响应头、Cache-Control、Expires、ETag、Vary等机制共同决定。 GET响应通常更容易参与HTTP缓存,因为GET主要用于获取资源;但是否实际缓存取决于响应的缓存策略。 POST响应也并非绝对不能缓存,HTTP规范允许在特定条件下缓存某些POST响应,只是实际Web基础设施通常对POST的缓存处理更加谨慎。 因此,开发者不应该使用“GET一定缓存、POST一定不缓存”来设计业务逻辑。 如果担心用户重复提交注册、订单或者支付表单,更重要的是使用幂等设计、唯一约束、请求ID或者支付平台提供的幂等键,而不是简单依赖POST“不缓存”。 表单重复提交不能靠POST解决 例如用户提交订单以后,浏览器因为网络延迟让用户连续点击两次提交按钮。 即使两个请求都是POST,也可能产生两个订单。 因此生产环境经常采用Post/Redirect/Get模式。 用户提交POST以后,服务器完成业务处理,然后返回重定向,让浏览器使用GET请求访问结果页面。 这样用户刷新结果页面时,不会再次提交原来的POST请求。 对于支付、订单和会员开通等关键业务,还应该在数据库和服务端增加幂等控制。 例如订单系统可以使用唯一订单号或者幂等键,确保同一业务请求重复到达时不会重复扣款或者重复创建权益。 GET和POST只是请求方式,真正的安全边界还在服务器 无论参数来自: $_GET 还是: $_POST 都不能相信它。 用户可以自己构造HTTP请求: curl "https://example.com/article.php?id=100" 也可以手工发送POST: curl -X POST \ -d "username=test&email=test@example.com" \ https://example.com/register.php 因此,网页上的HTML表单并不是安全边界。 服务器必须假设所有请求参数都可能被修改。 如果一个后台页面要求: user_id=100 服务器不能因为这个字段来自隐藏表单就相信它。 用户完全可以改成: user_id=101 真正的权限判断必须在服务器端完成。 API设计中的GET和POST 在API设计中,GET通常用于读取资源,例如: GET /api/articles/100 POST则经常用于创建新的资源: POST /api/articles 如果需要修改资源,则可能使用PUT或者PATCH;删除资源则通常使用DELETE。 例如: GET /api/articles/100 POST /api/articles PATCH /api/articles/100 DELETE /api/articles/100 这比把所有操作都设计成POST /api.php?action=xxx更加清晰。 不过,实际项目不一定必须严格实现完整REST架构。最重要的是接口语义清晰、权限明确、参数验证充分,并且能够正确处理重复请求和异常情况。 文件上传为什么必须使用POST 文件上传一般需要:
PHP随后通过$_FILES读取上传文件。 这里的关键并不是“POST比GET安全”,而是multipart/form-data提供了适合传输文件和普通表单字段的编码方式。 服务器还需要检查上传错误、文件大小、实际文件类型、文件内容、保存位置和文件名。 尤其不能只检查: $extension = pathinfo( $_FILES['file']['name'], PATHINFO_EXTENSION ); 因为文件扩展名完全可以由用户伪造。 实际网站应该怎样选择 如果操作主要是读取资源、搜索、筛选、分页、排序或者定位某一篇文章,GET通常更加合适。 如果操作会创建或者修改服务器端数据,POST、PUT、PATCH等修改型HTTP方法通常更合适。 如果涉及密码、认证信息或者其他敏感数据,不能放进URL,应使用请求体,并通过HTTPS保护传输。 如果需要上传文件,则通常使用POST配合multipart/form-data。 如果页面状态需要能够收藏、复制和分享,GET通常具有明显优势。 如果操作具有副作用,例如删除文章、创建订单、修改账户资料,就不应该设计成普通GET链接。 最重要的一点,是不要把“GET等于不安全、POST等于安全”作为PHP开发原则。GET和POST首先是HTTP语义不同的两种请求方法。安全性来自HTTPS、身份认证、权限控制、CSRF防护、输入验证、参数化查询、输出编码、文件上传限制以及正确的业务逻辑。 PHP开发真正需要掌握的,也不是背下“搜索用GET、登录用POST”这样几条口诀,而是理解数据从浏览器进入服务器以后,每一层应该承担什么责任。GET负责表达资源查询条件,POST等方法负责提交相应的业务操作;验证负责确认数据是否符合规则;权限系统负责确认用户能不能执行操作;PDO负责安全地把参数交给数据库;输出编码负责保护HTML等最终上下文;HTTPS则负责保护网络传输。 当这些边界被正确划分以后,$_GET和$_POST就不再只是PHP中的两个数组,而是整个Web应用请求处理体系中非常基础的一环。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP