所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

必藏!ThinkPHP5 Request请求对象大全:常用方法+实战技巧全解析

必藏!ThinkPHP5 Request请求对象大全:常用方法+实战技巧全解析 一

文章目录CloseOpen

别慌,这篇文章就是你的“Request对象实用手册”。我们把ThinkPHP5中Request请求对象的常用方法全收录——从基础的GET/POST参数获取、Header信息读取,到请求类型(AJAX/POST/GET)判断、IP地址获取,再到文件上传的完整流程;更贴心加了实战避坑技巧:比如如何安全过滤参数防止注入、多端请求的兼容性处理、大文件上传的优化方法。

不管你是刚入门的新手(怕记不住方法),还是熟手(想提升效率),这篇“大全”都能帮你把Request的知识点串成体系。不用再零散查文档,遇到请求问题直接翻,省时间更省心。赶紧往下看,把这些实用技巧收进你的开发工具箱!

做ThinkPHP5开发的你,是不是常遇到这些麻烦?想拿POST参数,记混了post()input();判断AJAX请求,写了isAjax()又怕不兼容;处理文件上传,明明传了文件却拿不到参数?我之前做过3个TP5项目,光请求处理就踩了不下10个坑,后来把Request对象的常用方法和避坑技巧整理成了这套“速查表”,今天分享给你,看完至少省你半天查文档的时间。

Request对象最常用的10个方法,帮你解决80%的请求问题

先抛个 TP5的Request对象里,80%的需求都能用10个方法解决——我去年帮朋友做电商系统时,把这些方法贴在桌面,3个月没再查过文档。接下来一个个说,每个都结合我踩过的坑。

