laravel模块之http

前言:laravel模块解读,测试是最好的解读

http

http模块可以说是laravel中重要的模块了

1
2
3
4
5
6
7
"require": {
"php": "^7.1.3",
"illuminate/session": "5.7.*",
"illuminate/support": "5.7.*",
"symfony/http-foundation": "^4.1",
"symfony/http-kernel": "^4.1"
},

可以看出是依赖了symfony的http模块

Request 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Request extends Symfony\Component\HttpFoundation\Request implements Arrayable, ArrayAccess{}

class Request
{
/**
* @param array $query The GET parameters GET参数
* @param array $request The POST parameters POST参数
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) 请求参数解析成属性数组
* @param array $cookies The COOKIE parameters 会话参数
* @param array $files The FILES parameters 文件参数
* @param array $server The SERVER parameters 服务参数
* @param string|resource|null $content The raw body data 请求体,类型是字符串或资源或空
*/
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
// 初始化
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
}

public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
$this->request = new ParameterBag($request);
$this->query = new ParameterBag($query);
$this->attributes = new ParameterBag($attributes);
$this->cookies = new ParameterBag($cookies);
$this->files = new FileBag($files);
$this->server = new ServerBag($server);
$this->headers = new HeaderBag($this->server->getHeaders());

$this->content = $content;
$this->languages = null;
$this->charsets = null;
$this->encodings = null;
$this->acceptableContentTypes = null;
$this->pathInfo = null;
$this->requestUri = null;
$this->baseUrl = null;
$this->basePath = null;
$this->method = null;
$this->format = null;
}

public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
{
// 这里省略参数的处理,最后利用静态工厂方法创建请求
return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content);
}

// 私有静态工厂方法+单例创建请求,妙啊,23333
private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
if (self::$requestFactory) {
$request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content);

if (!$request instanceof self) {
throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
}

return $request;
}

return new static($query, $request, $attributes, $cookies, $files, $server, $content);
}

}

// ParameterBag is a container for key/value pairs.
// 参数袋是键/值对的容器。简单讲就是参数数组的处理类
class ParameterBag implements \IteratorAggregate, \Countable{}

测试

Laravel的Request继承自Symfony,只是封装了一些符合自身框架的方法而已,大同小异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 测试创建
public function testCreate()
{
$request = Request::create('http://test.com/foo?bar=baz');
$this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
$this->assertEquals('/foo', $request->getPathInfo());
$this->assertEquals('bar=baz', $request->getQueryString());
$this->assertEquals(80, $request->getPort());
$this->assertEquals('test.com', $request->getHttpHost());
$this->assertFalse($request->isSecure());

$request = Request::create('https://test.com/foo?bar=baz');
$this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
$this->assertEquals('/foo', $request->getPathInfo());
$this->assertEquals('bar=baz', $request->getQueryString());
$this->assertEquals(443, $request->getPort());
$this->assertEquals('test.com', $request->getHttpHost());
$this->assertTrue($request->isSecure());
}

Response 响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Response extends Symfony\Component\HttpFoundation\Response{}

class Response
{
public function __construct($content = '', int $status = 200, array $headers = array())
{
$this->headers = new ResponseHeaderBag($headers);
$this->setContent($content);
$this->setStatusCode($status);
$this->setProtocolVersion('1.0');
}

public static function create($content = '', $status = 200, $headers = array())
{
return new static($content, $status, $headers);
}

}

class JsonResponse extends Response
{
public function __construct($data = null, int $status = 200, array $headers = array(), bool $json = false)
{
parent::__construct('', $status, $headers);

if (null === $data) {
$data = new \ArrayObject();
}

$json ? $this->setJson($data) : $this->setData($data);
}

public static function create($data = null, $status = 200, $headers = array())
{
return new static($data, $status, $headers);
}

}

class RedirectResponse extends Response
{
public function __construct(?string $url, int $status = 302, array $headers = array())
{
parent::__construct('', $status, $headers);

$this->setTargetUrl($url);

if (!$this->isRedirect()) {
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
}

if (301 == $status && !array_key_exists('cache-control', $headers)) {
$this->headers->remove('cache-control');
}
}

public static function create($url = '', $status = 302, $headers = array())
{
return new static($url, $status, $headers);
}

}