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
- PHP >= 8.5
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 parameter | Description |
|---|---|
autoEnd | When processBegin was called, catch all relevant content into the storage automatically? The default value is "false" |
autoStart | Call processBegin before every request? The default value is "false" |
basePath | Prefix for all generated file paths in the processFileName helper. The default value is "/" |
destination | Destination folder to write the generated static content. The default value is "%wwwDir%" |
productionMode | Production mode suppresses a possible exception when writing to the read-only filesystem and creates a log entry |
readOnly | Flag if the file system is in read-only mode. The default value null is used for autodetection by path in the destination parameter |
writeFlags | Used 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 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 interitty/static-content-generator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
repository php library
Bookdown.io With Bootswatch Styles And Prism Syntax Highlighting
TwigStan is a static analyzer for Twig templates powered by PHPStan
Laravel 5 - Repositories to the database layer
Nette Framework adapter for I18n package
Build forms from schema
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 17
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-03-26