PHP 语言 使用PSR 251标准实现HTTP消息工厂

PHP阿木 发布于 2025-07-01 10 次阅读


摘要:

随着互联网技术的发展,HTTP协议已经成为现代网络通信的基础。在PHP开发中,正确处理HTTP请求和响应是构建高效、可维护的应用的关键。PSR-251标准为HTTP消息工厂提供了规范,本文将围绕这一标准,探讨如何在PHP中实现一个符合PSR-251的HTTP消息工厂。

关键词:PHP,PSR-251,HTTP消息工厂,请求,响应

一、

PSR-251(PHP Standard Recommendation: HTTP Message Factory)是PHP社区推出的一个标准,旨在提供一个统一的接口来创建HTTP请求和响应对象。遵循这一标准,可以确保不同HTTP客户端和服务器之间的兼容性和互操作性。

二、PSR-251标准概述

PSR-251定义了一个接口,该接口允许开发者创建HTTP请求和响应对象。这些对象应该包含所有必要的HTTP头部、主体和状态码等信息。以下是PSR-251标准中定义的主要接口和类:

1. `HttpFactoryInterface`:定义了创建HTTP请求和响应对象的接口。

2. `RequestInterface`:定义了HTTP请求对象的接口。

3. `ResponseInterface`:定义了HTTP响应对象的接口。

三、实现HTTP消息工厂

下面是一个简单的PHP实现,遵循PSR-251标准:

php

<?php

namespace HttpFactory;

use PsrHttpMessageRequestFactoryInterface;


use PsrHttpMessageRequestInterface;


use PsrHttpMessageResponseFactoryInterface;


use PsrHttpMessageResponseInterface;

class HttpFactory implements RequestFactoryInterface, ResponseFactoryInterface


{


public function createRequest(string $method, $uri): RequestInterface


{


return new Request($method, $uri);


}

public function createResponse(): ResponseInterface


{


return new Response();


}


}

class Request implements RequestInterface


{


private $method;


private $uri;


private $headers = [];


private $body = '';


private $version = '1.1';

public function __construct(string $method, $uri)


{


$this->method = $method;


$this->uri = $uri;


}

public function getMethod(): string


{


return $this->method;


}

public function getUri(): UriInterface


{


// 这里应该返回一个实现了UriInterface的对象


return new Uri($this->uri);


}

public function withMethod($method): RequestInterface


{


$new = clone $this;


$new->method = $method;


return $new;


}

public function withUri($uri, $preserveHost = false): RequestInterface


{


$new = clone $this;


$new->uri = $uri;


return $new;


}

public function getHeaders(): array


{


return $this->headers;


}

public function hasHeader(string $name): bool


{


return isset($this->headers[$name]);


}

public function getHeader(string $name): array


{


return $this->hasHeader($name) ? $this->headers[$name] : [];


}

public function withHeader(string $name, $value): RequestInterface


{


$new = clone $this;


$new->headers[$name] = $value;


return $new;


}

public function withAddedHeader(string $name, $value): RequestInterface


{


$new = clone $this;


$new->headers[$name] = $value;


return $new;


}

public function withoutHeader(string $name): RequestInterface


{


$new = clone $this;


unset($new->headers[$name]);


return $new;


}

public function getBody(): BodyInterface


{


return new Body($this->body);


}

public function withBody(BodyInterface $body): RequestInterface


{


$new = clone $this;


$new->body = $body;


return $new;


}

public function getProtocolVersion(): string


{


return $this->version;


}

public function withProtocolVersion($version): RequestInterface


{


$new = clone $this;


$new->version = $version;


return $new;


}


}

class Response implements ResponseInterface


{


private $statusCode = 200;


private $reasonPhrase = 'OK';


private $headers = [];


private $body = '';


private $version = '1.1';

public function getStatusCode(): int


{


return $this->statusCode;


}

public function getReasonPhrase(): string


{


return $this->reasonPhrase;


}

public function withStatus($code, $reasonPhrase = ''): ResponseInterface


{


$new = clone $this;


$new->statusCode = $code;


$new->reasonPhrase = $reasonPhrase;


return $new;


}

public function getHeaders(): array


{


return $this->headers;


}

public function hasHeader(string $name): bool


{


return isset($this->headers[$name]);


}

public function getHeader(string $name): array


{


return $this->hasHeader($name) ? $this->headers[$name] : [];


}

public function withHeader(string $name, $value): ResponseInterface


{


$new = clone $this;


$new->headers[$name] = $value;


return $new;


}

public function withAddedHeader(string $name, $value): ResponseInterface


{


$new = clone $this;


$new->headers[$name] = $value;


return $new;


}

public function withoutHeader(string $name): ResponseInterface


{


$new = clone $this;


unset($new->headers[$name]);


return $new;


}

public function getBody(): BodyInterface


{


return new Body($this->body);


}

public function withBody(BodyInterface $body): ResponseInterface


{


$new = clone $this;


$new->body = $body;


return $new;


}

public function getProtocolVersion(): string


{


return $this->version;


}

public function withProtocolVersion($version): ResponseInterface


{


$new = clone $this;


$new->version = $version;


return $new;


}


}

class Body implements BodyInterface


{


private $body;

public function __construct($body)


{


$this->body = $body;


}

public function getContents(): string


{


return $this->body;


}

public function getIterator(): Traversable


{


return new ArrayIterator((array) $this->body);


}

public function getStream(): StreamInterface


{


// 这里应该返回一个实现了StreamInterface的对象


return new Stream($this->body);


}

public function close(): void


{


// 这里可以添加关闭资源的逻辑


}


}

class Uri implements UriInterface


{


private $uri;

public function __construct($uri)


{


$this->uri = $uri;


}

// UriInterface的其他方法实现...


}

class Stream implements StreamInterface


{


private $stream;

public function __construct($stream)


{


$this->stream = $stream;


}

// StreamInterface的其他方法实现...


}

?>


四、使用HTTP消息工厂

在实现了HTTP消息工厂之后,我们可以使用它来创建请求和响应对象:

php

<?php

use HttpFactoryHttpFactory;

$factory = new HttpFactory();

$request = $factory->createRequest('GET', 'http://example.com');


$response = $factory->createResponse();

// 设置请求头部


$request = $request->withHeader('Host', 'example.com');

// 设置响应状态码和头部


$response = $response->withStatus(200)->withHeader('Content-Type', 'text/html');

// 设置响应主体


$response->getBody()->write('<html><body>Hello, World!</body></html>');

// 输出响应


echo $response->getBody()->getContents();

?>


五、总结

本文介绍了PSR-251标准,并实现了一个简单的PHP HTTP消息工厂。通过遵循这一标准,我们可以确保在不同PHP应用之间共享HTTP请求和响应对象,从而提高代码的可维护性和可扩展性。在实际开发中,可以根据需要扩展和优化HTTP消息工厂,以适应不同的业务需求。