PivotPHP Core provides a complete PSR-7 compliant HTTP message implementation with high-performance optimizations.
- ServerRequest: Server-side HTTP request representation
- Request: Client-side HTTP request
- Response: HTTP response with fluent interface
- Stream: Efficient stream handling for message bodies
- Uri: URI manipulation and parsing
- UploadedFile: File upload handling
- Full PSR-7 Compliance: Implements all PSR-7 interfaces
- Performance Optimized: Object pooling, header caching
- Memory Efficient: Lazy loading, stream management
- Type Safe: PHPStan Level 9 compliance
PivotPHP Core v1.0.1 uses PSR-7 v2.0 interfaces but allows installation with both v1.x and v2.x. See PSR-7 Version Compatibility for details.
use PivotPHP\Core\Http\Psr7\ServerRequest;
use PivotPHP\Core\Http\Psr7\Stream;
// From globals
$request = ServerRequest::fromGlobals();
// Manual creation
$request = new ServerRequest(
'POST',
'/api/users',
Stream::createFromString('{"name":"John"}'),
['Content-Type' => ['application/json']]
);use PivotPHP\Core\Http\Psr7\Response;
// JSON response
$response = new Response();
$response = $response
->withStatus(200)
->withHeader('Content-Type', 'application/json')
->withBody(Stream::createFromString('{"status":"ok"}'));
// Using factory methods (if available)
$response = Response::json(['status' => 'ok']);use PivotPHP\Core\Http\Psr7\Stream;
// From string
$stream = Stream::createFromString('Hello World');
// From file
$stream = Stream::createFromFile('/path/to/file.txt');
// Operations
$content = $stream->getContents();
$stream->rewind();
$stream->write('Additional content');PivotPHP Core uses object pools for frequently created objects:
- Header value arrays
- Stream instances
- Small response objects
Headers are normalized and cached to avoid repeated string operations:
// Efficient header handling
$response = $response
->withHeader('X-Custom', 'value1')
->withAddedHeader('X-Custom', 'value2');-
Immutability: All PSR-7 objects are immutable. Use the returned instance:
// Correct $response = $response->withStatus(404); // Incorrect (original unchanged) $response->withStatus(404);
-
Stream Reuse: When possible, reuse stream instances:
$stream = Stream::createFromString(''); foreach ($data as $chunk) { $stream->write($chunk); }
-
Header Validation: Use built-in validation for security:
// Validates header name and values $response = $response->withHeaderStrict('X-Custom', $value);
PivotPHP's HTTP components work seamlessly with PSR-15 middleware:
class CustomMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
// Modify request
$request = $request->withAttribute('custom', 'value');
// Process
$response = $handler->handle($request);
// Modify response
return $response->withHeader('X-Processed', 'true');
}
}class EncryptedStream extends Stream
{
protected function write(string $string): int
{
$encrypted = encrypt($string);
return parent::write($encrypted);
}
public function getContents(): string
{
$contents = parent::getContents();
return decrypt($contents);
}
}// Store route parameters
$request = $request->withAttribute('route.params', [
'controller' => 'UserController',
'action' => 'show',
'id' => 123
]);
// Retrieve in controller
$params = $request->getAttribute('route.params', []);use PHPUnit\Framework\TestCase;
use PivotPHP\Core\Http\Psr7\ServerRequest;
use PivotPHP\Core\Http\Psr7\Response;
class HttpTest extends TestCase
{
public function testRequest(): void
{
$request = new ServerRequest('GET', '/test');
$this->assertEquals('GET', $request->getMethod());
$this->assertEquals('/test', $request->getUri()->getPath());
}
public function testResponse(): void
{
$response = (new Response())
->withStatus(201)
->withHeader('Location', '/resource/123');
$this->assertEquals(201, $response->getStatusCode());
$this->assertEquals('/resource/123', $response->getHeaderLine('Location'));
}
}