第一个必须说param()方法。你是不是也试过,用get('id')拿URL里的id,用post('name')拿表单里的name,结果遇到路由传参(比如/user/:id)就蒙了?我之前做用户详情页时,就是因为用get('id')没拿到路由参数,导致页面报错。后来查官方文档才知道(https://www.thinkphp.cn/doc/nofollow),param()会自动合并GET、POST、路由参数,而且会自动过滤非法字符(比如标签),比单独用get()post()安全多了。比如你要拿用户ID,直接写$id = request()->param('id');,不管参数是从URL来的还是表单来的,都能拿到,省得你一个个判断。

第二个常用方法是isPost()isAjax()。做登录功能时,你肯定要判断是不是POST请求吧?isPost()就是干这个的,但要注意:它只判断请求的方法类型,不判断内容类型——比如如果前端用POST传了JSON数据,isPost()还是会返回true,但post()方法拿不到参数(因为JSON数据要用水input('put')或者raw())。我之前做API接口时就踩过这坑:前端用POST传JSON,我用isPost()判断后用post()拿参数,结果啥也没拿到,后来换成param()才解决。再说说isAjax(),它是判断是不是AJAX请求,但有些手机浏览器的AJAX请求没带X-Requested-With: XMLHttpRequest头,这时候isAjax()会返回false。我做点赞功能时就遇到过:安卓端的WebView发的AJAX没带这个头,导致点赞失败,后来改成if (request()->isAjax() || request()->header('X-Requested-With') == 'XMLHttpRequest'),才算兼容了所有情况——这是TP5官方文档里提过的解决方案(https://www.thinkphp.cn/doc/nofollow)。

第三个要重点说的是file()方法,处理文件上传必用。我之前做图片上传功能时,用$_FILES直接拿文件,结果遇到大文件上传时,$_FILES是空的,后来才知道TP5里要用file()方法——它会帮你处理php.ini里的upload_max_filesizepost_max_size限制,还能配合validate()方法验证文件类型。比如你要上传头像,写$file = request()->file('avatar');,然后用$file->validate(['size'=>2048000, 'ext'=>'jpg,png,gif'])->move('./uploads');,就能限制文件大小不超过2M,格式只能是图片——比自己写$_FILES省心多了。对了,file()返回的是ThinkFile对象,不是数组,所以别用$_FILES的方式操作它,不然会报错。

我把这些常用方法整理成了一张表,你直接存手机里,需要时查一下:

方法名 用途 示例代码 注意事项
param() 获取GET/POST/路由参数 $id = request()->param(‘id’); 自动过滤非法参数,优先用这个代替get/post
isPost() 判断是否POST请求 if (request()->isPost()) {} 不判断内容类型,JSON数据要用raw()
file() 获取上传文件对象 $file = request()->file(‘avatar’); 返回ThinkFile对象,需配合validate()验证
ip() 获取客户端IP地址 $ip = request()->ip(); 自动处理代理IP(如X-Forwarded-For)
header() 获取请求头信息 $ua = request()->header(‘user-agent’); 键名不区分大小写(如User-Agent或user-agent都能拿到)

除了这些,还有raw()(获取原始请求数据,比如JSON)、cookie()(获取Cookie)、session()(获取Session)这些方法,不过用得没那么频繁,你记不住也没关系,先把上面5个用熟,就能解决大部分问题。

实战中踩过的3个坑,我用Request对象搞定了

光会用方法还不够,实战中你肯定会踩坑——我之前做项目时遇到的3个坑,都是用Request对象解决的,今天分享给你,帮你避坑。

坑一:参数过滤不全,导致SQL注入

去年帮朋友做电商系统时,我用get('id')获取商品ID,直接拼进SQL语句:$goods = Db::name('goods')->where('id', $id)->find();。结果上线没几天,就被黑客注入了——黑客在URL里写id=1 OR 1=1,直接把所有商品都查出来了。后来我才意识到,get()方法不会过滤逻辑运算符,得用param()filter参数。比如改成$id = request()->param('id', '', 'intval');intval会把id强制转成整数,不管黑客传什么字符串,都会变成数字,这样就没法注入了。ThinkPHP官方文档里明确说过(https://www.thinkphp.cn/doc/nofollow):“filter参数是防止SQL注入的有效手段, 所有参数都用它过滤”——我现在写项目,不管拿什么参数,都会加个filter,比如拿用户名用strip_tags(过滤HTML标签),拿邮箱用email(验证邮箱格式),再也没遇到过注入问题。

坑二:AJAX请求判断错误,导致点赞失败

做博客系统的点赞功能时,我用isAjax()判断请求类型:if (request()->isAjax()) { / 处理点赞 / }。结果上线后,很多用户反馈“点了赞没反应”。我查日志发现,安卓手机的WebView发的AJAX请求没带X-Requested-With头,导致isAjax()返回false,点赞逻辑没执行。后来我改成了双重判断if (request()->isAjax() || request()->header('X-Requested-With') == 'XMLHttpRequest')。为什么要加header()判断?因为isAjax()本质就是检查X-Requested-With头,有些浏览器没带这个头,所以直接查头更保险。我还特意查了TP5的源码,isAjax()的实现就是:

public function isAjax()

{

return $this->isXmlHttpRequest() || $this->get('ajax') || $this->post('ajax');

}

public function isXmlHttpRequest()

{

return strtolower($this->header('X-Requested-With')) == 'xmlhttprequest';

}

所以加header()判断其实是补了isAjax()的漏洞——现在这个点赞功能运行了半年,再也没出现过问题。

坑三:文件上传时,参数丢失

做商品发布功能时,前端要传“商品名称”和“商品图片”,我用post('name')拿商品名称,用file('image')拿图片。结果测试时发现,有时候post('name')拿不到值——明明前端传了,后端就是空。后来查了资料才知道,当表单用enctype="multipart/form-data"(上传文件必须用这个)时,post()方法只能拿到普通表单数据,但如果前端传了很多参数(比如商品描述、价格、分类),post()会遗漏部分参数。解决办法很简单:把post('name')改成param('name')——param()会自动处理multipart/form-data类型的表单,不管你传了多少参数,都能拿到。我后来把所有表单参数都换成param(),再也没遇到过参数丢失的问题。

你看,这些坑其实都是因为没把Request对象的方法用对——要么用错了方法,要么没注意方法的细节。我把这些坑整理成了“避坑清单”:

  • 拿参数优先用param(),别用get()post()
  • 判断AJAX请求要加header()检查;
  • 上传文件时,所有参数都用param()拿;
  • 所有参数都要加filter过滤,比如intvalstrip_tags
  • 最后再提醒你一句:用Request对象之前,一定要记得实例化——要么用request()助手函数,要么用app('request'),别直接new Request(),不然会拿不到当前请求的参数。我之前就犯过这低级错误:new了个Request对象,结果拿不到参数,以为是框架bug,后来才知道request()助手函数会自动绑定当前请求的实例,比new靠谱多了。

    如果你按我说的方法试了,欢迎回来告诉我效果——比如你用param()解决了参数丢失的问题,或者用filter避免了注入,都可以在评论区留个言,让我也高兴高兴~


    TP5里拿请求参数,用post()还是param()好?

    优先用param()更省心。因为param()会自动合并GET、POST和路由参数(比如/user/:id这种路由传参),之前我做用户详情页时,用get()没拿到路由参数导致报错,换成param()就解决了。而且param()还会自动过滤非法字符(比如标签),比单独用post()或get()更安全。

    比如要拿用户ID,直接写$id = request()->param(‘id’);,不管参数是从URL、表单还是路由来的,都能拿到,不用一个个判断。

    Ajax请求用isAjax()判断总失败,怎么办?

    很多安卓手机的WebView发Ajax请求时,没带X-Requested-With: XMLHttpRequest头,这时候isAjax()会返回false。我之前做点赞功能时就遇到这问题,后来改成双重判断就兼容了:if (request()->isAjax() || request()->header(‘X-Requested-With’) == ‘XMLHttpRequest’)。

    因为isAjax()本质就是检查这个请求头,直接查header能覆盖更多情况,现在我做项目都用这方法,再也没出现过Ajax判断失败的问题。

    处理文件上传时,表单里的其他参数拿不到怎么解决?

    如果表单用了enctype=”multipart/form-data”(上传文件必须用这个),用post()拿普通表单参数容易遗漏。我之前做商品发布功能时,用post(‘name’)拿不到商品名称,后来改成param(‘name’)就好了。

    因为param()能处理multipart/form-data类型的表单参数,不管是文件还是普通字段,都能一起拿到, 上传文件时所有参数都用param()获取。

    怎么防止Request参数导致的SQL注入?

    用param()的时候加filter参数就行。比如拿商品ID,写$id = request()->param(‘id’, ”, ‘intval’);,intval会把参数强制转成整数,就算黑客传id=1 OR 1=1,也会变成1,没法注入。

    我之前做电商系统时没加filter,被黑客注入过,后来按官方文档 (https://www.thinkphp.cn/doc/nofollow),所有参数都加filter,比如拿用户名用strip_tags过滤HTML标签,拿邮箱用email验证格式,再也没出过问题。

    TP5的Request对象需要new吗?还是用助手函数?

    别直接new Request(),不然拿不到当前请求的参数。我之前犯过这低级错误,new了个Request对象结果啥参数都没拿到,后来才知道用request()助手函数(或者app(‘request’))会自动绑定当前请求的实例,能正确获取参数。

    现在我做项目都直接用request(),比如request()->param(‘id’),方便又不会错。

    原文链接:https://www.mayiym.com/50079.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码