我们都知道 laravel 框架自带认证脚手架,只要执行
php artisan make:auth
连视图都有了,很方便,比如我们就以其中的一个注册功能开始,图就不贴了:
// 假设我们的注册页的 url 是 127.0.0.1/register?age=18
public function postRegister(Request $request)
{
$method = $request->method();
$url = $request->url();
$fullUrl() = $request->fullUrl();
$uri = $request->path();
$input = $request->input();
$query = $request->query();
$all = $request->all();
$email = $request->input('email');
$only = $request->only('email', 'password');
$except = $request->except('email', 'password');
}
以上都是我们熟知的 laravel Request请求实例的方法,介绍下其中两个方法对应的源码,了解下实现的原理:
Illuminate\Http\Request.php
// 从请求实例中获取所有的输入和文件
public function all()
{
// array_replace()函数使用后面的数组的值替换第一个数组的值,加了个 `recursive`,没错就是递归替换,具体用法参考手册
return array_replace_recursive($this->input(), $this->allFiles());
}
// 检索请求实例中的输入项
public function input($key = null, $default = null)
{
$input = $this->getInputSource()->all() + $this->query->all();
return data_get($input, $key, $default);
}
// 从请求实例中获取输入源
protected function getInputSource()
{
if ($this->isJson()) {
return $this->json();
}
return $this->getMethod() == 'GET' ? $this->query : $this->request;
}
// 检索请求实例中的请求项
public function query($key = null, $default = null)
{
return $this->retrieveItem('query', $key, $default);
}
// 从给定的源检索一个参数项
protected function retrieveItem($source, $key, $default)
{
if (is_null($key)) {
return $this->$source->all();
}
return $this->$source->get($key, $default);
}
}
上面我们提到了请求实例的输入源,其实指的就是存储请求参数的实例对象,在 laravel 框架运行时,请求类初始化的过程中,所有的请求参数都分类存储在 ParameterBag
类或以其为基类的实例对象中,这个类是来自 \Symfony\Component\HttpFoundation\ParameterBag
,对,没错,就是 Symfony 框架中的请求基类,我们说的输入源指的就是这些实例对象。
其中 ParameterBag
类中有个方法为 all()
,即获取该实例对象中存储的所有参数,还有一个 get()
方法,该方法根据输入参数的名称获取存储的参数。请求实例获取参数的方法就是基于这些实例对象和该实例对象中相应的获取方法。如在 all()
方法中会调用 input()
方法,而 input()
方法首先根据请求方法获取 $query
属性或 $request
属性,这两个属性实际上都是 ParameterBag
类的实例对象,分别存储着全局数组变量 $_GET
和 $_POST
中的值,再通过 all()
方法获取相应实例对象中存储的参数,实际上就是获取全局数组变量 $_GET
和 $_POST
的值。query()
方法就是根据输入的参数名称获取指定的请求参数,其实现原理和 all()
方法相同。