承接 interitty/static-content-generator 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

interitty/static-content-generator

Composer 安装命令:

composer require interitty/static-content-generator

包简介

Static content generator persists application output for future use, saving time and money.

README 文档

README

Static content generator persists application output for future use, saving time and money.

Requirements

Installation

The best way to install interitty/static-content-generator is using Composer:

composer require interitty/static-content-generator

Then register the extension in the Nette config file:

# app/config/config.neon
extensions:
    staticContentGenerator: Interitty\StaticContentGenerator\Nette\DI\StaticContentGeneratorExtension

Settings

There are some more settings, you can need to fit your suit.

Neon parameterDescription
autoEndWhen processBegin was called, catch all relevant content into the storage automatically? The default value is "false"
autoStartCall processBegin before every request? The default value is "false"
basePathPrefix for all generated file paths in the processFileName helper. The default value is "/"
destinationDestination folder to write the generated static content. The default value is "%wwwDir%"
productionModeProduction mode suppresses a possible exception when writing to the read-only filesystem and creates a log entry
readOnlyFlag if the file system is in read-only mode. The default value null is used for autodetection by path in the destination parameter
writeFlagsUsed file_put_contents flags. The default value is "LOCK_EX"

Usage

For comfortable work with the Static content generator, there is a Nette DI extension, that registers all required services for future work. It also allows registering into the Nette lifecycle to automatically persist all relevant static content into the specified folder.

Example: catch all relevant static content automatically

This configuration catches all the responses with HTTP status 200: OK that is allowed to be cached (it means, that HTTP header Cache-Control or Pragma does not contain "no-cache" or "no-store" value).

extensions:
    staticContentGenerator: Interitty\StaticContentGenerator\Nette\DI\StaticContentGeneratorExtension

staticContentGenerator:
    autoStart: true
    destination: %wwwDir%

Example: catch specific static content automatically

There can be many cases, where it could be useful to set up, which Presenter:action should be stored. For this occasion, there is autoEnd parameter, which means to catch all relevant responses every time the processBegin was called manually.

extensions:
    staticContentGenerator: Interitty\StaticContentGenerator\Nette\DI\StaticContentGeneratorExtension

staticContentGenerator:
    autoStart: false # Default behavior
    autoEnd: true

The processBegin was not called automatically, because the autoStart parameter is false by default. It allows having any sophisticated condition, to specify, which page should be persisted

class CmdPresenter extends \Nette\Application\UI\Presenter
{
    /** @var \Interitty\StaticContentGenerator\StaticContentGenerator @inject */
    protected $generator;

    public function actionDefault($page)
    {
        if($page !== 'Admin') {
            $this->staticContentGenerator->processBegin();
        }
    }
}

Partial usage

The StaticContentGenerator class can simply catch the output content and persist them into the given storage. Thanks to the FlySystem, the generator can store almost anywhere locally, on remote FTP, or cloud storage like AWS S3 or Azure. Because of a need to persist more files with their contents at once, like in the cache warmup process, each part is separated by the StaticContentHandler class.

Example: catch content into the file by the StaticContentHandler

The following example catches any content that was sent to the output and stores them in the file specified by the given $filename variable. Because the optional parameter $muteOutput is specified as false, everything will be also sent to the output or another registered Output buffer handler.

// Flysystem setup
$destination = sys_get_temp_dir();
$adapter = new \League\Flysystem\Adapter\Local($destination);
$filesystem = new \League\Flysystem\Filesystem($adapter);

// OutputBufferManager setup
$outputBufferManager = new \Interitty\OutputBufferManager\OutputBufferManager();

$filename = 'data.txt';
$muteOutput = false;
$storage = new \Interitty\StaticContentGenerator\Storage\FilesystemStorage($filesystem);
$handler = new \Interitty\StaticContentGenerator\Handler\StaticContentHandler($storage, $filename, $muteOutput);
$outputBufferManager->begin('…', [$handler, 'processManageOutput']);
$handler->processBegin();

// Any content that was sent to the output
echo 'testContent';

$outputBufferManager->end('…');
$handler->processEnd();

Example: cache warmup by the StaticContentGenerator

The following example simulates the cache warmup process, which catches any content that was sent to the output and stores them into the files specified by the given $filename variable. Because the optional parameter $muteOutput is specified as true, nothing will be sent to the output or another registered Output buffer handler.

