Installation:
composer require hyperf/http-message
Ensure your composer.json includes "hyperf/hyperf": "^3.0" as a dependency, as this package is part of the Hyperf ecosystem.
First Use Case:
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpMessage\Uri;
use Hyperf\HttpMessage\RequestMessage;
use Hyperf\HttpMessage\ResponseMessage;
// Create a request
$request = new RequestMessage(
'GET',
new Uri('https://example.com/api'),
['Host' => 'example.com']
);
// Create a response
$response = new ResponseMessage(200, ['Content-Type' => 'application/json']);
$response->getBody()->write(json_encode(['success' => true]));
Key Classes to Explore:
RequestMessage: For handling incoming HTTP requests.ResponseMessage: For constructing HTTP responses.Stream\SwooleStream: For stream operations (Swoole-specific).Uri: For URI manipulation.$request = new RequestMessage(
$method,
new Uri($uri),
$headers,
$body ?? null
);
$method = $request->getMethod(); // GET, POST, etc.
$uri = $request->getUri();
$headers = $request->getHeaders();
$body = $request->getBody()->__toString();
Uri to parse query strings or path segments:
$uri = new Uri('/users/{id}?sort=name');
$pathSegments = $uri->getPathSegments(); // ['users', '{id}']
$queryParams = $uri->getQueryParams(); // ['sort' => 'name']
$response = new ResponseMessage(200, ['X-Custom-Header' => 'value']);
$response->getBody()->write(json_encode(['data' => 'value']));
$response->withCookie(new Cookie('token', 'abc123', 3600));
$response->withHeader('Location', '/new-path')->setStatusCode(302);
$stream = new SwooleStream(fopen('file.txt', 'r'));
$request->getBody()->rewind();
$request->getBody()->pipeTo($stream); // Stream upload to file
class LogMiddleware
{
public function __invoke(RequestMessage $request, callable $next)
{
logger()->info('Request:', [
'method' => $request->getMethod(),
'uri' => $request->getUri()->__toString(),
]);
return $next($request);
}
}
Register in config/middleware.php:
return [
\App\Middleware\LogMiddleware::class,
];
use Hyperf\HttpServer\Request;
use Hyperf\HttpServer\Response;
$request = Request::capture();
$response = new Response();
$response->json(['message' => 'Hello, Hyperf!']);
$response->send();
Stream Detachment:
SwooleStream) must be detached before being passed to non-Swoole contexts (e.g., logging, storage):
$stream = $request->getBody();
$detachedStream = $stream->detach(); // Critical for non-Swoole operations
file_put_contents('log.txt', $detachedStream);
Header Case Sensitivity:
getHeaderLine() for exact matches:
$request->hasHeader('content-type'); // Case-insensitive
$request->getHeaderLine('Content-Type'); // Exact match
URI Parsing Quirks:
Uri::withQuery() overwrites existing queries. Use Uri::withAddedQuery() to append:
$uri = (new Uri('/users'))->withAddedQuery('sort', 'name');
Body Consumption:
$body = $request->getBody();
$body->rewind(); // Reset stream pointer
$content = $body->__toString();
Inspect Headers/Body:
logger()->debug('Request Headers:', $request->getHeaders());
logger()->debug('Request Body:', $request->getBody()->__toString());
Validate Responses:
ResponseMessage::toPsrResponse() to convert to PSR-7 for compatibility checks:
$psrResponse = $response->toPsrResponse();
$status = $psrResponse->getStatusCode();
Swoole-Specific Issues:
fclose in PHP).Custom Stream Adapters:
Psr\Http\Message\StreamInterface for non-Swoole streams (e.g., Symfony streams):
class SymfonyStream implements StreamInterface
{
private $symfonyStream;
public function __construct(\Symfony\Component\HttpFoundation\StreamedResponse $stream)
{
$this->symfonyStream = $stream->getStream();
}
// Implement StreamInterface methods...
}
Middleware Decorators:
RequestMessage/ResponseMessage to add cross-cutting concerns:
class AuthMiddleware
{
public function __invoke(RequestMessage $request, callable $next)
{
if (!$request->hasHeader('authorization')) {
throw new \RuntimeException('Unauthorized');
}
return $next($request);
}
}
PSR-7 Interoperability:
Hyperf\HttpMessage\Psr7\Psr7Request/Psr7Response for PSR-7 compatibility:
$psrRequest = new Psr7Request($request);
$psrResponse = new Psr7Response($response);
Performance Optimization:
RequestMessage/ResponseMessage objects where possible to avoid overhead:
$requestPool = new ObjectPool(
fn() => new RequestMessage('GET', new Uri('/')),
fn(RequestMessage $request) => $request->getBody()->rewind()
);
Default Headers:
Server, Date). Override in config/http.php:
return [
'default_headers' => [
'X-Powered-By' => ['hyperf', 'http-message'],
],
];
Stream Buffers:
$stream = new SwooleStream(fopen('file.txt', 'r'), false); // Disable buffering
How can I help you explore Laravel packages today?