Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.3",
"maglnet/composer-require-checker": "^4.7.1",
"phpbench/phpbench": "^1.4.3",
"phpunit/phpunit": "^10.5.48",
"rector/rector": "^2.1.2",
"spatie/phpunit-watcher": "^1.24",
Expand Down Expand Up @@ -82,6 +83,7 @@
},
"scripts": {
"test": "phpunit --testdox --no-interaction",
"test-watch": "phpunit-watcher watch"
"test-watch": "phpunit-watcher watch",
"bench": "phpbench run"
}
}
18 changes: 18 additions & 0 deletions docs/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,21 @@ all dependencies are correctly defined in `composer.json`. To run the checker, e
```shell
./vendor/bin/composer-require-checker
```

## Benchmarks

The package provides performance benchmarks for the main use-cases, implemented with [phpbench](https://phpbench.readthedocs.io/).

Benchmarks are located in `tests/Benchmark` and configured via `phpbench.json`.

To run the benchmarks:

```shell
./vendor/bin/phpbench run
```

Or via Composer script:

```shell
composer bench
```
7 changes: 7 additions & 0 deletions phpbench.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"runner.bootstrap": "vendor/autoload.php",
"runner.path": "tests/Benchmark",
"runner.revs": 1000,
"runner.iterations": 10,
"runner.retry_threshold": 2
}
74 changes: 74 additions & 0 deletions tests/Benchmark/BlocksBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Files\FileHelper;
use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\View;

final class BlocksBench
{
private readonly View $view;

public function __construct()
{
$basePath = __DIR__ . '/../public/tmp/blocks-bench';
FileHelper::ensureDirectory($basePath);

$contentView = $basePath . '/content.php';
if (!is_file($contentView)) {
file_put_contents(
$contentView,
<<<'PHP'
<?php

declare(strict_types=1);

/** @var \Yiisoft\View\View $this */

$this->setBlock('block-id-1', '...content of block1...');
$this->setBlock('block-id-2', '...content of block2...');
PHP
);
}

$layoutView = $basePath . '/layout.php';
if (!is_file($layoutView)) {
file_put_contents(
$layoutView,
<<<'PHP'
<?php

declare(strict_types=1);

/** @var \Yiisoft\View\View $this */
?>
<?php if ($this->hasBlock('block-id-1')): ?>
<?= $this->getBlock('block-id-1') ?>
<?php else: ?>
... default content for block1 ...
<?php endif; ?>

<?php if ($this->hasBlock('block-id-2')): ?>
<?= $this->getBlock('block-id-2') ?>
<?php else: ?>
... default content for block2 ...
<?php endif; ?>
PHP
);
}

$this->view = new View($basePath, new SimpleEventDispatcher());
}

public function benchRenderBlocksWithTemplates(): void
{
// Render content view to define blocks.
$this->view->render('content');

// Render layout view which reads the defined blocks.
$this->view->render('layout');
}
}
79 changes: 79 additions & 0 deletions tests/Benchmark/MultiRendererBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Files\FileHelper;
use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\TemplateRendererInterface;
use Yiisoft\View\View;
use Yiisoft\View\ViewInterface;