// Test data
$testData = [
    'test1.txt' => 'Test 1',
    'test2.txt' => 'Test 2',
];

// Flysystem setup
$destination = __DIR__;
$adapter = new \League\Flysystem\Adapter\Local($destination);
$filesystem = new \League\Flysystem\Filesystem($adapter);

// OutputBufferManager setup
$muteOutput = true;
$outputBufferManager = new \Interitty\OutputBufferManager\OutputBufferManager();
$storage = new \Interitty\StaticContentGenerator\Storage\FilesystemStorage($filesystem);
$generator = new \Interitty\StaticContentGenerator\StaticContentGenerator($outputBufferManager, $storage);

foreach ($testData as $filename => $content) {
    $handler = $generator->createHandler($filename, $muteOutput);
    $generator->setHandler($handler);
    $generator->processBegin();

    // Any content that was sent to the output
    echo $content;

    $generator->processEnd();
}

Example: cache warmup from a list of URLs

The cache warmup process is mostly based on the list of URLs. Because of that, the StaticContentGenerator contains the processFileName() helper method that detects the sdestination filename from the path part of the given URL.

// Test data
$testData = [
    '/' => 'Index test',
    '/test.html' => 'Test',
    '/test' => 'Subfolder test',
];

// Flysystem setup
$destination = __DIR__;
$adapter = new \League\Flysystem\Adapter\Local($destination);
$filesystem = new \League\Flysystem\Filesystem($adapter);

// OutputBufferManager setup
$muteOutput = true;
$outputBufferManager = new \Interitty\OutputBufferManager\OutputBufferManager();
$storage = new \Interitty\StaticContentGenerator\Storage\FilesystemStorage($filesystem);
$generator = new \Interitty\StaticContentGenerator\StaticContentGenerator($outputBufferManager, $storage);

foreach ($testData as $path => $content) {
    $filename = $generator->processFileName($path);
    $handler = $generator->createHandler($filename, $muteOutput);
    $generator->setHandler($handler);
    $generator->processBegin();

    // Any content that was sent to the output
    echo $content;

    $generator->processEnd();
}

Example: catch Request/Response content into a file by the MiddlewareStaticContentGenerator

It can be useful to catch the content of the HTTP response for the incoming request.

// Request/Response setup
$url = 'http://localhost/';
$urlScript = new \Nette\Http\UrlScript($url);
$request = new \Nette\Http\Request($urlScript);
$response = new \Nette\Http\Response();
$response->setCode(\Nette\Http\IResponse::S200_OK);

// Flysystem setup
$destination = __DIR__;
$adapter = new \League\Flysystem\Adapter\Local($destination);
$filesystem = new \League\Flysystem\Filesystem($adapter);

// OutputBufferManager setup
$outputBufferManager = new \Interitty\OutputBufferManager\OutputBufferManager();
$storage = new \Interitty\StaticContentGenerator\Storage\FilesystemStorage($filesystem);
$generator = new \Interitty\StaticContentGenerator\Nette\MiddlewareStaticContentGenerator($request, $response, $outputBufferManager, $storage);
$generator->processBegin();

// Any content that was sent to the output
echo 'testContent';

$generator->processEnd();

Read-only filesystem (Docker support)

If the application is packaged in a docker container, it is advisable to run it in read-only mode in the production environment.

In this mode, all static assets should already be pre-generated and used by the web server (apache, nginx, …), which should result in the PHP application not being called at all. So if it does get called, it can be considered a deficiency and is logged as such.

By default, this mode is automatically detected based on the folder permissions specified by the destination parameter combined with the productionMode flag. In a development environment, the read-only mode does not make much sense, but if it is still active, the exception is not caught to resolve the situation as soon as possible. Both of these parameters can be adjusted in the configuration

extensions:
    staticContentGenerator: Interitty\StaticContentGenerator\Nette\DI\StaticContentGeneratorExtension

staticContentGenerator:
    productionMode: %productionMode% # Default behavior
    readOnly: null # Default behavior

interitty/static-content-generator 适用场景与选型建议

interitty/static-content-generator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 03 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「cache」 「static」 「nette」 「interitty」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

围绕 interitty/static-content-generator 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-03-26