定制 joby/smol-response 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

joby/smol-response

Composer 安装命令:

composer require joby/smol-response

包简介

A straightforward abstraction layer for building and rendering HTTP responses.

README 文档

README

A straightforward, type-safe HTTP response builder for PHP. Build and send HTTP responses with proper headers, cache control, content types, and status codes. Designed to minimize footguns, maximize productivity, and provide useful hinting and IntelliSense features in your IDE.

Features:

  • Type-safe response building with fluent interfaces
  • First-class cache control headers
  • Automatic content type detection and charset handling
  • Range request support for efficient streaming
  • Built-in content types: strings, JSON, files, callbacks, and empty responses
  • Requires PHP 8.4+

Installation

composer require joby/smol-response

Quick Start

use Joby\Smol\Response\Response;

// Simple text response
$response = new Response(200, 'Hello World');

// JSON response
$response = Response::json(['status' => 'ok', 'data' => $results]);

// File download
$response = Response::file('/path/to/file.pdf');

// Redirect
$response = Response::redirect('https://example.com', permanent: true);

// Render the response
$renderer = new \Joby\Smol\Response\Renderer();
$renderer->render($response);

Core Components

Response (Response)

The main response builder. Create responses with various content types and configurations.

Factory Methods:

  • json($data, $status = 200) - Create JSON response
  • file($path, $status = 200) - Create file response
  • redirect($url, $permanent = false, $preserve_method = false) - Create redirect response

Fluent Methods:

$response = (new Response(201, 'Created'))
    ->cachePublicContent()
    ->setStatus(200);

Status (Status)

Type-safe HTTP status codes with standard reason phrases:

$status = new Status(404);
echo $status->code;           // 404
echo $status->reason_phrase;  // "Not Found"

Cache Control (CacheControl)

First-class cache control with support for modern caching strategies:

Presets:

  • publicContent($max_age = 300, $max_stale_age = 86400) - Public HTML pages
  • publicMedia($max_age = 31536000, $max_stale_age = 31536000) - Public static assets
  • privateContent($max_age = 300, $max_stale_age = 600) - Private HTML pages
  • privateMedia($max_age = 31536000, $max_stale_age = 31536000) - Private static assets
  • neverCached() - No caching (CSRF forms, CAPTCHAs)
$response->cache = CacheControl::publicMedia();
// Renders: public, max-age=31536000, s-maxage=31536000, 
//          stale-while-revalidate=31536000, stale-if-error=31536000

$response->cachePublicContent(); // Fluent helper method

Headers (Headers)

Normalized header collection with automatic header name formatting:

$response->headers['content-type'] = 'application/json';
$response->headers['X-Custom-Header'] = 'value';

// Headers are automatically normalized to proper case
foreach ($response->headers as $name => $value) {
    echo "$name: $value\n";
    // Content-Type: application/json
    // X-Custom-Header: value
}

Content Types

All content types implement ContentInterface with automatic metadata handling.

StringContent

For text and HTML content:

// With optional filename parameter (defaults to 'page.html')
$content = new StringContent('<h1>Hello World</h1>', 'custom.html');
$response->content = $content;

// Or set filename separately
$content = new StringContent('<h1>Hello World</h1>');
$content->setFilename('page.html');
$response->content = $content;

CallbackContent

For dynamic content generation with callbacks:

// Simple callback with optional filename parameter (defaults to 'page.html')
$content = new CallbackContent(function() {
    echo renderTemplate('page.html', ['title' => 'Welcome']);
}, 'welcome.html');

// With external data
$data = fetchDataFromDatabase();
$content = new CallbackContent(function() use ($data) {
    foreach ($data as $item) {
        echo "<li>{$item->name}</li>";
    }
});

// Supports any callable type
$content = new CallbackContent([$templateEngine, 'render'], 'output.html');
$response->content = $content;

JsonContent

For JSON responses:

