interitty/static-content-generator

静态内容生成器将应用输出持久化以便将来使用,节省时间和金钱。

v1.0.5 2024-09-01 12:01 UTC

This package is auto-updated.

Last update: 2024-09-01 10:04:10 UTC


README

静态内容生成器将应用输出持久化以便将来使用,节省时间和金钱。

要求

安装

安装 interitty/static-content-generator 的最佳方式是使用 Composer

composer require interitty/static-content-generator

然后在 Nette 配置 文件中注册扩展

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

设置

还有一些其他设置,您可能需要根据需要进行调整。

Neon 参数描述
autoEnd当调用 processBegin 时,是否自动将所有相关内容捕获到存储中?默认值是 "false"
autoStart在每个请求之前调用 processBegin?默认值是 "false"
basePathprocessFileName 助手中所有生成的文件路径的前缀。默认值是 "/"
destination写入生成的静态内容的目标文件夹。默认值是 "%wwwDir%"
productionMode生产模式抑制写入只读文件系统时的可能异常,并创建日志条目
readOnly标志文件系统是否处于只读模式。默认值 null 用于通过 destination 参数中的路径自动检测
writeFlags使用 file_put_contents 标志。默认值是 "LOCK_EX"

使用方法

为了方便使用 静态内容生成器,有一个 Nette DI 扩展,该扩展注册了所有必需的服务以供将来使用。它还允许注册到 Nette 生命周期中,以自动将所有相关静态内容持久化到指定的文件夹。

示例:自动捕获所有相关静态内容

此配置捕获所有具有 HTTP 状态 200: OK 的响应,允许缓存 (这意味着 HTTP 标头 Cache-ControlPragma 不包含 "no-cache" 或 "no-store" 值)

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

staticContentGenerator:
    autoStart: true
    destination: %wwwDir%

示例:自动捕获特定静态内容

有许多情况下,可能需要设置应存储哪个 Presenter:action。为此,有一个 autoEnd 参数,表示每次手动调用 processBegin 时都捕获所有相关响应。

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

staticContentGenerator:
    autoStart: false # Default behavior
    autoEnd: true

processBegin 没有自动调用,因为默认情况下 autoStart 参数为 false。这允许有任何复杂的条件,以指定应持久化哪个页面

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

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

部分使用

StaticContentGenerator 类可以简单地捕获输出内容,并将它们持久化到指定的存储中。多亏了 FlySystem,生成器可以存储在几乎所有地方 本地、远程 FTP 或云存储,如 AWS S3Azure。由于需要一次性持久化更多文件及其内容,如缓存预热过程中,每个部分都由 StaticContentHandler 类分开。

示例:通过 StaticContentHandler 将内容捕获到文件中

以下示例捕获所有发送到输出的内容,并将它们存储在由给定 $filename 变量指定的文件中。因为可选参数 $muteOutput 被指定为 false,所以所有内容也将被发送到输出或另一个已注册的 输出缓冲区 处理器。

// 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();

示例:通过 StaticContentGenerator 进行缓存预热

以下示例模拟缓存预热过程,捕获所有发送到输出的内容,并将它们存储到由给定 $filename 变量指定的文件中。因为可选参数 $muteOutput 被指定为 true,所以将不会将任何内容发送到输出或另一个已注册的 输出缓冲区 处理器。

// 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();
}

示例:从URL列表中进行缓存预热

缓存预热过程主要基于URL列表。因此,StaticContentGenerator 包含一个名为 processFileName() 的辅助方法,用于从给定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();
}

示例:通过 MiddlewareStaticContentGenerator 将请求/响应内容捕获到文件中

捕获传入请求的HTTP响应内容可能很有用。

// Request/Response setup
$url = 'https:///';
$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();

只读文件系统(Docker支持)

如果应用程序打包在 docker 容器中,建议在生产环境中以 只读 模式运行。

在此模式下,所有静态资产应已由Web服务器(apachenginx等)预先生成和使用,这应导致PHP应用程序根本不会被调用。因此,如果它确实被调用,则可以将其视为缺陷,并记录为此类。

默认情况下,此模式会根据由 destination 参数指定的文件夹权限和 productionMode 标志自动检测。在开发环境中,只读模式没有太多意义,但如果它仍然处于活动状态,异常不会被捕获以尽快解决这种情况。这两个参数都可以在配置中调整。

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

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