final class MultiRendererBench
{
private readonly View $view;

public function __construct()
{
$basePath = __DIR__ . '/../public/tmp/multi-renderer-bench';
FileHelper::ensureDirectory($basePath);

$phpView = $basePath . '/view.php';
if (!is_file($phpView)) {
file_put_contents(
$phpView,
<<<'PHP_WRAP'
<?php

declare(strict_types=1);

/** @var \Yiisoft\View\View $this */

echo 'PHP view';
PHP_WRAP
Comment on lines +27 to +34

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heredoc content has inconsistent leading whitespace. Lines 28-33 have excessive leading spaces that will be included in the file content, which may not be intended.

Suggested change
<?php
declare(strict_types=1);
/** @var \Yiisoft\View\View $this */
echo 'PHP view';
PHP_WRAP
<?php
declare(strict_types=1);
/** @var \Yiisoft\View\View $this */
echo 'PHP view';
PHP_WRAP

Copilot uses AI. Check for mistakes.
);
}

$bladeView = $basePath . '/view.blade.php';
if (!is_file($bladeView)) {
file_put_contents($bladeView, 'Blade view');
}

$tplView = $basePath . '/view.tpl';
if (!is_file($tplView)) {
file_put_contents($tplView, 'TPL view');
}

$this->view = (new View($basePath, new SimpleEventDispatcher()))
->withRenderers([
'blade' => new class () implements TemplateRendererInterface {
public function render(ViewInterface $view, string $template, array $parameters): string
{
return file_get_contents($template);
}
},
'tpl' => new class () implements TemplateRendererInterface {
public function render(ViewInterface $view, string $template, array $parameters): string
{
return file_get_contents($template);
}
},
]);
}

public function benchRenderPhpView(): void
{
$this->view->render('view');
}

public function benchRenderBladeView(): void
{
$this->view->render('view.blade.php');
}

public function benchRenderTplView(): void
{
$this->view->render('view.tpl');
}
}
51 changes: 51 additions & 0 deletions tests/Benchmark/NestedViewsBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Files\FileHelper;
use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\View;

final class NestedViewsBench
{
private readonly View $view;

public function __construct()
{
$basePath = __DIR__ . '/../public/tmp/nested-bench';
FileHelper::ensureDirectory($basePath);

$baseView = $basePath . '/base.php';
$subDir = $basePath . '/sub';
FileHelper::ensureDirectory($subDir);

if (!is_file($baseView)) {
file_put_contents(
$baseView,
<<<'PHP'
<?php

declare(strict_types=1);

/** @var \Yiisoft\View\View $this */

echo $this->render('./sub/sub');
PHP
);
}

$subView = $subDir . '/sub.php';
if (!is_file($subView)) {
file_put_contents($subView, 'nested-view-content');
}

$this->view = new View($basePath, new SimpleEventDispatcher());
}

public function benchRenderNestedView(): void
{
$this->view->render('base');
}
}
25 changes: 25 additions & 0 deletions tests/Benchmark/ViewBasicBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\View;

final class ViewBasicBench
{
private readonly View $view;

public function __construct()
{
$this->view = new View(__DIR__ . '/../public/view', new SimpleEventDispatcher());
}

public function benchRenderSimpleView(): void
{
$this->view->render('only-content', [
'content' => 'benchmark',
]);
}
}
32 changes: 32 additions & 0 deletions tests/Benchmark/ViewLocaleBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Files\FileHelper;
use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\View;

final class ViewLocaleBench
{
private readonly View $view;

public function __construct()
{
$basePath = __DIR__ . '/../public/tmp/locale-bench';

FileHelper::ensureDirectory($basePath . '/es');

file_put_contents($basePath . '/file.php', 'test en render');
file_put_contents($basePath . '/es/file.php', 'test es render');

$this->view = new View($basePath, new SimpleEventDispatcher());
$this->view->setLocale('es');
}

public function benchRenderLocalizedView(): void
{
$this->view->render('file');
}
}
44 changes: 44 additions & 0 deletions tests/Benchmark/ViewThemeBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Yiisoft\View\Tests\Benchmark;

use Yiisoft\Test\Support\EventDispatcher\SimpleEventDispatcher;
use Yiisoft\View\Theme;
use Yiisoft\View\View;

final class ViewThemeBench
{
private readonly View $view;

public function __construct()
{
$basePath = __DIR__ . '/../public/view';
$themePath = __DIR__ . '/../public/tmp/theme-basic/views';

@mkdir($themePath, 0777, true);

// ensure themed file exists
$sourceFile = $basePath . '/only-content.php';
$themedFileDir = dirname($themePath . '/only-content.php');
@mkdir($themedFileDir, 0777, true);
if (is_file($sourceFile) && !is_file($themePath . '/only-content.php')) {
copy($sourceFile, $themePath . '/only-content.php');
}

$theme = new Theme([
$basePath => $themePath,
]);

$this->view = new View($basePath, new SimpleEventDispatcher());
$this->view->setTheme($theme);
}

public function benchRenderThemedView(): void
{
$this->view->render('only-content', [
'content' => 'benchmark',
]);
}
}
Loading
Loading