$content = new JsonContent(['status' => 'ok', 'items' => $items]);
$response->content = $content;

FileContent

For serving files with automatic MIME detection:

// Filename defaults to basename of the file path
$content = new FileContent('/path/to/file.pdf');
$response->content = $content;

// Or override with custom filename
$content = new FileContent('/path/to/file.pdf', 'document.pdf');
$response->content = $content;

EmptyContent

For responses with no body:

$response = new Response(204, new EmptyContent());

Advanced Features

Range Requests

Efficiently serve partial content for video streaming and resumable downloads:

// Content automatically supports range requests
$content = new FileContent('/path/to/video.mp4');

// Apply a range manually
$ranged = new AppliedRangeContent($content, 0, 1024);
$response->content = $ranged;

// Renderer automatically sets 206 status and Content-Range header

Custom Content Types

Create your own content types by implementing ContentInterface or extending AbstractContent:

class TemplateContent extends AbstractContent
{
    public function __construct(private string $template, private array $data) {
        $this->filename = 'page.html';
    }
    
    public function render(): void {
        echo $this->engine->render($this->template, $this->data);
    }
    
    public function size(): int|null {
        return null; // Unknown until rendered
    }
}

Response Rendering

The Renderer handles all HTTP output:

$renderer = new Renderer();
$renderer->render($response);

// Or test header generation without sending
$headers = $renderer->buildHeaders($response);

Automatic Header Generation:

  • Content-Type with charset for text content
  • Content-Length for known-size content
  • Content-Disposition with filename for downloads
  • Etag from content hashes
  • Last-Modified from file modification times
  • Accept-Ranges for range-capable content
  • Content-Range for partial content responses

Fluent Response Building

Chain methods for readable response construction:

$response = Response::json($data)
    ->setStatus(201)
    ->cachePublicContent();

$response->headers['Location'] = '/api/resource/123';

Content Metadata

All content types provide rich metadata:

echo $content->filename();       // 'document.pdf'
echo $content->mime();           // 'application/pdf'
echo $content->contentType();    // 'application/pdf'
echo $content->size();           // File size in bytes
echo $content->etag();           // MD5 hash for caching
echo $content->lastModified();   // DateTime of last modification

Use Cases

Static File Router

Build a simple static file server with aggressive caching:

$path = '/var/www/public' . $_SERVER['REQUEST_URI'];

if (file_exists($path)) {
    $response = Response::file($path)->cachePublicMedia();
    (new Renderer())->render($response);
}

API Responses

Consistent JSON API responses:

function apiSuccess($data, $code = 200) {
    return Response::json(['success' => true, 'data' => $data], $code)
        ->cacheNever();
}

function apiError($message, $code = 400) {
    return Response::json(['success' => false, 'error' => $message], $code)
        ->cacheNever();
}

Content Transformations

Transform content before serving:

$djot = file_get_contents('content.djot');
$html = renderDjotToHtml($djot);

$response = (new Response(200, $html))
    ->cachePublicContent();

$response->headers['Content-Type'] = 'text/html; charset=UTF-8';

Dynamic Content Generation

Use callbacks for complex rendering logic:

// Template rendering with caching
$response = new Response(200, new CallbackContent(function() use ($templateEngine, $data) {
    echo $templateEngine->render('dashboard.html', $data);
}));
$response->cachePublicContent();

// Streaming output
$response = new Response(200, new CallbackContent(function() {
    foreach (generateLargeDataset() as $chunk) {
        echo json_encode($chunk) . "\n";
    }
}));

Requirements

Fully tested on PHP 8.3+, static analysis for PHP 8.1+.

License

MIT License - See LICENSE file for details.

joby/smol-response 适用场景与选型建议

joby/smol-response 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 383 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 07 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 joby/smol-response 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 joby/smol-response 我们能提供哪些服务?
定制开发 / 二次开发

基于 joby/smol-response 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 383
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 24
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-07